在打开的单例类中调用单例类方法
Posted
技术标签:
【中文标题】在打开的单例类中调用单例类方法【英文标题】:Calling Singleton Class Methods Inside Open Singleton Class 【发布时间】:2020-01-01 18:19:38 【问题描述】:我试图理解为什么我不能从开放类中调用单例类上定义的方法,但我可以从实际类中调用。
谁能解释为什么第一个例子失败而第二个例子没有?
class One
class << self
def one; end
one
end
end
NameError (undefined local variable or method 'one' for #<Class:One>)
class Two
class << self
def one; end
end
self.one
end
=> nil
【问题讨论】:
我认为(如果我错了,请有人纠正我)元类习语更像是模块扩展而不是继承模式,例如module One; def one; end; end
然后 class Two; extend One; end
在这种情况下 One
没有方法 one
但是通过扩展 Two
有。因此One.one #=> NoMethodError
但是Two.one
工作正常
【参考方案1】:
你的例子比它需要的更令人困惑。它根本不需要单例类:
class Foo
def bar; end
bar # NameError
end
Foo.new.bar
在这里,我们有一个类Foo
和一个实例方法bar
。单例类仍然只是一个类,所以这实际上与您的示例完全相同。
def
没有显式定义,定义了最接近的词法封闭类定义的实例方法,在本例中为 Foo
。没有像bar
这样的显式接收者发送的消息将消息发送到self
。在类定义体内,self
是类本身。
所以,def bar
在Foo
中定义了一个实例方法,即您可以在Foo
的实例 上调用的方法。
类定义体内的bar
向self
发送消息,即Foo
。由于Foo
不是自身的实例,所以没有名为bar
的方法,所以,方法调用失败。
这与单例类完全相同,因为它仍然只是一个类。
【讨论】:
【参考方案2】:首先,您对方法所属的位置做出了错误的假设。从类上下文中调用实例方法one
应该不会成功。在您的第一个 sn-p 中,您尝试从 One
的单例类的单例类中调用方法 one
(因为它是从 singleton_class
上下文中调用的)。
用普通类/实例方法举例说明:
class One
def self.one()
puts :class
end
def one
puts :instance
end
one()
end
#⇒ class
因此,预期的行为将是提高NameError
。现在答案很简单:它引发了NameError
,因为这个方法不存在。
【讨论】:
以上是关于在打开的单例类中调用单例类方法的主要内容,如果未能解决你的问题,请参考以下文章