我经常需要获取对象的纯类名,如下面的代码所示:
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; ?
答案 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
会变得更慢