何年も使ってるのに、基本的な関数知らないとか!とか、思った。
同僚がはまっていたので知ったのですが、sort のスカラコンテキストでの振る舞いは未定義だそうです。実際問題、sort をスカラで受けるとか意味わからない。ちゃんと警告も出ます。
Useless use of sort in scalar context at -e line 1.
そもそも、リストをスカラで受けるのは、かなり嫌な感じになるため、経験的に避けます。
my $item = qw/a b c/;
$item に入るのは、リストの最後の要素、'c' なのですが、意図してこんなコードは書きませんよね。
ちなみに、
my ($item) = qw/a b c/;
の場合は、$item に入るのは、'a' です。
grep, map に関しては、要素数が取れるので、また違った感じですが、要素数を取る目的ではあんまり使った覚えがない。grep を scalar コンテキストで使う場合は、だいぶ昔は if の中とかで使ってた気がするけど、そういうケースでは、List::Util の any のほうが良いですね。
if (any {$_ > 1} @array) { # ... }
map をスカラコンテキストで使った覚えがないなぁ。使うケースが思いつかない。
で、sort なのですが、(Ubuntu 13.04で、Perl 5.16.3 と 5.12.3 で試しました)
my $item = sort qw/a b c/;
$item は空になります。perldoc -f sort では、
sort SUBNAME LIST
http://perldoc.jp/func/sort
sort BLOCK LIST
sort LIST
リストコンテキストでは、LIST をソートし、ソートされたリスト値を返します。 スカラコンテキストでは、sort() の振る舞いは未定義です。
「 スカラコンテキストでは、sort() の振る舞いは未定義」なので、空になる保証もないわけですが。
そもそも、リストコンテキスト以外は意味ないからsort自体の処理に入らないようです。
最初の警告の説明には、以下のように書かれています。
Useless use of sort in scalar context
(W void) こんな風に、ソートをスカラコンテキストで使いました:my $x = sort @y;
http://perldoc.jp/docs/perl/perldiag.pod
これは全く便利ではないので、perl は現在のところ最適化して取り除きます。
以下の通り。
$ perl -e 'scalar sort {die($a) } (1,2); ' # scalar context $ perl -e 'sort {die($a) } (1,2); ' # void context $ perl -e 'my @x = sort {die($a) } (1,2); ' # list context 2 at -e line 1.
dieしているのは、最後のものだけでした。
どうでも良いのですが、リスト操作系の関数でスカラコンテキストでは意味無さげな reverse はどうなんだろうと思ったら、こんな感じでした。
print scalar reverse "dlrow ,", "olleH"; # Hello, world
どこで使うのかと小一時間悩みましたが、回文かどうかチェックするのが簡単でした(引用: http://kaibun21.jp/works/13200/)。
perl -CA -e 'print join("", @ARGV) eq reverse(@ARGV);' かいあたえ しつくしくつし えたあいか
もはや、記事名となんの関係もないけど、最後にまとめると、
リスト ... 最後の要素 配列 ... 要素数 sort ... 未定義 grep ... 要素数 map ... 要素数 reverse ... 引数の順番も中身もひっくり返す
て、感じでした。