尝试使用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