=encoding euc-jp =head1 NAME =begin original Class::Accessor - Automated accessor generation =end original Class::Accessor - アクセサの自動生成 =head1 SYNOPSIS 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'); =head1 DESCRIPTION =begin original This module automagically generates accessor/mutators for your class. =end original このモジュールは、あなたのクラスに自動でアクセサ/ミューテータを生成する。 =begin original Most of the time, writing accessors is an exercise in cutting and pasting. You usually wind up with a series of methods like this: =end original 通常、アクセサを書くことはカット&ペーストの練習だ。いつも このように一連のメソッドを書くはめになる: # $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}; } # 等々... =begin original 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. =end original オブジェクト内のデータの各部分をみてみる。あるものは独特で、値のチェックや 特殊なデータ保持の技巧を行なう一方、大部分は単純な反復作業だ。繰り返される コードの山をつくるのは、「悪いスタイル」であるだけでなく、全くもって [訳補足:Perlの美徳である]無精でもない。これは真の悲劇である。 =begin original 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! =end original もしもあなたのモジュールをClass::Accessorのサブクラスにし、mk_accessors()で アクセサフィールドを宣言するなら、自動的に生成されたアクセサの一揃いを見出す だろう。このアクセサはカスタマイズさえ可能だ! =begin original The basic set up is very simple: =end original 基本的な段取りは大変シンプルだ: package My::Class; use base qw(Class::Accessor); My::Class->mk_accessors( qw(foo bar car) ); =begin original Done. My::Class now has simple foo(), bar() and car() accessors defined. =end original さあできた。My::Classには今やfoo()、bar()そしてcar()というアクセサが 定義された。 =head2 What Makes This Different? (何が違うの?) =begin original What makes this module special compared to all the other method generating modules (L<"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. =end original 他の全てのメソッド生成モジュール(L<"参考">)と比較して、このモジュールを 特別なものにしているのは何か? get()及びset()メソッドをオーバーライドする ことによって、クラス全体でアクセサの振る舞いを変更させることができる。また、 アクセサはクロージャとして実装されるので、各アクセサ用のメソッドを生成する 他の大部分の解決方法に比べて、メモリ消費が若干少なくなるはずだ。 =head2 Methods (メソッド) =over 4 =item B my $obj = Class->new; my $obj = $other_obj->new; my $obj = Class->new(\%fields); my $obj = $other_obj->new(\%fields); =begin original 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. =end original Class::Accessorは基本的なコンストラクタを提供する。これはハッシュベースの オブジェクト生成し、クラスメソッドとしてもオブジェクトメソッドとしても 呼び出すことができる。 =begin original 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... =end original オプションとして%fieldsハッシュを取り、オブジェクトの初期化に利用される (読取専用アクセサに使うと便利だ)。ハッシュのフィールドはアクセサの 名前に対応する。だから… package Foo; use base qw(Class::Accessor); Foo->mk_accessors('foo'); my $obj = Class->new({ foo => 42 }); print $obj->foo; # 42 =begin original however %fields can contain anything, new() will shove them all into your object. Don't like it? Override it. =end original だが%fieldsはどんなものでも含むことができる。new()はそれらを全て オブジェクトに押し込むだろう。それは嫌だって?オーバーライドすればよい。 =pod =item B Class->mk_accessors(@fields); =begin original 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: =end original これは@fieldsで与えられたフィールド用のアクセサ/ミューテータメソッドを 作成する。@fieldsの各フィールド用に、二つのアクセサが生成される。一つは "field()"で、もう一つは"_field_accessor()"と呼ばれる。例えば: # foo()、_foo_accessor()、bar()そして_bar_accessor()が生成される Class->mk_accessors(qw(foo bar)); =begin original See L for details. =end original 詳細はL<警告とトリック/"自動生成されたアクセサのオーバーライド">を参照のこと。 =pod =item B =item B Class->mk_ro_accessors(@read_only_fields); =begin original 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(). =end original 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); # ボッカ〜ン! あら、お行儀悪い =pod =item B Class->mk_wo_accessors(@write_only_fields); =begin original 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(). =end original mk_accessors()と同じだが、書き込み専用アクセサを生成する(つまり ミューテータだ)。このアクセサで値を取得しようとすると、例外を 投げる。このメソッドはset()だけを使い、get()は使わない。 =begin original B 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. =end original B<注意> 私はなぜこれが便利なのか完全には確信が持てない。だが、誰かがそれを 必要とすると確信している。もし使い道を知っているなら、私に教えてほしい。 [訳者:最後一文が訳せませんでした] 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; # ボッカ〜ン! このアクセサからは読めない =pod =back =begin original The rest is details. =end original 残りは詳細について。 =head1 DETAILS (詳細) =begin original An accessor generated by Class::Accessor looks something like this: =end original Class::Accessorが生成するアクセサは、このようになっている: # fooには色々なバリエーションがあるだろう sub foo { my($self) = shift; if(@_) { # set return $self->set('foo', @_); } else { return $self->get('foo'); } } =begin original 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. =end original とても単純だ。やっていることは、あなたが値をセットしたいのか取得したい のかを決定し、適切なメソッドを呼び出しているだけだ。Class::Accessorは デフォルトのget()及びset()メソッドを提供する。これはあなたのクラスで オーバーライドすることができる。これについては後で細かく扱う。 =head2 Modifying the behavior of the accessor (アクセサの振る舞いを変更する) =begin original 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(). =end original アクセサそれ自身を本当に変更するよりもむしろ、そのアクセサを呼び出す 二つのキーメソッドを単純にオーバーライドしたほうがずっと実際的だ。 すなわち、set()とget()のオーバーライドである。 =begin original If you -really- want to, you can override make_accessor(). =end original もしあなたが-本当に-望むなら、make_accessor()をオーバーライドできる。 =over 4 =item B $obj->set($key, $value); $obj->set($key, @values); =begin original set() defines how generally one stores data in the object. =end original set()は、オブジェクト内のデータを一般的にどのように保持するか定義する。 =begin original override this method to change how data is stored by your accessors. =end original このメソッドをオーバーライドすると、アクセサのデータ保持の仕方が変化する。 =pod =item B $value = $obj->get($key); @values = $obj->get(@keys); =begin original get() defines how data is retreived from your objects. =end original get()は、オブジェクトからどのようにデータを取り出すかを定義する。 =begin original override this method to change how it is retreived. =end original このメソッドをオーバーライドすると、取り出し方が変化する。 =item B $accessor = Class->make_accessor($field); =begin original Generates a subroutine reference which acts as an accessor for the given $field. It calls get() and set(). =end original $field用のアクセサとして動作するサブルーチンへのリファレンスを生成する。 それはget()とset()を呼び出す。 =begin original If you wish to change the behavior of your accessors, try overriding get() and set() before you start mucking with make_accessor(). =end original アクセサの振る舞いを変更したいなら、make_accessor()をいじくる前に get()とset()をオーバーライドしてみること。 =pod =item B $read_only_accessor = Class->make_ro_accessor($field); =begin original Generates a subroutine refrence which acts as a read-only accessor for the given $field. It only calls get(). =end original $field用の読み取り専用アクセサとして振舞うサブルーチンリファレンスを 生成する。このメソッドはget()を呼び出すだけだ。 =begin original Override get() to change the behavior of your accessors. =end original get()をオーバーライドしてアクセサの振る舞いを変更できる。 =pod =item B $read_only_accessor = Class->make_wo_accessor($field); =begin original Generates a subroutine refrence which acts as a write-only accessor (mutator) for the given $field. It only calls set(). =end original $field用の書き込み専用アクセサ(ミューテータ)として振舞う サブルーチンリファレンスを生成する。このメソッドはset()を呼び出すだけだ。 =begin original Override set() to change the behavior of your accessors. =end original set()をオーバーライドしてアクセサの振る舞いを変更できる。 =pod =back =head1 EFFICIENCY (効率) =begin original 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. =end original Class::Accessorはオートローダーを使っていない。それゆえ、あなたが 思っているよりずっと高速だ。生成されたメソッドが、あなた自身で書いた 場合に生じるであろう特別なペナルティを被ることはない。 =begin original Here's the results of benchmarking Class::Accessor, Class::Accessor::Fast, a hand-written accessor and direct hash access (generated by examples/bench). =end original 以下は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) =begin original 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. =end original Class::Accessor::Fastはあなた自身が書いた場合と同じ速さだ。その一方 Class::Accessorは柔軟性のために支払われるコストのため、倍遅くなる。 直接ハッシュにアクセスするのは約6倍高速だ。だがカプセル化と柔軟性は 提供されない。 =begin original 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. =end original もちろん、「Class::Accessorは自分で書くより倍遅い」と言えるほど単純では ない。これらは最も単純なアクセサによるベンチマークであり、 あなたのアクセサが何らかの複雑な仕事(データベースとの対話やファイル への書き込みのようなもの)の類を行なうなら、その作業にかかる時間の方が アクセサを呼び出すのにかかる時間をいっきに圧倒するだろう。その場合、 Class::Accessorとあなたが書くものとは同じ速さに向かうことになる。 =head1 EXAMPLES (例) =begin original Here's an example of generating an accessor for every public field of your class. =end original パブリックな全クラスフィールド用のアクセサ生成例。 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!'を出力 =begin original Here's a simple example of altering the behavior of your accessors. =end original アクセサの振る舞いを変更する簡単な例。 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); } =head1 CAVEATS AND TRICKS (警告とトリック) =begin original 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. =end original Class::Accessorは、その仕事を素早く効率よくやるために内部で 変わったことをやらねばならない。このため、知っておくべきいくつかの トリックとトラップとがある。 =begin original Hey, nothing's perfect. =end original やあ、完璧なものなんてないのさ。 =head2 Don't make a field called DESTROY (DESTROYという名前のフィールドをつくらないこと) =begin original 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". =end original これはまずい。DESTROYはマジカルメソッドであるため、その名前を 使ったアクセサを定義するとまずいことになるだろう。フィールド名に "DESTROY"とつけようと試みた場合、Class::Accessorはcarpする。 =head2 Overriding autogenerated accessors (自動生成されたアクセサのオーバーライド) =begin original 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: =end original あなたは自動生成されたアクセサをオーバーライドしたいと思うかもしれない。 しかもそのカスタマイズしたアクセサは、デフォルトのアクセサを呼ぶ。 例えば、入力をチェックするアクセサが欲しい場合。通常、次のような動作を 期待するだろう: 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(@_); } =begin original There's a subtle problem in the last example, and its in this line: =end original 最後の例に微妙な問題が存在する。それは次の行にある: return $self->SUPER::email(@_); =begin original 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: =end original 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); =begin original And now Foo::email() can override the generated Pure::Organic::Foo::email() and use it as SUPER::email(). =end original 今度はFoo::email()が生成されたPure::Organic::Foo::email()を オーバーライドし、それをSUPER::email()として利用できる。 =begin original 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: =end original これは恐らく私以外の万人にとって最も明快な解決方法だろう。代わりに、 私がまず理解できたのは、mk_accessors()がemail()のエイリアスである _email_accessor()を定義することだった。この解決方法を使えば、 Foo::email()は以下のように書かれるだろう: return $self->_email_accessor(@_); =begin original instead of the expected SUPER::email(). =end original これでSUPER::email()の代わりになる。 =head1 AUTHOR Michael G Schwern =head1 THANKS (謝辞) Thanks to Tels for his big feature request/bug report. =head1 SEE ALSO L =begin original These are some modules which do similar things in different ways L, L, L, L, L =end original 違う方法で似たようなことを行なうモジュール L, L, L, L, L =begin original L for an example of this module in use. =end original Lにはこのモジュールの例がある。