既存の特異メソッドモジュール

Perlで特異メソッドでは「標準モジュールにも特異メソッドを実現するものはない」と書いたが,そういえばPerl 5.10.0から標準モジュールになったObject::Accessorというものがあることを思い出した。これは直接特異メソッドを定義するのではないが,振る舞いとしては特異メソッドそのものである。実際,Class::Monadicもadd_field()というアクセサを作成する機能を提供している。
Object::AccessorのSYNOPSISより:

    ### using the object as base class
    package My::Class;
    use base 'Object::Accessor';

    $obj   = My::Class->new;            # create base object
    $bool  = $obj->mk_accessors('foo'); # create accessors, etc...

しかし,その実装はClass::Monadicとはまったく異なる。
Class::Monadicが実際に新しいクラス(シンボルテーブル)を作成するのに対し,Object::Accessorでは特異メソッドの処理をAUTOLOADで行っている。したがって,アクセサの定義は早いが呼び出しは非常に遅い。また,この機能を使うためにはObject::Accessorを継承しなければならず,既存のクラスに対して特異メソッドを定義することはできない。

なお,CPANにあるClass::Componentも特異メソッドを定義するコンポーネントを提供している*1。こちらの実装はClass::Monadicと同様であり,新しいクラスを作成してそのクラスにメソッドを定義している。
使用法は以下の通り:

#!perl -w
use strict;
{
  package MyClass;
  use Class::Component;
  __PACKAGE__->load_components(qw(Autocall::SingletonMethod));
  package MyComponent;
  use base qw(Class::Component::Plugin);
  sub hello{
    print "Hello, world!\n";
  }
}
my $o = MyClass->new();
$o->register_method(
  hello => 'MyComponent',
);
$o->hello();
__END__

これはその場で特異メソッドを定義するというより,オブジェクトに特異的にコンポーネントを組み込むという感じだろうか。これは以下に示すように,Class::Monadic->inject_base()に近い機能であるように見える:

#!perl -w
use strict;
use Class::Monadic;
{
  package MyClass;
  sub new{
    bless {}, shift;
  }
  package MyComponent;
  sub hello{
    print "Hello, world!\n";
  }
}
my $o = MyClass->new();
Class::Monadic->initialize($o)->inject_base('MyComponent');
$o->hello();
__END__

いずれにせよ実装のための基本的な考え方は同じである。

*1:id:yappoのブクマコメントより。