我正在尝试使用Ruby 1.9.1作为嵌入式脚本语言,这样“最终用户”代码就可以在Ruby块中编写。这样做的一个问题是,我希望用户能够在块中使用' return‘关键字,这样他们就不需要担心隐式返回值。考虑到这一点,这是我希望能够做的事情:
def thing(*args, &block)
value = block.call
puts "value=#{value}"
end
thing {
return 6 * 7
}
如果我在上面的例子中使用'return‘,我会得到一个LocalJumpError。我知道这是因为有问题的块是一个Proc而不是lambda。如果我删除了'return',代码就可以工作了,但我真的更喜欢在这个场景中使用'return‘。这个是可能的吗?我尝试将块转换为lambda,但结果是相同的。
发布于 2010-02-24 19:33:48
你从错误的角度来看待它。这是thing
的问题,不是lambda的问题。
def thing(*args, &block)
block.call.tap do |value|
puts "value=#{value}"
end
end
thing {
6 * 7
}
发布于 2010-02-24 19:32:06
在哪里调用的东西?你在一个班级里吗?
你可以考虑使用类似这样的东西:
class MyThing
def ret b
@retval = b
end
def thing(*args, &block)
implicit = block.call
value = @retval || implicit
puts "value=#{value}"
end
def example1
thing do
ret 5 * 6
4
end
end
def example2
thing do
5 * 6
end
end
end
发布于 2014-10-12 04:55:03
我在ruby中为web框架编写DSL时也遇到了同样的问题……( web框架Anorexic将会很棒!)...
无论如何,我深入研究了ruby的内部机制,发现了一个简单的解决方案,它使用Proc调用return时返回的LocalJumpError……到目前为止,它在测试中运行得很好,但我不确定它是完全可靠的:
def thing(*args, &block)
if block
block_response = nil
begin
block_response = block.call
rescue Exception => e
if e.message == "unexpected return"
block_response = e.exit_value
else
raise e
end
end
puts "value=#{block_response}"
else
puts "no block given"
end
end
救援段中的if语句可能如下所示:
if e.is_a? LocalJumpError
但这对我来说是未知的领域,所以我将坚持我到目前为止测试过的内容。
https://stackoverflow.com/questions/2325471
复制相似问题