使用Ruby`yield`时如何防止`return`从块中出现问题
正如每个
Ruby程序员最终都会发现的那样,调用包含返回语句的块或者进程可能是危险的,因为这可能会退出你当前的上下文:
def some_method(&_block) puts 1 yield # The following line will never be executed in this example # as the yield is actually a `yield-and-return`. puts 3 end def test some_method do puts 2 return end end test # This prints "1n2n" instead of "1n2n3n" 如果你想绝对确定你调用了一个块或者proc后有些代码运行,你可以使用begin …确保构造.但是,如果在收益期间有异常,那么确保也会被调用,它需要更多的工作. 我创建了一个tiny module,以两种不同的方式处理这个问题: >使用safe_yield,检测是否使用return关键字返回生成的块或proc.如果是这样,它会引起一个例外. unknown_block = proc do return end ReturnSafeYield.safe_yield(unknown_block) # => Raises a UnexpectedReturnException exception >使用call_then_yield,您可以调用一个块,然后确保执行第二个块,即使第一个块包含return语句. unknown_block = proc do return end ReturnSafeYield.call_then_yield(unknown_block) do # => This line is called even though the above block contains a `return`. end 我正在考虑创建一个快速宝石,还是有内置的解决方案,以防止我错过的嵌套块的快速返回? 解决方法
有一个内置解决方案来检测块是否包含return语句.
您可以使用 这是一个示例实现: def safe_yield(&block) if RubyVM::InstructionSequence.disasm(block) =~ /^d+ throw +1$/ raise LocalJumpError end block.call end 以下是您将其纳入您的图书馆的方式: def library_method(&block) safe_yield(&block) puts "library_method succeeded" rescue LocalJumpError puts "library_method encountered illegal return but resumed execution" end 而这里的用户体验是一个行为良好和行为不端的用户: def nice_user_method library_method { 1 + 1 } end nice_user_method # library_method succeeded def naughty_user_method library_method { return false if rand > 0.5 } end naughty_user_method # library_method encountered illegal return but resumed execution 评论: 使用raise LocalJumpError / rescue LocalJumpError可以解决您在使用毯子时遇到的问题. 我选择了LocalJumpError,因为它似乎是相关的,因为(我想!)没有可能的Ruby代码会导致在这个上下文中“自然”地引发LocalJumpError.如果事实证明是假的,您可以轻松地替换自己的新异常类. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 10.6 Swift中subscripts基本语法
- c – std :: unique_ptr删除函数,initializer_list – 驱动
- ORA-00130: invalid listener address
- ajax – 如何让Selenium WebDriver等待一段时间?
- Flex数字类型和Java数字类型的比较
- Oracle数据库疑问:函数出现no_data_found不报异常
- flutter框架:关于Flutter初始化流程
- C# 保存文件
- ruby-on-rails – Rails attr_accessible:object vs:obje
- 转载:REDO LOG 与 UNDO LOG这两个概念的区别