为什么Ruby使用yield? [英] Why does Ruby use yield?
问题描述
我是 Ruby 的新手.我使用了很多允许高阶函数的 C# 和 JavaScript,我通常每天都在使用它们.
Ruby 对我来说似乎有点奇怪.each
函数可能如下所示:
定义每个@items.each 做 |item|产量(项目)结尾结尾items.each { |item|放置项目 }
然而,Ruby 也有一些对高阶函数的支持.上面的内容可以改写为:
def each(proc)@items.each 做 |item|过程调用项结尾结尾items.each ->(item) { puts item } # 或者...items.each lambda { |item|放置项目 }
甚至:
def each(&proc)@items.each 做 |item|过程调用项结尾结尾# 语法上没有区别.items.each { |item|放置项目 }
这与大多数其他语言更相似,而且只是长了几个字符.一切似乎都使用 yield
,而不是显式地传入一个块.
yield
本身看起来很疯狂、神奇和神秘.毕竟,它会到达调用的起点并在调用之后立即抓取一个块.这看起来很奇怪和不自然,我不知道在另一种语言中有任何类似的功能.
那么 yield
是怎么回事?
Yield Passes Objects to a Method's Block
<块引用>[Yield is] 前往调用的起点并在调用后立即抓取一个块.
不是真的.yield
将参数传递给块;它不会抓住一个块"或用它做任何事情.换句话说,这是:
def foo;屈服自我;结尾foo { |x|x.检查}# =>主要的"
在这里,yield
没有做任何事情,只是将参数传递给传递给 foo
方法的块.每个 Ruby 方法都支持一个可选块——除非一个块实际上是强制性的——所以唯一的魔法"是该语言允许传递一个块,即使它没有明确声明为方法签名的一部分.
更多示例
要查看此隐式签名的实际效果,请考虑:
def foo;puts block_given?;结尾foo { |x|x.检查}
这将打印true"并返回 nil
,这是 puts
方法的预期返回值.
当然,如果没有 yield
,块就什么也做不了.例如:
def foo;结尾foo { |x|x.检查}# =>零
I am new to Ruby. I have used a lot of C# and JavaScript which allow higher-order functions and I typically use them on a daily basis.
Ruby seems a little strange to me though. An each
function might look like:
def each
@items.each do |item|
yield(item)
end
end
items.each { |item| puts item }
Yet Ruby also has some support for higher-order functions. The above could be rewritten to something like:
def each(proc)
@items.each do |item|
proc.call item
end
end
items.each -> (item) { puts item } # Or...
items.each lambda { |item| puts item }
Or even:
def each(&proc)
@items.each do |item|
proc.call item
end
end
# No difference in syntax.
items.each { |item| puts item }
Which is more on par with most other languages, and is just a few characters longer. Instead of explicitly passing in a block, everything seems to use yield
.
yield
itself seems crazy, magical, and mysterious. After all, it's going to the origin of the call and grabbing a block immediately following the call. This seems bizarre and unnatural, and I'm not aware of any parallel of this feature in another language.
So what's the deal with yield
?
Yield Passes Objects to a Method's Block
[Yield is] going to the origin of the call and grabbing a block immediately following the call.
Not really. yield
passes an argument to a block; it doesn't "grab a block" or do anything with it. In other words, this:
def foo; yield self; end
foo { |x| x.inspect }
# => "main"
Here, yield
isn't doing anything but passing an argument to the block that is passed into the foo
method. Every Ruby method supports an optional block—except when a block is actually mandatory—so the only "magic" is that the language allows a block to be passed even when it isn't explicitly declared as part of the method signature.
Further Examples
To see this implicit signature in action, consider this:
def foo; puts block_given?; end
foo { |x| x.inspect }
which will print "true" and return nil
, which is the expected return value from the puts
method.
Of course, without yield
the block doesn't do anything at all. For example:
def foo; end
foo { |x| x.inspect }
# => nil
这篇关于为什么Ruby使用yield?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!