日向夏特殊応援部隊

俺様向けメモ

DBIx::Class::Componentised Source Code Reading

d:id:ZIGOROu:20080317:1205779889 の続きです。

DBIx::Class::Componentisedとは

恐らくDBIC関連のdistにおける基底クラスだと考えて良いと思います。
DBIx::Classはこのクラスを継承していて、DBIx::Class::Componentisedは前回説明した、Class::C3::Componentisedを継承しています。

inject_base()

Class::C3::Componentisedでは、

特定のクラスに対して複数のコンポーネントをinjectする。 一回reverseしてからその特定のクラスがコンポーネントを継承していないならば、継承順位で先頭にどんどん突っ込んで行く。

と言う処理でした。
このinject_baseはload_*_components()で呼び出されるメソッドです。

DBIx::Class::Componentisedは同名のメソッドを定義して*1いて、

sub inject_base {
  my ($class, $target, @to_inject) = @_;
  {
    no strict 'refs';
    foreach my $to (reverse @to_inject) {
      my @comps = qw(DigestColumns ResultSetManager Ordered UTF8Columns);
           # Add components here that need to be loaded before Core
      foreach my $first_comp (@comps) {
        if ($to eq 'DBIx::Class::Core' &&
            $target->isa("DBIx::Class::${first_comp}")) {
          warn "Possible incorrect order of components in ".
               "${target}::load_components($first_comp) call: Core loaded ".
               "before $first_comp. See the documentation for ".
               "DBIx::Class::$first_comp for more information";
        }
      }
      unshift( @{"${target}::ISA"}, $to )
        unless ($target eq $to || $target->isa($to));
    }
  }

  $class->next::method($target, @to_inject);
}

となってよりDBICのcomponentに対して具体的なコードになっていて、

  • DBIx::Class::Coreがloadされるよりも前に他のcomponentがloadないしは継承されていた場合は警告を出す
  • targetに対して@ISAにinjectしたいclassunshiftしていく

となっていて、Class::C3::Componentisedと大体同じ事をやっている。(2番目のは全く同じ)
当然、このクラス内で@to_injectにあったクラスは全てtargetの@ISAに収まるからnextで呼び出されたClass::C3::Componentisedは結果的に何もしなくなる。

前者の方はqw(DigestColumns ResultSetManager Ordered UTF8Columns)とCoreの関係を追えば何故こういう処理をしているか自ずと明らかになりそうなのでスルー。

load_optional_class()

Class::C3::Componentisedのload_optional_components()から呼ばれているcomponentのフィルタ条件がこのメソッド

sub load_optional_class {
  my ($class, $f_class) = @_;
  if ($class->ensure_class_found($f_class)) {
    $class->ensure_class_loaded($f_class);
    return 1;
  } else {
    return 0;
  }
}
  • クラスが見つかって
  • ロードされてれば

真を返すのでただの存在確認。ensure_class_*()はClass::C3::Componentisedのメソッド

まとめ

  • DBIx::Class::Componentisedは別段特別な事をやってる訳じゃない

まぁClass::C3::Componentisedとほとんど変わらないって事で良さそう。

*1:overrideとはC3の場合は言わない?