【问题标题】:Ruby: is_a? and instance_of? in BasicObject红宝石:is_a?和instance_of?在基本对象
【发布时间】:2018-11-07 08:35:41
【问题描述】:

is_a 怎么样?和instance_of?方法与 BasicObject 的子类一起使用?

class My < BasicObject
  DELEGATE = [:is_a?, :instance_of?]
  def method_missing(name, *args, &blk)
    superclass unless DELEGATE.include? name
    ::Kernel.send(name,*args, &blk) 
  end
end

my = My.new
my.is_a? BasicObject  #=> true
my.is_a? My           #=> false ???
my.instance_of? My    #=> false ???

【问题讨论】:

    标签: ruby introspection delegation


    【解决方案1】:

    你可以从Kernel窃取is_a?

    class My < BasicObject
      define_method(:is_a?, ::Kernel.method(:is_a?))
    end
    
    m = My.new
    m.is_a?(My)          #=> true
    m.is_a?(BasicObject) #=> true
    m.is_a?(Object)      #=> false
    

    如果您要构建自己的对象层次结构,您还可以定义自己的Kernel,例如:

    module MyKernel
      [:is_a?, :instance_of?, :class].each do |m|
        define_method(m, ::Kernel.method(m))
      end
    end
    
    class My < BasicObject
      include ::MyKernel
    end
    

    【讨论】:

    • MyKernel 的好主意,这正是我想要的。谢谢
    【解决方案2】:

    ::Kernel.send(name,*args, &amp;blk) 使用参数args 和块&amp;blkKernel 类上调用方法name

    当您运行 my.is_a? My 时,name:is_a?*argsMy&amp;blknil。你真的在运行Kernel.is_a? My

    相反,如果您想为BasicObject 重新实现is_a?,您可以走您班级的ancestors...

      def is_a?(target)
        # I don't know how to get the current class from an instance
        # that isn't an Object, so I'm hard coding the class instead.
        return ::My.ancestors.include?(target)
      end
    

    【讨论】:

    • 您可以在is_a?的定义中使用Module#<..
    猜你喜欢
    • 2014-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 2019-03-18
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多