公開型メモ帳

ますます激しくなる物忘れへの対策

【Perl6】文字列を変数の『前に』追加する

少し試行錯誤して見つけたので、メモしておく。


先に結論を書いておく:

=========================================
Perl6では、

# 変数 $strの『前に』文字列 'abc' を追加する
$str = 'abc' ~ $str;

を、

$str [R~]= 'abc';

と書くことができる。
=========================================


以下に試行錯誤の過程を書く。


ある変数に数を足したり、文字列を追加したりという処理はよくあるので、
Perlに限らず、さまざまなプログラミング言語で省略記法が用意されている。

Perl5の場合はこう:

# 加算
$num = $num + 1;
# 省略記法
$num += 1;

# 文字列の連結
$str = $str . 'abc';
# 省略記法
$str .= 'abc';

これは特に、変数の名前が長かったリ、複雑なデータ構造だったりするときに役に立つ:

$very_very_long_name_variable[42]{'xyz'}[3] .= 'abc';

# こうは書きたくない・・・
$very_very_long_name_variable[42]{'xyz'}[3] = $very_very_long_name_variable[42]{'xyz'}[3] . 'abc';


ところが、これらの省略記法は変数の『後ろに』追加する場合にしか使えない。

つまり、

$long_name_variable = 'abc' . $long_name_variable;

に対する省略記法がないのである。
Perl5 だけでなく、他のプログラミング言語にもない(と思う)。
こういうのを書かなきゃいけなくなるたびに、何とかならないものかと思っていた。


さて、Perl6には「Rメタ演算子」というものがある。
「メタ演算子」とは「演算子に対して作用する演算子」という意味。
Rは「Reverse」の略で、ある演算の左項と右項を入れ替える。

例を見た方が早い:

$str = 'a' R~ 'b';  # Perl6では文字列連結は「~」を使う
#  ==> 'b' ~ 'a';
#  ==> 'ba'

これを使えば、文字列を変数の『前に』追加できるんじゃないか?
と、思って試行錯誤を開始。

my $str = 'a';
$str = $str R~ 'b';
# ==> 'ba'

いい感じ。
これをさらに進めて、

$str R~= 'b';

でいけるかと思ったら、これはエラーになる。

$str R~= 'b';
# ==> 'b' ~= $str;

と解釈されてしまうため。
Rメタ演算子が、「~=」に対して作用してしまっている。

これを何とか「R~」と「=」だと認識させる方法はないだろうか、
数学ならカッコを使うところだけど・・・
と考えて、最後に思いついたのがこの方法:

$str [R~]= 'b'
# ==> 'ba';

見事成功。

・・・とここまで書いて、次にこの角カッコは何かというのを説明しようとしたのだけど、
よく考えると、これでなんでうまく行くのか分からなくなってきた。

$str [R~]= 'b'
# ==> $str = $str [R~] 'b';

っていうことなんだけど、
あれ?角カッコを中置するとどういう意味になるんだっけ??


ということで、だれかがここまで読んでくれていたら申し訳ないのだけど、
いつか時間ができたらまた書く。