2008年06月03日 06:00 [Edit]

perl - 勝手に添削 - Perl入門#1@ITPro

camel

さすがに出典が日経Linux 2003年7月号だけあって、少しトウがたってはいるけど、現在でもわずかな修正で使える記事。さすが川合さんといったところか。

というわけで、この記事の「現代化」Patchを。


全般

  • use strict;だけではなくuse warnings;も加えましょう。
  • さらに,調べても分からないことがあれば,メーリング・リストやユーザー・グループ*2に質問してみてもよいでしょう。

    blogに書くのもアリです。あと私は使っていないけどIRCとか。

  • ビルトイン関数は()でくくらない方が視認性が上がります。
    before:
    chomp($sLine);
    
    after:
    chomp $sLine;
    
  • 後置のifの条件も、()でくくらない方がよいでしょう。
    before:
    next if(($aList[-1] eq '.') or ($aList[-1] eq '..'));
    
    after:
    next if $aList[-1] eq '.' or $aList[-1] eq '..';
    

ファイルの操作

はてブでも複数指摘があった通り、ベアワードのファイルハンドルの使用は、STDIN, STDOUT, STDERR, ARGVなど、あらかじめ用意されているものに限り、あとはopen my $fh, ...opendir my $dh ...を使いましょう。

あと、openが失敗した場合に備えましょう。

before:
open IN, '< _lsres_';
after:
open my $fh, '<', '_lsres_' or die $!;
または
my $filename = '_lsres_';
open my $fh, '<',  $filename or die "filename : $!";

めんどいという場合は、Fatalモジュールを使う手もあります。

use Fatal qw/open close/;
# ....
open my $fh, '<', '_lsres_'; # or die $! したのと同じになる

もう一つ、IO::Fileを使ってファイルハンドルをオブジェクトとして利用する方法もあります。

use IO::File;
# ....
my $fh = IO::File->new('_lsres_', 'w') or die $!;

普通にファイルハンドルとして使うこともできますし、メソッドを呼び出すことも出来ます。

print $fh "Like a filehandle.\n";
$fh->print("Like an object.\n");

このあたりはお好みで。

パイプ

安全性を考えると、

open IN, "ls -la $sDir |";

は感心しません。$sDirの中身が`rm *`だったりしたら気まずい思いをします。この書き方だとperlは裏でshellを使うので危険が避けられません。

shellに依存しないようにするためには、以下のようにします。

open my $pipe, '-|' or exec 'ls', '-la', $sdir or die $!;

このあたりのことは、perldoc perlsecを参照のこと。

なお、CPANにはコマンドに頼らずにPerl内で行うためのモジュールが多数用意されています。そちらを率先して使いましょう。コマンド呼び出しは最後の武器と心得ましょう。

readdir関数

opendir IN, $sDir;
while(my $sFile=readdir(IN)) {
    next if(($sFile eq '.') or ($sFile eq '..'));
    my $iSize = (-s "$sDir/$sFile");
    print "$sFileバックスラッシュt$iSizeバックスラッシュn";
    $iSum += $iSize;
}
closedir $dh;

この「ディレクトリの中身を全て処理する」には idiom (慣用句)があります。この際覚えておきましょう。

opendir my $dh, $sDir or die "$sDir : $!";
for my $sFile (grep !/^\.\.?/, readdir($dh)) {
    my $iSize = (-s "$sDir/$sFile");
    print "$sFileバックスラッシュt$iSizeバックスラッシュn";
    $iSum += $iSize;
}
closedir $dh;

まとめと参考文献の紹介

だいたいこんなところでしょうか。

それにしても、これだけ古い記事がWebに再掲載されたのは、YAPC::Asia::2008のSchwernの檄の賜物でしょうか。

きちんとやりたい人は、以下の本を入手しておくとよいでしょう。「404 Blog Not Found:perl - "Hello, world!"から始めたくない人は」でレビューしてます。

Enjoy!


Dan the Perl Monger


この記事へのトラックバックURL

この記事へのトラックバック
Cross the Sea: Three Tips About Perl I Have Known in Recent Days [cross-the-sea.blogspot.com] if ( $error_contents ){ unless ( defined $fh ){ open ($fh, "$dir_store/report.txt"); } print $fh "$error_contents\n";} んーこれはかなり旧式な書き方。 これだと、$...
definedで調べなくてもmy $fhでOK【M.C.P.C.】at 2009年03月25日 12:24
第1回 Perlの文法の基本:ITpro という記事の はてブコメントを見ていたら、Perl なすごい人達が文句言ってた。 otsune 2006年のhyuki Catalyst記事を載せるのもアレなのに2003年の記事を載せるのは無しだろ……open IN, ...のあたりは有害情報なので全力で見逃せ TAKESAKO
[perl]Perl 2008年のファイルオープン【てっく煮ブログ】at 2008年06月03日 09:54
この記事へのコメント
close() のエラーチェックは不要なのかなー
Posted by tateisu at 2008年06月09日 22:08
for my $sFile (grep !/^\.\.?/, readdir($dh)) {

for my $sFile (grep !/^\.\.?$/, readdir($dh)) {
か?
Posted by rsh at 2008年06月03日 13:23
open my $fh, '<', $filename or die "filename : $!";

open my $fh, '<', $filename or die "$filename : $!";
か?
Posted by at 2008年06月03日 09:36