Ruby 1.9 中更自然的 Proc 调用方式
Posted
技术标签:
【中文标题】Ruby 1.9 中更自然的 Proc 调用方式【英文标题】:More natural way of Proc calling in Ruby 1.9 【发布时间】:2012-09-24 07:49:19 【问题描述】:我们知道,在 Ruby 1.9 中有几种 Proc 调用方式
f =->n [:hello, n]
p f[:ruby] # => [:hello, :ruby]
p f.call(:ruby) # => [:hello, :ruby]
p f.(:ruby) # => [:hello, :ruby]
p f === :ruby # => [:hello, :ruby]
我很好奇,调用 Proc 的更“自然”方式是什么? “自然”可能意味着更多类似计算机科学的方式。
【问题讨论】:
我会选择选项 2。这似乎很自然。其余的看起来很奇怪。 【参考方案1】:第二个选项是迄今为止最常用的。
p f.call(:ruby) # => [:hello, :ruby]
它使它更类似于标准方法。此外,一些库在验证参数检查 #call
方法的可用性时实际上依赖于鸭子类型。在这种情况下,使用 #call
可确保您可以提供响应 #call
的 lambda 或任何其他对象(包括类)。
Rack
中间件是这种约定的一个很好的例子。基本中间件可以是 lambda,也可以使用类提供更复杂的逻辑。
【讨论】:
+1 用于鸭子打字部分——这很重要。在我自己的很多代码中,我使用.responds_to(:call)
,以便人们可以传递Method
、Proc
或lambda(或任何其他带有call
方法的东西)。
是的,已修复。我数了第一行。 :P
所有这些也适用于f.(:ruby)
,因为这只是f.call(:ruby)
的语法糖。【参考方案2】:
我总是使用选项 3。考虑到能够在没有括号的情况下调用方法的语法歧义,这是最接近实际方法调用语法的方法。
【讨论】:
【参考方案3】:我在Rack源代码中看到了第一种方式。让我困惑了很久。它选自 lib/rack/builder.rb(版本:1.6.0.alpha)
module Rack
class Builder
...
def to_app
app = @map ? generate_map(@run, @map) : @run
fail "missing run or map statement" unless app
# This is the first option calling a proc
# @use is a array of procs (rack middleware)
@use.reverse.inject(app) |a,e| e[a]
end
...
end
end
【讨论】:
以上是关于Ruby 1.9 中更自然的 Proc 调用方式的主要内容,如果未能解决你的问题,请参考以下文章