Ruby:如何确定一个对象是否是单例对象

Ruby:如何确定一个对象是否是单例对象,ruby,singleton,Ruby,Singleton,Ruby文档用于: 返回obj的单例类。此方法将创建一个新的 如果obj没有单例类,则为单例类 因此,(尽管有一些注释)一个对象并不总是有一个单例类。在下面我将一个对象称为singleton,如果这个对象有singleton类 新创建的对象没有单例类,因此不是单例: a = "string" # => "string" # not (yet) a singleton b = String.new("another one")

Ruby文档用于:

返回obj的单例类。此方法将创建一个新的 如果obj没有单例类,则为单例类

因此,(尽管有一些注释)一个对象并不总是有一个单例类。在下面我将一个对象称为singleton,如果这个对象有singleton类

新创建的对象没有单例类,因此不是单例:

a = "string"                     # => "string"          # not (yet) a singleton
b = String.new("another one")    # => "another one"     # not (yet) a singleton
[a.class, b.class]               # => [String, String]
Marshal.dump(a, $stdout)
# TypeError: singleton can't be dumped

Marshal.dump(b, $stdout)
# TypeError: singleton can't be dumped
只有在定义了singleton方法之后,对象才会成为singleton

def a.greet
  "hello"
end
或者,由于为对象的单例类定义了类变量而创建了单例类之后

class << b
  @var = 42
end
仅需调用Marshal.dump即可揭示对象是否为单例:

a = "string"                     # => "string"          # not (yet) a singleton
b = String.new("another one")    # => "another one"     # not (yet) a singleton
[a.class, b.class]               # => [String, String]
Marshal.dump(a, $stdout)
# TypeError: singleton can't be dumped

Marshal.dump(b, $stdout)
# TypeError: singleton can't be dumped

有没有其他更优雅的方法来确定一个物体是否是单体的?

经过一些额外的研究后,我正在更新这个答案。感谢他对我的问题的深刻回答

您可以使用两个单例方法来确定对象是否包含阻止封送的“实质性”单例

a = "string-a"
b = "string-b"
c = "string-c"

def a.greet
  "hello"
end

class << b
  @var = 42
end

def no_substantial_singleton?(obj)
  obj.singleton_class.instance_methods(false).empty? &&
  obj.singleton_class.instance_variables.empty?
end

def marshal_if_possible(obj)
    puts Marshal.dump(obj) if no_substantial_singleton?(obj)
end

marshal_if_possible(a) #=>
marshal_if_possible(b) #=>
marshal_if_possible(c) #=> 'string-c:ET'
a=“string-a”
b=“字符串-b”
c=“string-c”
问候
“你好”
终止
班
如果可能,封送(b)#=>
如果可能的话封送(c)#=>'string-c:ET'

你能澄清你的问题吗?Ruby中的每个对象都有一个singleton类。Ruby中的每个对象始终是其singleton类的singleton实例。你所说的“对象是一个单体”到底是什么意思?你对“成为一个单身汉”的确切定义是什么?此外,你可以简单地使用
“a”。singleton_class
你的意思是给定方法
m=a.method(:greet)
你想知道它是否定义在一个单身汉类上吗?如果是这样,
m.owner.singleton_类?#=>正确
,而
为C类;问候;终止终止C.new.method(:greet).owner.singleton_class#=>false?
请参阅。(@Jörg,请评论逻辑。)@JörgWMittag我已经澄清了我的问题。@MarcinKołodziej是的,我可以。但如果还不存在,它将创建一个单例类。我不想创造一个。我只是想知道这个物体是否已经有了。这适用于我的问题中的对象
a
。但不幸的是,不是对象
b
。你好,Min-Soo。我已经更新了我的答案,并用对象b解决了这个问题。