/
perlopentut.pod
executable file
·2177 lines (1520 loc) · 67.4 KB
/
perlopentut.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
perlopentut - tutorial on opening things in Perl
=end original
perlopentut - Perl でいろんなものを開くためのチュートリアル
=head1 DESCRIPTION
=begin original
Perl has two simple, built-in ways to open files: the shell way for
convenience, and the C way for precision. The shell way also has 2- and
3-argument forms, which have different semantics for handling the filename.
The choice is yours.
=end original
Perl には、ファイルを開くための 2 つの単純な組み込みの手段があります:
利便性のためのシェル風の方法と、正確性のための C 風の方法です。
シェル風の方法には 2 引数と 3 引数があり、ファイル名の扱いに関して
異なった動作をします。
選択はあなた次第です。
=head1 Open E<agrave> la shell
(シェル風に開く)
=begin original
Perl's C<open> function was designed to mimic the way command-line
redirection in the shell works. Here are some basic examples
from the shell:
=end original
Perl の C<open> 関数は、シェルでのコマンドラインのリダイレクトをまねて
設計されています。
以下はシェルでの基本的な例です:
$ myprogram file1 file2 file3
$ myprogram < inputfile
$ myprogram > outputfile
$ myprogram >> outputfile
$ myprogram | otherprogram
$ otherprogram | myprogram
=begin original
And here are some more advanced examples:
=end original
そして以下はもう少し高度な例です:
$ otherprogram | myprogram f1 - f2
$ otherprogram 2>&1 | myprogram -
$ myprogram <&3
$ myprogram >&4
=begin original
Programmers accustomed to constructs like those above can take comfort
in learning that Perl directly supports these familiar constructs using
virtually the same syntax as the shell.
=end original
上述のような方法に慣れているプログラマにとっては、Perl がシェルと事実上
同じ文法を使った親しんでいる構造に直接対応していることは
学ぶのが容易になります。
=head2 Simple Opens
(単純に開く)
=begin original
The C<open> function takes two arguments: the first is a filehandle,
and the second is a single string comprising both what to open and how
to open it. C<open> returns true when it works, and when it fails,
returns a false value and sets the special variable C<$!> to reflect
the system error. If the filehandle was previously opened, it will
be implicitly closed first.
=end original
C<open> 関数は 2 つの引数を取ります: 1 つめはファイルハンドルで、
2 つめは何を開くかとどう開くかで構成される単一の文字列です。
C<open> は成功すると真を返し、失敗すると偽を返して特殊変数 C<$!> に
システムエラーを反映します。
指定されたファイルハンドルが以前に開かれていた場合は、暗黙の内に
まず閉じられます。
=begin original
For example:
=end original
例えば:
open(INFO, "datafile") || die("can't open datafile: $!");
open(INFO, "< datafile") || die("can't open datafile: $!");
open(RESULTS,"> runstats") || die("can't open runstats: $!");
open(LOG, ">> logfile ") || die("can't open logfile: $!");
=begin original
If you prefer the low-punctuation version, you could write that this way:
=end original
句読点が少ない方が好みなら、以下のようにも書けます:
open INFO, "< datafile" or die "can't open datafile: $!";
open RESULTS,"> runstats" or die "can't open runstats: $!";
open LOG, ">> logfile " or die "can't open logfile: $!";
=begin original
A few things to notice. First, the leading less-than is optional.
If omitted, Perl assumes that you want to open the file for reading.
=end original
いくつか気がつくことがあります。
まず、先頭の「大なり」は省略可能です。
省略されると、Perl はファイルを読み込みのために開きたいと仮定します。
=begin original
Note also that the first example uses the C<||> logical operator, and the
second uses C<or>, which has lower precedence. Using C<||> in the latter
examples would effectively mean
=end original
最初の例は C<||> 論理演算子を使っていて、二つめの例はより優先順位の低い
C<or> を使っていることにも注意してください。
後者の例で C<||> を使うと、実際には以下のような意味になり
open INFO, ( "< datafile" || die "can't open datafile: $!" );
=begin original
which is definitely not what you want.
=end original
あなたが望んでいるのと全く違うことになります。
=begin original
The other important thing to notice is that, just as in the shell,
any whitespace before or after the filename is ignored. This is good,
because you wouldn't want these to do different things:
=end original
他の注意するべき重要なこととしては、シェルと同様、ファイル名の前後の
空白は無視されることです。
これはよいことです; なぜなら、以下のものが違うことをすることは
望まないだろうからです:
open INFO, "<datafile"
open INFO, "< datafile"
open INFO, "< datafile"
=begin original
Ignoring surrounding whitespace also helps for when you read a filename
in from a different file, and forget to trim it before opening:
=end original
周りの空白を無視することは、ファイル名を別のファイルから読み込んで、
開く前に空白を取り除くのを忘れたときにも助けになります:
$filename = <INFO>; # oops, \n still there
open(EXTRA, "< $filename") || die "can't open $filename: $!";
=begin original
This is not a bug, but a feature. Because C<open> mimics the shell in
its style of using redirection arrows to specify how to open the file, it
also does so with respect to extra whitespace around the filename itself
as well. For accessing files with naughty names, see
L<"Dispelling the Dweomer">.
=end original
これはバグではありません、仕様です。
C<open> はどのようにファイルを開くかを指定するのにリダイレクトの矢印を
使うことでシェルを真似ているので、ファイル名の周りの空白についても
同じように扱います。
行儀の悪い名前のファイルにアクセスするためには、
L<"Dispelling the Dweomer"> を参照してください。
=begin original
There is also a 3-argument version of C<open>, which lets you put the
special redirection characters into their own argument:
=end original
また、3 引数版の C<open> もあって、これは特殊なリダイレクト文字を
独立した引数にしたものです:
open( INFO, ">", $datafile ) || die "Can't create $datafile: $!";
=begin original
In this case, the filename to open is the actual string in C<$datafile>,
so you don't have to worry about C<$datafile> containing characters
that might influence the open mode, or whitespace at the beginning of
the filename that would be absorbed in the 2-argument version. Also,
any reduction of unnecessary string interpolation is a good thing.
=end original
この場合、開くファイル名は C<$datafile> の実際の文字列なので、
C<$datafile> に開くモードに影響を与える文字や、
2 引数版では吸収されるファイル名の先頭の空白が含まれているかどうかを
心配する必要はありません。
また、不必要な文字列変換が削減されるのもよいことです。
=head2 Indirect Filehandles
(間接ファイルハンドル)
=begin original
C<open>'s first argument can be a reference to a filehandle. As of
perl 5.6.0, if the argument is uninitialized, Perl will automatically
create a filehandle and put a reference to it in the first argument,
like so:
=end original
C<open> の最初の引数は、ファイルハンドルへのリファレンスにすることも出来ます。
perl 5.6.0 以降、引数が初期化されていない場合、Perl は
以下のように、自動的にファイルハンドルを作成して、それへのリファレンスを
最初の引数に設定します:
open( my $in, $infile ) or die "Couldn't read $infile: $!";
while ( <$in> ) {
# do something with $_
}
close $in;
=begin original
Indirect filehandles make namespace management easier. Since filehandles
are global to the current package, two subroutines trying to open
C<INFILE> will clash. With two functions opening indirect filehandles
like C<my $infile>, there's no clash and no need to worry about future
conflicts.
=end original
間接ファイルハンドルは、名前空間管理をより容易にします。
ファイルハンドルは現在のパッケージに対してグローバルなので、
二つのサブルーチンが C<INFILE> を開こうとすると衝突します。
二つの関数が C<my $infil> のように間接ファイルハンドルで開いていると、
衝突は発生せず、将来の衝突を気にする必要もありません。
=begin original
Another convenient behavior is that an indirect filehandle automatically
closes when it goes out of scope or when you undefine it:
=end original
もう一つの便利は振る舞いとして、間接ファイルハンドルは、スコープ外に出るか
undef にされると、自動的に閉じます:
sub firstline {
open( my $in, shift ) && return scalar <$in>;
# no close() required
}
=head2 Pipe Opens
(パイプを開く)
=begin original
In C, when you want to open a file using the standard I/O library,
you use the C<fopen> function, but when opening a pipe, you use the
C<popen> function. But in the shell, you just use a different redirection
character. That's also the case for Perl. The C<open> call
remains the same--just its argument differs.
=end original
C では、標準 I/O ライブラリを使ってファイルを開きたいときは C<fopen> を
使いますが、パイプを開くときには C<popen> 関数を使います。
しかし、シェルでは、単に違うリダイレクト文字を使います。
これは Perl の場合にも当てはまります。
C<open> 呼び出しは同じままです -- 単にその引数が変わります。
=begin original
If the leading character is a pipe symbol, C<open> starts up a new
command and opens a write-only filehandle leading into that command.
This lets you write into that handle and have what you write show up on
that command's standard input. For example:
=end original
先頭の文字がパイプ記号の場合、C<open> は新しいコマンドを準備して、
そのコマンドへと導かれる書き込み専用のファイルハンドルを開きます。
これによって、あなたがこのハンドルに書き込んだものがコマンドの
標準入力に渡されるようになります。
例えば:
open(PRINTER, "| lpr -Plp1") || die "can't run lpr: $!";
print PRINTER "stuff\n";
close(PRINTER) || die "can't close lpr: $!";
=begin original
If the trailing character is a pipe, you start up a new command and open a
read-only filehandle leading out of that command. This lets whatever that
command writes to its standard output show up on your handle for reading.
For example:
=end original
末尾の文字がパイプの場合、新しいコマンドを準備して、
そのコマンドから導かれる読み込み専用のファイルハンドルを開きます。
これにより、そのコマンドが標準出力にしたものはなんでも読み込み用の
ファイルハンドルに現れます。
例えば:
open(NET, "netstat -i -n |") || die "can't fork netstat: $!";
while (<NET>) { } # do something with input
close(NET) || die "can't close netstat: $!";
=begin original
What happens if you try to open a pipe to or from a non-existent
command? If possible, Perl will detect the failure and set C<$!> as
usual. But if the command contains special shell characters, such as
C<E<gt>> or C<*>, called 'metacharacters', Perl does not execute the
command directly. Instead, Perl runs the shell, which then tries to
run the command. This means that it's the shell that gets the error
indication. In such a case, the C<open> call will only indicate
failure if Perl can't even run the shell. See L<perlfaq8/"How can I
capture STDERR from an external command?"> to see how to cope with
this. There's also an explanation in L<perlipc>.
=end original
存在しないコマンドに対してパイプを開こうとすると何が起こるでしょうか?
可能なら、Perl は失敗を検出していつも通り C<$!> をセットします。
しかし、もしコマンドに「メタ文字」と呼ばれる C<E<gt>> や C<*> のような
特殊シェル文字が含まれていると、Perl はコマンドを直接実行しません。
その代わりに、Perl はシェルを実行し、それからコマンドを
実行しようとします。
これは、エラーを受け取るのはシェルであることを意味します。
このような場合、C<open> 呼び出しは、たとえ Perl がシェルを実行できなかった
場合でも、失敗を示すだけです。
これを扱う方法については、
L<perlfaq8/"How can I capture STDERR from an external command?"> を
参照してください。
L<perlipc> にも説明があります。
=begin original
If you would like to open a bidirectional pipe, the IPC::Open2
library will handle this for you. Check out
L<perlipc/"Bidirectional Communication with Another Process">
=end original
双方向パイプを開きたい場合は、IPC::Open2 ライブラリが使えます。
L<perlipc/"Bidirectional Communication with Another Process"> を
参照してください。
=begin original
perl-5.6.x introduced a version of piped open that executes a process
based on its command line arguments without relying on the shell. (Similar
to the C<system(@LIST)> notation.) This is safer and faster than executing
a single argument pipe-command, but does not allow special shell
constructs. (It is also not supported on Microsoft Windows, Mac OS Classic
or RISC OS.)
=end original
perl-5.6.x から、シェルに頼らずにコマンドライン引数を基にしてプロセスを
実行するパイプオープンが導入されました。
(C<system(@LIST)> 記法と同様です。)
これは 1 引数のパイプコマンドを実行するより安全で高速ですが、特殊シェル
構文は使えません。
(また、Microsoft Windows, Mac OS Classic, RISC OS でも対応していません。)
=begin original
Here's an example of C<open '-|'>, which prints a random Unix
fortune cookie as uppercase:
=end original
以下は C<open '-|'> の例で、ランダムな Unix おみくじを大文字で表示します:
my $collection = shift(@ARGV);
open my $fortune, '-|', 'fortune', $collection
or die "Could not find fortune - $!";
while (<$fortune>)
{
print uc($_);
}
close($fortune);
=begin original
And this C<open '|-'> pipes into lpr:
=end original
そしてこれは C<open '|-'> パイプを lpr に送ります:
open my $printer, '|-', 'lpr', '-Plp1'
or die "can't run lpr: $!";
print {$printer} "stuff\n";
close($printer)
or die "can't close lpr: $!";
=head2 The Minus File
("-" ファイル)
=begin original
Again following the lead of the standard shell utilities, Perl's
C<open> function treats a file whose name is a single minus, "-", in a
special way. If you open minus for reading, it really means to access
the standard input. If you open minus for writing, it really means to
access the standard output.
=end original
再び標準シェルの機能に合わせるように、Perl の
C<open> 関数は、名前がマイナス一つ "-" だけのファイルを特別に扱います。
読み込み用にマイナスを開くと、実際には標準入力にアクセスします。
書き込み用にマイナスを開くと、実際には標準出力にアクセスします。
=begin original
If minus can be used as the default input or default output, what happens
if you open a pipe into or out of minus? What's the default command it
would run? The same script as you're currently running! This is actually
a stealth C<fork> hidden inside an C<open> call. See
L<perlipc/"Safe Pipe Opens"> for details.
=end original
マイナスがデフォルトの入力やデフォルトの出力として使えるとすると、
パイプに対してマイナスを使うとどうなるでしょう?
デフォルトのコマンドとして何が実行されるのでしょう?
今実行している同じスクリプトです!
これは実際には C<open> 呼び出し内で隠れた C<fork> が行われます。
詳しくは L<perlipc/"Safe Pipe Opens"> を参照してください。
=head2 Mixing Reads and Writes
(読み書きを混ぜる)
=begin original
It is possible to specify both read and write access. All you do is
add a "+" symbol in front of the redirection. But as in the shell,
using a less-than on a file never creates a new file; it only opens an
existing one. On the other hand, using a greater-than always clobbers
(truncates to zero length) an existing file, or creates a brand-new one
if there isn't an old one. Adding a "+" for read-write doesn't affect
whether it only works on existing files or always clobbers existing ones.
=end original
読み書きアクセス双方を指定することは可能です。
必要なことはリダイレクトの前に "+" の文字を加えるだけです。
しかしシェルの場合と同様、ファイルに小なり記号を使っても新しいファイルが
作成されることはありません; すでにあるファイルを開くだけです。
一方、大なり記号を使うと、ファイルがある場合には常に上書き
(長さ 0 に切り詰め)られ、ファイルがない場合は新しいファイルが作成されます。
読み書き用に "+" を追加しても、既にあるファイルにだけ動作するか
既にあるファイルを上書きするかということには影響を与えません。
open(WTMP, "+< /usr/adm/wtmp")
|| die "can't open /usr/adm/wtmp: $!";
open(SCREEN, "+> lkscreen")
|| die "can't open lkscreen: $!";
open(LOGFILE, "+>> /var/log/applog")
|| die "can't open /var/log/applog: $!";
=begin original
The first one won't create a new file, and the second one will always
clobber an old one. The third one will create a new file if necessary
and not clobber an old one, and it will allow you to read at any point
in the file, but all writes will always go to the end. In short,
the first case is substantially more common than the second and third
cases, which are almost always wrong. (If you know C, the plus in
Perl's C<open> is historically derived from the one in C's fopen(3S),
which it ultimately calls.)
=end original
一つ目のものは新しいファイルを作ることはなく、二つ目のものは常に古い
ファイルを上書きします。
三つ目のものは必要があれば新しいファイルを作りますが、古いファイルを
上書きせず、ファイルのどの地点でも読み込むことができますが、
書き込みは常に末尾に行われます。
要するに、一つ目のものは(ほとんど常に間違っている)二つ目や三つ目の
ものよりもかなり一般的です。
(もし C を知っているなら、Perl の C<open> で使われるプラス記号が
歴史的には (最終的に呼ばれることになる) C の fopen(3S) に由来しています。)
=begin original
In fact, when it comes to updating a file, unless you're working on
a binary file as in the WTMP case above, you probably don't want to
use this approach for updating. Instead, Perl's B<-i> flag comes to
the rescue. The following command takes all the C, C++, or yacc source
or header files and changes all their foo's to bar's, leaving
the old version in the original filename with a ".orig" tacked
on the end:
=end original
実際、ファイルを更新するとき、上述の WTMP の場合のようなバイナリファイルに
対して作業をするのでない限り、おそらく更新のためにこの手法を
使いたくないでしょう。
代わりに、Perl の B<-i> フラグが助けになります。
以下のコマンドは C, C++, yacc 全てののソースファイルとヘッダファイルを
取って、その中の全ての foo を bar に変更し、原版は元のファイル名の末尾に
".orig" を付けたファイルに保持します:
$ perl -i.orig -pe 's/\bfoo\b/bar/g' *.[Cchy]
=begin original
This is a short cut for some renaming games that are really
the best way to update textfiles. See the second question in
L<perlfaq5> for more details.
=end original
これは実際にはテキストファイルを更新するための最良の方法であるリネーム
手法へのショートカットです。
さらなる詳細については L<perlfaq5> の 2 番目の質問を参照してください。
=head2 Filters
(フィルタ)
=begin original
One of the most common uses for C<open> is one you never
even notice. When you process the ARGV filehandle using
C<< <ARGV> >>, Perl actually does an implicit open
on each file in @ARGV. Thus a program called like this:
=end original
C<open> のもっとも一般的な使い方の一つは、使っていることを
気づきすらしないものです。
ARGV ファイルハンドルを C<< <ARGV> >> を使って処理するとき、Perl は
実際は @ARGV の各ファイルを暗黙の内に開いています。
従って、以下のようなプログラムは:
$ myprogram file1 file2 file3
=begin original
can have all its files opened and processed one at a time
using a construct no more complex than:
=end original
以下のようなものより複雑な構文を使わなくても、それぞれのファイルを
開いて一度に処理できます:
while (<>) {
# do something with $_
}
=begin original
If @ARGV is empty when the loop first begins, Perl pretends you've opened
up minus, that is, the standard input. In fact, $ARGV, the currently
open file during C<< <ARGV> >> processing, is even set to "-"
in these circumstances.
=end original
ループが最初に開始したときに @ARGV が空なら、Perl はマイナス記号
(つまり標準入力) を開いたかのように振る舞います。
実際、C<< <ARGV> >> で現在開いているファイルを示す $ARGV には、
この慣習によって "-" がセットされます。
=begin original
You are welcome to pre-process your @ARGV before starting the loop to
make sure it's to your liking. One reason to do this might be to remove
command options beginning with a minus. While you can always roll the
simple ones by hand, the Getopts modules are good for this:
=end original
好みの形にするために、ループの開始前に @ARGV を前処理しても問題ありません。
こうするための理由の一つは、マイナスから始まるコマンドオプションを
削除するためです。
いつでも自分で単純なものを作ることができる一方、
Getopts モジュールはこれを行うのによいものです:
use Getopt::Std;
# -v, -D, -o ARG, sets $opt_v, $opt_D, $opt_o
getopts("vDo:");
# -v, -D, -o ARG, sets $args{v}, $args{D}, $args{o}
getopts("vDo:", \%args);
=begin original
Or the standard Getopt::Long module to permit named arguments:
=end original
あるいは、名前付きの引数を使えるようにするための
標準の Getopt::Long モジュールもあります:
use Getopt::Long;
GetOptions( "verbose" => \$verbose, # --verbose
"Debug" => \$debug, # --Debug
"output=s" => \$output );
# --output=somestring or --output somestring
=begin original
Another reason for preprocessing arguments is to make an empty
argument list default to all files:
=end original
引数を前処理するためのもう一つの理由は、空引数リストの時は
デフォルトで全てのファイルとする場合です:
@ARGV = glob("*") unless @ARGV;
=begin original
You could even filter out all but plain, text files. This is a bit
silent, of course, and you might prefer to mention them on the way.
=end original
プレーンなテキストファイル以外をフィルタリングすることもできます。
これはもちろん少し静かなので、途中でそれに言及したいかもしれません。
@ARGV = grep { -f && -T } @ARGV;
=begin original
If you're using the B<-n> or B<-p> command-line options, you
should put changes to @ARGV in a C<BEGIN{}> block.
=end original
もし B<-n> や B<-p> のコマンドラインオプションを使っているなら、
@ARGV への変更は C<BEGIN{}> ブロックで行うべきです。
=begin original
Remember that a normal C<open> has special properties, in that it might
call fopen(3S) or it might called popen(3S), depending on what its
argument looks like; that's why it's sometimes called "magic open".
Here's an example:
=end original
通常の C<open> は特別な特性を持っていて、引数が何に見えるかによって、
fopen(3S) を呼ぶかもしれませんし、popen(3S) を呼ぶかもしれません;
これが時々「マジカルに開く」と呼ばれる理由です。
以下は例です:
$pwdinfo = `domainname` =~ /^(\(none\))?$/
? '< /etc/passwd'
: 'ypcat passwd |';
open(PWD, $pwdinfo)
or die "can't open $pwdinfo: $!";
=begin original
This sort of thing also comes into play in filter processing. Because
C<< <ARGV> >> processing employs the normal, shell-style Perl C<open>,
it respects all the special things we've already seen:
=end original
このようなことはフィルタ処理でも起こります。
C<< <ARGV> >> 処理は通常のシェル風の Perl C<open> を用いるので、
今までに見てきた全ての特別なことが反映されます:
$ myprogram f1 "cmd1|" - f2 "cmd2|" f3 < tmpfile
=begin original
That program will read from the file F<f1>, the process F<cmd1>, standard
input (F<tmpfile> in this case), the F<f2> file, the F<cmd2> command,
and finally the F<f3> file.
=end original
このプログラムはファイル F<f1>、プロセス F<cmd1>、標準入力
(この場合は F<tmpfile>)、ファイル F<f2>、コマンド F<cmd2>、
ファイル F<f3> から読み込みます。
=begin original
Yes, this also means that if you have files named "-" (and so on) in
your directory, they won't be processed as literal files by C<open>.
You'll need to pass them as "./-", much as you would for the I<rm> program,
or you could use C<sysopen> as described below.
=end original
はい、これは、"-" (あるいは同じような) 名前を持つファイルがある場合、
C<open> によってそのまま処理することができないことも意味します。
I<rm> プログラムに対して行うのと同様に "./-" という形で渡すか、後述する
C<sysopen> を使う必要があります。
=begin original
One of the more interesting applications is to change files of a certain
name into pipes. For example, to autoprocess gzipped or compressed
files by decompressing them with I<gzip>:
=end original
もっと興味深いアプリケーションの一つは、ある名前を持ったファイルを
パイプに変更するものです。
例えば、gzip や compress されたファイルを、I<gzip> を使って自動的に
展開するには:
@ARGV = map { /\.(gz|Z)$/ ? "gzip -dc $_ |" : $_ } @ARGV;
=begin original
Or, if you have the I<GET> program installed from LWP,
you can fetch URLs before processing them:
=end original
あるいは、LWP からインストールされる I<GET> プログラムがあるなら、
処理する前に URL をフェッチできます:
@ARGV = map { m#^\w+://# ? "GET $_ |" : $_ } @ARGV;
=begin original
It's not for nothing that this is called magic C<< <ARGV> >>.
Pretty nifty, eh?
=end original
これがマジカルな C<< <ARGV> >> と呼ばれるのは理由のないことではありません。
かなりしゃれてるでしょ?
=head1 Open E<agrave> la C
(C 風に開く)
=begin original
If you want the convenience of the shell, then Perl's C<open> is
definitely the way to go. On the other hand, if you want finer precision
than C's simplistic fopen(3S) provides you should look to Perl's
C<sysopen>, which is a direct hook into the open(2) system call.
That does mean it's a bit more involved, but that's the price of
precision.
=end original
シェルの便利さを求めているなら、Perl の C<open> はまさにぴったりです。
一方、C の単純な fopen(3S) が提供しているものより高い精度を求めているなら、
open(2) システムコールへの直接的なフックである、Perl の
C<sysopen> を見るべきです。
これはもう少し深く関わることを意味しますが、これは精度のコストです。
=begin original
C<sysopen> takes 3 (or 4) arguments.
=end original
C<sysopen> は 3 (または 4) 引数を取ります。
sysopen HANDLE, PATH, FLAGS, [MASK]
=begin original
The HANDLE argument is a filehandle just as with C<open>. The PATH is
a literal path, one that doesn't pay attention to any greater-thans or
less-thans or pipes or minuses, nor ignore whitespace. If it's there,
it's part of the path. The FLAGS argument contains one or more values
derived from the Fcntl module that have been or'd together using the
bitwise "|" operator. The final argument, the MASK, is optional; if
present, it is combined with the user's current umask for the creation
mode of the file. You should usually omit this.
=end original
HANDLE 引数は C<open> と同様のファイルハンドルです。
PATH はリテラルなパスで、大なりや小なりやパイプやマイナスや空白の
無視といったことに一切注意を払いません。
もしこれらの文字があれば、それはパスの一部です。
FLAGS 引数は、ビット単位 "|" 演算子で結合できる、Fcntl モジュールに
由来する一つ以上の値を指定します。
最後の引数である MASK はオプションです; もしあれば、これは
ファイルの作成モードのためのユーザーの現在の umask と組み合わされます。
普通はこれは省略するべきです。
=begin original
Although the traditional values of read-only, write-only, and read-write
are 0, 1, and 2 respectively, this is known not to hold true on some
systems. Instead, it's best to load in the appropriate constants first
from the Fcntl module, which supplies the following standard flags:
=end original
読み込み専用、書き込み専用、読み書きを示す伝統的な値は
それぞれ 0, 1, 2 ですが、これが正しくないシステムもあることが
知られています。
代わりに、以下の標準フラグを提供している Fcntl モジュールから
最初に適切な定数を読み込むのが最善です:
O_RDONLY Read only
O_WRONLY Write only
O_RDWR Read and write
O_CREAT Create the file if it doesn't exist
O_EXCL Fail if the file already exists
O_APPEND Append to the file
O_TRUNC Truncate the file
O_NONBLOCK Non-blocking access
=begin original
Less common flags that are sometimes available on some operating
systems include C<O_BINARY>, C<O_TEXT>, C<O_SHLOCK>, C<O_EXLOCK>,
C<O_DEFER>, C<O_SYNC>, C<O_ASYNC>, C<O_DSYNC>, C<O_RSYNC>,
C<O_NOCTTY>, C<O_NDELAY> and C<O_LARGEFILE>. Consult your open(2)
manpage or its local equivalent for details. (Note: starting from
Perl release 5.6 the C<O_LARGEFILE> flag, if available, is automatically
added to the sysopen() flags because large files are the default.)
=end original
オペレーティングシステムによっては、
C<O_BINARY>, C<O_TEXT>, C<O_SHLOCK>, C<O_EXLOCK>,
C<O_DEFER>, C<O_SYNC>, C<O_ASYNC>, C<O_DSYNC>, C<O_RSYNC>,
C<O_NOCTTY>, C<O_NDELAY>, C<O_LARGEFILE> のような、それほど有名ではない
フラグも利用可能です。
詳しくは open(2) man ページその等価物を参照してください。
(注意: Perl リリース 5.6 から、もし利用可能なら、sysopen() のフラグに
自動的に C<O_LARGEFILE> フラグが付きます; 大きなファイルがデフォルトに
なったからです。)
=begin original
Here's how to use C<sysopen> to emulate the simple C<open> calls we had
before. We'll omit the C<|| die $!> checks for clarity, but make sure
you always check the return values in real code. These aren't quite
the same, since C<open> will trim leading and trailing whitespace,
but you'll get the idea.
=end original
これは、前述した単純な C<open> をエミュレートするために C<sysopen> を
使う方法です。
明確化のために C<|| die $!> のチェックは省略しましたが、実際のコードでは
常に返り値をチェックするようにしてください。
C<open> は前後の空白を削除するのでこれは全く同じというわけではありませんが、
想像はできるでしょう。
=begin original
To open a file for reading:
=end original
ファイルを読み込み用に開くには:
open(FH, "< $path");
sysopen(FH, $path, O_RDONLY);
=begin original
To open a file for writing, creating a new file if needed or else truncating
an old file:
=end original
ファイルを書き込み用に開いて、必要なら新しいファイルを作り、そうでなければ
古いファイルを切り詰めるには:
open(FH, "> $path");
sysopen(FH, $path, O_WRONLY | O_TRUNC | O_CREAT);
=begin original
To open a file for appending, creating one if necessary:
=end original
ファイルを追加用に開いて、もし必要なら新しいファイルを作るには:
open(FH, ">> $path");
sysopen(FH, $path, O_WRONLY | O_APPEND | O_CREAT);
=begin original
To open a file for update, where the file must already exist:
=end original
既に存在しているファイルを更新用に開くには:
open(FH, "+< $path");
sysopen(FH, $path, O_RDWR);
=begin original
And here are things you can do with C<sysopen> that you cannot do with
a regular C<open>. As you'll see, it's just a matter of controlling the
flags in the third argument.
=end original
そしてここでは普通の C<open> では出来ないことを C<sysopen> でしています。
見てきたように、これは単に 3 番目の引数のフラグの制御の問題です。
=begin original
To open a file for writing, creating a new file which must not previously
exist:
=end original
既に存在していたりはしない新しいファイルを作成して、ファイルを書き込み用に
開くには:
sysopen(FH, $path, O_WRONLY | O_EXCL | O_CREAT);
=begin original
To open a file for appending, where that file must already exist:
=end original
既に存在している必要があるファイルを追加用に開くには:
sysopen(FH, $path, O_WRONLY | O_APPEND);
=begin original
To open a file for update, creating a new file if necessary:
=end original
必要なら新しいファイルを作成して、ファイルを更新用に開くには:
sysopen(FH, $path, O_RDWR | O_CREAT);
=begin original
To open a file for update, where that file must not already exist:
=end original
予め存在していてはならないファイルを交信用に開くには:
sysopen(FH, $path, O_RDWR | O_EXCL | O_CREAT);
=begin original