我在rails来源中发现&Proc.new
的使用情况:
# rails/railties/lib/rails/engine.rb
def routes
@routes ||= ActionDispatch::Routing::RouteSet.new
@routes.append(&Proc.new) if block_given?
@routes
end
我不明白表达式&Proc.new
是如何工作的。
我写了类似的代码而失败了:
def method_name
&Proc.new if block_given?
end
proc = method_name{ puts 'Hello world!' }
proc.call
我收到语法错误:
syntax error, unexpected &
&Proc.new if block_given?
&Proc.new
在方法中的作用是什么?答案 0 :(得分:4)
首先,您应该了解并了解哪些块和过程是什么。基本上它们是ruby提供闭包的方式。 Here是一个很好的链接。
ruby中的一元&符号运算符有3种用法(所有这些都与块和过程相关):
如果应用于方法定义中的参数,则隐式块参数将使用参数名称存储为Proc。
如果在方法调用中应用于Proc,则Proc中包含的块将作为隐式块参数传递。它保留Proc是否是lambda。方法总是lambdas。
如果在方法调用中应用于其他对象,则调用方法#to_proc,并按照第二种情况传递生成的Proc。
The & Operator in Ruby详细解释了这一点。
答案 1 :(得分:3)
&
在参数列表中有特殊含义 - 当用作Proc对象的前缀时,它将其作为块传递给被调用的方法。在方法体内,它只是一个二元运算符。
答案 2 :(得分:0)
如果从方法内部调用Proc.new而没有自己的任何参数,它将返回一个新的Proc,其中包含赋予其周围方法的块。
def foo
Proc.new.call
end
foo { puts "hello world" }
# hello world
这意味着现在可以在不使用& block参数的情况下在方法之间传递块:
class C
def bar
puts "called bar..."
baz &Proc.new
end
def baz
puts "called baz..."
yield
end
end
C.new.bar { puts "called block..." }
# called bar...
# called baz...
# called block...
这个技巧被Rails用于
# File railties/lib/rails/engine.rb, line 533
def routes
@routes ||= ActionDispatch::Routing::RouteSet.new_with_config(config)
@routes.append(&Proc.new) if block_given?
@routes
end
的更多详情