我正在创建一个类(比如说,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是私有的)

10-06 10:38