Ruby 我能把一个区块传给一个进程吗?
我想知道是否可以将一个块传递给一个进程。仅将块传递给Ruby 我能把一个区块传给一个进程吗?,ruby,Ruby,我想知道是否可以将一个块传递给一个进程。仅将块传递给Proc.call不起作用: foo = Proc.new { yield } foo.call { puts "test" } 结果: LocalJumpError:未提供块(产量) 兰博达斯也是如此。但是,该方法不适用于方法对象: class Foo def bar yield end end bar = Foo.new.method :bar bar.call { puts "Success!" } 结果
Proc.call
不起作用:
foo = Proc.new {
yield
}
foo.call {
puts "test"
}
结果:
LocalJumpError:未提供块(产量)
兰博达斯也是如此。但是,该方法不适用于方法对象:
class Foo
def bar
yield
end
end
bar = Foo.new.method :bar
bar.call { puts "Success!" }
结果:
成功
奇怪的是,将method对象转换为proc后,它仍然可以工作:
bar.to_proc.call { puts "Success!" }
结果:
成功
那么,为什么由块生成的Proc不接受块,而最初是方法的Proc接受块呢?可以从接受块的块创建进程吗?进程不能接受块作为隐式参数(您正在尝试的格式)。proc可以显式地或使用&arguments接收其他proc对象作为参数。例如:
a = Proc.new do |&block|
block.call
end
a.call() {puts "hi"}
yield
是一种语言级的魔法,只在方法的上下文中起作用 以上答案并非100%正确,因此不能接受。特别是这一部分
Procs无法接受块作为隐式参数(您正在尝试的格式)。proc可以显式地或使用&arguments接收其他proc对象作为参数 这是错误的。proc和lambda可以在它们的体内调用
yield
。要记住的事实是,Proc/lambda主体有一个词法范围
!这意味着,如果在定义Proc/lambda时存在块,yield
将成功执行,如下所示
def foo
my_proc = Proc.new { yield }
my_proc.call
end
foo { puts "Hello world!" } # would print "Hello world!"
如您所见,收益率
有效!因为在定义过程时出现了阻塞
可以说,Proc被展开为方法,该方法在调用时具有块,因此yield
worked。这也是错误的,很容易用下面的代码片段来反驳
def foo
@my_proc ||= Proc.new { yield }
@my_proc.call
end
foo { puts "Hello again!" } # would print "Hello world!"
foo # would print "Hello world!"
正如您再次看到的,它是关于在定义过程时使用block
如果您想更好地理解什么是词汇范围的意思,让我们看看下面的示例
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”是因为,在定义过程时,名称是“Alice”。对我来说,可能的重复仍然是一个开放的相关问题:可以从产生的块创建产生的方法吗?可能的重复是否意味着块不能接受其他块作为隐式参数?因为正如我在问题中所演示的,如果proc从方法转换为proc,那么proc就可以了。@Codemonkey:我很确定too proc会创建一个&参数。我会将
proc.new do|&block
更改为proc do|&block
,否则这是一个很好的答案。是的,proc和lambdas可以在它们的体内产生。然而,语句“Procs不能接受块作为隐式参数(您正在尝试的格式)。”并不否认这一点。这只是说调用yield
不会调用传递给proc调用的块。(意思是它称之为外部语境的障碍。)我没有说它100%错了,我说它不是100%正确和误导。