Это довольно странный кусок кода, но это то, что он делает:
вы определяете метод с именем method
специальный метод super
означает вызов метода с тем же именем в родительском (супер) классе.
вы берете результат super
, который должен быть «перечисляемым» объектом, таким как массив или хэш, и вызываете select
для этого объекта
select
проходит через перечислимый объект (предположим, что это массив) и вызывает блок с каждым элементом. Обычно он используется для фильтрации (или выбора) некоторых объектов из массива. Каждый раз, когда блок вызывается, он возвращает истинное или ложное значение. Если правда, то этот элемент сохраняется в результирующем массиве. Если фальсифицировано, его выбрасывают.
Хорошо, так что каждый элемент этого массива будет выполнять это на нем:
a.meets_condition? || true
, что странно, потому что это вызовет meets_condition?
для элемента массива, и если он возвращает истинное значение, то этот элемент (a) сохраняется в массиве.
но что, если a.meets_condition?
является ложью?
Затем мы переходим к следующей части or
(двойные трубы) и делаем это.
Что возвращает true.
Таким образом, в основном это выражение будет возвращать копию массива, который вы передали.
Давайте превратим пример в настоящий рабочий пример:
class RandomDigit
# gives you a object containing a random digit between 0 and 9
def initialize
@n = rand(10)
end
def meets_condition? # returns true if @n is even
@n % 2 == 0
end
end
class TheParentClass
def method
# returns array of 4 random digits (between 0 and 9)
[RandomDigit.new, RandomDigit.new, RandomDigit.new, RandomDigit.new]
end
end
class TheChildClass < TheParentClass
def method
# super means we are calling TheParentClass.method
# select will try each element of the the array
# and builds a new array, with elements that returned true
# but the trouble is || true means its always going to return true
super.select { |a| a.meets_condition? || true }
end
end
puts TheChildClass.new.method # -> returns 4 random digits
Вы можете нажать на эту ссылку, чтобы запустить код и увидеть, как он работает
http://opalrb.com/try/?code:class%20RandomDigit%0A%20%20def%20initialize%0A%20%20%20%20%40n%20%3D%20rand(10)%0A%20%20end%0A%20%20def%20meets_condition%3F%0A%20%20%20%20%40n%20%25%202%20%3D%3D%200%20%23%20returns%20true%20if%20%40n%20is%20even%0A%20%20end%0Aend%0A%0Aclass%20TheParentClass%0A%20%20def%20method%0A%20%20%20%20%23%20returns%204%20random%20digits%20(between%200%20and%209)%0A%20%20%20%20%5BRandomDigit.new%2C%20RandomDigit.new%2C%20RandomDigit.new%2C%20RandomDigit.new%5D%0A%20%20end%0Aend%0A%0Aclass%20TheChildClass%20%3C%20TheParentClass%0A%20%20def%20method%0A%20%20%20%20super.select%20%7B%20%7Ca%7C%20a.meets_condition%3F%20%7C%7C%20true%20%7D%0A%20%20end%0Aend%0A%0Aputs%20TheChildClass.new.method
Просто чтобы прояснить, единственная вещь, которая на самом деле не имеет здесь смысла, - это || true
часть.
В противном случае вы определяете новый класс и немного изменяете поведение method
, чтобы оно работало подобно исходному method
, но отфильтровывало элементы.
Обычно вы можете увидеть что-то вроде a.question_1? || a.question_2?
что было бы попробовать вопрос_1? и если он возвращает true, то все готово.
если он не возвращает true, тогда попробуйте вопрос_2.
Это потому, что ||
- это поток операций управления ... вторая часть НЕ выполняется, если первая часть уже выполнена.
&&
является противоположным, поскольку вторая часть не выполняется, если только первая часть не истинна.