获取没有父名的Ruby纯类名,任何直接的方法吗?

时间:2014-09-26 10:38:38

标签: ruby

我经常需要获取对象的纯类名,如下面的代码所示:

class Foo
    class Bar

    end
end
obj = Foo::Bar.new
puts obj.class.name  # It shows "Foo::Bar", while what I want is just "Bar"

我知道它可以通过obj.class.name.split(' ::')完成。但是,不应该有一个方法只需返回" Bar& #34; ?

4 个答案:

答案 0 :(得分:2)

在vanilla Ruby中,我非常确定class.name.split('::').last是最好的选择。但是,如果您碰巧使用ActiveSupport(如果您正在使用Rails,那么将加载此库)会有一个名为demodulize的变形器。

class Foo
    class Bar
    end
end
obj = Foo::Bar.new
puts obj.class.name.demodulize # => Bar

答案 1 :(得分:2)

类在Ruby中确实没有“名称”。类是与任何其他对象一样的对象,它像任何其他对象一样被分配给变量。类没有名称,就像数字或字符串没有名称一样。

举个例子:

foo = Class.new

Bar = foo
Baz = foo

Bar = nil
remove_const :Bar

在这个例子中,该类的“名称”应该是什么?

嗯, name类中名为Module的方法。它的作用如下: if 第一次将类对象分配给常量,该常量的名称(注意,即使 是一个模糊概念!)成为类的名称,否则名称将只是nil

扩展上面的示例:

foo = Class.new

foo.name
# => nil

Bar = foo

foo.name
# => 'Bar'
Bar.name
# => 'Bar'

Baz = foo

Baz.name
# => 'Bar'

Bar = nil
remove_const :Bar

foo.name
# => 'Bar'

这是另一个例子:

foo = Class.new
Bar = foo
Baz = foo

class Baz
  class Quux; end

  Xyzzy = Quux
end

foo::Xyzzy.name
# => 'Bar::Quux'

请注意,即使在Quux内定义Baz并通过foo::Xyzzy访问,它仍会打印Bar::Quux作为其名称。

此外,两个不同的类可以具有相同的名称:

Foo = Class.new

Bar = Foo

Foo = nil
remove_const :Foo

Foo = Class.new

Baz = Foo

Foo = nil
remove_const :Foo

Bar.name
# => Foo

Baz.name
# => Foo

Bar == Baz
# => false

类的“名称”只是人类读者的调试帮助,你应该从不将其用于其他任何东西,并且永远不要以编程方式使用它(或者甚至取决于它的特定结构)字符串)。

答案 2 :(得分:0)

不,没有方法只返回类的名称。从技术上讲,只有包含任何外部模块和类别时,名称才是准确的。

#name类定义Module方法; see the documentation了解更多信息。

答案 3 :(得分:0)

基于thomax的答案,我对此进行了研究...

require 'benchmark'

class String
  def demodulize
    self[(rindex('::') || -2) + 2..-1]
  end

  def split_last
    split('::').last
  end

  def demodulize_vs_split_last n = 5000000
    Benchmark.bm(10) do |x|
      x.report('split_last') { n.times { split_last } }
      x.report('demodulize') { n.times { demodulize } }
    end
  end
end

得到了:

> 'Core::String'.demodulize_vs_split_last
                 user     system      total        real
split_last   1.960688   0.008501   1.969189 (  1.983187)
demodulize   1.807694   0.005815   1.813509 (  1.826771)

对于短字符串,它与大多数相似

> 'Core::Exten::sions::String::Inf::lect::ions'.demodulize_vs_split_last
                 user     system      total        real
split_last   4.386797   0.024131   4.410928 (  4.447739)
demodulize   1.875757   0.005089   1.880846 (  1.895737)

但是如果您的课程嵌套得更深,split('::').last会变得更慢