如何确定一个方法定义的类?

时间:2016-01-12 11:14:53

标签: ruby reflection

我想动态确定当前方法定义的类。

以下是我正在尝试做的一个静态示例:

class A
  def foo
    puts "I was defined in A"
  end
end

class B < A
  def foo
    puts "I was defined in B"
    super
  end
end

A.new.foo
# I was defined in A

B.new.foo
# I was defined in B
# I was defined in A  <- this is the tricky one

如何使用动态表达式替换上面字符串中的AB

显然,#{self.class}不起作用。 (它会为I was defined in B)打印B两次

我怀疑答案是“你不能”,但也许我忽视了一些事情。

3 个答案:

答案 0 :(得分:5)

这个怎么样?

class A
  def foo
    puts "I was defined in #{Module.nesting.first}"
  end
end

class B < A
  def foo
    puts "I was defined in #{Module.nesting.first}"
    super
  end
end

根据WandMaker的建议进行了更正。

答案 1 :(得分:3)

您可以使用Module.nesting.first

然而,请注意,这纯粹是词法上的,与常量分辨率的工作方式相同,因此如果您有更多动态需求,它不会削减它:

Foo = Class.new do
  def foo
    Module.nesting
  end  
end

Foo.new.foo # => []

答案 2 :(得分:3)

我有这种唠叨的感觉,如果你能做到这一点,它会违反面向对象的封装,虽然我不能完全指责确切原因。所以,这很难让人感到意外。

如果您愿意修改方法定义,我可以看到一种方法:

class A
  this = self
  define_method(:foo) do
    puts "I was defined in #{this}"
  end
end

class B < A
  this = self
  define_method(:foo) do
    puts "I was defined in #{this}"
    super()
  end
end

A.new.foo
# I was defined in A

B.new.foo
# I was defined in B
# I was defined in A