如何从singleton方法访问实例变量?
class Test
def initialize(a)
@a = a
end
def item
item = "hola"
def item.singl
[self, @a].join(" + ")
end
item
end
end
test = Test.new("cao")
item = test.item
item.singl
#=> ... @a is nil
Run Code Online (Sandbox Code Playgroud)
尝试使用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 + "
Run Code Online (Sandbox Code Playgroud)
在你的例子中,你仍然有问题,在字符串的单例类中,@ 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
重要的是要注意两种方法之间的差异.在第一种方法中,我们通过原始对象保留对原始实例变量的引用.在第二种方法中,我们创建一个新的实例变量,绑定在新的单例类下,包含原始测试的副本.@ a.
如果您使用的是非本机对象,则可以使用两种方法的混合方法.通过指针引用旧实例变量的对象和singelton类的新实例变量,但这对int,string,float等不起作用......
编辑:正如Benoit指出的那样,在第二种方法中,"set"方法应该只是一个attr_accessor.实际上,您可以设置实例变量而无需定义新方法.通过item.instance_variable_set(:@, "cao")
| 归档时间: |
|
| 查看次数: |
1199 次 |
| 最近记录: |