Perl 名前付き引数、スライス

最近、仕事でPerlを使う機会があってPerlがちょっと理解できるようになったので、
ついでにPerl使いになろうかと↓を読んでる。

Effective Perl (ASCII Addison Wesley Programming Series)

Effective Perl (ASCII Addison Wesley Programming Series)

Perlの名前付き引数の実装方法と、スライスの活用方法がオモシロイ。

名前付き引数

'=>' 演算子はハッシュの初期化に使う演算子だと思っていたが、この演算子、どうやら ',' とほぼ
同義の演算子らしい。ただ、左側が常に文字列として扱われる。
つまり、

func( "hoo", "bar" );

という呼び出しと

func( "hoo" => "bar" );
または
func( hoo => "bar" );

という呼び出しは、全く同じように、 @_ には("hoo", "bar")が入ってくる。
名前付き引数に対応している関数は後者のような呼び出し方をしてもらって、

sub func 
{
  my %params = @_;
}

というように、ハッシュをリストで初期化するコードを入れ込む。
こうすると、

func( hoo => "bar", hoge => "huga" );

の呼び出しで

my %params = (
  "hoo", "bar", "hoge", "huga"
)
つまり
my %params = (
  hoo => "bar",
  hoge => "huga"
)

のように%paramが初期化される。
なんかすげぇ黒魔術的。

スライス

スライスは @array[.] か @hash{} の形をしていて、[]か{}の中がリストコンテキスト。

@array[0,1] = @array[1,0];

とか書くと、array配列の0番目の変数と1番目の変数が交換できてしまう。
同じように、ハッシュにもスライスが存在して

@hash{'old', 'new'} = @hash{'new', 'old'};

と書くと、$hash{'old'}と$hash{'new'}のバリューの交換ができる。
関数の名前付き引数で、内部のハッシュを初期化するときに、あるキー以外の(キー、バリュー)の組み合わせを捨てて
しまいたいときは、以下のように実装する。

sub func
{
    %params = (
      key1 => 'default_value1',
      key2 => 'default_value2',
    );

    %params_in = @_;

    @params{keys %params} = values %params_in;
}

こう実装すると、

func( key1 => 1, key3 => 3);

と呼び出されても、(kye3, 3)の組み合わせは無視される。
リストコンテキスト恐るべし。

Perlは全体的に、キーワードのコンテキスト依存の使われ方が多い。
これは、よく言えば、自然に書けるってことなんだろうけど、覚えなきゃいかんイディオムが多すぎ。
よく「自分の書いたPerlのコードを後からみると意味不明」って言われるけど、これは
コンテキスト依存の書き方を多用できるからのように思う。