当用作回调时,Ruby块中的`return`和`break`是无用的吗?

Skilldrick 3 ruby ruby-on-rails block

在Rails中,块可以用作回调,例如:

class User < ActiveRecord::Base
  validates_presence_of :login, :email

  before_create {|user| user.name = user.login.capitalize
    if user.name.blank?}
end

当一个块被这样使用,有没有用于任何用途breakreturn?我问,因为通常在一个块中,break将突破循环,并将return从封闭方法返回.但是在回调的背景下,我无法理解这意味着什么.

Ruby编程语言表明return可能导致a LocalJumpError但我无法在Rails回调中重现这一点.


编辑:使用以下代码我期望a LocalJumpError,但所有的return操作都是停止执行的其余回调.

class User < ActiveRecord::Base
  validates_presence_of :login, :email

  before_create do |user|
    return
    user.name = user.login.capitalize
end

Yehuda Katz.. 10

其实这很有意思......

当您在Rails 3中使用before_create时,我们会使用您提供给我们的块或lambda并将其转换为方法.然后,我们使用当前的ActiveRecord对象调用该方法,以便与旧的Rails方法向后兼容.

因此,以下内容相当于您的代码段:

class User < ActiveRecord::Base
  validates_presence_of :login, :email

  before_create do
    self.name = login.capitalize if name.blank?
  end
end

由于这种行为,你可以从块中调用return,它的行为与普通方法中的return相同(因为它一种常规方法).

通常,continue在块中"返回"块.

普通块的具体行为是:

  • 在调用时continue,您正在跳过块的其余部分,并将控制权返回给调用块的方法.
  • 当您调用时break,您正在跳过块的其余部分,并且还会立即从调用块的方法返回.

您可以在普通迭代器中看到该行为:

value = [1,2,3,4].each do |i|
  continue if i == 2
  puts i
end

在这种情况下,value将是[1,2,3,4],方法的正常返回值,each输出将是:

1
3
4

在休息的情况下:

value = [1,2,3,4].each do |i|
  break if i == 2
  puts i
end

在这种情况下,value将是nil,因为break也立即从each方法返回.您可以通过使用强制具有特定价值回报break n,这将使value一样n.上述情况的输出将是:

1

重要的是,continue并且break不仅仅适用于迭代器,尽管它们的语义设计为在迭代器的情况下表现得像它们在C中的等价物.