2012-02-08 25 views
3
class Person < ActiveRecord::Base 
    validates :terms_of_service, :acceptance => true 
end 

上記では、Rubyの観点からはvalidatesとは何ですか?そのメソッドではありません定義、そのデータ定義や宣言ではないので、明らかにメソッドの呼び出し、クラスの本文にあります。私は、メソッド定義の外でクラスの中で直接そのように呼び出されるメソッドを見たことはありませんでした。私が今行っているRubyプログラミングのチュートリアルでさえ、http://ruby-doc.org/docs/ProgrammingRuby/です。クラス定義のメソッド呼び出し?

したがって、そのメソッド呼び出しがどの時点で呼び出されているかを示します。私はテストとして次のことを試してみました:

class Person 

    print "cat" 

end 

#p = Person.new 
#q = Person.new 

print "cat"は、任意の実際のPersonオブジェクトが宣言かいないされているかどうかに関係なく、一度だけ実行されているので、クラス定義を解析するだけのとき明らかに、Rubyはメソッドのプリントを見て言います「OK、私は今すぐこれを実行しますが、決してこれを実行しません」。

SOどこ私はvalidates

上記のおかげで何が起こっているか理解するのに役立ちますRubyのドキュメントがあります。

+0

を私が「以来、長い時間がかかりましたRubyのプログラミングを読んでいますが、私はクラス本体のメッセージ送信は非常に早い段階で行われています。特に 'attr_reader'、' attr_writer'、 'attr_accessor'です。 –

答えて

8

Rubyでは、クラス宣言はコードのまとまりであり、順番に実行されます。

クラス定義内では、selfがクラス自体を指していることを覚えておくことが重要です。 validatesは、クラスメソッドActiveRecordです。クラスが定義されると、定義内のコードが実行されます。 validatesメソッドは、ActiveRecordのクラスメソッドに解決されるので、クラス定義の間にと呼ばれます。

Personの例では、クラスを1回しか定義しないので、この例は1回だけ印刷されます。

は、以下を考慮してください

class Foo 
    def self.validates_nothing(sym) 
    (@@syms ||= []) << sym 
    puts "!!! Here there be logic" 
    end 

    def validate 
    @@syms.each { |s| puts s } 
    end 
end 

これはクラスメソッドvalidates_nothing、およびインスタンスメソッド、validate持つクラスを定義します。 validates_nothingは、それが与えられた引数を収集するだけで、validateはそれらをダンプします。

class Bar < Foo 
    validates_nothing :anything 
    validates_nothing :at_all 
end 

これはサブクラスを定義します。クラスメソッドvalidates_nothingが呼び出されたときに、それが印刷されることに注意してください。

Here there be logic 
Here there be logic 

我々は新しいバーを作成し、検証を呼び出した場合、我々は、予想される出力を得る:

> Bar.new.validate 
!!!anything 
!!!at_all 
+0

さて、Railsで "validates"がどのように実行されるのですか? "print cat"は新しい(私が呼び出されると仮定した)場所では呼び出されていません。 Rubyインタプリタが最初にテキスト内に "print cat"を見つけたときに一度呼び出され、その後は決して再び見えません。 – Mark

+0

@Mark How?クラス定義は、クラスが定義されているとき*実行されるRubyコードで構成されているため*。 'new'を呼び出すとクラスが定義されず、新しいインスタンスが作成されます。'validates'はクラス定義プロセス自体の間に*呼び出されます。クラス定義の本体は 'new'の間に実行されると信じていますが、それは間違っていますし、意味がないかもしれません - 例えばメソッド定義が再実行(または定義されたものなど)であることを暗示します。 –

+0

ここで私と一緒にいらっしゃるのですが、上記のバリデーションの例では、いくつのPersonオブジェクトが宣言されるかにかかわらず、validatesは正確に1回だけ呼び出されますか? – Mark

関連する問題