上述答案并非 100% 正确,因此不能被接受。尤其是部分;
Procs 不能接受块作为隐式参数(您正在尝试的格式)。proc 可以接收其他 proc 对象作为参数,无论是显式的,还是使用 & 参数。
这是错误的。Procs 和 lambdas 可以调用yield
它们的主体。要记住的事实是,Proc/lambda bodies have a lexical scope
!这意味着,如果在定义 Proc/lambda 时有一个块,yield
将成功执行,如下所示;
def foo
my_proc = Proc.new { yield }
my_proc.call
end
foo { puts "Hello world!" } # would print "Hello world!"
如您所见,yield
工作!因为在定义 Proc 时出现了阻塞。
可以说,Proc 被展开为在调用时有阻塞的方法,因此yield
有效。这也是错误的,可以通过以下代码段轻松反驳;
def foo
@my_proc ||= Proc.new { yield }
@my_proc.call
end
foo { puts "Hello again!" } # would print "Hello world!"
foo # would print "Hello world!"
正如您再次看到的,这是关于在定义 Proc 时有阻塞。
如果您想更好地理解词法范围的含义,让我们看一下以下示例。
class Foo
def self.hello_proc
Proc.new { puts name }
end
def self.name
"Alice"
end
end
class Bar
def self.put_name
Foo.hello_proc.call
end
def self.name
"Bob"
end
end
Bar.put_name # would print "Alice"
您可以将上面的代码复制并粘贴到 irb 会话中,以查看输出是什么。它放置“Alice”的原因是,在定义 Proc 时名称是“Alice”。