Ruby 从singleton方法访问实例变量
如何从singleton方法访问实例变量Ruby 从singleton方法访问实例变量,ruby,singleton,Ruby,Singleton,如何从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 您试
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
您试图在
Test
类上设置实例变量并在字符串实例中检索它,这些对象不同,不共享实例变量。您可以执行以下操作在两个实例之间传递它:
class Test
def initialize(a)
@a = a
end
def item
item = "hola"
item.singleton_class.send :attr_accessor, :a
# set the item's @a with the Test instance one
item.a = @a
def item.singl
[self, @a].join(" + ")
end
item
end
end
test = Test.new("cao")
item = test.item
puts item.singl
尝试使用define_方法。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的singleton类中,还没有定义。这主要是因为在此上下文中self是字符串实例,而不是存在@a
的测试实例。要解决此问题,可以将实例变量重新绑定到其他对象,但这可能不是您要寻找的行为。您还可以在新的singleton类中设置实例变量
比如说,
重新绑定变量
设置一个实例字符串变量
注意这两种方法之间的差异很重要。在第一种方法中,我们通过原始对象保留对原始实例变量的引用。在第二个方法中,我们创建一个新的实例变量,绑定在新的singleton类下,包含原始测试的副本。@a
如果您使用的是非本机对象,则可以同时使用这两种方法。通过指针使用singelton类新实例变量引用旧实例变量的对象,但这对int、string、float等不起作用
编辑:正如Benoit指出的,在第二种方法中,“set”方法应该只是一个attr_访问器。事实上,您可以设置实例变量,而无需定义新方法。通过
item.instance\u variable\u set(:@,“cao”)
您没有试图访问item
的实例变量item
是一个String
对象,而@a
是Test
对象Test
的一个实例变量
两者都是独立的。从项目
访问@a
的唯一方法是在项目
中引用测试
(或@a
),例如
class Test
attr_reader :a
def initialize(a)
@a = a
end
def item
item = "hola"
def item.singl
[self, @parent.a].join(" + ")
end
item.instance_variable_set(:@parent, self)
item
end
end
test = Test.new("cao")
item = test.item
item.singl
我很难理解上一个示例,您在item类中硬编码“cao”字符串,而不是获取传递给测试初始值设定项的内容。你想把它定义为属性设置器吗?我太懒了。我做出这种区分是为了说明第二种方法中的两个@a并不相同。我假设op可以推断这个方法“应该”是一个属性设置器。我会澄清的。谢谢在您的示例中,您有一个小问题。新项引用了@a的副本,而不是@a本身。这是一个问题,如果测试。a不断变化。例如,这将导致不正确的结果。项目1.1;test.a=“hi”;项目1.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
class Test
attr_reader :a
def initialize(a)
@a = a
end
def item
item = "hola"
def item.singl
[self, @parent.a].join(" + ")
end
item.instance_variable_set(:@parent, self)
item
end
end
test = Test.new("cao")
item = test.item
item.singl