我遇到了以下Ruby代码:
class MyClass
attr_accessor :items
...
def each
@items.each{|item| yield item}
end
...
end
each
方法有什么作用?特别是,我不明白yield
的作用。
答案 0 :(得分:31)
这是一个充实示例代码的示例:
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
的块。产生的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
上,迭代器从数组的末尾掉了下来。这是使用块的 NOT 的潜在缺陷,因为如果您不知道数组中有多少元素,您可以请求太多项并获得异常。
将each
与一个块一起使用将遍历@items
接收器并在到达最后一个项目时停止,避免错误,并保持良好和干净。
答案 1 :(得分:15)
当您编写一个带块的方法时,您可以使用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
答案 2 :(得分:10)
接收代码块的Ruby方法通过使用yield
关键字调用它来调用它。它可以用于迭代列表,但它不是像其他语言中那样的迭代器。
Here是一个很好的解释,可以解释它比我能做到的更好。
答案 3 :(得分:5)
yield
告诉ruby调用传递给该方法的块,并为其提供参数。
yield
如果未使用块调用该方法,则会产生错误,而return
语句不会产生错误。
return
只能在Yield
返回巨大值的对象时发送单个值。
答案 4 :(得分:5)
根据我的理解,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}"}
输出:
将以id为12
调用yield我被产量名称12调用
将以id为14
调用yield我被yield name 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
:
装载
加载游戏
答案 5 :(得分:4)
实际效果是在MyClass实例上调用.each与在该实例的.items上调用.each相同。
答案 6 :(得分:4)
作为一个新手,通过一些答案让我困惑,直到我打到Abhi的答案。
yield命令暂停执行方法中的代码,而是将控制权传递回调用它的代码块,执行该代码,然后继续执行该方法的其余部分。这是一个为我澄清的例子:
def hello
puts "hello"
yield
puts "world"
end
hello do
puts "there"
end
输出:
您好
有
世界
答案 7 :(得分:3)
当cpm说它接受阻止并执行它
简单示例:
def my_method
yield
end
my_method do
puts "Testing yield"
end
Testing yield
=> nil