嘗試使用define_method。 Def讓你進入一個新的範圍。
class Test
def initialize(a)
@a = a
end
def item
item = "hola"
item.singleton_class.send(:define_method, :singl) do
[self, @a].join(" + ")
end
item
end
end
test = Test.new("cao")
item = test.item
item.singl #=> "hola + "
在你的例子中,你仍然有一個問題,在一個字符串@a的單例類中還沒有定義。這主要是因爲在這種情況下self是字符串實例,而不是存在@a
的測試實例。要解決這個問題,你可以將實例變量重新綁定到別的東西上,但這可能不是你想要的行爲。你也可以在你的新單例類中設置實例變量。
例如,
重新綁定變量
class Test
def initialize(a)
@a = a
end
def item
item = "hola"
new_self = self
item.singleton_class.send(:define_method, :singl) do
[self, new_self.instance_variable_get(:@a)].join(" + ")
end
item
end
end
test = Test.new("cao")
item = test.item
item.singl
設置一個實例字符串變量
class Test
def initialize(a)
@a = a
end
def item
item = "hola"
item.singleton_class.send(:define_method, :singl) do
[self, @a].join(" + ")
end
item.singleton_class.send(:define_method, :set) do
@a = "cao"
end
item
end
end
test = Test.new("cao")
item = test.item
item.set
item.singl
其重要的要注意這兩種方法之間的差異。在第一種方法中,我們通過原始對象保留對原始實例變量的引用。在第二種方法中,我們創建一個新的實例變量,綁定在新的單例類下,包含原始測試的副本。
如果您使用的是非本地對象,那麼您可能會混合使用這兩種方法。編輯:作爲Benoit指出,在第二種方法「set」方法應該只是一個attr_accessor。實際上,你可以設置實例變量而不需要定義新的方法。通過item.instance_variable_set(:@, "cao")
我無法理解你的最後一個例子,你正在對項目類中的「cao」字符串進行硬編碼,而不是獲取傳遞給Test初始值設定項的內容。你是否想將它定義爲屬性設置器? –
我很懶。我用這個區別來說明這樣一個事實,即用第二種方法,兩個@ a不一樣。我認爲這個方法可以推斷出這個方法「應該」是一個屬性設置器。我會澄清。謝謝! – diedthreetimes