元编程:如何发现对象的真实类? [英] Metaprogramming: How to discover the real class of an object?

查看:86
本文介绍了元编程:如何发现对象的真实类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在开玩笑Ruby中的元编程,我做了这段代码:

I was kidding with metaprogramming in Ruby and I did this code:

class Class
  def ===(other)
    other.kind_of?(self)
  end
end
class FakeClass
  def initialize(object)
    methods.each {|m| eval "undef #{m}" if m.to_sym != :methods }
    define = proc do |m|
      eval(<<-END)
        def #{m}(*a, &b)
          @object.#{m}(*a, &b)
        rescue Object
          raise $!.class, $!.message.gsub("FakeClass", @object.class.to_s),
                $!.backtrace-[$!.backtrace[-caller.size-1]]
        end
      END
    end
    object.methods.each {|m| define[m] }
    def method_missing(name, *a, &b)
      if @object.methods.include?(name.to_s)
        define[name]
        eval "@object.#{name}(*a, &b)"
      elsif @object.methods.include?("method_missing")
        eval "@object.#{name}(*a, &b)"
      else
        super
      end
    rescue Object
      raise $!.class, $!.message.gsub("FakeClass", @object.class.to_s),
            $!.backtrace-[$!.backtrace[-caller.size-1]]
    end
    @object = object
  end
end

这将创建一个模仿对象的伪类.看:

This creates a fake class that mimics a object. Look:

a = FakeClass.new(1)  # => 1
a.class               # => Fixnum
a.methods             # => Return all Fixnum methods
a + 1                 # => 2 (is not a FakeClass)
Fixnum === a          # => true
a.something           # => NoMethodError:
                      #    undefined method `something' for 1:Fixnum
class Fixnum
  def foo
    true
  end
end

a.foo                 # => true

问题是,现在我不知道如何知道一个物体是真实的还是假的.换句话说,如果#class返回对象的真实类.存在一些纯粹的红宝石方式来区分吗?

The problem is, now I don't know how to know if a object is real or fake. In others words, if #class returns the true class of the object. Exist some pure ruby way to differentiate?

在我不知道FakeClass存在或我不知道FakeClass的名称的情况下思考.这意味着我无法编辑FakeClass来添加类似#is_fake?的方法.

Think in a scenario where I don't know that FakeClass exist or I don't know what is the name of the FakeClass. It means I can't edit the FakeClass to add a method like #is_fake?.

PS:我知道a.instance_eval {self}返回对象(不是伪造的).但是,检查a是否为伪造并没有帮助.

PS: I know that a.instance_eval {self} returns the object (not fake). But it doesn't help to check if a is fake.

推荐答案

这是另一个答案:

a = FakeClass.new(1)
b = 1
da = Marshal.dump(a)
db = Marshal.dump(b)
puts da == db            #=> false

这篇关于元编程:如何发现对象的真实类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆