【问题标题】:Why Curly Braces on Rails Callback?为什么花括号 on Rails 回调?
【发布时间】:2015-10-10 02:32:56
【问题描述】:

我正在学习 Ruby on Rails,在处理概念的同时,我也在处理语法,当您开始 RoR 时,这有点奇怪。根据 Michael Hartl 的教程

当哈希是函数调用中的最后一个参数时,花括号 是可选的

我明白,但是作者提到回调的时候,出现了这行代码:

before_save { self.email = email.downcase }

我理解 before_save 是方法。有人可以为我分析一下这个论点吗?为什么你不能去掉大括号?

【问题讨论】:

    标签: ruby-on-rails callback


    【解决方案1】:

    您的代码中没有哈希值。您正在查看的是一个块,它是一种匿名函数。 Ruby 有两种不同的块语法。这段代码:

    before_save { self.email = email.downcase }
    

    ...等价于这段代码:

    before_save do
      self.email = email.downcase
    end
    

    一般来说,大括号用于单行,do ... end 用于多行。无论哪种情况,您所做的是定义代码“块”,然后将其作为参数传递给before_save 方法。这允许 Rails 将该代码块存储在变量中并稍后执行,或者将代码传递给其他方法。上面两个例子在很大程度上等价于这个:

    my_block = proc do
      self.email = email.downcase
    end
    
    before_save(&my_block)
    

    块参数是特殊的。一个方法只能有一个块参数,并且它必须是最后一个参数。在最后一段代码中,我使用了procProc.new 的快捷方式)实际上将块保存到变量,然后将该变量作为参数传递给before_save& 告诉 Ruby 它应该将该 Proc 视为 before_save 的块参数。

    不过,有一些语法陷阱会出现在块中。例如,这是有效的:

    [ "two", "three" ].reduce "one" do |memo, item|
      memo << item
    end
    # => "onetwothree"
    

    但这不是:

    [ "two", "three" ].reduce "one" {|memo, item| memo << item }
    # => SyntaxError: unexpected '{', expecting end-of-input
    

    当你使用花括号语法并有参数时(如上面的"one"),你必须使用括号:

    [ "two", "three" ].reduce("one") {|memo, item| memo << item }
    # => "onetwothree"
    

    除了块和 Procs,Ruby 有一种特殊的 Proc,称为 lambda。你会在一些 Rails 文档中看到 lambda,它们看起来像这样:

    scope :published, -> { where(published: true) }
    

    这是一个捷径:

    scope :published, lambda { where(published: true) }
    # ...or...
    scope :published, lambda do
      where(published: true)
    end
    

    ...这些都等价于这个:

    my_lambda = ->{ where(published: true) }
    scope :published, my_lambda
    

    请注意,第二行的my_lambda 之前没有&amp;。这是因为 Rails 的开发人员选择让 scope 将 lambda 作为常规参数——而不是它的块参数——我认为,大多数情况下,它不必是最后一个参数。

    blocks、procs 和 lambdas 之间的区别超出了这个答案的范围,有时甚至是微妙的,但这是很好的知识。我推荐这篇文章以获取更多信息:https://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/18-blocks/lessons/64-blocks-procs-lambdas

    【讨论】:

      【解决方案2】:

      您所指的作为参数传递的花括号是一个块。
      传递给回调的块通过instance_eval 执行,因此它的范围是记录本身。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        • 2017-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-14
        相关资源
        最近更新 更多