Ruby:是否可以在不对类名进行硬编码的情况下确定我的Ruby方法正在执行的类?

时间:2017-01-08 21:24:59

标签: ruby

我是Ruby的Nuby。我正在寻找一种方法来获取当前执行行的方法的包含Class对象。这可能没有硬编码类名吗?

# hardcoded example
class A
  def to_s
    "I am a " + A.to_s   # Class "A" is hardcoded here. Is there another way to reference the class A?
  end
end

我认为self.class可能会有效,但是当这个类被子类化时,它并没有给我我想要的东西。

# Following Outputs=> I am a Camel I am a Camel I am a Camel
# but I want       => I am a Camel I am a Mammal I am a Animal

class Animal
  def to_s
    "I am a " + self.class.to_s
  end
end

class Mammal < Animal
  def to_s
    "I am a " + self.class.to_s + " " + super
  end
end

class Camel < Mammal
  def to_s
    "I am a " + self.class.to_s + " " + super
  end
end

puts Camel.new()

那么,是否存在允许访问包含类的关键字,方法或其他内容?

2 个答案:

答案 0 :(得分:5)

您需要Class#ancestors

Camel.ancestors
#=> [Camel, Mammal, Animal, Object, Kernel, BasicObject]

您将获得比您定义的课程更多的课程,因此您需要停留在Object

class Animal
  def to_s
    "I am a " + self.class.ancestors.take_while{|klass| klass != Object}.join(' and a ')
  end
end

class Mammal < Animal
end

class Camel < Mammal
end

puts Animal.new
# => I am a Animal
puts Mammal.new
# => I am a Mammal and a Animal
puts Camel.new
# => I am a Camel and a Mammal and a Animal

ancestors可以是模块或类,所以如果你只想要类,你可以使用:

def to_s
  "I am a " + self.class.ancestors.take_while{|klass| klass < Object}.join(' and a ')
end
  

那么,是否存在允许访问的关键字,方法或其他内容   包含类?

我找不到一个。添加

puts method(__method__).owner

Animal#to_sMammal#to_s仍会返回Camel

答案 1 :(得分:3)

试试这个

Class.nesting.first

这为您提供了方法的定义类。

class A
  def example
    { defining_class: Class.nesting.first, self_class: self.class }
  end
end

class B < A
end

B.new.example
# => {:defining_class=>A, :self_class=>B}