Ruby 如何以编程方式删除;“单身信息”;在一个实例上使其封送?

Ruby 如何以编程方式删除;“单身信息”;在一个实例上使其封送?,ruby,singleton,metaprogramming,marshalling,Ruby,Singleton,Metaprogramming,Marshalling,我创建了一个由于“在运行时执行单例元类定义”而无法封送的对象(代码的描述正确吗?) 这由以下代码执行: # define class X that my use singleton class metaprogramming features # through call of method :break_marshalling! class X def break_marshalling! meta_class = class << self self

我创建了一个由于“在运行时执行单例元类定义”而无法封送的对象(代码的描述正确吗?)

这由以下代码执行:

# define class X that my use singleton class metaprogramming features
# through call of method :break_marshalling!
class X
   def break_marshalling!
     meta_class = class << self
       self 
     end
     meta_class.send(:define_method, :method_y) do 
      return 
    end
  end
end

# prepare my instance of X now
instance_of_x = X.new

# marshalling fine here
Marshal.dump instance_of_x

# break marshalling with metprogramming features
instance_of_x.break_marshalling!

Marshal.dump instance_of_x
# fails with TypeError: singleton can't be dumped 
#定义使用单例类元编程功能的类X
#通过调用方法:中断编组!
X类
def break_编组!
meta_class=class您可以:


我不认为有这样的事情是
删除单例类信息,但您可以尝试通过编程取消singleton类中的定义

根据Marshal的说法,他不喜欢使用单例方法的对象。通过一些实验,它似乎也不喜欢带有带有实例变量的单例类的对象

class Foo
  def break_marshal
    singleton_class.class_eval do
      @@x = true
      @x = false
      define_method :bar do
        puts @@x
        puts singleton_class.instance_variable_get(:@x)
        puts singleton_class.send(:baz)
        puts singleton_class.const_get(:X)
      end
      define_singleton_method :baz do
        "Singleton method in a singleton"
      end
    end
  end

  def fix_marshal
    singleton_methods.each { |m| singleton_class.send(:remove_method, m) }
    singleton_class.class_eval do
      instance_variables.each { |v| remove_instance_variable v }
    end
  end
end

f = Foo.new
f.break_marshal
f.singleton_class.const_set(:X, 1)
f.bar
f.fix_marshal

Marshal.dump f
请注意,我是多么努力地试图打破元帅。我给了singleton一个类变量、一个实例变量、一个方法、它自己的singleton方法和一个常量。但是,如果只删除singleton方法和实例变量,封送处理就可以正常工作

然而,我认为这不是封送这样一个对象的正确方法@mdesantis关于定义自己的
封送转储
封送加载
的回答更为恰当。

实例中(通常)删除单例信息的一种线性方法:

instance_of_x = instance_of_x.dup

我提出了这个方法,它递归地从对象和分配给实例变量的对象中删除singleton_方法:

def self.strip_singleton(obj)
  obj = obj.dup unless (obj.nil? || obj.singleton_methods.empty?)
  obj.instance_variables.each do |var|
    obj.instance_variable_set(var, strip_singleton(obj.instance_variable_get(var)))
  end
  obj
end

你的意思是说,在我看到问题之前,我在你的答案中注意到了它。哦,首先谢谢你的回答。询问者实际上并没有在代码中使用这种添加单例方法的方法,而是尝试封送由其项目中使用的库创建的对象。顺便说一句,他对理解ruby内部的行为也很感兴趣。克里斯,为什么你指的是第三人称中的询问者???你不是那个询问者吗???我很困惑!!!:实际上我是。所以你真的可以停止困惑了。问得好,但你引起了我最大的不满!它叫“世界杯”。我们也不需要发送hack。那么@Max你有没有遇到过通过编程方式“重置”任何ruby类实例的singleton_类的方法?类似于
remove\u singleton\u class\u信息也许?;)
instance_of_x = instance_of_x.dup
def self.strip_singleton(obj)
  obj = obj.dup unless (obj.nil? || obj.singleton_methods.empty?)
  obj.instance_variables.each do |var|
    obj.instance_variable_set(var, strip_singleton(obj.instance_variable_get(var)))
  end
  obj
end