2009-06-10 72 views
2

我在試着理解這個函數。self.class_eval << DEF ... DEF

我可以看到的是一個屬性和類型傳遞給opal()方法。

然後type_name只要typeSymbolString需要從type其值。否則,在type上調用name方法。我想象name方法類似於class方法來獲得type參數的類。

self.class_eval我有點失落,但我的猜測是這是定義可能是一個代碼塊被添加到self引用的類。

這是如何工作我不確定。

如果有人能解釋self.class_eval << DEF後發生了什麼,我們將不勝感激。

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

爲什麼這次被投票?它與編程有關,這個問題似乎並不清楚。 – 2009-06-10 05:00:55

回答

5

<<DEFDEF之間的一切都只是一個字符串和#{ ... } S於該字符串像任何其他的工作。

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 2009-06-10 05:20:04

3

爲了便於理解,讓我們假設「ATTR」的值是「富」,這裏是它看起來像現在:

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方法,並在類級別對其進行評估。