我正在创建一个类(比如说,Bar
)来让另一个类(比如说,Foo#bar
)的方法返回一个对象,几乎MatchData
对象是由Regexp#match
返回的。
但是这个类没有MatchData
!
我知道我不需要模仿.new
实现,但我想理解它,并知道当我发现它有趣时如何去做假设我不希望客户端创建MatchData
对象,除非通过调用Bar
。
问题:
在内部,如何在没有Foo#bar
的情况下创建MatchData
对象?
我如何实现它(是否模仿)?
最佳答案
MatchData.new
方法是:
rb_cMatch = rb_define_class("MatchData", rb_cObject);
rb_define_alloc_func(rb_cMatch, match_alloc);
rb_undef_method(CLASS_OF(rb_cMatch), "new"); // <- here
在纯Ruby中也可以通过explicitly undefined:
class Bar
class << self
undef_method :new
end
def initialize
@bar = '123' # <- for demonstration purposes
end
end
尝试调用
undef_method
将导致错误:Bar.new #=> undefined method `new' for Bar:Class (NoMethodError)
要创建不带
Bar.new
方法的新实例,可以手动调用new
(也可以调用allocate
):bar = Bar.allocate #=> #<Bar:0x007f9eba047cd8>
Bar.send(:initialize) #=> "123"
bar #=> #<Bar:0x007fd8e0847658 @bar="123">
(
initialize
是必需的,因为send
是私有的)