从其单例 class 中检索 Ruby 对象?
Retrieve a Ruby object from its singleton class?
可以通过以下方式从 Ruby 对象访问 singleton class:
some_object.singleton_class
是否可以进行反向操作:在单例中访问原始对象class?
class << some_object
# how to reference some_object without actually typing some_object?
end
我想干这个 :
class Example
PARENTS = []
class << PARENTS
FATHER = :father
MOTHER = :mother
PARENTS.push(FATHER, MOTHER)
end
end
并尝试用更通用的东西替换 class 中的 PARENTS
。
我不知道有任何内置方法或关键字,但您可以编写一个方法,将(单例)方法添加到对象的单例 class,返回对象本身:
class Object
def define_instance_accessor(method_name = :instance)
singleton_class.define_singleton_method(method_name, &method(:itself))
end
end
用法:
obj = Object.new #=> #<Object:0x00007ff58e8742f0>
obj.define_instance_accessor
obj.singleton_class.instance #=> #<Object:0x00007ff58e8742f0>
在您的代码中:
class Example
PARENTS = []
PARENTS.define_instance_accessor
class << PARENTS
FATHER = :father
MOTHER = :mother
instance.push(FATHER, MOTHER)
end
end
在内部,YARV 将对象存储在名为 __attached__
的实例变量中。实例变量没有通常的 @
前缀,因此在 Ruby.
中不可见或不可访问
这里有一个小的 C 扩展来公开它:
#include <ruby.h>
static VALUE
instance_accessor(VALUE klass)
{
return rb_ivar_get(klass, rb_intern("__attached__"));
}
void Init_instance_accessor()
{
rb_define_method(rb_cClass, "instance", instance_accessor, 0);
}
用法:
irb -r ./instance_accessor
> obj = Object.new
#=> #<Object:0x00007f94a11e1260>
> obj.singleton_class.instance
#=> #<Object:0x00007f94a11e1260>
>
出于好奇(请不要在家里或学校使用)
object = []
class << object
type, id = to_s[/(?<=:#<).*?(?=>)/].split(':')
ObjectSpace.each_object(Kernel.const_get(type)).find do |e|
e.__id__ == id.to_i(16) >> 1
end << :father
end
#⇒ [:father]
我们可以这样做。
def singleton_class_to_object(sc)
ObjectSpace.each_object(Object).find { |o|
(o.singleton_class == sc) rescue false }
end
o = Object.new
#=> #<Object:0x00005b52e502d030>
singleton_class_to_object(o.singleton_class)
#=> #<Object:0x00005b52e502d030>
class C; end
singleton_class_to_object(C.singleton_class)
#=> C
内联救援是处理直接对象的对象o
,没有单例类。
在 MRI v2.7.0 中,
ObjectSpace.each_object(Object).to_a.size
#=> 35362
微不足道。
可以通过以下方式从 Ruby 对象访问 singleton class:
some_object.singleton_class
是否可以进行反向操作:在单例中访问原始对象class?
class << some_object
# how to reference some_object without actually typing some_object?
end
我想干这个
class Example
PARENTS = []
class << PARENTS
FATHER = :father
MOTHER = :mother
PARENTS.push(FATHER, MOTHER)
end
end
并尝试用更通用的东西替换 class 中的 PARENTS
。
我不知道有任何内置方法或关键字,但您可以编写一个方法,将(单例)方法添加到对象的单例 class,返回对象本身:
class Object
def define_instance_accessor(method_name = :instance)
singleton_class.define_singleton_method(method_name, &method(:itself))
end
end
用法:
obj = Object.new #=> #<Object:0x00007ff58e8742f0>
obj.define_instance_accessor
obj.singleton_class.instance #=> #<Object:0x00007ff58e8742f0>
在您的代码中:
class Example
PARENTS = []
PARENTS.define_instance_accessor
class << PARENTS
FATHER = :father
MOTHER = :mother
instance.push(FATHER, MOTHER)
end
end
在内部,YARV 将对象存储在名为 __attached__
的实例变量中。实例变量没有通常的 @
前缀,因此在 Ruby.
这里有一个小的 C 扩展来公开它:
#include <ruby.h>
static VALUE
instance_accessor(VALUE klass)
{
return rb_ivar_get(klass, rb_intern("__attached__"));
}
void Init_instance_accessor()
{
rb_define_method(rb_cClass, "instance", instance_accessor, 0);
}
用法:
irb -r ./instance_accessor
> obj = Object.new
#=> #<Object:0x00007f94a11e1260>
> obj.singleton_class.instance
#=> #<Object:0x00007f94a11e1260>
>
出于好奇(请不要在家里或学校使用)
object = []
class << object
type, id = to_s[/(?<=:#<).*?(?=>)/].split(':')
ObjectSpace.each_object(Kernel.const_get(type)).find do |e|
e.__id__ == id.to_i(16) >> 1
end << :father
end
#⇒ [:father]
我们可以这样做。
def singleton_class_to_object(sc)
ObjectSpace.each_object(Object).find { |o|
(o.singleton_class == sc) rescue false }
end
o = Object.new
#=> #<Object:0x00005b52e502d030>
singleton_class_to_object(o.singleton_class)
#=> #<Object:0x00005b52e502d030>
class C; end
singleton_class_to_object(C.singleton_class)
#=> C
内联救援是处理直接对象的对象o
,没有单例类。
在 MRI v2.7.0 中,
ObjectSpace.each_object(Object).to_a.size
#=> 35362
微不足道。