ruby - 如何定义专门用于变量作用域的 block 类型

标签 ruby

更新:

我刚刚写了这个小 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/

相关文章:

ruby - 单独运行每个 RSpec 规范文件

ruby-on-rails - 带排序和限制的 Rails Active Record 连接查询

ruby - 在 Ruby 中找到两个字符串之间的第一个不同字符

java - 如何从 .erb 文件中的函数调用中提取函数名称?

arrays - Flatten 在直接调用和在方法中调用时的工作方式不同

ruby - MongoDB rub​​y​​ 驱动程序更新单个字段

Ruby 将对象转换为哈希

ruby - Integer(value) 和 value.to_i 之间的区别

ruby-on-rails - 将 Mac Pro 中的操作系统更新为 mavericks 后无法创建 Rails 应用程序

ruby-on-rails - 正则表达式忽略以下划线开头的单词或文件开头的路径