[英]Ruby block, procs and instance_eval
我最近尝试做类似这样的事情:
a = "some string"
b = Proc.new{ upcase }
a.instance_eval b
这给出了错误:
类型错误:无法将 Proc 转换为 String
但这有效:
def b(&block)
"some string".instance_eval &block
end
b{ upcase }
进一步看一下这个方法:
def b(&block)
"some string".instance_eval block
end
产生相同的Proc to String
错误。
所以......我对块的理解是它们只是过程。 但显然有这个&
符号有一些特别之处......
谁可以给我解释一下这个? 是否可以将普通 proc 转换为这个&block
对象的特殊之处?
刚刚想通了我的第二个问题,在 proc 前面加上&
......这很容易,但这到底在做什么?
要使第一个示例工作,您所要做的就是:
>> a.instance_eval &b #=> "SOME STRING"
原因是instance_eval
需要一个字符串或一个块,而&符号提供后者。
不同之处在于a.instance_eval b
将b
作为常规参数传递给 instance_eval,而a.instance_eval &b
将其作为块传递。 这是两个不同的东西。
考虑这个方法调用:
obj.foo(bar) do |x|
stuff(x)
end
它使用一个常规参数 ( bar
) 和一个块参数 ( do |x| stuff(x) end
) 调用方法foo
。 在方法定义中,它们通过在块参数前加上&
来区分:
def foo(arg, &block)
如果你想传递一个变量表达式而不是一个文字块,同样可以通过在表达式前加上&来实现(它应该产生一个 Proc)。
如果你传递一个没有&
的参数,它会进入arg插槽而不是块插槽。 参数恰好是 Proc 的一个实例并不重要。 语法规定了方法如何传递和处理它。
这是因为 instance_eval 接受一个字符串来 eval 或一个块。 instance_eval(&block)
正在将您的block
作为块传递给 instance_eval。
关键的区别在于Proc 实例是一个对象,而块不是一个对象。 &
是一个操作符,可以相互交换块和 Proc 实例。
方法的所有参数都必须是对象。 除了参数之外,方法还可以接受一个块。 instance_eval
是一种接受字符串参数或块的方法。 传递 Proc 对象不会满足这两种情况。 如果将&
附加到 Proc 对象,它将作为块处理。
这将起作用:
a = "some string"
b = Proc.new{ upcase }
a.instance_eval &b
instance_eval
方法可以接收块参数。 b
是一个Proc
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.