我是
Ruby的新手.我使用了很多C#和
JavaScript,它允许高阶函数,我通常每天使用它们.
Ruby似乎对我来说有点奇怪.每个功能可能如下所示:
def each @items.each do |item| yield(item) end end items.each { |item| puts item }
def each(proc) @items.each do |item| proc.call item end end items.each -> (item) { puts item } # Or... items.each lambda { |item| puts item }
甚至:
def each(&proc) @items.each do |item| proc.call item end end # No difference in Syntax. items.each { |item| puts item }
哪个更符合大多数其他语言,只有几个字符更长.而不是明确地传递一个块,一切似乎都使用yield.
屈服本身似乎是疯狂,神奇和神秘.毕竟,它将到达呼叫的起点,并在呼叫之后立即抓取一个块.这似乎是奇怪和不自然的,我不知道这个功能在另一种语言的任何并行.
那么收益是多少呢?
解决方法
产量将对象传递给方法的块
[Yield is] going to the origin of the call and grabbing a block immediately following the call.
不是真的. yield将一个参数传递给块;它不会“抓块”或做任何事情.换句话说,这个:
def foo; yield self; end foo { |x| x.inspect } # => "main"
在这里,yield只是将参数传递给传递给foo方法的块.每个Ruby方法都支持一个可选的块 – 除非块实际上是必需的 – 所以唯一的“魔术”就是语言允许一个块被传递,即使没有被明确声明为方法签名的一部分.
其他例子
要查看此隐含签名的行为,请考虑:
def foo; puts block_given?; end foo { |x| x.inspect }
这将打印“true”并返回nil,这是puts方法的预期返回值.
当然,没有收益,块根本不做任何事情.例如:
def foo; end foo { |x| x.inspect } # => nil