简体   繁体   English

Ruby:is_a? 和instance_of? 在BasicObject中

[英]Ruby: is_a? and instance_of? in BasicObject

How do is_a? is_a怎么样? and instance_of? 和instance_of? methods work with a subclass of BasicObject ? 方法与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 ???

::Kernel.send(name,*args, &blk) calls the method name on the class Kernel with the arguments args and the block &blk . ::Kernel.send(name,*args, &blk)使用参数args和块&blk调用类Kernel上的方法name

When you run my.is_a? My 当您运行my.is_a? My my.is_a? My name is :is_a? my.is_a? My name:is_a? , *args is My , and &blk is nil . *argsMy&blknil You're really running Kernel.is_a? My 您真的在运行Kernel.is_a? My Kernel.is_a? My . Kernel.is_a? My

Instead, if you want to reimplement is_a? 相反,如果要重新实现is_a? for BasicObject you can walk your class's ancestors ... 对于BasicObject您可以遍历类的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

You can steal is_a? 你可以偷is_a? from Kernel : 来自Kernel

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

If you're going to build your own object hierarchy, you could also define your own Kernel , something like: 如果要构建自己的对象层次结构,则还可以定义自己的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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM