更新:
我刚刚写了这个小 gem :var_block希望能帮助到你! :)
问题:
有没有办法做下面这样的事情?
vegetable = 'bean' # is there a ruby way equivalent to this "with" that I just wrote? with( fruit: -> {'apple'} ) do puts vegetable puts fruit end # => 'bean' # => 'fruit' puts vegetable # => 'bean' puts fruit # => NameError: undefined local variable or method `fruit'
我正在寻找一种仅在该“种类 block ”内定义变量的方法(在本例中:
fruit
变量),但同时在该 block 外部的上下文中执行(就像您只是复制该 block 内的所有代码,然后将其粘贴到该 block 外部一样)
用法:
希望我可以将 Rails 应用程序中的“嵌套逻辑”代码简化为类似的代码(注意:这是简化的用例):
# app/models/user.rb has_many :apples validates :name, presence: true with(has_an_apple: -> { apples.present? ) do validate :should_have_a_cart, if: { has_an_apple } with(has_a_ripe_apple: -> { apples.ripe.present? ) do validate :should_have_energy_to_harvest_apples, if: -> { has_an_apple && has_a_ripe_apple } end with(has_a_rotten_apple: -> { apples.rotten.present? ) do validate :should_have_energy_to_dispose_of_rotten_apples, if: -> { has_an_apple && has_a_rotten_apple } end end
备注:
- 我依稀记得很久以前,我在ruby中看到过这样的东西,但现在我已经记不清了,即使在互联网上搜索了无数次。
- 可以说,不使用这个“ block ”可能会更干净,只需在上面编写具有相同缩进的所有
validates
,并且看起来更干净,但我想将“东西”分组起来现在我注意到我现在有很多具有重复if
条件的验证,而且我现在更容易以这种方式理解它,因为我可以立即看到“缩进”和“ block ”让我关注一个又一个特定场景。
尝试:
# begin ... end does not seem to work as the variable can still be accessed outside it
begin
fruit = 'apple'
puts fruit
end
# => 'apple'
puts fruit
# => 'apple'
最佳答案
您可以使用 Proc
(或 lambda),就像在 ECMAScript 或 Scheme 中实现封装一样:
vegetable = 'bean'
-> fruit = 'apple' {
puts vegetable
puts fruit
}.()
# bean
# apple
puts vegetable
# bean
puts fruit
# NameError: undefined local variable or method `fruit'
但是,一般来说,不编写如此复杂的代码以至于您无法再跟踪局部变量被认为是更惯用的做法。
关于ruby - 如何定义专门用于变量作用域的 block 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43891007/