【问题标题】:Difference between lambda and -> operator in RubyRuby 中 lambda 和 -> 运算符的区别
【发布时间】:2021-08-28 01:21:55
【问题描述】:

以下两个作用域生成相同的结果,哪种语法更可取,还有其他区别吗?

scope :paid, lambda { |state| where(state: state) }

scope :paid, ->(state) { where(state: state) }

【问题讨论】:

    标签: ruby-on-rails ruby lambda


    【解决方案1】:

    由于可读性原因,最好对单行块使用新语法->(在 Ruby 1.9 中引入),对多行块使用 lambda。示例:

    # single-line
    l = ->(a, b) { a + b }
    l.call(1, 2)
    
    # multi-line
    l = lambda do |a, b|
      tmp = a * 3
      tmp * b / 2
    end
    l.call(1, 2)
    

    这似乎是在bbatsov/ruby-style-guide 建立的社区公约。

    所以,在你的情况下,会更好:

    scope :paid, ->(state) { where(state: state) }
    

    【讨论】:

      【解决方案2】:

      -> 是文字语法,如"。其含义由语言规范确定。

      Kernel#lambda 是一种方法,就像任何其他方法一样。它可以被覆盖、删除、覆盖、monkeypatched、拦截……

      因此,从语义上讲,它们是非常不同的。

      它们的性能也可能不同。 Kernel#lambda至少会有方法调用的开销。执行引擎实际上无法知道 Kernel#lambda 在运行时做了什么(因为它可能会被猴子补丁)也排除了任何静态优化,尽管我不相信任何现有的 Ruby 执行引擎以任何有意义的方式静态优化 lambda 文字。

      【讨论】:

        【解决方案3】:

        没有区别,两者都返回相同的Proc对象:

        irb(main):033:0> lambda {|x| x*x}
        => #<Proc:0x007ff525b55b90@(irb):33 (lambda)>
        irb(main):034:0> ->(x) {x*x}
        => #<Proc:0x007ff525b7e068@(irb):34 (lambda)>
        

        在我看来,-&gt; 更具可读性。

        【讨论】:

          【解决方案4】:

          市场的答案是正确的答案。一个快速的补充——如果需要一个多行 lambda 作为参数,有两种方法可以工作。例如,在模型中创建范围,您可能需要考虑:

          class User < ApplicationRecord
            # Bad - this will error because we are passing a block as an argument in
            # a method without parenthesis
            scope cool_users lambda do |arg|
              # some long query
            end
          
            # OK - when parenthesis are added, the lambda block will work 
            # without error (and passes rubocop). However, using parenthesis 
            # around a lambda block looks weird IMO
            scope(cool_users lambda do |arg|
              # some long query
            end)
          
            # Good - replacing do / end with {} functions without error, passes 
            # rubocop and looks good IMO
            scope cool_users lambda { |arg|
              # some long query
            }
          end
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-03-18
            • 2013-07-06
            • 2012-04-30
            • 2013-07-27
            • 2013-06-05
            • 1970-01-01
            相关资源
            最近更新 更多