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 をモンキー パッチ可能にする大きな要因の 1 つです (これは Rubyist の観点からはプラスですが、他の多くの人は実践に眉をひそめています)。

于 2012-05-17T06:54:55.223 に答える
2

それがRubyの仕組みです。それがエラーの原因になるとは思い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 に答える