/
perlboot.pod
executable file
·1903 lines (1301 loc) · 51.1 KB
/
perlboot.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
perlboot - Beginner's Object-Oriented Tutorial
=end original
perlboot - Perl オブジェクト指向導入編
=head1 DESCRIPTION
=begin original
If you're not familiar with objects from other languages, some of the
other Perl object documentation may be a little daunting, such as
L<perlobj>, a basic reference in using objects, and L<perltoot>, which
introduces readers to the peculiarities of Perl's object system in a
tutorial way.
=end original
他の言語でオブジェクトに親しんでいたのでなければ、他の Perl オブジェクトの
ドキュメントのいくつかは気力をくじかせるでしょう;
オブジェクトを使うための基本的なリファレンス L<perlobj>、Perl の
オブジェクトシステムの特性のチュートリアル的な紹介 L<perltoot> 等のように。
=begin original
So, let's take a different approach, presuming no prior object
experience. It helps if you know about subroutines (L<perlsub>),
references (L<perlref> et. seq.), and packages (L<perlmod>), so become
familiar with those first if you haven't already.
=end original
そこで、別のアプローチをとって、オブジェクトの経験がないことを
前提にしましょう。
もし、サブルーチン(L<perlsub>)や、リファレンス(L<perlref>等)、
パッケージ(L<perlmod>) を知っているのならそれが役に立ちますので、
もしまだわからなければまずそちらを先に知っておくべきでしょう。
=head2 If we could talk to the animals...
(もし動物と会話できたら…)
=begin original
Let's let the animals talk for a moment:
=end original
動物さんたちにちょっとしゃべってもらいましょう。
sub Cow::speak {
print "a Cow goes moooo!\n";
}
sub Horse::speak {
print "a Horse goes neigh!\n";
}
sub Sheep::speak {
print "a Sheep goes baaaah!\n";
}
Cow::speak;
Horse::speak;
Sheep::speak;
=begin original
This results in:
=end original
これは次の結果を得ます:
a Cow goes moooo!
a Horse goes neigh!
a Sheep goes baaaah!
=begin original
Nothing spectacular here. Simple subroutines, albeit from separate
packages, and called using the full package name. So let's create
an entire pasture:
=end original
目新しいことはありません。
別々のパッケージに分かれていて完全なパッケージ名を使って呼び出していますが、
単なるサブルーチンです。
では、牧場を作ってみましょう。
# Cow::speak, Horse::speak, Sheep::speak as before
@pasture = qw(Cow Cow Horse Sheep Sheep);
foreach $animal (@pasture) {
&{$animal."::speak"};
}
=begin original
This results in:
=end original
これは次の結果を得ます:
a Cow goes moooo!
a Cow goes moooo!
a Horse goes neigh!
a Sheep goes baaaah!
a Sheep goes baaaah!
=begin original
Wow. That symbolic coderef de-referencing there is pretty nasty.
We're counting on C<no strict refs> mode, certainly not recommended
for larger programs. And why was that necessary? Because the name of
the package seems to be inseparable from the name of the subroutine we
want to invoke within that package.
=end original
うわ。
ここにあるシンボリック coderef のデリファレンスはかなり粗雑です。
C<no strict refs> モードも考えてみると、大きなプログラムには全然向きません。
なぜその様なものが必要とされるのでしょう?
それはパッケージ名を、そのパッケージの呼び出そうとしているサブルーチンの
名前から分離できないからです。
=begin original
Or is it?
=end original
ではどうしましょう?
=head2 Introducing the method invocation arrow
(メソッド呼び出しの矢印)
=begin original
For now, let's say that C<< Class->method >> invokes subroutine
C<method> in package C<Class>. (Here, "Class" is used in its
"category" meaning, not its "scholastic" meaning.) That's not
completely accurate, but we'll do this one step at a time. Now let's
use it like so:
=end original
いまのところ、C<< Class->method >> は C<Class> パッケージの C<method>
サブルーチンを呼び出すとだけ言っておきましょう。
(ここで "Class" は "カテゴリ" の意味です; "学級" ではありません。)
完全に厳密ではありませんが、少しずつ進めていきましょう。
これは次のように使います:
# Cow::speak, Horse::speak, Sheep::speak as before
Cow->speak;
Horse->speak;
Sheep->speak;
=begin original
And once again, this results in:
=end original
そしてこれは次の結果を得ます:
a Cow goes moooo!
a Horse goes neigh!
a Sheep goes baaaah!
=begin original
That's not fun yet. Same number of characters, all constant, no
variables. But yet, the parts are separable now. Watch:
=end original
別におもしろくもありませんね。
同じ文字数ですし全て定数で変数もありません。
でも、今度はパッケージ名を分離できるのです。
次を見てください:
$a = "Cow";
$a->speak; # invokes Cow->speak
=begin original
Ahh! Now that the package name has been parted from the subroutine
name, we can use a variable package name. And this time, we've got
something that works even when C<use strict refs> is enabled.
=end original
ああ!
関数名からパッケージ名を分けれるので、パッケージ名に変数を
使うことができるのです。
そして今度は C<use strict refs> が有効であってもちゃんと機能するのです。
=head2 Invoking a barnyard
(裏庭の呼び出し)
=begin original
Let's take that new arrow invocation and put it back in the barnyard
example:
=end original
新しい矢印呼び出しを使って、裏庭の例に戻ってみましょう:
sub Cow::speak {
print "a Cow goes moooo!\n";
}
sub Horse::speak {
print "a Horse goes neigh!\n";
}
sub Sheep::speak {
print "a Sheep goes baaaah!\n";
}
@pasture = qw(Cow Cow Horse Sheep Sheep);
foreach $animal (@pasture) {
$animal->speak;
}
=begin original
There! Now we have the animals all talking, and safely at that,
without the use of symbolic coderefs.
=end original
みんなちゃんとしゃべってくれます!
また今度はシンボリック coderef を使っていなくて安全です。
=begin original
But look at all that common code. Each of the C<speak> routines has a
similar structure: a C<print> operator and a string that contains
common text, except for two of the words. It'd be nice if we could
factor out the commonality, in case we decide later to change it all
to C<says> instead of C<goes>.
=end original
でも、コードをよく見てみると、各 C<speak> 関数はよく似た構造を持っています。
C<print> 演算子と、2 語を除くと同一のテキストを含んでいるだけです。
共通箇所を分解するのはよいことです; 例えば、後で全ての C<goes> を C<says> に
変えることもできるようになります。
=begin original
And we actually have a way of doing that without much fuss, but we
have to hear a bit more about what the method invocation arrow is
actually doing for us.
=end original
また、大騒ぎすることなくそれを行う方法も実際ありますが、メソッド呼び出しの
矢印が何を行ってくれているのかについてここで少し
知っておかなければなりません。
=head2 The extra parameter of method invocation
(メソッド呼び出しの追加パラメータ)
=begin original
The invocation of:
=end original
メソッド呼び出し:
Class->method(@args)
=begin original
attempts to invoke subroutine C<Class::method> as:
=end original
は、C<Class::Method> 関数を次のように呼び出そうとします:
Class::method("Class", @args);
=begin original
(If the subroutine can't be found, "inheritance" kicks in, but we'll
get to that later.) This means that we get the class name as the
first parameter (the only parameter, if no arguments are given). So
we can rewrite the C<Sheep> speaking subroutine as:
=end original
(もし関数を見つけることができなかったときには、「継承」が走査されます。
これに関してはあとで説明します。)
これは最初のパラメータとしてクラス名を得ることを意味します
(もし引数がなければそれがただ一つのパラメータになります)。
このことから C<Sheep> のおしゃべり関数を次のように書き改めることができます:
sub Sheep::speak {
my $class = shift;
print "a $class goes baaaah!\n";
}
=begin original
And the other two animals come out similarly:
=end original
また他の動物たちも同様になります:
sub Cow::speak {
my $class = shift;
print "a $class goes moooo!\n";
}
sub Horse::speak {
my $class = shift;
print "a $class goes neigh!\n";
}
=begin original
In each case, C<$class> will get the value appropriate for that
subroutine. But once again, we have a lot of similar structure. Can
we factor that out even further? Yes, by calling another method in
the same class.
=end original
それぞれにおいて C<$class> にはその関数の特定の値を得ます。
しかしもう一度考え直してみると、かなりよく似た構造になっています。
さらに分離することはできないでしょうか?
それは同じクラスの別のメソッドを呼ぶことで可能です。
=head2 Calling a second method to simplify things
(簡単に 2 つ目のメソッドを呼び出す)
=begin original
Let's call out from C<speak> to a helper method called C<sound>.
This method provides the constant text for the sound itself.
=end original
C<speak> から補助メソッド C<sound> を呼び出してみましょう。
このメソッドはその鳴き声として固定文字列を提供します。
{ package Cow;
sub sound { "moooo" }
sub speak {
my $class = shift;
print "a $class goes ", $class->sound, "!\n";
}
}
=begin original
Now, when we call C<< Cow->speak >>, we get a C<$class> of C<Cow> in
C<speak>. This in turn selects the C<< Cow->sound >> method, which
returns C<moooo>. But how different would this be for the C<Horse>?
=end original
さて、C<< Cow->speak >> を呼び出すと C<speak> では C<$class> として
C<Cow> を得ました。
これを使って C<moooo> を返す C<< Cow->sound >> メソッドを選択します。
では C<Horse> の時はどこが変わるでしょう。
{ package Horse;
sub sound { "neigh" }
sub speak {
my $class = shift;
print "a $class goes ", $class->sound, "!\n";
}
}
=begin original
Only the name of the package and the specific sound change. So can we
somehow share the definition for C<speak> between the Cow and the
Horse? Yes, with inheritance!
=end original
パッケージ名と鳴き声の指定だけが変わりました。
ところで Cow と Horse で C<speak> の定義を共有する方法はないでしょうか?
それが継承です!
=head2 Inheriting the windpipes
(気管を継承する)
=begin original
We'll define a common subroutine package called C<Animal>, with the
definition for C<speak>:
=end original
共通の関数のパッケージとして C<Animal> を作ります;
ここで C<speak> を定義します
{ package Animal;
sub speak {
my $class = shift;
print "a $class goes ", $class->sound, "!\n";
}
}
=begin original
Then, for each animal, we say it "inherits" from C<Animal>, along
with the animal-specific sound:
=end original
次に各動物たちに対して、それぞれの鳴き声の定義と一緒に、
C<Animal> から「継承」します:
{ package Cow;
@ISA = qw(Animal);
sub sound { "moooo" }
}
=begin original
Note the added C<@ISA> array (pronounced "is a"). We'll get to that in a minute.
=end original
ここで、C<@ISA> (「イズア」と発音します))配列が加えられていることに
注意してください。
少々これについて説明します。
=begin original
But what happens when we invoke C<< Cow->speak >> now?
=end original
ところで、ここで C<< Cow->speak >> を呼び出すとなにが起こるのでしょう?
=begin original
First, Perl constructs the argument list. In this case, it's just
C<Cow>. Then Perl looks for C<Cow::speak>. But that's not there, so
Perl checks for the inheritance array C<@Cow::ISA>. It's there,
and contains the single name C<Animal>.
=end original
まず、Perl が引数リストを構築します。
今回は単純に C<Cow> だけです。
それから Perl は C<Cow::speak> を探します。
しかしそれはありません; そのため Perl は継承配列 C<@Cow::ISA> を調べます。
それは存在し、名前を一つ C<Animal> を格納しています。
=begin original
Perl next checks for C<speak> inside C<Animal> instead, as in
C<Animal::speak>. And that's found, so Perl invokes that subroutine
with the already frozen argument list.
=end original
Perl は次に C<Animal> の C<speak> を C<Animal::speak> の様に調べます。
今度は見つかりました; そこで Perl はこの関数をさっき作っておいた引数リストで
呼び出します。
=begin original
Inside the C<Animal::speak> subroutine, C<$class> becomes C<Cow> (the
first argument). So when we get to the step of invoking
C<< $class->sound >>, it'll be looking for C<< Cow->sound >>, which
gets it on the first try without looking at C<@ISA>. Success!
=end original
C<Animal::speak> 関数においては、C<$class> は C<Cow> になります
(これが一つめの引数です)。
そのため C<< $class->sound >> の呼び出しにおいて C<< Cow->sound >> を
得ます; 最初は C<@ISA> を探すことなく調べます。
そしてこれは成功します。
=head2 A few notes about @ISA
(@ISA に関して追記)
=begin original
This magical C<@ISA> variable has declared that C<Cow> "is a" C<Animal>.
Note that it's an array, not a simple single value, because on rare
occasions, it makes sense to have more than one parent class searched
for the missing methods.
=end original
この魔法の C<@ISA> 変数は、C<Cow> が C<Animal> の「一種である(is-a)」と
宣言しています。
これが単なる一つの値ではなく配列であることに注意してください;
稀ではありますが、メソッドが見つからなかったときに探す親クラスを
一つ以上もつこともあるためです。
=begin original
If C<Animal> also had an C<@ISA>, then we'd check there too. The
search is recursive, depth-first, left-to-right in each C<@ISA> by
default (see L<mro> for alternatives). Typically, each C<@ISA> has
only one element (multiple elements means multiple inheritance and
multiple headaches), so we get a nice tree of inheritance.
=end original
もし C<Animal> も C<@ISA> をもっていたらそれも同様に調べられます。
デフォルトでは、検索は C<@ISA> の中を再帰的に、深さ優先、左から右に
行われます(代替案については L<mro> を参照してください)。
典型的に、各 C<@ISA> がただ1つのみ要素を持っています
(複数の要素を持っていれば複数の継承、複数の難問を持っています);
そのため良好な継承ツリーを得ます。
=begin original
When we turn on C<use strict>, we'll get complaints on C<@ISA>, since
it's not a variable containing an explicit package name, nor is it a
lexical ("my") variable. We can't make it a lexical variable though
(it has to belong to the package to be found by the inheritance mechanism),
so there's a couple of straightforward ways to handle that.
=end original
C<use strict> を有効にしたとき、C<@ISA> は明示的なパッケージ名を
持っていないため、そしてレキシカル変数 ("my") でもないため警告を受けます。
この変数はレキシカル変数にはできません;
(継承メカニズムが探索できるように、パッケージに属していなければなりません)
これに対処する方法は 2 つあります。
=begin original
The easiest is to just spell the package name out:
=end original
一番簡単な方法はパッケージ名をつけて使うことです:
@Cow::ISA = qw(Animal);
=begin original
Or declare it as a package global variable:
=end original
またはこれをパッケージグローバル変数として宣言します:
package Cow;
our @ISA = qw(Animal);
=begin original
Or allow it as an implicitly named package variable:
=end original
もしくは暗黙に名付けられたパッケージ変数を許可することです:
package Cow;
use vars qw(@ISA);
@ISA = qw(Animal);
=begin original
If the C<Animal> class comes from another (object-oriented) module, then
just employ C<use base> to specify that C<Animal> should serve as the basis
for the C<Cow> class:
=end original
C<Animal> クラスが他の (オブジェクト指向) モジュールから来ている場合、
C<Animal> が C<Cow> クラスの規定となることを指定するために、単に
C<use base> を使います:
package Cow;
use base qw(Animal);
=begin original
Now that's pretty darn simple!
=end original
これでかなり単純になりました!
=head2 Overriding the methods
(メソッドのオーバーライド)
=begin original
Let's add a mouse, which can barely be heard:
=end original
ねずみを追加してみましょう; その声は微かでしょう。
# Animal package from before
{ package Mouse;
@ISA = qw(Animal);
sub sound { "squeak" }
sub speak {
my $class = shift;
print "a $class goes ", $class->sound, "!\n";
print "[but you can barely hear it!]\n";
}
}
Mouse->speak;
=begin original
which results in:
=end original
これは次の結果になります:
a Mouse goes squeak!
[but you can barely hear it!]
=begin original
Here, C<Mouse> has its own speaking routine, so C<< Mouse->speak >>
doesn't immediately invoke C<< Animal->speak >>. This is known as
"overriding". In fact, we don't even need to say that a C<Mouse> is
an C<Animal> at all, because all of the methods needed for C<speak> are
completely defined for C<Mouse>; this is known as "duck typing":
"If it walks like a duck and quacks like a duck, I would call it a duck"
(James Whitcomb). However, it would probably be beneficial to allow a
closer examination to conclude that a C<Mouse> is indeed an C<Animal>,
so it is actually better to define C<Mouse> with C<Animal> as its base
(that is, it is better to "derive C<Mouse> from C<Animal>").
=end original
ここでは C<Mouse> は C<< Animal->speak >> を呼ぶのではなく
自分用のおしゃべりルーティン C<< Mouse->speak >> を持っています。
これは、「オーバーライド」と呼ばれています。
事実、C<Mouse> が C<Animal> の一種であるという必要はまったくありません。
おしゃべり(C<speak>)に必要なメソッドは全て C<Mouse> に定義されています;
これは「ダックタイピング」(duck typing) として知られています":
「あひるのように歩いてあひるのように鳴くなら、あひると呼ぼう」
(James Whitcomb)。
しかし、C<Mouse> が確かに C<Animal> であると結論づけるためのより詳細な検査を
出来ることはおそらく有益なので、実際には C<Animal> を基底として C<Mouse> を
定義する方が良い(つまり、「C<Animal> から C<Mouse> を派生させる方が
良い」)です。
=begin original
Moreover, this duplication of code could become a maintenance headache
(though code-reuse is not actually a good reason for inheritance; good
design practices dictate that a derived class should be usable wherever
its base class is usable, which might not be the outcome if code-reuse
is the sole criterion for inheritance. Just remember that a C<Mouse>
should always act like an C<Animal>).
=end original
さらに、このような重複は頭痛の種となります (しかしコードの再利用は
実際には継承の良い理由ではありません; よい設計プラクティスは基底クラスが
使えるところではどこでも派生クラスが使えるべきと指示していて、
コードの再利用が継承の唯一の基準だと効果がないかもしれません。
単に C<Mouse> は常に C<Animal> のように動作するべきと言うことを
覚えておいてください)。
=begin original
So, let's make C<Mouse> an C<Animal>!
=end original
それで、C<Mouse> を C<Animal> にしましょう!
=begin original
The obvious solution is to invoke C<Animal::speak> directly:
=end original
明らかな解決方法は C<Animal::speak> を直接起動することです:
# Animal package from before
{ package Mouse;
@ISA = qw(Animal);
sub sound { "squeak" }
sub speak {
my $class = shift;
Animal::speak($class);
print "[but you can barely hear it!]\n";
}
}
=begin original
Note that we're using C<Animal::speak>. If we were to invoke
C<< Animal->speak >> instead, the first parameter to C<Animal::speak>
would automatically be C<"Animal"> rather than C<"Mouse">, so that
the call to C<< $class->sound >> in C<Animal::speak> would become
C<< Animal->sound >> rather than C<< Mouse->sound >>.
=end original
C<Animal::speak> を使っていることに注意してください。
代わりに C<< Animal->speak >> を起動すると、C<Animal::speak> への最初の引数は
C<"Mouse"> ではなく自動的に C<"Animal"> になるので、C<Animal::speak> での
C<< $class->sound >> の呼び出しは C<< Mouse->sound >> ではなく
C<< Animal->sound >> になります。
=begin original
Also, without the method arrow C<< -> >>, it becomes necessary to specify
the first parameter to C<Animal::speak> ourselves, which is why C<$class>
is explicitly passed: C<Animal::speak($class)>.
=end original
また、メソッド矢印 C<< -> >> なしだと、C<Animal::speak> への最初の引数を
自分自身で指定する必要があるようになります; これが C<$class> が明示的に
渡されている理由です: C<Animal::speak($class)>。
=begin original
However, invoking C<Animal::speak> directly is a mess: Firstly, it assumes
that the C<speak> method is a member of the C<Animal> class; what if C<Animal>
actually inherits C<speak> from its own base? Because we are no longer using
C<< -> >> to access C<speak>, the special method look up mechanism wouldn't be
used, so C<speak> wouldn't even be found!
=end original
しかし、直接 C<Animal::speak> を起動するのは大変です: 最初に、C<speak>
メソッドは C<Animal> クラスのメンバであることを仮定しています;
C<Animal> が実際には独自の基底クラスから C<speak> を継承していたら?
もはや C<speak> にアクセスするのに C<< -> >> を使わないので、特別なメソッド
検索機構が使われておらず、C<speak> は発見すらされていません!
=begin original
The second problem is more subtle: C<Animal> is now hardwired into the subroutine
selection. Let's assume that C<Animal::speak> does exist. What happens when,
at a later time, someone expands the class hierarchy by having C<Mouse>
inherit from C<Mus> instead of C<Animal>. Unless the invocation of C<Animal::speak>
is also changed to an invocation of C<Mus::speak>, centuries worth of taxonomical
classification could be obliterated!
=end original
二つ目の問題はより微妙です: C<Animal> はサブルーチン選択に
ハードコーディングされています。
C<Animal::speak> が存在すると仮定してみましょう。
後で起こることは、誰かが C<Mouse> を C<Animal> ではなく C<Mus> から
継承することでクラス階層を拡張します。
C<Animal::speak> の起動が C<Mus::speak> の起動も変更されない限り、
分類学の世紀的な価値が破壊されます!
=begin original
What we have here is a fragile or leaky abstraction; it is the beginning of a
maintenance nightmare. What we need is the ability to search for the right
method wih as few assumptions as possible.
=end original
ここにあるものは脆弱で漏れやすい抽象化です; これは保守の悪夢の始まりです。
必要としているものは出来るだけ仮定を少なくして正しいメソッドを探す能力です。
=head2 Starting the search from a different place
(異なる場所から探索を始める)
=begin original
A I<better> solution is to tell Perl where in the inheritance chain to begin searching
for C<speak>. This can be achieved with a modified version of the method arrow C<< -> >>:
=end original
I<よりよい> 解決法は、継承チェーンのどこから C<speak> の検索を始めるのかを
Perl に伝えることです。
これはメソッド矢印 C<< -> >> の修正版で達成できます:
ClassName->FirstPlaceToLook::method
=begin original
So, the improved C<Mouse> class is:
=end original
それで、改良された C<Mouse> クラスは:
# same Animal as before
{ package Mouse;
# same @ISA, &sound as before
sub speak {
my $class = shift;
$class->Animal::speak;
print "[but you can barely hear it!]\n";
}
}
=begin original
Using this syntax, we start with C<Animal> to find C<speak>, and then
use all of C<Animal>'s inheritance chain if it is not found immediately.
As usual, the first parameter to C<speak> would be C<$class>, so we no
longer need to pass C<$class> explicitly to C<speak>.
=end original
この構文を使うことで、C<speak> の探索を C<Animal> から開始することができ、
それから直接見つからなくても C<Animal> の全ての継承連鎖を使う
ことができます。
いつも通り、C<speak> への一つめのパラメータは C<$class> になるため、
もはや C<$class> を明示的に C<speak> に渡す必要はありません。
=begin original
But what about the second problem? We're still hardwiring C<Animal> into
the method lookup.
=end original
しかし、二つ目の問題はどうでしょう?
まだメソッド検索に C<Animal> をハードコーディングしています。
=head2 The SUPER way of doing things
(SUPER 解答)
=begin original
If C<Animal> is replaced with the special placeholder C<SUPER> in that
invocation, then the contents of C<Mouse>'s C<@ISA> are used for the
search, beginning with C<$ISA[0]>. So, all of the problems can be fixed
as follows:
=end original
この起動で C<Animal> が特別なプレースホルダ C<SUPER> で置き換えられると、
C<Mouse> の C<@ISA> の内容が使われ、C<$ISA[0]> から始められます。
それで、以下のようにして全ての問題が修正できます:
# same Animal as before
{ package Mouse;
# same @ISA, &sound as before
sub speak {
my $class = shift;
$class->SUPER::speak;
print "[but you can barely hear it!]\n";
}
}
=begin original
In general, C<SUPER::speak> means look in the current package's C<@ISA>
for a class that implements C<speak>, and invoke the first one found.
The placeholder is called C<SUPER>, because many other languages refer
to base classes as "I<super>classes", and Perl likes to be eclectic.
=end original
一般的に、C<SUPER::speak> は現在のパッケージの C<@ISA> から C<speak> を
実装するクラスを探し、最初に見つかったものを呼び出します。
プレースホルダは C<SUPER> と呼ばれます; その他の言語では基底クラスを
"I<super>classes"(スーパークラス)として参照し、Perl は折衷主義だからです。
=begin original
Note that a call such as
=end original
以下のように呼び出すと
$class->SUPER::method;
=begin original
does I<not> look in the C<@ISA> of C<$class> unless C<$class> happens to
be the current package.
=end original
C<$class> がたまたま現在のパッケージでない限り、C<$class> の C<@ISA> を
I<見ない> ことに注意してください。
=head2 Let's review...
=begin original
So far, we've seen the method arrow syntax:
=end original
これまでに見てきたものは、メソッド矢印構文:
Class->method(@args);
=begin original
or the equivalent:
=end original
その等価な文:
$a = "Class";
$a->method(@args);
=begin original
which constructs an argument list of:
=end original
構築される引数リスト:
("Class", @args)
=begin original
and attempts to invoke:
=end original
呼び出され方:
Class::method("Class", @args);
=begin original
However, if C<Class::method> is not found, then C<@Class::ISA> is examined
(recursively) to locate a class (a package) that does indeed contain C<method>,
and that subroutine is invoked instead.
=end original
しかし、C<Class:method> が見つからなければ C<@Class::ISA> が(再帰的に)
実際 C<method> を含んでいるクラス(パッケージ)を探すために使われます。
=begin original
Using this simple syntax, we have class methods, (multiple) inheritance,
overriding, and extending. Using just what we've seen so far, we've
been able to factor out common code (though that's never a good reason
for inheritance!), and provide a nice way to reuse implementations with
variations.
=end original
この簡単な構文を使うことでクラスメソッド、(複数の)継承、オーバーライド、
そして拡張を行えるようになりました。
これまでに見てきたもので共通処理を抽出し、(しかし、これは決して継承のよい
理由ではありません!)、様々な実装に再利用する良好な方法を提供できます。
=begin original
Now, what about data?
=end original
それで、データについては?
=head2 A horse is a horse, of course of course, or is it?
(馬は馬、もちろん -- ですか?)
=begin original
Let's start with the code for the C<Animal> class
and the C<Horse> class:
=end original
C<Animal> クラスと C<Horse> クラスを書いてみましょう。
{ package Animal;