/
perltie.pod
executable file
·2298 lines (1616 loc) · 62.3 KB
/
perltie.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
X<tie>
=begin original
perltie - how to hide an object class in a simple variable
=end original
perltie - オブジェクトクラスを単純な変数に隠す方法
=head1 SYNOPSIS
tie VARIABLE, CLASSNAME, LIST
$object = tied VARIABLE
untie VARIABLE
=head1 DESCRIPTION
=begin original
Prior to release 5.0 of Perl, a programmer could use dbmopen()
to connect an on-disk database in the standard Unix dbm(3x)
format magically to a %HASH in their program. However, their Perl was either
built with one particular dbm library or another, but not both, and
you couldn't extend this mechanism to other packages or types of variables.
=end original
5.0 より前の Perl では、プログラマは dbmopen() を使ってディスクにある
標準 UNIX dbm(3x) フォーマットのデータベースをプログラム中の %HASH と
結び付けることができました。
しかしながら、Perl は特定の dbm ライブラリか別のものを使って
ビルドすることができたものの、両方一度にはできませんでした。
そして、この仕組みを他のパッケージや変数の型に拡張することは
できなかったのです。
=begin original
Now you can.
=end original
今はできます。
=begin original
The tie() function binds a variable to a class (package) that will provide
the implementation for access methods for that variable. Once this magic
has been performed, accessing a tied variable automatically triggers
method calls in the proper class. The complexity of the class is
hidden behind magic methods calls. The method names are in ALL CAPS,
which is a convention that Perl uses to indicate that they're called
implicitly rather than explicitly--just like the BEGIN() and END()
functions.
=end original
tie() 関数は変数と、その変数に対するアクセスメソッドの実装を提供する
クラス(パッケージ)とを結び付けます。
この魔法が一度働けば、tie された変数は自動的に適切なクラスにある
メソッド呼び出しを実行します。
クラスのすべての複雑性はメソッド呼び出しに隠されます。
それらのメソッドの名前は、BEGIN() や END() と同様に(そのメソッドを) Perl が
こっそりと呼び出すことを示すための規約に従って全て大文字です。
=begin original
In the tie() call, C<VARIABLE> is the name of the variable to be
enchanted. C<CLASSNAME> is the name of a class implementing objects of
the correct type. Any additional arguments in the C<LIST> are passed to
the appropriate constructor method for that class--meaning TIESCALAR(),
TIEARRAY(), TIEHASH(), or TIEHANDLE(). (Typically these are arguments
such as might be passed to the dbminit() function of C.) The object
returned by the "new" method is also returned by the tie() function,
which would be useful if you wanted to access other methods in
C<CLASSNAME>. (You don't actually have to return a reference to a right
"type" (e.g., HASH or C<CLASSNAME>) so long as it's a properly blessed
object.) You can also retrieve a reference to the underlying object
using the tied() function.
=end original
tie() コールの中で、C<VARIABLE> は魔法を掛けられる変数の名前です。
C<CLASSNAME> は正しい型のオブジェクトを実装するクラスの名前です。
C<LIST> にあるその他の引数はクラスの適切なコンストラクタメソッド
TIESCALAR()、TIEARRAY()、TIEHASH()、TIEHANDLE() のいずれかに
渡されます(典型的にはこれらの引数は C の dbminit() 関数に渡すのと
同じものです)。
"new" メソッドから返されたオブジェクトは同様に関数 tie() からも
返されます。
これはあなたが C<CLASSNAME> の中の別のメソッドでアクセスしたいというときに
便利でしょう(あなたは実際には正しい「型」(HASH か C<CLASSNAME>) の
参照を、それが適切な bless されたオブジェクトであるということから
返す必要はありません)。
また、関数 tied() を使って、基礎となるオブジェクトへのリファレンスを
取得することができます。
=begin original
Unlike dbmopen(), the tie() function will not C<use> or C<require> a module
for you--you need to do that explicitly yourself.
=end original
dbmopen() とは異なり、tie() はモジュールを C<use> したり C<require> したり
することはありません。
あなたが、自分自身でそれを明示的に行わなければなりません。
=head2 Tying Scalars
X<scalar, tying>
(スカラを tie する)
=begin original
A class implementing a tied scalar should define the following methods:
TIESCALAR, FETCH, STORE, and possibly UNTIE and/or DESTROY.
=end original
tie されたスカラを実装するクラスは、TIESCALAR, FETCH, STORE,
そして可能であれば UNTIE や DESTROY といったメソッドを定義しておくべきです。
=begin original
Let's look at each in turn, using as an example a tie class for
scalars that allows the user to do something like:
=end original
以下のような操作を、ユーザーに許しているスカラに対してクラスを
tie する例を使って順に見て行きましょう。
tie $his_speed, 'Nice', getppid();
tie $my_speed, 'Nice', $$;
=begin original
And now whenever either of those variables is accessed, its current
system priority is retrieved and returned. If those variables are set,
then the process's priority is changed!
=end original
こうした後ではこれらの変数のいずれかがアクセスされたときには、カレントの
システム優先順位が取得されたり返されたりします。
もし変数に代入が行われれば、プロセスの優先順位は変更されます!
=begin original
We'll use Jarkko Hietaniemi <F<jhi@iki.fi>>'s BSD::Resource class (not
included) to access the PRIO_PROCESS, PRIO_MIN, and PRIO_MAX constants
from your system, as well as the getpriority() and setpriority() system
calls. Here's the preamble of the class.
=end original
システムの PRIO_PROCESS, PRIO_MIN, PRIO_MAX といった定数に
アクセスするために Jarkko Hietaniemi <F<jhi@iki.fi>> の
BSD::Resource クラスを使います。
以下はこのクラスの前置きです。
package Nice;
use Carp;
use BSD::Resource;
use strict;
$Nice::DEBUG = 0 unless defined $Nice::DEBUG;
=over 4
=item TIESCALAR classname, LIST
X<TIESCALAR>
=begin original
This is the constructor for the class. That means it is
expected to return a blessed reference to a new scalar
(probably anonymous) that it's creating. For example:
=end original
これはクラスのためのコンストラクタです。
その役割は作成された新たな(おそらくは無名の)スカラへの bless された
参照を返すことです。
たとえば、
sub TIESCALAR {
my $class = shift;
my $pid = shift || $$; # 0 means me
if ($pid !~ /^\d+$/) {
carp "Nice::Tie::Scalar got non-numeric pid $pid" if $^W;
return undef;
}
unless (kill 0, $pid) { # EPERM or ERSCH, no doubt
carp "Nice::Tie::Scalar got bad pid $pid: $!" if $^W;
return undef;
}
return bless \$pid, $class;
}
=begin original
This tie class has chosen to return an error rather than raising an
exception if its constructor should fail. While this is how dbmopen() works,
other classes may well not wish to be so forgiving. It checks the global
variable C<$^W> to see whether to emit a bit of noise anyway.
=end original
このtie クラスでは、コンストラクタが失敗したときに例外を起こすのではなく
エラーを返すことを選択しました。
dbmopen() が動作している間に、他のクラスは例外が起きることを
好まないかもしれないからです。
グローバル変数 C<$^W> でエラーメッセージを出すかどうかを検査しています。
=item FETCH this
X<FETCH>
=begin original
This method will be triggered every time the tied variable is accessed
(read). It takes no arguments beyond its self reference, which is the
object representing the scalar we're dealing with. Because in this case
we're using just a SCALAR ref for the tied scalar object, a simple $$self
allows the method to get at the real value stored there. In our example
below, that real value is the process ID to which we've tied our variable.
=end original
このメソッドは tie された変数がアクセス(読み出し)される度に起動されます。
これは自分のリファレンス、つまり私たちが扱おうとしている
スカラを表現するオブジェクトの他に引数は取りません。
この場合、単に SCALAR の参照をtieされたスカラオブジェクトとして
使うので、単純な $$self がそこに格納されている実際の値を取得する
メソッドとなります。
以下に示した例では、実際の値は変数に tie されたプロセス ID です。
sub FETCH {
my $self = shift;
confess "wrong type" unless ref $self;
croak "usage error" if @_;
my $nicety;
local($!) = 0;
$nicety = getpriority(PRIO_PROCESS, $$self);
if ($!) { croak "getpriority failed: $!" }
return $nicety;
}
=begin original
This time we've decided to blow up (raise an exception) if the renice
fails--there's no place for us to return an error otherwise, and it's
probably the right thing to do.
=end original
ここでは、renice に失敗した場合には例外を引き起こすようにしました。
エラーを返すための場所がなく、例外を引き起こすことがおそらく妥当です。
=item STORE this, value
X<STORE>
=begin original
This method will be triggered every time the tied variable is set
(assigned). Beyond its self reference, it also expects one (and only one)
argument--the new value the user is trying to assign. Don't worry about
returning a value from STORE -- the semantic of assignment returning the
assigned value is implemented with FETCH.
=end original
このメソッドは tie された変数に代入される度毎に起動されます。
自分の参照のほか、ただ一つの引数としてユーザーが代入しようとする
新しい値を取ります。
STORE から返される値は気にしないで下さい --
代入された値を返す代入の動作は FETCH で実装されています。
sub STORE {
my $self = shift;
confess "wrong type" unless ref $self;
my $new_nicety = shift;
croak "usage error" if @_;
if ($new_nicety < PRIO_MIN) {
carp sprintf
"WARNING: priority %d less than minimum system priority %d",
$new_nicety, PRIO_MIN if $^W;
$new_nicety = PRIO_MIN;
}
if ($new_nicety > PRIO_MAX) {
carp sprintf
"WARNING: priority %d greater than maximum system priority %d",
$new_nicety, PRIO_MAX if $^W;
$new_nicety = PRIO_MAX;
}
unless (defined setpriority(PRIO_PROCESS, $$self, $new_nicety)) {
confess "setpriority failed: $!";
}
}
=item UNTIE this
X<UNTIE>
=begin original
This method will be triggered when the C<untie> occurs. This can be useful
if the class needs to know when no further calls will be made. (Except DESTROY
of course.) See L<The C<untie> Gotcha> below for more details.
=end original
このメソッドは、C<untie> が発生すると起動されます。
これは、クラスが、もはや呼び出されなくなるのはいつかを知る必要がある場合に
便利です。
(もちろん DESTROY を除いてです。)
さらなる詳細については後述する L<The C<untie> Gotcha> を参照してください。
=item DESTROY this
X<DESTROY>
=begin original
This method will be triggered when the tied variable needs to be destructed.
As with other object classes, such a method is seldom necessary, because Perl
deallocates its moribund object's memory for you automatically--this isn't
C++, you know. We'll use a DESTROY method here for debugging purposes only.
=end original
このメソッドは tie された変数を破棄する必要があるときに起動されます。
他のオブジェクトクラスと同じように、このようなメソッドは
ほとんど必要ありません。
それは、Perl は消滅しかかったオブジェクトのメモリを自動的に
解放するからです。
これは C++ ではないのです。
いいですね?。
私たちはここでは DESTROY メソッドをデバッグのためだけに使います。
sub DESTROY {
my $self = shift;
confess "wrong type" unless ref $self;
carp "[ Nice::DESTROY pid $$self ]" if $Nice::DEBUG;
}
=back
=begin original
That's about all there is to it. Actually, it's more than all there
is to it, because we've done a few nice things here for the sake
of completeness, robustness, and general aesthetics. Simpler
TIESCALAR classes are certainly possible.
=end original
これがすべきことの全てです。
実際のところ、それよりも多くのことがあります。
ですから、私たちはここでちょっとした完全性、堅牢性、一般的な美しさと
いうものを込めました。
もっと簡単な TIESCALAR クラスを作ることも可能です。
=head2 Tying Arrays
X<array, tying>
(配列を tie する)
=begin original
A class implementing a tied ordinary array should define the following
methods: TIEARRAY, FETCH, STORE, FETCHSIZE, STORESIZE and perhaps UNTIE and/or DESTROY.
=end original
tie された配列を実装するクラスは TIEARRAY, FETCH, STORE, FETCHSIZE,
STORESIZE、そしておそらく UNTIE や DESTROY といったメソッドを
実装すべきでしょう。
=begin original
FETCHSIZE and STORESIZE are used to provide C<$#array> and
equivalent C<scalar(@array)> access.
=end original
FETCHSIZE と STORESIZE は C<$#array> と
C<scalar(@array)> アクセスに等価なものを提供します。
=begin original
The methods POP, PUSH, SHIFT, UNSHIFT, SPLICE, DELETE, and EXISTS are
required if the perl operator with the corresponding (but lowercase) name
is to operate on the tied array. The B<Tie::Array> class can be used as a
base class to implement the first five of these in terms of the basic
methods above. The default implementations of DELETE and EXISTS in
B<Tie::Array> simply C<croak>.
=end original
POP, PUSH, SHIFT, UNSHIFT, SPLICE, DELETE, EXIST といったメソッドは
同名の perl の演算子(ただし小文字)が tie された配列に対して
操作を行うときに必要となります。
B<Tie::Array> クラスは、これらのうち、最初の 5 つの基本的なメソッドを
実装するための基底クラスとして使用できます。
B<Tie::Array> での DELETE と EXISTS のデフォルトの実装は
単なる C<croak> です。
=begin original
In addition EXTEND will be called when perl would have pre-extended
allocation in a real array.
=end original
それに加え、EXTEND は perl が実際の配列中であらかじめ
拡張するようなときに呼び出されます。
=begin original
For this discussion, we'll implement an array whose elements are a fixed
size at creation. If you try to create an element larger than the fixed
size, you'll take an exception. For example:
=end original
ここでの説明のため、要素数が生成時に固定されたサイズである配列を実装します。
固定サイズを越えた要素を作ろうとすると、例外が発生します。
例えば:
use FixedElem_Array;
tie @array, 'FixedElem_Array', 3;
$array[0] = 'cat'; # ok.
$array[1] = 'dogs'; # exception, length('dogs') > 3.
=begin original
The preamble code for the class is as follows:
=end original
このクラスに対する 前置きコードは以下の通りです。
package FixedElem_Array;
use Carp;
use strict;
=over 4
=item TIEARRAY classname, LIST
X<TIEARRAY>
=begin original
This is the constructor for the class. That means it is expected to
return a blessed reference through which the new array (probably an
anonymous ARRAY ref) will be accessed.
=end original
これはクラスのためのコンストラクタです。
その役割は作成された新たな(おそらくは無名の配列の参照)配列への
bless された参照を返すことです。
=begin original
In our example, just to show you that you don't I<really> have to return an
ARRAY reference, we'll choose a HASH reference to represent our object.
A HASH works out well as a generic record type: the C<{ELEMSIZE}> field will
store the maximum element size allowed, and the C<{ARRAY}> field will hold the
true ARRAY ref. If someone outside the class tries to dereference the
object returned (doubtless thinking it an ARRAY ref), they'll blow up.
This just goes to show you that you should respect an object's privacy.
=end original
私たちの例では、あなたにあなたが I<実際には> ARRAY のリファレンスを
返さなくてもよいということを示すためだけに、使用するオブジェクトを
表わす HASH の参照を選びました。
HASH は汎用的なレコード型と同じように働きます。
C<{ELEMSIZE}> フィールドは許される最大の要素の数を格納し、
C<{ARRAY}> フィールドは本物の ARRAY のリファレンスを保持します。
誰かがクラスの外側で返されたオブジェクトのデリファレンスを試みた場合
(それが ARRAY のリファレンスであると疑いなく考えて)、それは失敗します。
これはあなたがオブジェクトのプライバシーを尊重すべきであるという
ことなのです。
sub TIEARRAY {
my $class = shift;
my $elemsize = shift;
if ( @_ || $elemsize =~ /\D/ ) {
croak "usage: tie ARRAY, '" . __PACKAGE__ . "', elem_size";
}
return bless {
ELEMSIZE => $elemsize,
ARRAY => [],
}, $class;
}
=item FETCH this, index
X<FETCH>
=begin original
This method will be triggered every time an individual element the tied array
is accessed (read). It takes one argument beyond its self reference: the
index whose value we're trying to fetch.
=end original
このメソッドは tie された配列の個々の要素がアクセス(読み出し)される毎に
起動されます。
これは自分の参照のほかに、一つの引数、フェッチしようとする値の
インデックスをとります。
sub FETCH {
my $self = shift;
my $index = shift;
return $self->{ARRAY}->[$index];
}
=begin original
If a negative array index is used to read from an array, the index
will be translated to a positive one internally by calling FETCHSIZE
before being passed to FETCH. You may disable this feature by
assigning a true value to the variable C<$NEGATIVE_INDICES> in the
tied array class.
=end original
配列からの読み込みに負数の添え字が使われると、添え字は
FETCH に渡される前に FETCHSIZE を呼び出すことで正の数に変換されます。
tie された配列クラスの C<$NEGATIVE_INDICES> に真の値を代入することで
この機能を無効にできます。
=begin original
As you may have noticed, the name of the FETCH method (et al.) is the same
for all accesses, even though the constructors differ in names (TIESCALAR
vs TIEARRAY). While in theory you could have the same class servicing
several tied types, in practice this becomes cumbersome, and it's easiest
to keep them at simply one tie type per class.
=end original
すでに気がついたかもしれませんが、FETCH メソッド(など)の名前は全ての
アクセスについて、たとえコンストラクタが別の名前であった
(TIESCALAR と TIEARRAY)としても同じ名前になっています。
理論的には、幾つかの tie されたクラスをサービスする同じクラスを
持つこともできるでしょうが、実際にはこれは厄介なものになり、
単にクラスあたり一つの状態にするのが最も簡単です。
=item STORE this, index, value
X<STORE>
=begin original
This method will be triggered every time an element in the tied array is set
(written). It takes two arguments beyond its self reference: the index at
which we're trying to store something and the value we're trying to put
there.
=end original
このメソッドは、tie された配列にある要素に対する書き込みがある度毎に
起動されます。
これは自分の参照のほかに、何かを格納しようとする場所の添え字と、
格納しようとしている値という二つの引数を取ります。
=begin original
In our example, C<undef> is really C<$self-E<gt>{ELEMSIZE}> number of
spaces so we have a little more work to do here:
=end original
この例では、C<undef> は実際は C<$self-E<gt>{ELEMSIZE}> 個の空白なので、
ここでもう少し作業が必要です:
sub STORE {
my $self = shift;
my( $index, $value ) = @_;
if ( length $value > $self->{ELEMSIZE} ) {
croak "length of $value is greater than $self->{ELEMSIZE}";
}
# fill in the blanks
$self->EXTEND( $index ) if $index > $self->FETCHSIZE();
# right justify to keep element size for smaller elements
$self->{ARRAY}->[$index] = sprintf "%$self->{ELEMSIZE}s", $value;
}
=begin original
Negative indexes are treated the same as with FETCH.
=end original
インデックスの値が負数の場合、FETCH と同様に扱われます。
=item FETCHSIZE this
X<FETCHSIZE>
=begin original
Returns the total number of items in the tied array associated with
object I<this>. (Equivalent to C<scalar(@array)>). For example:
=end original
オブジェクト I<this> と結び付けられた tie された配列の合計要素数を返します。
(C<scalar(@array)> と等価です)。
例えば:
sub FETCHSIZE {
my $self = shift;
return scalar @{$self->{ARRAY}};
}
=item STORESIZE this, count
X<STORESIZE>
=begin original
Sets the total number of items in the tied array associated with
object I<this> to be I<count>. If this makes the array larger then
class's mapping of C<undef> should be returned for new positions.
If the array becomes smaller then entries beyond count should be
deleted.
=end original
オブジェクト I<this> に結び付けられた tie された配列のアイテムの合計数を
I<count> にセットします。
もし配列がより大きくなるなら、新しい位置ではクラスのマッピングは
C<undef> を返すべきです。
もし配列がより小さくなるなら、count を超えたエントリは削除されるべきです。
=begin original
In our example, 'undef' is really an element containing
C<$self-E<gt>{ELEMSIZE}> number of spaces. Observe:
=end original
この例では、'undef' というのは実際には C<$self-E<gt>{ELEMSIZE}> 個の空白を
含む要素です。
これを見てください:
sub STORESIZE {
my $self = shift;
my $count = shift;
if ( $count > $self->FETCHSIZE() ) {
foreach ( $count - $self->FETCHSIZE() .. $count ) {
$self->STORE( $_, '' );
}
} elsif ( $count < $self->FETCHSIZE() ) {
foreach ( 0 .. $self->FETCHSIZE() - $count - 2 ) {
$self->POP();
}
}
}
=item EXTEND this, count
X<EXTEND>
=begin original
Informative call that array is likely to grow to have I<count> entries.
Can be used to optimize allocation. This method need do nothing.
=end original
配列が、I<count> エントリに大きくなりそうだということを通知する
呼び出しです。
割り当ての最適化に使えます。
このメソッドで何かをしなければならないということはありません。
=begin original
In our example, we want to make sure there are no blank (C<undef>)
entries, so C<EXTEND> will make use of C<STORESIZE> to fill elements
as needed:
=end original
例では、空白 (C<undef>) のエントリがないことを確実にしたいので、
C<EXTEND> は必要に応じて要素を埋めるために C<STORESIZE> を使います:
sub EXTEND {
my $self = shift;
my $count = shift;
$self->STORESIZE( $count );
}
=item EXISTS this, key
X<EXISTS>
=begin original
Verify that the element at index I<key> exists in the tied array I<this>.
=end original
tie された配列 I<this> にインデックスが I<key> である要素が存在するかを
検証します。
=begin original
In our example, we will determine that if an element consists of
C<$self-E<gt>{ELEMSIZE}> spaces only, it does not exist:
=end original
この例では、要素が C<$self-E<gt>{ELEMSIZE}> 個の空白のみで構成されていれば、
これは存在しません:
sub EXISTS {
my $self = shift;
my $index = shift;
return 0 if ! defined $self->{ARRAY}->[$index] ||
$self->{ARRAY}->[$index] eq ' ' x $self->{ELEMSIZE};
return 1;
}
=item DELETE this, key
X<DELETE>
=begin original
Delete the element at index I<key> from the tied array I<this>.
=end original
インデックス I<key> の要素を tie された配列 I<this> から削除します。
=begin original
In our example, a deleted item is C<$self-E<gt>{ELEMSIZE}> spaces:
=end original
この例では、削除された要素は C<$self-E<gt>{ELEMSIZE}> 個の空白です:
sub DELETE {
my $self = shift;
my $index = shift;
return $self->STORE( $index, '' );
}
=item CLEAR this
X<CLEAR>
=begin original
Clear (remove, delete, ...) all values from the tied array associated with
object I<this>. For example:
=end original
オブジェクト I<this> に関連付けられた tie された配列から全ての値を
削除します。
例えば:
sub CLEAR {
my $self = shift;
return $self->{ARRAY} = [];
}
=item PUSH this, LIST
X<PUSH>
=begin original
Append elements of I<LIST> to the array. For example:
=end original
I<LIST> の要素を配列に追加します。
例えば:
sub PUSH {
my $self = shift;
my @list = @_;
my $last = $self->FETCHSIZE();
$self->STORE( $last + $_, $list[$_] ) foreach 0 .. $#list;
return $self->FETCHSIZE();
}
=item POP this
X<POP>
=begin original
Remove last element of the array and return it. For example:
=end original
配列の最後の要素を取り除いてそれを返します。
例えば:
sub POP {
my $self = shift;
return pop @{$self->{ARRAY}};
}
=item SHIFT this
X<SHIFT>
=begin original
Remove the first element of the array (shifting other elements down)
and return it. For example:
=end original
配列の最初の要素を取り除いて(残りの要素はシフトします)、その要素を返します。
例えば:
sub SHIFT {
my $self = shift;
return shift @{$self->{ARRAY}};
}
=item UNSHIFT this, LIST
X<UNSHIFT>
=begin original
Insert LIST elements at the beginning of the array, moving existing elements
up to make room. For example:
=end original
LIST 要素を配列の先頭に挿入し、すでにある要素は場所を空けるために
移動します。
例えば:
sub UNSHIFT {
my $self = shift;
my @list = @_;
my $size = scalar( @list );
# make room for our list
@{$self->{ARRAY}}[ $size .. $#{$self->{ARRAY}} + $size ]
= @{$self->{ARRAY}};
$self->STORE( $_, $list[$_] ) foreach 0 .. $#list;
}
=item SPLICE this, offset, length, LIST
X<SPLICE>
=begin original
Perform the equivalent of C<splice> on the array.
=end original
配列に対する C<splice> と等価に振る舞います。
=begin original
I<offset> is optional and defaults to zero, negative values count back
from the end of the array.
=end original
I<offset> はオプションでデフォルトは 0 です; 負数は配列の最後からの
位置を示します。
=begin original
I<length> is optional and defaults to rest of the array.
=end original
I<length> はオプションで、デフォルトは配列の残りです。
=begin original
I<LIST> may be empty.
=end original
I<LIST> は空かもしれません。
=begin original
Returns a list of the original I<length> elements at I<offset>.
=end original
元の、I<offset> の位置から I<length> 要素分のリストを返します。
=begin original
In our example, we'll use a little shortcut if there is a I<LIST>:
=end original
この例では、I<LIST> がある場合は少し近道をします:
sub SPLICE {
my $self = shift;
my $offset = shift || 0;
my $length = shift || $self->FETCHSIZE() - $offset;
my @list = ();
if ( @_ ) {
tie @list, __PACKAGE__, $self->{ELEMSIZE};
@list = @_;
}
return splice @{$self->{ARRAY}}, $offset, $length, @list;
}
=item UNTIE this
X<UNTIE>
=begin original
Will be called when C<untie> happens. (See L<The C<untie> Gotcha> below.)
=end original
C<untie> が起きると呼び出されます。
(後述する L<The C<untie> Gotcha> を参照してください。)
=item DESTROY this
X<DESTROY>
=begin original
This method will be triggered when the tied variable needs to be destructed.
As with the scalar tie class, this is almost never needed in a
language that does its own garbage collection, so this time we'll
just leave it out.
=end original
このメソッドは tie された変数を破棄する必要があるときに呼び出されます。
スカラを tie したクラスと同様、このメソッドはガベージコレクションを
言語自体が行っているのでほとんど必要ありません。
ですから、今回はこのまま放っておきます。
=back
=head2 Tying Hashes
X<hash, tying>
(ハッシュを tie する)
=begin original
Hashes were the first Perl data type to be tied (see dbmopen()). A class
implementing a tied hash should define the following methods: TIEHASH is
the constructor. FETCH and STORE access the key and value pairs. EXISTS
reports whether a key is present in the hash, and DELETE deletes one.
CLEAR empties the hash by deleting all the key and value pairs. FIRSTKEY
and NEXTKEY implement the keys() and each() functions to iterate over all
the keys. SCALAR is triggered when the tied hash is evaluated in scalar
context. UNTIE is called when C<untie> happens, and DESTROY is called when
the tied variable is garbage collected.
=end original
ハッシュは tie される最初の Perl データ型でした(dbmopen() を参照)。
tie されたハッシュを実装するクラスは、以下のメソッドを定義すべきです。
TIEHASH はコンストラクタです。
FETCH と STORE はキーと値のペアにアクセスします。
EXIST はキーがハッシュにあるかどうかを報告し、DELETE はキーを削除します。
CLEAR はすべてのキーと値のペアを削除することによりハッシュを空にします。
FIRSTKEY と NEXTKEY は全てのキーを反復するための関数 keys() と each() を
実装します。
SCALAR は tie されたハッシュがスカラコンテキストで評価されたときに
呼び出されます。
UNTIE は C<untie> が起きたときに呼び出され、DESTROY は tie された変数が
ガーベジコレクションされるときに呼び出されます。
=begin original
If this seems like a lot, then feel free to inherit from merely the
standard Tie::StdHash module for most of your methods, redefining only the
interesting ones. See L<Tie::Hash> for details.
=end original
もしこれがたくさんありすぎると感じられるのなら、標準の Tie::StdHash
モジュールを単純に継承し、再定義を必要とするものだけを自分で
実装することもできます。
詳しくは L<Tie::Hash> を参照してください。
=begin original