Что делает ключевое слово "yield" в Ruby?
я столкнулся со следующим кодом Ruby:
class MyClass
attr_accessor :items
...
def each
@items.each{|item| yield item}
end
...
end
что значит each
метод do? В частности, я не понимаю, что yield
делает.
8 ответов
это пример флеширования вашего примера кода:
class MyClass
attr_accessor :items
def initialize(ary=[])
@items = ary
end
def each
@items.each do |item|
yield item
end
end
end
my_class = MyClass.new(%w[a b c d])
my_class.each do |y|
puts y
end
# >> a
# >> b
# >> c
# >> d
each
петли над коллекцией. В этом случае он зацикливается на каждом элементе в @items
массив, инициализированный / созданный, когда я сделал new(%w[a b c d])
заявление.
yield item
на MyClass.each
метод передает item
к блоку, прикрепленному к my_class.each
. The item
получение присваивается локальному y
.
это поможет?
, вот немного больше о том, какeach
строительство. Используя то же определение класса, вот код:
my_class = MyClass.new(%w[a b c d])
# This points to the `each` Enumerator/method of the @items array in your instance via
# the accessor you defined, not the method "each" you've defined.
my_class_iterator = my_class.items.each # => #<Enumerator: ["a", "b", "c", "d"]:each>
# get the next item on the array
my_class_iterator.next # => "a"
# get the next item on the array
my_class_iterator.next # => "b"
# get the next item on the array
my_class_iterator.next # => "c"
# get the next item on the array
my_class_iterator.next # => "d"
# get the next item on the array
my_class_iterator.next # =>
# ~> -:21:in `next': iteration reached an end (StopIteration)
# ~> from -:21:in `<main>'
обратите внимание, что на последнем next
итератор упал с конца массива. Это потенциальная ловушка для не использование блока, потому что если вы не знаете, сколько элементов в массиве, вы можете запросить слишком много элементов и получить исключение.
используя each
С блоком переберем @items
приемник и стоп когда он достигает последний деталь, избегая ошибка и поддержание порядка.
когда вы пишете метод, который принимает блок, вы можете использовать yield
ключевое слово для выполнения блока.
например, each
могло быть реализовано в классе Array следующим образом:
class Array
def each
i = 0
while i < self.size
yield( self[i] )
i = i + 1
end
end
end
MyClass#each
принимает блок. Он выполняет этот блок один раз для каждого элемента в экземпляре items
массив, передавая текущий элемент в качестве аргумента.
он может использоваться следующим образом:
instance = MyClass.new
instance.items = [1, 2, 3, 4, 5]
instance.each do |item|
puts item
end
метод Ruby, который получает блок кода, вызывает его, вызывая его с помощью yield
ключевое слово. Он может использоваться для итерации по списку, но это не итератор, как то, что вы найдете на других языках.
здесь это хорошее объяснение, которое объясняет это лучше, чем я когда-либо был бы в состоянии.
yield
говорит ruby вызвать блок, переданный методу, давая ему свой аргумент.
yield
приведет к ошибке, если метод не был вызван с блоком, где as return
оператор не производит ошибку.
return
может отправлять только отдельные значения, где as Yield
возврат объекта огромных значений.
согласно моему пониманию yield выполняет код из блока.
def name
puts "A yield will be called with id of 12"
yield 12
puts "A yield will be called with id of 14"
yield 14
end
name {|i| puts "I am called by yield name #{i}"}
выход:
выход будет вызываться с идентификатором 12
меня зовут по имени 12
выход будет вызываться с идентификатором 14
меня зовут по имени 14
как работает выход?
когда name
функция бежит везде, где выход приходит код блока бежит. Которая составляет name {|i| puts "I am called by yield name #{i}"}
вы можете смотрите, что есть слово yield 12
yield запускает код внутри блока, передавая 12 как значение i
.
вот пример игры за нее:
def load_game
puts "Loading"
yield
end
load_game { puts "Game loaded" }
выводит game loaded
сразу после печати loading
:
загрузка
Игра Загружается
чистый эффект-это вызов .каждый экземпляр MyClass совпадает с вызовом .каждый на своем .элементы этого экземпляра.
как Новичок, просматривая ряд ответов, смутил меня, пока я не попал в ответ Абхи.
команда yield приостанавливает выполнение кода в методе и вместо этого передает управление обратно блоку кода, который вызвал его, выполняет этот код, а затем продолжает выполнение остальной части метода после этого. Вот пример, который прояснил это для меня:
def hello
puts "hello"
yield
puts "world"
end
hello do
puts "there"
end
выход:
привет
здесь
мир
Как сказал cpm, он берет блок и выполняет его
простой пример:
def my_method
yield
end
my_method do
puts "Testing yield"
end
Testing yield
=> nil