2009-06-10 17 views
2

私はこの機能を理解しようとしています。self.class_eval << DEF ... DEF

属性と型はopal()メソッドに渡されます。

そしてtype_nameは限りtypeSymbol又はStringあるようtypeからその値をとります。それ以外の場合は、nameメソッドがtypeで呼び出されます。私はnameメソッドがtype引数のクラスを得るためにclassメソッドに似ていると想像します。

self.class_evalの後に私は迷っていますが、これはおそらくselfで参照されるクラスに追加されるコードブロックを定義していると思います。

どのように動作しますかわかりません。

self.class_eval << DEFの後に何が起こっているのかを誰かが説明できるかどうか分かりますか。 <<DEFDEF

def opal(attr, type) 
     self.ds "#{attr}_id" 
     type_name = (type.is_a?(Symbol) || type.is_a?(String)) ? type : type.name 
     self.class_eval <<DEF 
    def #{attr} 
    if defined?(@#{attr}) 
     @#{attr} 
    else 
     @#{attr} = if self.#{attr}_id 
      #{type_name}.get(self.#{attr}_id) 
     else 
      nil 
     end 
    end 
    end 

    def #{attr}=(value) 
    self.#{attr}_id = value.key 
    @#{attr} = value 
    end 
DEF 
    end 
+2

なぜこれが投票されたのですか?それはプログラミングに関連しており、質問は不明瞭ではないようです。 –

答えて

5

すべては単なる文字列と他と同様、その文字列に#{ ... }の仕事です。

class_evalは、インタープリタをモジュールのコンテキスト内の文字列で実行させます。

attrtypeが分かっている場合は、クラスにメソッドを追加するために実行されているコードを調べることができます。

attr"foo"であり、type"Bazzle"であるとします。実行されるコードは次のようになります。

def foo 
    if defined?(@foo) 
    @foo 
    else 
    @foo = if self.foo_id 
     Bazzle.get(self.foo_id) 
    else 
     nil 
    end 
    end 
end 

def foo=(value) 
    self.foo_id = value.key 
    @foo = value 
end 
+0

あなたは "class_evalはインタプリタをモジュールの文脈で文字列上で実行させる"と言う。だから私がself.class_eval "def bar end"と言うなら、インタプリタはクラスに "bar"メソッドを追加しますか? – franz

+1

はい。もしあなたがそれを行い、すでにクラスに 'bar'メソッドがあったら、それはオーバーライドされます。 – toholio

+0

ありがとう。 – franz

3

理解を容易にする、のは「のattr」の値が「foo」であると仮定してみましょう、ここではそれが今のようになります。

self.class_eval <<DEF 
    def foo 
    if defined?(@foo) # Return the value of attr if it's defined 
     @foo 
    else 
     @foo = if self.foo_id 
      #{type_name}.get(self.foo_id) 
     else 
      nil 
     end 
    end 
    end 

    def foo=(value) # Define setter 
    self.foo_id = value.key 
    @foo = value 
    end 
DEF 

だから、です@fooのgetterメソッドとsetterメソッドを定義し、それをクラスレベルで評価するだけです。

関連する問題