2009-06-10 17 views
2

Ich versuche diese Funktion zu verstehen.self.class_eval << DEF ... DEF

Was ich sehen kann, ist ein Attribut und Typ werden an die opal() -Methode übergeben.

type_name Dann nimmt seinen Wert von type solange type a Symbol oder String ist. Andernfalls wird die name-Methode unter type aufgerufen. Ich stelle mir vor, die name Methode ist ähnlich der class Methode, um die Klasse der type Argument zu bekommen.

Nach self.class_eval bin ich irgendwie verloren, aber meine Vermutung ist dies definiert möglicherweise einen Block von Code, um die Klasse von self referenziert werden.

Wie das funktioniert, bin ich mir nicht sicher.

Würde mich freuen, wenn jemand erklären könnte, was nach self.class_eval << DEF vor sich geht.

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

warum wurde dies abgelehnt? Es ist programmierungsbezogen und die Frage scheint nicht unklar zu sein. –

Antwort

5

Alles zwischen <<DEF und DEF ist nur eine Zeichenfolge und der #{ ... } Arbeit auf dieser Zeichenfolge wie jedes andere.

class_eval bewirkt, dass der Interpreter im Kontext des Moduls auf der Zeichenfolge ausgeführt wird.

Also, wenn Sie wissen, was attr und type sind dann können Sie herausfinden, welcher Code ausgeführt wird, um der Klasse Methoden hinzuzufügen.

Sagen wir attr ist "foo" und type ist "Bazzle". Der Code ist Lauf wäre:

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

Sie sagen "class_eval bewirkt, dass der Interpreter im Kontext des Moduls mit der Zeichenfolge ausgeführt wird". Wenn ich also self.class_eval "def bar end" sage, fügt der Interpreter der Klasse eine "bar" -Methode hinzu? – franz

+1

Ja. Wenn Sie das getan haben und es bereits eine 'bar'-Methode in der Klasse gab, würde diese außer Kraft gesetzt werden. – toholio

+0

Bekam es. Vielen Dank . – franz

3

Um es einfach zu machen, zu verstehen, wollen wir den Wert von ‚attr‘ annehmen, ist ‚foo‘, hier ist, wie es jetzt aussieht:

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 

So ist es Definieren Sie einfach einige Getter- und Setter-Methoden für @foo und evaluieren Sie diese auf Klassenebene.