传递 Class 或字符串化的 class 名称?
Pass a Class or stringified class name?
在 Ruby 中传递 class 或字符串化的 class 名称更好吗?
比如我有一个parser/builder可以判断解析记录的class类型。我将其传递给进口商 class,但我可以将 class 的名称作为字符串或其常量传递。有理由不做其中之一吗?
x = ParsedRecord.new(value: 1, type: MyClass)
对
x = ParsedRecord.new(value: 2, type: 'MyClass')
进口商会:
x.type.new
对
x.type.constantize.new
通过 class 似乎 更容易 但我没有看到很多(即 Rails 让你字符串化 class 协会名称)。可能跟负载有关 order/autoloading?
除非你需要延迟加载class名称,否则最好直接传递常量。
原因是因为将 String 转换为相应的 class-name 常量是一个额外的步骤,会增加一些执行开销。如果您已经有了 class 名称,只需传递它即可。将其转换为字符串,然后再转换回常量没有任何优势。
之所以看到字符串在其他库中传递,是因为为了将 MyClass
作为参数传递,必须加载 class 定义。在某些情况下,例如在 Rails 中,您正在引用将被延迟加载的 class 的 class 名称(这是 rescue_from
宏的典型情况) .使用字符串不会强制您加载 class 定义,直到您有效地需要它。
A class 是一个与其他任何对象一样的对象。所以,这真的不是关于 classes.
问问自己:您是愿意传递一个对象作为参数,还是传递一个 String
包含某个范围内某处某个变量的名称,然后您以元编程方式再次将其转换为对象?
哦,那 class 那些没有名字的呢?或者谁的名字与访问他们的变量不对应?
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
传递 class 本身还允许您创建一个匿名的 class 内联,例如作为单元测试中的存根:
ParsedRecord.new(value: 1, type: Class.new)
ParsedRecord.new(value: 2, type: Class.new do def initialize; @foo = 42 end end)
在 Ruby 中传递 class 或字符串化的 class 名称更好吗?
比如我有一个parser/builder可以判断解析记录的class类型。我将其传递给进口商 class,但我可以将 class 的名称作为字符串或其常量传递。有理由不做其中之一吗?
x = ParsedRecord.new(value: 1, type: MyClass)
对
x = ParsedRecord.new(value: 2, type: 'MyClass')
进口商会:
x.type.new
对
x.type.constantize.new
通过 class 似乎 更容易 但我没有看到很多(即 Rails 让你字符串化 class 协会名称)。可能跟负载有关 order/autoloading?
除非你需要延迟加载class名称,否则最好直接传递常量。
原因是因为将 String 转换为相应的 class-name 常量是一个额外的步骤,会增加一些执行开销。如果您已经有了 class 名称,只需传递它即可。将其转换为字符串,然后再转换回常量没有任何优势。
之所以看到字符串在其他库中传递,是因为为了将 MyClass
作为参数传递,必须加载 class 定义。在某些情况下,例如在 Rails 中,您正在引用将被延迟加载的 class 的 class 名称(这是 rescue_from
宏的典型情况) .使用字符串不会强制您加载 class 定义,直到您有效地需要它。
A class 是一个与其他任何对象一样的对象。所以,这真的不是关于 classes.
问问自己:您是愿意传递一个对象作为参数,还是传递一个 String
包含某个范围内某处某个变量的名称,然后您以元编程方式再次将其转换为对象?
哦,那 class 那些没有名字的呢?或者谁的名字与访问他们的变量不对应?
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
传递 class 本身还允许您创建一个匿名的 class 内联,例如作为单元测试中的存根:
ParsedRecord.new(value: 1, type: Class.new)
ParsedRecord.new(value: 2, type: Class.new do def initialize; @foo = 42 end end)