在Rails中,blocks can be used as callbacks,例如:
class User < ActiveRecord::Base validates_presence_of :login,:email before_create {|user| user.name = user.login.capitalize if user.name.blank?} end
当像这样使用一个块时,有没有用于中断和返回的用途?我问,因为通常在一个块中,break会突破循环,return将从封闭方法返回.但是在回调的背景下,我无法理解这意味着什么.
The Ruby Programming Language表明返回可能导致LocalJumpError,但我无法在Rails回调中重现这一点.
编辑:使用以下代码我期望一个LocalJumpError,但所有返回操作都会停止执行其余的回调.
class User < ActiveRecord::Base validates_presence_of :login,:email before_create do |user| return user.name = user.login.capitalize end
解决方法
其实这很有意思……
当您在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时,您将跳过块的其余部分,并将控制权返回给调用块的方法.
>当您调用break时,您正在跳过块的其余部分,并且还会立即从调用块的方法返回.
您可以在普通迭代器中看到该行为:
value = [1,2,3,4].each do |i| continue if i == 2 puts i end
在这种情况下,值将是[1,4],每个方法的正常返回值,输出将是:
1 3 4
在休息的情况下:
value = [1,4].each do |i| break if i == 2 puts i end
在这种情况下,该值将为nil,因为中断也会立即从每个方法返回.您可以使用break n强制返回具有特定值的值,这将使n与n相同.上述情况的输出将是:
1
重要的是,continue和break不仅仅适用于迭代器,尽管它们的语义设计为在迭代器的情况下表现得像C中的等价物.