1

我正在学习一些 Rspec 的东西,并且不小心在我的模型类中引入了一些代码,我希望这会产生错误。但令我惊讶的是,没有。

class Address < ActiveRecord::Base
  attr_accessible :city, :country, :person_id, :street, :zip
  validates_presence_of :city, :zip, :street
  before_save :setDefaultCountry

  # -- Beginning strange code --

  if true
     puts "Hey! I shouldn't be able to do this"
  end       

  # -- End of strange code --

  private   
  def setDefaultCountry
    if self.country.blank?
      self.country = "US"
    end
  end
end

这是 rails 控制台输出:

Arman$ rails console
Loading development environment (Rails 3.2.3)
1.9.3p194 :001 > a = Address.new
Hey! I shouldn't be able to do this
 => #<Address id: nil, street: nil, city: nil, zip: nil, country: nil, person_id: nil, created_at: nil, updated_at: nil> 
1.9.3p194 :002 > 

为什么 ruby​​ 不抱怨在类定义中添加了奇怪的代码?

4

2 回答 2

3

因为class块只为代码的执行引入了一个新的上下文。Ruby 是 Ruby,而不是 C++——不要这样对待它。如果我们想在类定义期间执行一些代码,为什么你认为我们不应该能够?您可以在其中很好地执行代码 - 在此期间,self将指向Class代表您的类的对象,而不是其类的任何实例。这为您提供了极大的灵活性,并且是使 Ruby 猴子可修补的重要因素之一(从 Ruby 主义者的角度来看,这是一个加分项,尽管许多其他人不赞成这种做法)。

于 2012-05-17T06:54:55.223 回答
2

这就是红宝石的工作原理。您认为这不会attr_accessible导致错误,是吗?但这只是一个常规的方法调用!这是它的来源

# File activerecord/lib/active_record/base.rb, line 1083
def attr_accessible(*attributes)
  write_inheritable_attribute(:attr_accessible, 
                              Set.new(attributes.map(&:to_s)) + (accessible_attributes || []))
end

您可以在类定义中运行任意 ruby​​ 代码。这是一个功能,而不是一个错误:)

于 2012-05-17T06:55:03.590 回答