我读过一篇关于块和Proc
和yield
的文章,但我还没有明白。为了理解yield
我尝试编写一个返回数组的方法find_map
,除了它的工作方式类似于find_each
。
但是我不知道如何处理yield
以启用该功能。
class ActiveRecord::Base
def self.find_map
array = []
find_each
# TODO: push each result to `array`
yield
end
array
end
end
如何编写这样的方法?
yield
语句执行块,该块作为参数传递给方法:
def my_method
if block_given? # checks if block is passed to the method
yield
end
end
my_method{ puts 'Method to execute' }
#=> Method to execute
要修改对象,您需要将该对象作为参数传递给yield
例如:
class Array
def self.find_map
array = []
yield(array)
array
end
end
p Array.find_map{|arr| arr << 's' << 't' } #=> ["s", "t"]
您find_map
为类方法,可以调用为:ActiveRecord::Base.find_map
,通过查看您的代码期望find_each
类方法(它需要一个选项(。解决方法如下所示:
class ActiveRecord::Base
def self.find_map
array = []
find_each(*yield(array))
array
end
end
所以:
ActiveRecord::Base.find_map{|arr| arr << {:conditions => "age > 21"} }
当块被执行并作为{:conditions => "age > 21"}
传递到方法find_each
时,将{:conditions => "age > 21"}
插入到find_map
内部定义的array
中。
class MyCollection
include Enumerable
def initialize( someItems )
@items = someItems
end
def each
@items.each{ |i|
yield( i )
}
end
end
在这里,您使用数组初始化一个 MyCollection 对象,该数组将是存储在实例变量中,@items .调用其中一个方法时由可枚举模块提供(如最小、最大或集合(,这将调用每次获取一条数据的方法。所以,在这里每个方法将每个值从@items数组传递到块中,其中该项目被分配给块参数 i 。关键字 yield 是 Ruby 的一个特殊魔力,它运行传递给每个方法的代码块。(我在《红宝石之书》中找到了(