第5回 リファレンスと無名配列
さて、リファレンスの話をしたいと思う。
リファレンスというのは、「メインメモリのどこかを指し示している変数」である。
この言葉がわかりにくいなら、「メインメモリのどこかのアドレスが代入されている変数」と考えてもよい。
Perl以外の他の言語でもこの機構はよく存在する。C言語だとポインターがそうだし、Javaなんかだと、変数はオブジェクトを指しているし、JavaScriptなんかもそうである(まあ言語が違うのでビミョーにちがったりはするのですが)。
ただ、C言語とPerlがややこしいのは、「実態」にアクセスするときに元に戻す作業(Perlだとデリファレンスという)する必要があるからだ。
そこで、C言語でポインターを理解している人の為につぎのような記事を昔かいている
ビンゴ中西のほげほげC言語のポインタを使うときの方法
これが理解できれば、Perlのデリファレンスも同様だ。
ビンゴ中西のほげほげリファレンスをデリファレンスする方法
リファレンスを取得するときは、
\
を変数の前に付ければいいし、
デリファレンスするときは、上記リンクさきにある法則性にしたがって、元に戻してもらえばよい。
ここでは、配列のリファレンスとデリファレンスについてじっくり見ていくことにしよう。
use strict; my @array = ('a', 'b', 3); my $ref = \@array;
ということで、
use strict; my @array = ('a', 'b', 3); my $ref = \@array; for(@$ref){ print "$_", "\n"; }
結果:
a b 3
となるわけだ。
しかし、Perlお得意のスカラーという発想があるので、配列ひとつひとつの要素にアクセスするには、 @ を $に変える必要がある(Perl6では仕様が変わるんですけどな^_^ まあでも世の中にはPerl5があふれているのでPerl5を押さえましょう)。
ということで、@が$に変わる様子は次の記事を読んでいただきたい。
2008-10-11
2008-10-12
というわけで、 @が$に変わるのは、リファレンスでも例外ではない。
よって、
use strict; my @array = ('a', 'b', 3); my $ref = \@array; print "$$ref[0]", "\n"; print "$$ref[1]", "\n";
結果:
a b
あーー わけわかんない! となってはいけない。
もう一度、
ビンゴ中西のほげほげリファレンスをデリファレンスする方法
を読んで、
「\と同じだけの$で元にもどす。ただし、最後の記号はもとの変数に合わせる」
の法則を思い出そう!!
さて、これで、配列のデリファレンスの仕方がわかったのだが、
$$となるのはなんかみっともない。そこで、次のようにも書けるのだ。
use strict; my @array = ('a', 'b', 3); my $ref = \@array; print "$ref->[0]", "\n"; print "$ref->[1]", "\n";
結果:
a b
私はこの書き方が好きだ。なぜなら、つぎの絵とぴったりマッチするからだ。
デリファレンスするには、
「\と同じだけの$で元にもどす。ただし、最後の記号はもとの変数に合わせる」
と書いてきたが、「->」を使う場合は、次のように言い直せる。
「\と同じだけの$で元にもどす。ただし、最後の記号はもとの変数に合わせる。しかし、矢印を使う場合は、最後の記号は書かない」
$$ref[0] ↓ $ref->[0]
こういうことである。
ここまでで、配列のデリファレンスする書き方のお話は終わりである。
つぎからは、「無名配列」というものを紹介したい。
今まで、配列自体に名前をつけてきている。
my @array = ('a', 'b', 3); # arrayという名前をつけた my $ref = \@array # arrayという名前を使ってリファレンスを取得
しかし、arrayという名前を用意しなくても、一撃で、$refに配列の場所を教えてくれる書き方があるのだ。
[]
を使えばよい。
use strict; my $ref = ['a', 'b', 3]; print "$ref->[0]", "\n"; print "$ref->[1]", "\n";
結果:
a b
ただ、arrayという名前を用意せずに一撃で、リファレンスを取得する書き方それが、
[]
なのである。これは、プログラムを書いているうちでとても便利なことがわかってくるので、がしがしプログラムを書いてほしい。また、CPANにいけばこれを使った例がいくらでもある。
[]
これで「無名配列」がなぜ「無名」と呼ばれるかわかったと思います。いままで arrayと名前を用意していましたが、その名前を用意する箇所が減った(無くなった)のです。
このリファレンスと無名配列(および無名シリーズ)は使いこなせるとかなり強力になりますので、ぜひとも身につけていってください。
( 余談ですが、無名シリーズを覚えると、 JavaScriptとかなり類似性が出てきます ビンゴ中西のほげほげ如何にJavaScriptとPerlは似ているか )
それでは、また次回お会いしましょう〜