利用者:Senseequal/Perl/関数
関数と演算子の違い
編集print()は関数です。printは演算子です。このように、カッコを付けたものを関数、付けないものを演算子といいます。
printf
編集print "朝", int($x), "時に起きて、", int($y), "時に昼寝して、夜", int($z), "時に寝た。\n";
このような見にくいコードを、
printf "朝%d時に起きて、%d時に昼寝して、夜%d時に寝た。\n", $x, $y, $z;
このように見やすくするときに使います。
printfには$\が効かないので、ご注意を。
sprintf
編集十進法を十六進法に変換するときに使います。
my $hex = sprintf "%X", 16; # 10
substr
編集先頭/末尾1文字を見るときに使います。
while (<$fh>) {
next if substr($_, 0, 1) eq '#';
# ...
}
しかし、
while (<$fh>) {
next if /^#/;
# ...
}
こちらの方がタイプ量が少なくて済むという理由で好まれる場合もあります。
正規表現は遅いのですが、実生活に支障が出るほど遅いわけでもないからです。
上級者ほど後者の書き方を好む傾向にあります。
substrをタイプするのは面倒だが、正規表現を何度もコンパイルしたくないという場合は、
while (<$fh>) {
next if /^#/o;
# ...
}
oオプションを指定することもあります。
末尾1文字を切り出すには、
my $chop = substr $str, -1;
とします。
my $chop = chop $str;
は破壊的なため、遅い可能性があります。
map
編集後置forが使えず、かつ入れ子forより相応しい場合に使います。
つまり、手間を省いて一行で書きたい場合(あるいは結果が重要な場合)。
grepと同じく様々に使われます。
シュワルツ変換など。
warn
編集デバッグ時、あるいはprintの最後に\nを入れるのが面倒な場合に使います。
our $PI = 3.141592653589793;
# ...
warn $PI;
#!/usr/bin/perl
warn time;
die
編集openに失敗したときに使います。
open my $log, '<:utf8', "$logdir/$logfile"
or die $!;
pack/unpack
編集使いません。
split
編集一文字ずつ処理したい場合に使います。
my @chars = split //, $str;
binmode
編集utf8文字列を出力する可能性があるときに使います。
use utf8;
use Encode qw(find_encoding);
binmode STDOUT, ':utf8';
my $utf8 = find_encoding 'UTF-8';
warn $utf8->decode($0);
lc/lcfirst/uc/ucfirst
編集使いません。ただし、
print 1 if "apPlE" =~ /^APPLe\z/i;
よりも、
print 1 if lc "ApPlE" eq lc "aPPlE";
の方が良いとの意見はあります。
do
編集my $slurp = do { local $/; <$fh> };
grep
編集必要に応じて使い方は様々です。
grep { $_ ne 'a' and $_ ne 'b' } よりも grep !/a|b/, という形がよく使われます。
readdirする機会が多ければ、頻繁に使うでしょう。
length
編集文字数が必要な場合、長さに何らかの制限を設けたい場合、などか。
hex/chr/oct/ord
編集特殊な用途で使います。これらを使う用途では、packやunpackやvecやsubstr、sprintfも使うかもしれません。
chomp
編集getsした直後。
my @data = <>;
chomp @data;
whileとの兼ね合いも見られる。
while (<>) {
chomp;
# ...
}
入力の最後に\nが付加されるとは、駆け出しの頃は思いも寄りませんでした。
sort
編集数字順にしたいとき。
@files = sort { $a <=> $b } @files;
数字順 or 文字列順という場合は事前に分岐するか、あるいはno warningsを使うか。
qw
編集非オブジェクト指向モジュールから自動的にはインポートされない関数をインポートする場合。
use CGI::Carp qw/fatalsToBrowser/;
あるいは、自動的にインポートされるものの、明示的に指定しておきたい場合。
use File::Basename qw/basename/;
あるいは、自分の名前空間を汚されたくないので何から何までインポートしたくない場合。
use Encode qw(from_to);
何もインポートしたくない場合は、単なる空リストを渡します。
use List::Util ();
$\ = "\n";
print for List::Util::shuffle(@INC);
scalar
編集localtimeを文字列にしたい場合。
print scalar localtime;
日本標準時 (UTC+09:00) を得るには、
print gmtime time + 9 / 60 / 60;
すなわち
print gmtime time + 32400;
とします。localtimeは、海外のサーバではJSTを返さないでしょう。
time2dhms
編集秒を日時分秒に変換する関数です。私が発明しました。
sub time2dhms($) {
my $time = shift;
return unless defined $time;
my $d = int $time / 86200;
my $h = int $time % 86200 / 3600;
my $m = int $time % 3600 / 60;
my $s = $time % 60;
return ($d, $h, $m, $s);
}
これを日本語に変換するには、
sub time2ja($) {
my $time = shift;
return unless defined $time;
return '0秒' unless $time;
my ($d, $h, $m, $s) = time2dhms $time;
my $str;
$str .= "${d}日" if $d;
$str .= "${h}時間" if $h;
$str .= "${m}分" if $m;
$str .= "${s}秒" if $s;
return $str;
}
こんな感じです。