$aと$bを使うときに気をつけること
sort
で使う、$a
と$b
は特殊パッケージ変数なので、
同じブロック内でsort
を使うときは気をつける必要がある。(*1)
「特殊パッケージ変数」っていう単語は、ここから。
$a – perldoc.jp
まずは、なんでもないコードから。
use strict; use warnings; use v5.10; main(); sub main { say join ',', sort { $b <=> $a } 0..5; }
実行結果はこんな感じ。
$ perl aaa.pl
5,4,3,2,1,0
次に、my
を使って宣言する。
use strict; use warnings; use v5.10; main(); sub main { my ( $a, $b ) = ( 5, 10 ); say join ',', sort { $b <=> $a } 0..5; say "( \$a, \$b ) = ( $a, $b )"; }
これが、perldocに書かれていた、やってはいけないこと。
$ perl bbb.pl
Can't use "my $b" in sort comparison at bbb.pl line 9.
local
を使って宣言した場合は?
use strict; use warnings; use v5.10; main(); sub main { local ( $a, $b ) = ( 5, 10 ); say join ',', sort { $b <=> $a } 0..5; say "( \$a, \$b ) = ( $a, $b )"; }
これは、問題なし。
$ perl ccc.pl
5,4,3,2,1,0
( $a, $b ) = ( 5, 10 )
our
を使って宣言した場合は?
use strict; use warnings; use v5.10; main(); sub main { our ( $a, $b ) = ( 5, 10 ); say join ',', sort { $b <=> $a } 0..5; say "( \$a, \$b ) = ( $a, $b )"; }
これも、問題なし。
$ perl ddd.pl
5,4,3,2,1,0
( $a, $b ) = ( 5, 10 )
じゃぁ、何も付けない場合は?
use strict; use warnings; use v5.10; main(); sub main { ( $a, $b ) = ( 5, 10 ); say join ',', sort { $b <=> $a } 0..5; say "( \$a, \$b ) = ( $a, $b )"; }
すでに存在する$a
と$b
を書き換えただけなので、
もちろん、問題なし。
$ perl eee.pl
5,4,3,2,1,0
( $a, $b ) = ( 5, 10 )
最後に、違うブロックでmy
を使って宣言した場合。
use strict; use warnings; use v5.10; main(); foo(); sub main { say join ',', sort { $b <=> $a } 0..5; } sub foo { my ( $a, $b ) = ( 5, 10 ); say "( \$a, \$b ) = ( $a, $b )"; }
これなら、問題なし。
$ perl fff.pl
5,4,3,2,1,0
( $a, $b ) = ( 5, 10 )
という訳でまとめると、
my
で$a
と$b
を宣言しちゃうと、
local
で退避できないのでエラーになると考えれば、
とりあえず、納得はできる。
でも、なんで$a
と$b
使ったの?ってなるけど、
これはPerlのソースに、ハードコーディングされているらしいので、
それじゃ、仕方ないですね。(*2)
おしまい。
(*1) akiymさん++
(*2) aloelightさん++
Leave a Comment