Class-Accessor-0.18 > Class::Accessor
Class-Accessor-0.18

名前

Class::Accessor - Automated accessor generation

Class::Accessor - アクセサの自動生成

概要

  package Foo;

  use base qw(Class::Accessor);
  Foo->mk_accessors(qw(this that whatever));

  # Meanwhile, in a nearby piece of code!
  # Class::Accessor provides new().
  my $foo = Foo->new;

  my $whatever = $foo->whatever;    # $foo->{whatever}を取得
  $foo->this('likmi');              # $foo->{this} = 'likmi'に設定
  
  # @values = @{$foo}{qw(that whatever)}と同じ
  @values = $foo->get(qw(that whatever));
  
  # $foo->{that} = 'crazy thing'に設定
  $foo->set('that', 'crazy thing');

説明

This module automagically generates accessor/mutators for your class.

このモジュールは、あなたのクラスに自動でアクセサ/ミューテータを生成する。

Most of the time, writing accessors is an exercise in cutting and pasting. You usually wind up with a series of methods like this:

通常、アクセサを書くことはカット&ペーストの練習だ。いつも このように一連のメソッドを書くはめになる:

  # $obj->{foo}のアクセサ
  sub foo {
      my($self) = shift;

      if(@_ == 1) {
          $self->{foo} = shift;
      }
      elsif(@_ > 1) {
          $self->{foo} = [@_];
      }

      return $self->{foo};
  }


  # $obj->{bar}のアクセサ
  sub bar {
      my($self) = shift;

      if(@_ == 1) {
          $self->{bar} = shift;
      }
      elsif(@_ > 1) {
          $self->{bar} = [@_];
      }

      return $self->{bar};
  }

  # 等々...

One for each piece of data in your object. While some will be unique, doing value checks and special storage tricks, most will simply be exercises in repetition. Not only is it Bad Style to have a bunch of repetitious code, but its also simply not Lazy, which is the real tragedy.

オブジェクト内のデータの各部分をみてみる。あるものは独特で、値のチェックや 特殊なデータ保持の技巧を行なう一方、大部分は単純な反復作業だ。繰り返される コードの山をつくるのは、「悪いスタイル」であるだけでなく、全くもって [訳補足:Perlの美徳である]無精でもない。これは真の悲劇である。

If you make your module a subclass of Class::Accessor and declare your accessor fields with mk_accessors() then you'll find yourself with a set of automatically generated accessors which can even be customized!

もしもあなたのモジュールをClass::Accessorのサブクラスにし、mk_accessors()で アクセサフィールドを宣言するなら、自動的に生成されたアクセサの一揃いを見出す だろう。このアクセサはカスタマイズさえ可能だ!

The basic set up is very simple:

基本的な段取りは大変シンプルだ:

    package My::Class;
    use base qw(Class::Accessor);
    My::Class->mk_accessors( qw(foo bar car) );

Done. My::Class now has simple foo(), bar() and car() accessors defined.

さあできた。My::Classには今やfoo()、bar()そしてcar()というアクセサが 定義された。

何が違うの?

What makes this module special compared to all the other method generating modules ("SEE ALSO")? By overriding the get() and set() methods you can alter the behavior of the accessors class-wide. Also, the accessors are implemented as closures which should cost a bit less memory than most other solutions which generate a new method for each accessor.

他の全てのメソッド生成モジュール("参考")と比較して、このモジュールを 特別なものにしているのは何か? get()及びset()メソッドをオーバーライドする ことによって、クラス全体でアクセサの振る舞いを変更させることができる。また、 アクセサはクロージャとして実装されるので、各アクセサ用のメソッドを生成する 他の大部分の解決方法に比べて、メモリ消費が若干少なくなるはずだ。

メソッド

new
    my $obj = Class->new;
    my $obj = $other_obj->new;

    my $obj = Class->new(\%fields);
    my $obj = $other_obj->new(\%fields);

Class::Accessor provides a basic constructor. It generates a hash-based object and can be called as either a class method or an object method.

Class::Accessorは基本的なコンストラクタを提供する。これはハッシュベースの オブジェクト生成し、クラスメソッドとしてもオブジェクトメソッドとしても 呼び出すことができる。

It takes an optional %fields hash which is used to initialize the object (handy if you use read-only accessors). The fields of the hash correspond to the names of your accessors, so...

オプションとして%fieldsハッシュを取り、オブジェクトの初期化に利用される (読取専用アクセサに使うと便利だ)。ハッシュのフィールドはアクセサの 名前に対応する。だから…

    package Foo;
    use base qw(Class::Accessor);
    Foo->mk_accessors('foo');

    my $obj = Class->new({ foo => 42 });
    print $obj->foo;    # 42

however %fields can contain anything, new() will shove them all into your object. Don't like it? Override it.

だが%fieldsはどんなものでも含むことができる。new()はそれらを全て オブジェクトに押し込むだろう。それは嫌だって?オーバーライドすればよい。

mk_accessors
    Class->mk_accessors(@fields);

This creates accessor/mutator methods for each named field given in @fields. Foreach field in @fields it will generate two accessors. One called "field()" and the other called "_field_accessor()". For example:

これは@fieldsで与えられたフィールド用のアクセサ/ミューテータメソッドを 作成する。@fieldsの各フィールド用に、二つのアクセサが生成される。一つは "field()"で、もう一つは"_field_accessor()"と呼ばれる。例えば:

    # foo()、_foo_accessor()、bar()そして_bar_accessor()が生成される
    Class->mk_accessors(qw(foo bar));

詳細は"自動生成されたアクセサのオーバーライド" in 警告とトリックを参照のこと。

mk_ro_accessors
mk_readonly_accessors
  Class->mk_ro_accessors(@read_only_fields);

Same as mk_accessors() except it will generate read-only accessors (ie. true accessors). If you attempt to set a value with these accessors it will throw an exception. It only uses get() and not set().

mk_accessors()と同じだが、読み取り専用アクセサを生成する(つまり 真のアクセサだ)。このアクセサで値をセットしようとすると、例外を 投げる。このメソッドはget()だけを使い、set()は使わない。

    package Foo;
    use base qw(Class::Accessor);
    Class->mk_ro_accessors(qw(foo bar));

    # クラスFooのオブジェクト$fooがあると仮定しよう…
    print $foo->foo;  # ok、$foo->{foo}の値が何であろうと出力する
    $foo->foo(42);    # ボッカ〜ン! あら、お行儀悪い
mk_wo_accessors
  Class->mk_wo_accessors(@write_only_fields);

Same as mk_accessors() except it will generate write-only accessors (ie. mutators). If you attempt to read a value with these accessors it will throw an exception. It only uses set() and not get().

mk_accessors()と同じだが、書き込み専用アクセサを生成する(つまり ミューテータだ)。このアクセサで値を取得しようとすると、例外を 投げる。このメソッドはset()だけを使い、get()は使わない。

NOTE I'm not entirely sure why this is useful, but I'm sure someone will need it. If you've found a use, let me know. Right now its here for orthoginality and because its easy to implement.

注意 私はなぜこれが便利なのか完全には確信が持てない。だが、誰かがそれを 必要とすると確信している。もし使い道を知っているなら、私に教えてほしい。 [訳者:最後一文が訳せませんでした]

    package Foo;
    use base qw(Class::Accessor);
    Class->mk_wo_accessors(qw(foo bar));

    # クラスFooのオブジェクト$fooがあると仮定しよう…
    $foo->foo(42);      # OK、$self->{foo} = 42だ
    print $foo->foo;    # ボッカ〜ン! このアクセサからは読めない

The rest is details.

残りは詳細について。

詳細

An accessor generated by Class::Accessor looks something like this:

Class::Accessorが生成するアクセサは、このようになっている:

    # fooには色々なバリエーションがあるだろう
    sub foo {
        my($self) = shift;
        if(@_) {    # set
            return $self->set('foo', @_);
        }
        else {
            return $self->get('foo');
        }
    }

Very simple. All it does is determine if you're wanting to set a value or get a value and calls the appropriate method. Class::Accessor provides default get() and set() methods which your class can override. They're detailed later.

とても単純だ。やっていることは、あなたが値をセットしたいのか取得したい のかを決定し、適切なメソッドを呼び出しているだけだ。Class::Accessorは デフォルトのget()及びset()メソッドを提供する。これはあなたのクラスで オーバーライドすることができる。これについては後で細かく扱う。

アクセサの振る舞いを変更する

Rather than actually modifying the accessor itself, it is much more sensible to simply override the two key methods which the accessor calls. Namely set() and get().

アクセサそれ自身を本当に変更するよりもむしろ、そのアクセサを呼び出す 二つのキーメソッドを単純にオーバーライドしたほうがずっと実際的だ。 すなわち、set()とget()のオーバーライドである。

If you -really- want to, you can override make_accessor().

もしあなたが-本当に-望むなら、make_accessor()をオーバーライドできる。

set
    $obj->set($key, $value);
    $obj->set($key, @values);

set() defines how generally one stores data in the object.

set()は、オブジェクト内のデータを一般的にどのように保持するか定義する。

override this method to change how data is stored by your accessors.

このメソッドをオーバーライドすると、アクセサのデータ保持の仕方が変化する。

get
    $value  = $obj->get($key);
    @values = $obj->get(@keys);

get() defines how data is retreived from your objects.

get()は、オブジェクトからどのようにデータを取り出すかを定義する。

override this method to change how it is retreived.

このメソッドをオーバーライドすると、取り出し方が変化する。

make_accessor
    $accessor = Class->make_accessor($field);

Generates a subroutine reference which acts as an accessor for the given $field. It calls get() and set().

$field用のアクセサとして動作するサブルーチンへのリファレンスを生成する。 それはget()とset()を呼び出す。

If you wish to change the behavior of your accessors, try overriding get() and set() before you start mucking with make_accessor().

アクセサの振る舞いを変更したいなら、make_accessor()をいじくる前に get()とset()をオーバーライドしてみること。

make_ro_accessor
    $read_only_accessor = Class->make_ro_accessor($field);

Generates a subroutine refrence which acts as a read-only accessor for the given $field. It only calls get().

$field用の読み取り専用アクセサとして振舞うサブルーチンリファレンスを 生成する。このメソッドはget()を呼び出すだけだ。

Override get() to change the behavior of your accessors.

get()をオーバーライドしてアクセサの振る舞いを変更できる。

make_wo_accessor
    $read_only_accessor = Class->make_wo_accessor($field);

Generates a subroutine refrence which acts as a write-only accessor (mutator) for the given $field. It only calls set().

$field用の書き込み専用アクセサ(ミューテータ)として振舞う サブルーチンリファレンスを生成する。このメソッドはset()を呼び出すだけだ。

Override set() to change the behavior of your accessors.

set()をオーバーライドしてアクセサの振る舞いを変更できる。

効率

Class::Accessor does not employ an autoloder, thus it is much faster than you'd think. Its generated methods incur no special penalty over ones you'd write yourself.

Class::Accessorはオートローダーを使っていない。それゆえ、あなたが 思っているよりずっと高速だ。生成されたメソッドが、あなた自身で書いた 場合に生じるであろう特別なペナルティを被ることはない。

Here's the results of benchmarking Class::Accessor, Class::Accessor::Fast, a hand-written accessor and direct hash access (generated by examples/bench).

以下はClass::Accessor、Class::Accessor::Fast、手書きのアクセサ、及び 直接ハッシュにアクセスするやり方によるベンチマークの結果である (examples/benchで生成)。

  Benchmark: timing 500000 iterations of By Hand - get, By Hand - set, 
    C::A - get, C::A - set, C::A::Fast - get, C::A::Fast - set, 
    Direct - get, Direct - set...

  By Hand - get:  4 wallclock secs ( 5.09 usr +  0.00 sys =  5.09 CPU) 
                  @ 98231.83/s (n=500000)
  By Hand - set:  5 wallclock secs ( 6.06 usr +  0.00 sys =  6.06 CPU) 
                  @ 82508.25/s (n=500000)
  C::A - get:  9 wallclock secs ( 9.83 usr +  0.01 sys =  9.84 CPU) 
               @ 50813.01/s (n=500000)
  C::A - set: 11 wallclock secs ( 9.95 usr +  0.00 sys =  9.95 CPU) 
               @ 50251.26/s (n=500000)
  C::A::Fast - get:  6 wallclock secs ( 4.88 usr +  0.00 sys =  4.88 CPU) 
                     @ 102459.02/s (n=500000)
  C::A::Fast - set:  6 wallclock secs ( 5.83 usr +  0.00 sys =  5.83 CPU) 
                     @ 85763.29/s (n=500000)
  Direct - get:  0 wallclock secs ( 0.89 usr +  0.00 sys =  0.89 CPU) 
                 @ 561797.75/s (n=500000)
  Direct - set:  2 wallclock secs ( 0.87 usr +  0.00 sys =  0.87 CPU) 
                 @ 574712.64/s (n=500000)

So Class::Accessor::Fast is just as fast as one you'd write yourself while Class::Accessor is twice as slow, a price paid for flexibility. Direct hash access is about six times faster, but provides no encapsulation and no flexibility.

Class::Accessor::Fastはあなた自身が書いた場合と同じ速さだ。その一方 Class::Accessorは柔軟性のために支払われるコストのため、倍遅くなる。 直接ハッシュにアクセスするのは約6倍高速だ。だがカプセル化と柔軟性は 提供されない。

Of course, its not as simple as saying "Class::Accessor is twice as slow as one you write yourself". These are benchmarks for the simplest possible accessor, if your accessors do any sort of complicated work (such as talking to a database or writing to a file) the time spent doing that work will quickly swamp the time spend just calling the accessor. In that case, Class::Accessor and the ones you write will tend to be just as fast.

もちろん、「Class::Accessorは自分で書くより倍遅い」と言えるほど単純では ない。これらは最も単純なアクセサによるベンチマークであり、 あなたのアクセサが何らかの複雑な仕事(データベースとの対話やファイル への書き込みのようなもの)の類を行なうなら、その作業にかかる時間の方が アクセサを呼び出すのにかかる時間をいっきに圧倒するだろう。その場合、 Class::Accessorとあなたが書くものとは同じ速さに向かうことになる。

Here's an example of generating an accessor for every public field of your class.

パブリックな全クラスフィールド用のアクセサ生成例。

    package Altoids;
    
    use base qw(Class::Accessor Class::Fields);
    use fields qw(curiously strong mints);
    Altoids->mk_accessors( Altoids->show_fields('Public') );

    sub new {
        my $proto = shift;
        my $class = ref $proto || $proto;
        return fields::new($class);
    }

    my Altoids $tin = Altoids->new;

    $tin->curiously('Curiouser and curiouser');
    print $tin->{curiously};    # 'Curiouser and curiouser'を出力

    
    # サブクラスでも同様
    package Mint::Snuff;
    use base qw(Altoids);

    my Mint::Snuff $pouch = Mint::Snuff->new;
    $pouch->strong('Fuck you up strong!');
    print $pouch->{strong};     # 'Fuck you up strong!'を出力

Here's a simple example of altering the behavior of your accessors.

アクセサの振る舞いを変更する簡単な例。

    package Foo;
    use base qw(Class::Accessor);
    Foo->mk_accessor(qw(this that up down));

    sub get {
        my($self, @keys) = @_;

        # Note every time someone gets some data.
        print STDERR "Getting @keys\n";

        $self->SUPER::get(@keys);
    }

    sub set {
        my($self, $key, @values) = @_;

        # Note every time someone sets some data.
        print STDERR "Setting $key to @values\n";

        $self->SUPER::set($key, @values);
    }

警告とトリック

Class::Accessor has to do some internal wackiness to get its job done quickly and efficiently. Because of this, there's a few tricks and traps one must know about.

Class::Accessorは、その仕事を素早く効率よくやるために内部で 変わったことをやらねばならない。このため、知っておくべきいくつかの トリックとトラップとがある。

Hey, nothing's perfect.

やあ、完璧なものなんてないのさ。

DESTROYという名前のフィールドをつくらないこと

This is bad. Since DESTROY is a magical method it would be bad for us to define an accessor using that name. Class::Accessor will carp if you try to use it with a field named "DESTROY".

これはまずい。DESTROYはマジカルメソッドであるため、その名前を 使ったアクセサを定義するとまずいことになるだろう。フィールド名に "DESTROY"とつけようと試みた場合、Class::Accessorはcarpする。

自動生成されたアクセサのオーバーライド

You may want to override the autogenerated accessor with your own, yet have your custom accessor call the default one. For instance, maybe you want to have an accessor which checks its input. Normally, one would expect this to work:

あなたは自動生成されたアクセサをオーバーライドしたいと思うかもしれない。 しかもそのカスタマイズしたアクセサは、デフォルトのアクセサを呼ぶ。 例えば、入力をチェックするアクセサが欲しい場合。通常、次のような動作を 期待するだろう:

    package Foo;
    use base qw(Class::Accessor);
    Foo->mk_accessors(qw(email this that whatever));

    # 有効なアドレスだけを受け入れる
    sub email {
        my($self) = shift;
        my($email) = @_;

        if( @_ ) {  # セット
            require Email::Valid;
            unless( Email::Valid->address($email) ) {
                carp("$email doesn't look like a valid address.");
                return;
            }
        }

        return $self->SUPER::email(@_);
    }

There's a subtle problem in the last example, and its in this line:

最後の例に微妙な問題が存在する。それは次の行にある:

    return $self->SUPER::email(@_);

If we look at how Foo was defined, it called mk_accessors() which stuck email() right into Foo's namespace. There *is* no SUPER::email() to delegate to! Two ways around this... first is to make a "pure" base class for Foo. This pure class will generate the accessors and provide the necessary super class for Foo to use:

Fooがどのように定義されているかみてみると、Fooが呼び出した mk_accessors()は、email()をFooの名前空間に入れている。委譲するための SUPER::email()は存在*しない*! これについて二つの方法がある…一つ目は Fooのために"純粋な"ベースクラスをつくること。この純粋クラスは アクセサを生成し、Fooが利用するのに不可欠なスーパークラスに提供する:

    package Pure::Organic::Foo;
    use base qw(Class::Accessor);
    Pure::Organic::Foo->mk_accessors(qw(email this that whatever));

    package Foo;
    use base qw(Pure::Organic::Foo);

And now Foo::email() can override the generated Pure::Organic::Foo::email() and use it as SUPER::email().

今度はFoo::email()が生成されたPure::Organic::Foo::email()を オーバーライドし、それをSUPER::email()として利用できる。

This is probably the most obvious solution to everyone but me. Instead, what first made sense to me was for mk_accessors() to define an alias of email(), _email_accessor(). Using this solution, Foo::email() would be written with:

これは恐らく私以外の万人にとって最も明快な解決方法だろう。代わりに、 私がまず理解できたのは、mk_accessors()がemail()のエイリアスである _email_accessor()を定義することだった。この解決方法を使えば、 Foo::email()は以下のように書かれるだろう:

    return $self->_email_accessor(@_);

instead of the expected SUPER::email().

これでSUPER::email()の代わりになる。

作者

Michael G Schwern <[email protected]>

謝辞

Thanks to Tels for his big feature request/bug report.

SEE ALSO

Class::Accessor::Fast

These are some modules which do similar things in different ways Class::Struct, Class::Methodmaker, Class::Generate, Class::Class, Class::Contract

違う方法で似たようなことを行なうモジュール Class::Struct, Class::Methodmaker, Class::Generate, Class::Class, Class::Contract

Class::DBI for an example of this module in use.

Class::DBIにはこのモジュールの例がある。