2012-05-05 37 views
0

我有以下代碼,旨在將普通變量轉換爲實例變量。如何讓此代碼設置實例變量的值?

BasicObject.class_eval do 
    def instance(ins) 
     self.instance_variable_set("@#{ins}", ins) 
    end 
end 

比方說,用戶說

class X 
    foo = 3 
end 
bar = X.new 
bar.instance(:foo) 

我想什麼它做的是設置新創建的變量,@foo 3,相反,它集@foo:foo。我如何使代碼做我想要的?

+3

的代碼示例定義一個'foo'這僅僅是'class' ...'end'塊內可見。即使你回到X班,它已經消失了 - 它是詞彙範圍的一部分,而不是班級。這些「正常」變量在創建它們的範圍之外永遠不可見。一旦你點擊了關閉塊的'end',它們就只能被該塊內定義的代碼訪問。上面沒有任何這樣的代碼。 你試圖解決的實際問題是什麼? –

+1

無論如何,你爲什麼要這個令人費解的代碼?你的目標是什麼? – Phrogz

回答

1

在您的instance方法中,參數ins包含變量的名稱,而不是其值。正如所寫的,從那一點來看,沒有辦法從中獲得價值。

如果您從代碼中源代碼變量實際可見的地方調用instance,這不在您的示例中(請參閱上面的註釋),也可以傳遞局部變量綁定,然後使用它。事情是這樣的:

def instance(var, bound) 
    eval "@#{var}=#{var}", bound 
end 

這將這樣的工作:

foo = 3 
instance('foo', binding) 
@foo # => 3 
+0

即時通訊困惑,whaddaya意味着通過綁定? –

+1

一個Binding對象,它表示在代碼中某個點可見的變量集合。當前綁定是由'binding'方法返回的,所以上面的代碼是字面的; '綁定'是預先聲明的,你不需要做任何事情來使它工作。您可以將結果作爲第二個參數傳遞給'eval',這使得相同的一組變量對'eval'代碼可見 - 這幾乎可以用Binding對象完成。 –

+0

請參閱['Binding'](http://www.ruby-doc.org/core-1.9.3/Binding.html)和['Kernel#binding'](http://www.ruby-doc.org /core-1.9.3/Kernel.html#method-i-binding)。 – Phrogz