在Ruby中传递类或字符串化的类名是否更好?
例如,我有一个解析器/构建器,可以确定已解析记录的类类型。我将它传递给导入器类,但我可以将类的名称作为字符串或常量传递。有没有理由不去做其中一个?
x = ParsedRecord.new(value: 1, type: MyClass)
VS
x = ParsedRecord.new(value: 2, type: 'MyClass')
进口商要么:
x.type.new
VS
x.type.constantize.new
传递类似乎更容易但是我没有看到它很多(即.Rails使你为关联的类名字符串化)。也许它与加载顺序/自动加载有关?
答案 0 :(得分:2)
除非你需要延迟加载类名,否则最好直接传递常量。
原因是因为将String转换为相应的类名常量是一个额外的步骤,并将为执行添加一些开销。如果您已有类名,请将其传递给它。将它转换为字符串,然后再转换为常量是没有优势的。
原因是因为你看到在其他库中传递的字符串,是因为为了传递MyClass
作为参数,必须加载类定义。在某些情况下,例如在Rails中,您正在引用一个将延迟加载的类的类名(这是rescue_from
宏的典型情况)。使用String并不会强制您加载类定义,直到您有效地需要它为止。
答案 1 :(得分:2)
类就像任何其他类一样是一个对象。所以,这真的不是关于课程。
只要问问自己:你宁愿将一个对象作为参数传递,还是在一个某个范围内包含某个变量名称的String
,然后再将元编程转换为一个对象?
哦,那些没有名字的课程怎么样?或者其名称与可通过的变量相对应?
a = Class.new
a.name
# => nil
# has no name
A = a
a.name
# => 'A'
# has name A, is reachable via A and a
A = nil
a.name
# => 'A'
# still has name A, but is no longer reachable via A, only a
B = a
a = nil
B.name
# => 'A'
# still has name A, but is now only reachable via B
传递类本身也允许您只创建一个内联的匿名类,例如作为单元测试的存根:
ParsedRecord.new(value: 1, type: Class.new)
ParsedRecord.new(value: 2, type: Class.new do def initialize; @foo = 42 end end)