第6回 エイリアスという発想と破壊的!という考え方

Perlにおけるエイリアスという言葉を紹介します。これリファレンスとよく似たような考え方のものなのですが、ちょっと違っています。
ですが、リファレンスよりは簡単だと思います。

今まで、for文の中で $_ を使ってきましたね。

use strict;

my @array = 1..3;

for(@array){
 print "$_", "\n";
}

結果:

1
2
3

$_ はforが回ったときの配列の要素それ自身なのです。
では次のようなソースはどうでしょうか?

use strict;

my @array = 1..3;

print "------\n";  # 出力結果を見やすくするため

for(@array){
 print "$_", "\n";
 $_++;  # ++ している
}

print "------\n";  # 出力結果を見やすくするため

print "$_", "\n" for @array;


結果:

------
1
2
3
------
2
3
4

おや!! @arrayの値すべてが+1されてしまっています。

そうなんです。
forで回したときの $_ はまさに本当に配列の要素それ自体になるのです。
この機能を「エイリアス」と呼びます。
このことを知っていないと思わぬ思い違いのソースを書いてしまうかもしれないので十分注意してください。


さて、 $_ ですが、 $_ という名前なんかじゃなくて しっかり変数名を付けたい場合があります。
そういうときは つぎのような文法になります。

use strict;

my @array = ('a','b',3);

for my $i (@array){
 print "$i", "\n";
}

結果:

a
b
3
for my 変数名(  ){   }

という書式になる訳です。

ここで、C言語出身者だと $i と iを見た瞬間に、 ああインデックスが入るんだ と勘違いして
結果が

0
1
2

となると 思い込むときがありますが、それはとんだ勘違いです!!!

forは配列から要素を1つずつ取り出して、われわれに処理させてくれるのです。インデックスなどという余計な変数のことを考える必要はありません。


さて、この $_ に名前をつけた場合なんですけども、やはり$_と同じように配列の要素それ自身となります。

use strict;

my @array = ('a','b',3);

print "-------\n";

for my $i (@array){
 print "$i", "\n";
 $i = 1;   # $iに1を代入
}

print "-------\n";

print "$_", "\n" for @array;

結果:

-------
a
b
3
-------
1
1
1

十分に注意してください。


さて、Rubyには、「破壊的メソッド」というのがあります。これはそのメソッドを呼び出すオブジェクトのそれ自体を変えてしまうメソッドです。多くの破壊的メソッドは、それが破壊的であることを示す為に ! がついています。

例:

a = Array.new([1,2,3])

print "----\n"
p a
print "----\n"

a.reverse!
p a

結果:

----
[1, 2, 3]
----
[3, 2, 1]

しかし、つぎのように ! がついていないメソッドでもオブジェクト自身が変わってしまうものもあります。

a = Array.new([1,2,3])

print "----\n"
p a
print "----\n"

a.push(4)
p a

結果:

----
[1, 2, 3]
----
[1, 2, 3, 4]

とまあ、こんな感じでまちまちなのですが、


「それ自体が変わってしまう」という考え方は、プログラムの世界ではよくあることなので本当に注意が必要です
(※ 慣れていないとソースがよみづらいですし、 下手につかうとソースが非常にわかりづらくなったりします)


ということで、 Perlの「エイリアス」とRubyの「破壊的メソッド」で「それ自身が変わってしまう例」をみてきました。



それでは また〜