如何用Ruby原生代码实现类的括号式实例化(替代.new())
自定义Ruby类实现括号式实例化的纯Ruby方案
首先得明确:Ruby里Pathname(...)、Integer(...)这类写法不是类的原生构造语法,本质是调用Kernel模块中预定义的同名方法——这些方法由Ruby用C实现,内部逻辑就是创建对应类的实例(或做类型转换)。
对于自定义类,纯Ruby环境下,除了给全局作用域(或Kernel模块)添加同名方法,没有其他原生方式能实现类名(...)的实例化写法。不过可以更规范地把方法挂载到Kernel模块,和内置类的实现逻辑对齐:
module Kernel def Foo(*args) Foo.new(*args) end private :Foo # 可选,让方法仅能在私有上下文调用,和内置方法行为一致 end # 测试用自定义类 class Foo def initialize(*args) @args = args end end # 调用测试 Foo(1, 2, 3) # => #<Foo:0x00007f8b9c12d3a8 @args=[1, 2, 3]>
为什么这是唯一的纯Ruby方案?
Ruby的语法规则里,标识符(...)就是调用对应名称的方法:
Foo.new(...)是调用Foo类的new类方法;- 而
Foo(...)是调用当前上下文里名为Foo的方法,内置类能这么用完全是因为Kernel模块提前提供了同名方法。
你之前用到的Object.define_method(:Foo)本质和上面的方案等价——因为Object类包含了Kernel模块,给Object添加方法和给Kernel添加方法,最终在全局上下文都能访问到。
如果想完全避免手动添加方法,纯Ruby没有其他原生手段:Ruby本身没有为自定义类提供自动生成这类Kernel方法的语法糖,这个特性是内置类通过C扩展实现的专属机制。
内容的提问来源于stack exchange,提问作者RoUS
相关产品推荐
相关产品推荐

