/
perltoot.pod
executable file
·3823 lines (2882 loc) · 126 KB
/
perltoot.pod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
=encoding euc-jp
=head1 NAME
=begin original
perltoot - Tom's object-oriented tutorial for perl
=end original
perltoot - トムによる Perl オブジェクト指向チュートリアル
=head1 DESCRIPTION
=begin original
Object-oriented programming is a big seller these days. Some managers
would rather have objects than sliced bread. Why is that? What's so
special about an object? Just what I<is> an object anyway?
=end original
オブジェクト指向プログラミングは、昨今のビッグセラーです。
マネージャーには、薄切りパン(訳註: 良い発明のこと)よりもむしろ
オブジェクトを持ちたがる人もいます。
どうしてでしょうか?
オブジェクトの、何がそんなに特別なんでしょうか?
そもそも、オブジェクトとは一体 I<何でしょう>?
=begin original
An object is nothing but a way of tucking away complex behaviours into
a neat little easy-to-use bundle. (This is what professors call
abstraction.) Smart people who have nothing to do but sit around for
weeks on end figuring out really hard problems make these nifty
objects that even regular people can use. (This is what professors call
software reuse.) Users (well, programmers) can play with this little
bundle all they want, but they aren't to open it up and mess with the
insides. Just like an expensive piece of hardware, the contract says
that you void the warranty if you muck with the cover. So don't do that.
=end original
オブジェクトは、きちんとした小さな使いやすい包みに包んで、複雑なふるまいを
遠くへやってしまう方法以外のなにものでもありません。
(専門家は、このことを抽象化と呼びます。)
本当に難しい問題を片付けようと、何週間もぼーっと過ごしている、
賢い人たちは、普通の人でも使える、これらの素敵なオブジェクトを作ります。
(専門家は、このことをソフトウェアの再利用と呼びます。)
オブジェクトを使う人(たぶん、プログラマ)は、自分が欲しい小さな包みを
いじることができますが、その包みを開けて、中身にちょっかいを
出そうとはしません。
ちょうど、ハードウェアの高価な部分のように、契約は次のようになっています;
「カバーをいじくれば、保証は無効になります。」
ですから、そんなことをしてはいけません。
=begin original
The heart of objects is the class, a protected little private namespace
full of data and functions. A class is a set of related routines that
addresses some problem area. You can think of it as a user-defined type.
The Perl package mechanism, also used for more traditional modules,
is used for class modules as well. Objects "live" in a class, meaning
that they belong to some package.
=end original
オブジェクトの核心は、クラスです; これは守られた小さな私的な
名前空間であり、データと関数が詰まっています。
クラスはいくつかの問題領域を扱う関連したルーチンの集合です。
クラスをユーザ定義の型と考えることもできます。
Perl のパッケージの仕組みは、より伝統的なモジュールと同じように、
クラスモジュールにも使われます。
オブジェクトは、クラスの中に、「住んで」います; つまり、
オブジェクトがいくつかのパッケージに属していることを意味します。
=begin original
More often than not, the class provides the user with little bundles.
These bundles are objects. They know whose class they belong to,
and how to behave. Users ask the class to do something, like "give
me an object." Or they can ask one of these objects to do something.
Asking a class to do something for you is calling a I<class method>.
Asking an object to do something for you is calling an I<object method>.
Asking either a class (usually) or an object (sometimes) to give you
back an object is calling a I<constructor>, which is just a
kind of method.
=end original
たいてい、クラスは、それを使う人にいくつかの小さな包みを提供します。
それらの包みがオブジェクトです。
オブジェクトは、自分が属しているクラスを知っていて、どのように振る舞うかも
知っています。
クラスを使う人は、クラスに、何かをするように、例えば
「オブジェクトをちょうだい」のように、頼むか、
オブジェクトの 1 つに何かをするように頼むことができます。
クラスに何かをするように頼むことは、I<クラスメソッド> を呼ぶことです。
オブジェクトに何かをするように頼むことは、I<オブジェクトメソッド> を
呼ぶことです。
クラス(普通)または、オブジェクト(たまに)に、オブジェクトを返すように
頼むことは、単にメソッドの一種である I<コンストラクタ> を呼ぶことです。
=begin original
That's all well and good, but how is an object different from any other
Perl data type? Just what is an object I<really>; that is, what's its
fundamental type? The answer to the first question is easy. An object
is different from any other data type in Perl in one and only one way:
you may dereference it using not merely string or numeric subscripts
as with simple arrays and hashes, but with named subroutine calls.
In a word, with I<methods>.
=end original
それはそれとして、オブジェクトは Perl の他のデータ型とどのように
違うのでしょうか?
I<実際には>、オブジェクトは…オブジェクトの基礎の型は何なのでしょうか?
最初の質問に答えるのは、簡単です。
オブジェクトは、一つの、たった一つのやり方において、Perl の他のデータ型とは
違っています。
オブジェクトをデリファレンスするのに、単純な配列やハッシュのように、
単なる文字列や数字の添字ではなく、名前の付けられたサブルーチンの呼び出しを
使います。
一言でいえば、I<メソッド> でデリファレンスします。
=begin original
The answer to the second question is that it's a reference, and not just
any reference, mind you, but one whose referent has been I<bless>()ed
into a particular class (read: package). What kind of reference? Well,
the answer to that one is a bit less concrete. That's because in Perl
the designer of the class can employ any sort of reference they'd like
as the underlying intrinsic data type. It could be a scalar, an array,
or a hash reference. It could even be a code reference. But because
of its inherent flexibility, an object is usually a hash reference.
=end original
二番目の答えは、次のようになります。
オブジェクトはリファレンスですが、ただのリファレンスではありません。
注意してください。
特別なクラス(パッケージ)に I<祝福(bless)されている> リファレンスを
持っているものです。
リファレンスの種類は?
たぶん、その質問の答えは、あまり具体的にはなりません。
Perlでは、基礎となる固有のデータ型として、リファレンスならどんな種類の
ものでも、クラス設計者の好きなように使うことが出来るからです。
リファレンスなら、スカラでも、配列でも、ハッシュでもかまいません。
コードのリファレンスすらありえます。
ですが、持ち前の柔軟性により、普通、オブジェクトはハッシュリファレンスです。
=head1 Creating a Class
(クラスを作る)
=begin original
Before you create a class, you need to decide what to name it. That's
because the class (package) name governs the name of the file used to
house it, just as with regular modules. Then, that class (package)
should provide one or more ways to generate objects. Finally, it should
provide mechanisms to allow users of its objects to indirectly manipulate
these objects from a distance.
=end original
クラスを作る前に、クラスに何という名前を付けるかを決めなければなりません。
クラス(パッケージ)の名前は、普通のモジュールと同じように、クラスを納める
ファイル名を左右します。
それから、そのクラス(パッケージ)は、一つか、それ以上の方法で、オブジェクトを
生成する方法を提供すべきです。
最後に、クラス(パッケージ)は、オブジェクトを使う人に、離れたところから
間接的にオブジェクトを操作することのできるメカニズムを提供すべきです。
=begin original
For example, let's make a simple Person class module. It gets stored in
the file Person.pm. If it were called a Happy::Person class, it would
be stored in the file Happy/Person.pm, and its package would become
Happy::Person instead of just Person. (On a personal computer not
running Unix or Plan 9, but something like Mac OS or VMS, the directory
separator may be different, but the principle is the same.) Do not assume
any formal relationship between modules based on their directory names.
This is merely a grouping convenience, and has no effect on inheritance,
variable accessibility, or anything else.
=end original
例えば、単純な Person クラスモジュールを作ってみましょう。
このクラスモジュールは、Person.pm に保存されます。
もし、このクラスモジュールが、Happy::Person クラスと呼ばれるなら、
このクラスは、Happy/Person.pm ファイルに保存されます。
そして、そのパッケージは、ただの、Person ではなく、Happy::Person になります。
(Unix か、Plan 9 ではなく、Mac OS やVMS のような OS の動いている
パーソナルコンピュータ上では、ディレクトリのセパレータは
違っているでしょうが、原則は同じです)。
ディレクトリ名のベースとなるモジュールとの間にどのような公式な関係も
想定してはいけません。
これは、単に、グループ分けを便利にしているだけで、継承や変数の
アクセシビリティなど、その他諸々に、何の効果も与えません。
=begin original
For this module we aren't going to use Exporter, because we're
a well-behaved class module that doesn't export anything at all.
In order to manufacture objects, a class needs to have a I<constructor
method>. A constructor gives you back not just a regular data type,
but a brand-new object in that class. This magic is taken care of by
the bless() function, whose sole purpose is to enable its referent to
be used as an object. Remember: being an object really means nothing
more than that methods may now be called against it.
=end original
このモジュールに Exporter は使わないでおきましょう。
私たちは行儀が良いし、行儀が良いクラスモジュールはまったく何も
export しないからです。
オブジェクトを作るためには、クラスに、I<コンストラクタメソッド> が必要です。
コンストラクタは、普通のデータ型ではなく、おろしたてのクラスのオブジェクトを
返します。
この魔法は bless() 関数によって扱われます。
bless() の唯一の目的は、リファレンスをオブジェクトとして使えるように
することです。
銘記:オブジェクトであることは、実際には、メソッドが、そのオブジェクトを
背景にして、呼ばれるということ以上に何も意味しません。
=begin original
While a constructor may be named anything you'd like, most Perl
programmers seem to like to call theirs new(). However, new() is not
a reserved word, and a class is under no obligation to supply such.
Some programmers have also been known to use a function with
the same name as the class as the constructor.
=end original
コンストラクタは好きなように名付けても構いませんが、ほとんどの
Perl プログラマはコンストラクタを、new() と呼ぶのを好むようです。
ですが、new() は予約語ではありませんし、クラスにはそういったものを供給する
義務もありません。
コンストラクタとして、クラスと同じ名前の関数を使うプログラマにがいることも
知られています。
=head2 Object Representation
(オブジェクトの表現)
=begin original
By far the most common mechanism used in Perl to represent a Pascal
record, a C struct, or a C++ class is an anonymous hash. That's because a
hash has an arbitrary number of data fields, each conveniently accessed by
an arbitrary name of your own devising.
=end original
Pascal のレコードや、C の構造体や、C++ のクラスを表すために、
Perl で使われている、もっとも一般的なメカニズムは、無名ハッシュです。
ハッシュには任意の数のデータ領域があり、自分でつけた任意の名前で、
それぞれにアクセスしやすいからです。
=begin original
If you were just doing a simple
struct-like emulation, you would likely go about it something like this:
=end original
単純な構造体風なエミュレーションをするなら、次のようにすることができます:
$rec = {
name => "Jason",
age => 23,
peers => [ "Norbert", "Rhys", "Phineas"],
};
=begin original
If you felt like it, you could add a bit of visual distinction
by up-casing the hash keys:
=end original
違いをつけたいと感じたら、大文字のハッシュキーによって、
見た目に、ちょっとした違いを加えることができます:
$rec = {
NAME => "Jason",
AGE => 23,
PEERS => [ "Norbert", "Rhys", "Phineas"],
};
=begin original
And so you could get at C<< $rec->{NAME} >> to find "Jason", or
C<< @{ $rec->{PEERS} } >> to get at "Norbert", "Rhys", and "Phineas".
(Have you ever noticed how many 23-year-old programmers seem to
be named "Jason" these days? :-)
=end original
これで、C<< $rec->{NAME} >> で、"Jason" を見付けることができるようになり、
また、C<< @{ $rec->{PEERS} } >> で、"Norbert" と、"Rhys" と "Phineas" を
得ることができます。
(昨今、どれくらい多くの、23 才のプログラマが、Jason と
名付けられているか気にしたことがありますか? :-)
=begin original
This same model is often used for classes, although it is not considered
the pinnacle of programming propriety for folks from outside the
class to come waltzing into an object, brazenly accessing its data
members directly. Generally speaking, an object should be considered
an opaque cookie that you use I<object methods> to access. Visually,
methods look like you're dereffing a reference using a function name
instead of brackets or braces.
=end original
これと同じモデルは複数のクラスでよく使われてますが、
とはいっても、クラスの外から、皆がオブジェクトにワルツを踊らせて、
そのデータメンバにずうずうしく直接にアクセスすることは、
プログラミングの礼儀正しさの頂点をよく考えたものではありません。
概して、オブジェクトは I<オブジェクトメソッド> を使ってアクセスする、
不可解なクッキーと考えるべきです。
見た目には、メソッドは、ブラケットや、ブレイスの代わりに、
関数名を使って、リファレンスをデリファレンスしているように見えます。
=head2 Class Interface
(クラスのインターフェース)
=begin original
Some languages provide a formal syntactic interface to a class's methods,
but Perl does not. It relies on you to read the documentation of each
class. If you try to call an undefined method on an object, Perl won't
complain, but the program will trigger an exception while it's running.
Likewise, if you call a method expecting a prime number as its argument
with a non-prime one instead, you can't expect the compiler to catch this.
(Well, you can expect it all you like, but it's not going to happen.)
=end original
言語には、クラスのメソッドのための正式な総合のインターフェースを
提供しているものもありますが、Perl はそうではありません。
使う人がそれぞれのクラスのドキュメントを読むのを当てにしています。
定義されていないメソッドをオブジェクトで呼んだら、Perl は、文句を
言おうとはしませんが、プログラムは、実行中に例外をおこすでしょう。
同じように、引数に素数を期待するメソッドに、素数でない数字を引数にして
呼んだとしても、コンパイラがそのことを捕らえてくれることは期待できません。
(たぶん、あなたは、コンパイラにあなたの好むすべてを期待するでしょうが、
そんなことは起こりません。)
=begin original
Let's suppose you have a well-educated user of your Person class,
someone who has read the docs that explain the prescribed
interface. Here's how they might use the Person class:
=end original
Person クラスを使う人が、よく教育された、所定のインターフェースを
説明するドキュメントを読んでいる人だと想定しましょう。
Person クラスの使いかたがここにあります:
use Person;
$him = Person->new();
$him->name("Jason");
$him->age(23);
$him->peers( "Norbert", "Rhys", "Phineas" );
=begin original
push @All_Recs, $him; # save object in array for later
=end original
push @All_Recs, $him; # 後のために、オブジェクトを配列にいれます。
printf "%s is %d years old.\n", $him->name, $him->age;
print "His peers are: ", join(", ", $him->peers), "\n";
printf "Last rec's name is %s\n", $All_Recs[-1]->name;
=begin original
As you can see, the user of the class doesn't know (or at least, has no
business paying attention to the fact) that the object has one particular
implementation or another. The interface to the class and its objects
is exclusively via methods, and that's all the user of the class should
ever play with.
=end original
上のように、そのクラスを使う人は、オブジェクトにある特定の実装があるか、
他の実装があるかを知りません(少なくとも、その事実に注意を払うかは
無関係です)。
クラスとそのオブジェクトへのインターフェースは、専らメソッド経由です。
そして、クラスを使う人はみんな、メソッドをいじるべきです。
=head2 Constructors and Instance Methods
(コンストラクタとインスタンスメソッド)
=begin original
Still, I<someone> has to know what's in the object. And that someone is
the class. It implements methods that the programmer uses to access
the object. Here's how to implement the Person class using the standard
hash-ref-as-an-object idiom. We'll make a class method called new() to
act as the constructor, and three object methods called name(), age(), and
peers() to get at per-object data hidden away in our anonymous hash.
=end original
まだ、I<誰か> は、オブジェクトに何があるかを知る必要があります。
そして、その誰かとは、クラスです。
クラスはプログラマが、オブジェクトにアクセスするのに使うメソッドを実装します。
ここに示すのは、標準的なオブジェクトのようにハッシュリファレンスを使う
イディオムを使い、Person クラスに実装する方法です。
コンストラクタとして働く new() というクラスメソッドを作りましょう。
そして、3 つのオブジェクトメソッド、name() と、age() と、peers() を作り、
オブジェクトごとに、無名ハッシュにデータを隠すようにします。
package Person;
use strict;
=begin original
##################################################
## the object constructor (simplistic version) ##
##################################################
sub new {
my $self = {};
$self->{NAME} = undef;
$self->{AGE} = undef;
$self->{PEERS} = [];
bless($self); # but see below
return $self;
}
=end original
#########################################################
## オブジェクトのコンストラクタ (単純化したバージョン )##
#########################################################
sub new {
my $self = {};
$self->{NAME} = undef;
$self->{AGE} = undef;
$self->{PEERS} = [];
bless($self); # 下を見て下さい
return $self;
}
=begin original
##############################################
## methods to access per-object data ##
## ##
## With args, they set the value. Without ##
## any, they only retrieve it/them. ##
##############################################
=end original
#####################################################
## オブジェクトごとのデータにアクセスするメソッド ##
## ##
## 引数があれば、値をセットする。引数がなければ ##
## 値を返す。 ##
#####################################################
sub name {
my $self = shift;
if (@_) { $self->{NAME} = shift }
return $self->{NAME};
}
sub age {
my $self = shift;
if (@_) { $self->{AGE} = shift }
return $self->{AGE};
}
sub peers {
my $self = shift;
if (@_) { @{ $self->{PEERS} } = @_ }
return @{ $self->{PEERS} };
}
=begin original
1; # so the require or use succeeds
=end original
1; # require か、use を成功させるために
=begin original
We've created three methods to access an object's data, name(), age(),
and peers(). These are all substantially similar. If called with an
argument, they set the appropriate field; otherwise they return the
value held by that field, meaning the value of that hash key.
=end original
オブジェクトのデータにアクセスする3つのメソッド、name()、age()、peers() を、
作りました。
これらは、実質は、すべて似たようなものです。
引数つきで呼べば、しかるべきフィールドに、値をセットし、引数がなければ、
そのフィールドに保持されている値を返します。
ハッシュのキーの値を意味します。
=head2 Planning for the Future: Better Constructors
(将来を考える: よりよいコンストラクタ)
=begin original
Even though at this point you may not even know what it means, someday
you're going to worry about inheritance. (You can safely ignore this
for now and worry about it later if you'd like.) To ensure that this
all works out smoothly, you must use the double-argument form of bless().
The second argument is the class into which the referent will be blessed.
By not assuming our own class as the default second argument and instead
using the class passed into us, we make our constructor inheritable.
=end original
たとえ、この時点でその意味することを知らなくてよくても、いつの日か継承に
悩むことになるでしょう。
(お望みなら、今のところ継承を安全に無視し、後で、継承に悩むこともできます)。
継承が、全てスムーズにうまくいくことを保証するには、bless() に2つの引数を
渡さなければいけません。
2 番目の引数はクラスですが、リファレントを祝福(bless)するクラスです。
デフォルトでは、(訳註:2 番目の引数を省略すると)2 番目の引数として自分自身の
クラスを想定します。
そのかわりに、(訳註:コンストラクタの第一引数に)渡されるクラスを使います。
こうすることで、コンストラクタは継承できるようになります。
sub new {
my $class = shift;
my $self = {};
$self->{NAME} = undef;
$self->{AGE} = undef;
$self->{PEERS} = [];
bless ($self, $class);
return $self;
}
=begin original
That's about all there is for constructors. These methods bring objects
to life, returning neat little opaque bundles to the user to be used in
subsequent method calls.
=end original
これが、コンストラクタの全てです。
これらのメソッドは、オブジェクトに命をもたらし、きちんとした、小さくて、
不可解な束をユーザに返し、次のメソッドの呼出しに使われます。
=head2 Destructors
(デストラクタ)
=begin original
Every story has a beginning and an end. The beginning of the object's
story is its constructor, explicitly called when the object comes into
existence. But the ending of its story is the I<destructor>, a method
implicitly called when an object leaves this life. Any per-object
clean-up code is placed in the destructor, which must (in Perl) be called
DESTROY.
=end original
全ての話には、始まりがあり、終わりがあります。
オブジェクトの話の始まりには、コンストラクタがあり、オブジェクトが
存在しはじめる時には、明示的にコンストラクタが呼ばれます。
オブジェクトの話の終わりは、I<デストラクタ> ですが、このメソッドは、
オブジェクトがその命を無くすときに暗黙のうちに呼ばれます。
オブジェクトごとの後かたづけのコードがデストラクタにあり、デストラクタは、
(Perl では)DESTROY と呼ばれなければいけません。
=begin original
If constructors can have arbitrary names, then why not destructors?
Because while a constructor is explicitly called, a destructor is not.
Destruction happens automatically via Perl's garbage collection (GC)
system, which is a quick but somewhat lazy reference-based GC system.
To know what to call, Perl insists that the destructor be named DESTROY.
Perl's notion of the right time to call a destructor is not well-defined
currently, which is why your destructors should not rely on when they are
called.
=end original
コンストラクタは恣意的な名前であるのに、なぜ、デストラクタは
恣意的でないのでしょうか?
その理由は、コンストラクタは、明示的に呼ばれますが、デストラクタは
そうではないからです。
デストラクタの呼出しは、Perl のガベージコレクションシステム経由で、
自動的に起こります。
素早いですが、幾分、怠惰なリファレンスに基づいた、ガベージ
コレクションシステムです。
呼ぶべきものが何かわかるように、Perl は、デストラクタが DESTROY と
名付けられることを要求します。
Perl はデストラクタを呼ぶ適切な時期を考えますが、現在のところいつ
呼ばれるかははっきり定義されていません。
このために、デストラクタは、それがいつ呼ばれるかを当てに
すべきではありません。
=begin original
Why is DESTROY in all caps? Perl on occasion uses purely uppercase
function names as a convention to indicate that the function will
be automatically called by Perl in some way. Others that are called
implicitly include BEGIN, END, AUTOLOAD, plus all methods used by
tied objects, described in L<perltie>.
=end original
なぜ、DESTORY はすべて大文字なのでしょう?
Perl は、ときどき、慣例で全て大文字の関数名を使います。
この関数は、なんらかの方法で Perl によって自動的に呼ばれるかも
しれないことを示します。
DESTROY の他に、暗黙のうちに呼ばれるものには、BEGIN や END や AUTOLOAD、
加えて、L<perltie> に書かれている、tie されたオブジェクトに使われる全ての
メソッドなどが含まれます。
=begin original
In really good object-oriented programming languages, the user doesn't
care when the destructor is called. It just happens when it's supposed
to. In low-level languages without any GC at all, there's no way to
depend on this happening at the right time, so the programmer must
explicitly call the destructor to clean up memory and state, crossing
their fingers that it's the right time to do so. Unlike C++, an
object destructor is nearly never needed in Perl, and even when it is,
explicit invocation is uncalled for. In the case of our Person class,
we don't need a destructor because Perl takes care of simple matters
like memory deallocation.
=end original
本当によいオブジェクト指向プログラム言語では、ユーザは、デストラクタが
呼ばれるときを気にしません。
起こるであろうときに、ただ、起きるのです。
どんなガベージコレクションもまったくない、低レベルの言語では、
適切な時期にデストラクタが呼び出されることをまったく当てに出来ません。
そのため、プログラマは、明示的にデストラクタを呼び、メモリや状態の
後かたづけをする必要があります。
C++ とは違って、オブジェクトのデストラクタは、ほとんど、Perl では
必要とされていません。
そして、デストラクタがあるときでさえ、明示的呼び出しは、ありません。
Person クラスの場合は、デストラクタを必要としません。
というのは、メモリの割り当て解除のような単純な問題は、
Perl が面倒をみるからです。
=begin original
The only situation where Perl's reference-based GC won't work is
when there's a circularity in the data structure, such as:
=end original
Perl のリファレンスに基づく、ガベージコレクションが働かない唯一の状況は、
データ構造に循環性があるときです。
次のようなものです:
$this->{WHATEVER} = $this;
=begin original
In that case, you must delete the self-reference manually if you expect
your program not to leak memory. While admittedly error-prone, this is
the best we can do right now. Nonetheless, rest assured that when your
program is finished, its objects' destructors are all duly called.
So you are guaranteed that an object I<eventually> gets properly
destroyed, except in the unique case of a program that never exits.
(If you're running Perl embedded in another application, this full GC
pass happens a bit more frequently--whenever a thread shuts down.)
=end original
プログラムがメモリリークをしないことを期待するなら、この場合、自己参照を
手動で削除しなければなりません。
明らかに、エラーを起こしやすい状態で、これは、ただ今できるベストなことです。
にもかかわらず、プログラムが終わるときに、そのオブジェクトのデストラクタが
全て正式に呼ばれるので、安全が保証されます。
そのため、次のことが保証されます。
プログラムが終了していない唯一の場合をのぞいて、オブジェクトが、
I<最終的に>適切に、破壊されます。
(他のアプリケーションに埋め込んで Perl を走らせているなら、この徹底した
ガベージコレクションの通過は、普段より少々頻繁に - スレッドが終了する度に -
起こります)。
=head2 Other Object Methods
(他のオブジェクトメソッド)
=begin original
The methods we've talked about so far have either been constructors or
else simple "data methods", interfaces to data stored in the object.
These are a bit like an object's data members in the C++ world, except
that strangers don't access them as data. Instead, they should only
access the object's data indirectly via its methods. This is an
important rule: in Perl, access to an object's data should I<only>
be made through methods.
=end original
今までに話しているメソッドは、コンストラクタか、他は、単純な
"データメソッド"であり、
オブジェクトに蓄えられているデータへのインターフェースです。
これらのデータは、C++ での、オブジェクトのデータメンバに少し似ています。
見知らぬ人がデータとして、オブジェクトのデータメンバに
アクセスできないことを期待します。
その代わりに、オブジェクトのデータメンバにデータメソッド経由で、
間接的にアクセスすべきです。
このことは Perl で、重要なルールです。
Perl では、オブジェクトのデータへのアクセスは、メソッドを通して I<のみ>
なされるべきです。
=begin original
Perl doesn't impose restrictions on who gets to use which methods.
The public-versus-private distinction is by convention, not syntax.
(Well, unless you use the Alias module described below in
L<Data Members as Variables>.) Occasionally you'll see method names beginning or ending
with an underscore or two. This marking is a convention indicating
that the methods are private to that class alone and sometimes to its
closest acquaintances, its immediate subclasses. But this distinction
is not enforced by Perl itself. It's up to the programmer to behave.
=end original
Perl は、誰がどのメソッドを使えるかの制限を押しつけません。
パブリック と プライベート の違いは慣例によるもので、構文にはよりません。
(たぶん、L<Data Members as Variables> に、下の方で記述する Alias モジュールを
使わない場合は)。
メソッドの名前が一つか、2 つののアンダースコアで始まっているか、
終わっているものを見ることがあるでしょう。
このマークは、慣例的に次のことを示します。
そのメソッドがそのクラスだけ、および、密接なその知合い、つまりサブクラスの
プライベートなものであることを示します。
ですが、この区別は Perl 自身によって強制されてはいません。
そう振る舞うことは、プログラマ次第です。
=begin original
There's no reason to limit methods to those that simply access data.
Methods can do anything at all. The key point is that they're invoked
against an object or a class. Let's say we'd like object methods that
do more than fetch or set one particular field.
=end original
メソッドを単純なデータにアクセスするものだけに限定する理由はありません。
メソッドは、まったく、なんでもできます。
キーポイントは、メソッドは、オブジェクトかクラスを背景に
呼び出されるということです。
たとえば、一つの特別なフィールドから値を持ってきたりセットしたりする
以上のことをするオブジェクトメソッドを示しましょう。
sub exclaim {
my $self = shift;
return sprintf "Hi, I'm %s, age %d, working with %s",
$self->{NAME}, $self->{AGE}, join(", ", @{$self->{PEERS}});
}
=begin original
Or maybe even one like this:
=end original
または、次のようなもの:
sub happy_birthday {
my $self = shift;
return ++$self->{AGE};
}
=begin original
Some might argue that one should go at these this way:
=end original
次のような方法でやると言う人もいるでしょう:
sub exclaim {
my $self = shift;
return sprintf "Hi, I'm %s, age %d, working with %s",
$self->name, $self->age, join(", ", $self->peers);
}
sub happy_birthday {
my $self = shift;
return $self->age( $self->age() + 1 );
}
=begin original
But since these methods are all executing in the class itself, this
may not be critical. There are tradeoffs to be made. Using direct
hash access is faster (about an order of magnitude faster, in fact), and
it's more convenient when you want to interpolate in strings. But using
methods (the external interface) internally shields not just the users of
your class but even you yourself from changes in your data representation.
=end original
ですが、これらのメソッドはクラス自身ですべて実行できるので、このことは
重要ではないかもしれないません。
トレードオフがあります。
直接なハッシュのアクセスはそうでない場合より速く(実際のところ、
およそ桁違いに速く)、文字列に手を加えたい時には、より便利です。
ですが、メソッド(外部のインターフェース)を使うと、内部的に、
クラスを使う人だけでなく、クラスの作者自身が、データ表現に変更を
加えることの盾にもなります。
=head1 Class Data
(クラスデータ)
=begin original
What about "class data", data items common to each object in a class?
What would you want that for? Well, in your Person class, you might
like to keep track of the total people alive. How do you implement that?
=end original
"クラスデータ" - クラスのそれぞれのオブジェクトに共通のデータアイテム - とは
なんでしょう?
何のためにクラスデータが欲しいでしょう?
たぶん、Person クラスでは、生きている人々の総数を追っておきたいでしょう。
=begin original
You I<could> make it a global variable called $Person::Census. But about
only reason you'd do that would be if you I<wanted> people to be able to
get at your class data directly. They could just say $Person::Census
and play around with it. Maybe this is ok in your design scheme.
You might even conceivably want to make it an exported variable. To be
exportable, a variable must be a (package) global. If this were a
traditional module rather than an object-oriented one, you might do that.
=end original
$Person::Census と呼ばれるグローバル変数でそういうことが I<できます>。
ですが、そのようにする唯一の理由は、人々が直接にクラスデータを
得られるようにしたい場合です。
$Person::Census と言うだけで、それをいじることが出来ます。
あなたの考えでは、そういったことは構わないのかもしれません。
ひょっとすると、変数が持ち出されることさえ、望んでいるかもしれません。
持ち出されるのであれば、(パッケージの)グローバル変数でなければなりません。
これがオブジェクト指向的なモジュールでなく、伝統的なモジュールであれば、
そうすればいいでしょう。
=begin original
While this approach is expected in most traditional modules, it's
generally considered rather poor form in most object modules. In an
object module, you should set up a protective veil to separate interface
from implementation. So provide a class method to access class data
just as you provide object methods to access object data.
=end original
クラス変数をパッケージのグローバル変数にするやり方は、ほとんどの伝統的な
モジュールで、期待されています。
ですが、このやり方は、一般的に、ほとんどのオブジェクト指向のモジュールでは、
むしろ下手なものと考えられています。
オブジェクト指向のモジュールでは、(訳註: データを)保護をするベールを設けて、
実装とインターフェースを分離します。
ですから、オブジェクトデータにアクセスするオブジェクトメソッドを
提供するのと同じように、クラスデータにアクセスするクラスメソッドを提供します。
=begin original
So, you I<could> still keep $Census as a package global and rely upon
others to honor the contract of the module and therefore not play around
with its implementation. You could even be supertricky and make $Census a
tied object as described in L<perltie>, thereby intercepting all accesses.
=end original
それで、まだ、$Census をパッケージのグローバル変数とし続けることが、
I<できますし>、そして、他人がモジュールの契約を支持し、そのために、
その実装をいじくり回さないと信頼することが I<できます>。
かなりトリッキーに、L<perltie>に記述されているように、$Census を、
tie されたオブジェクトにすることもできます。
=begin original
But more often than not, you just want to make your class data a
file-scoped lexical. To do so, simply put this at the top of the file:
=end original
ですが、たいていは、クラスデータをファイルスコープのレキシカル変数に
したいと思います。
そうするためには、ファイルの上の方で、単純に次のものを置けばいいのです:
my $Census = 0;
=begin original
Even though the scope of a my() normally expires when the block in which
it was declared is done (in this case the whole file being required or
used), Perl's deep binding of lexical variables guarantees that the
variable will not be deallocated, remaining accessible to functions
declared within that scope. This doesn't work with global variables
given temporary values via local(), though.
=end original
my() のスコープは、ふつう宣言されたブロックが終わったとき(この場合では、
全てのファイルが必要とされ、使われているとき)が期限ですが、Perl の
レキシカル変数の深い束縛は、そのスコープ内で宣言された関数に
アクセスできる間は、変数が割り当て解除されないことを保証します。
このことは、local() にて、一時的な値を与えられたグローバル変数では、
働きません。
=begin original
Irrespective of whether you leave $Census a package global or make
it instead a file-scoped lexical, you should make these
changes to your Person::new() constructor:
=end original
$Census をパッケージのグローバル変数のままにするか、代わりに、
ファイルスコープのレキシカル変数にするかどうかに関わりなく、
Person::new() コンストラクタに、次のような変更をするべきです。
sub new {
my $class = shift;
my $self = {};
$Census++;
$self->{NAME} = undef;
$self->{AGE} = undef;
$self->{PEERS} = [];
bless ($self, $class);
return $self;
}
sub population {
return $Census;
}
=begin original
Now that we've done this, we certainly do need a destructor so that
when Person is destroyed, the $Census goes down. Here's how
this could be done:
=end original
こうしたことで、もちろん、Person が壊れたときに、$Census を減らすために、
デストラクタが必要になります。
次のようにします:
sub DESTROY { --$Census }
=begin original
Notice how there's no memory to deallocate in the destructor? That's
something that Perl takes care of for you all by itself.
=end original
デストラクタ内で、割り当て解除するためのメモリがないことに、どのようにして
気づくのでしょう?
そのことは、Perl 自身が面倒をみます。
=begin original
Alternatively, you could use the Class::Data::Inheritable module from
CPAN.
=end original
代わりに、CPANから、Class::Data::Inheritable モジュールを使うことも出来ます。
=head2 Accessing Class Data
(クラスデータにアクセスする)