はじめに
perl開発でリスト(配列)は良く使いますが
改めて初めてのPerl 第6版を読んだので初心に振り返ってリストを復習
ながれ
- リスト&配列とは
- 初期化
- リテラル
- qwショートカット
- index、個数
- 代入
- foreach
- コンテキスト
- 無名配列での良くある間違い例
1. リスト&配列とは
これはもうそのまんま引用です
リスト(list)とは、スカラーの集合に順序を付けて並べたもの
配列とは、リストを格納する変数
補足
この後からコードをいくつか載せますが、
めんどうなので最初にこれが書かれてる前提とします。
#! /usr/bin/perl use strict; use 5.010;
2. 初期化
配列の初期化についてです。
自分的なポイントだけまとめておきます
my @arr
;で初期化した際はmy @arr = ();
と同じ- スカラ変数に無名配列のリファレンスで代入することも可能(コードの$arr04)
ってことでコードで語る
my @arr01; # my @arr = ();と同じ say @arr01; # 結果-> なにも表示されない my @arr02 = (); say @arr02; # 結果-> なにも表示されない my @arr03 = (1,2,3); say @arr03; # 結果-> 123 # スカラ変数に無名配列のリファレンスの形で代入することも可能 my $arr04 = [1,2,3,4]; say @$arr04; # 結果-> 1234
3. リテラル
次はリテラルについて。
初期化の形で右辺にリテラルを書くことでいくつか試します。
自分的なポイント
ってことでコードで
# 数値でのリテラル my @arr01 = (1, 2, 3); say @arr01; # 結果-> 123 # 文字列でのリテラル my @arr02 = ('hoge', 'piyo', 'fuga'); say @arr02; # 結果-> hogepiyofuga # 数値と文字列でのリテラル my @arr03 = (1, 3, 5, 'hoge'); say @arr03; # 結果-> 135hoge # カラ my @arr04 = (); say @arr04; # 結果-> なにも表示されない # 範囲指定演算子 my @arr05 = (2..8); say @arr05; # 結果-> 2345678 # 小数点を指定すると切り捨て my @arr06 = (2.3..8.1); say @arr06; # 結果-> 2345678
4. qwショートカット
んで今度はqwショートカットです
これ普通に使ってはいましたが、qwショートカット
って言うんですね。呼び方を始めて知りましたw
自分的ポイント
- 空白文字は無視される
- デリミタは
/
や!
やカッコ系でもいい- 変数展開はされない
コード
# qwショートカット使って初期化例 my @arr01 = qw/hoge piyo fuga/; say @arr01; # 結果-> hoge piyo fuga # 空白文字は無視される my @arr02 = qw/ hoge piyo fuga /; say @arr02; # 結果-> hoge piyo huga # クオートでかこったやつもそのまま表示される my @arr03 = qw/"hoge" "piyo" "fuga"/; say @arr03; # 結果-> "hoge""piyo""fuga" # デリミタ例 my @arr04 = qw! hoge piyo fuga!; say @arr04; # 結果-> hogepiyofuga my @arr05 = qw# hoge piyo fuga#; say @arr05; # 結果-> hogepiyofuga my @arr06 = qw(hoge piyo huga); say @arr06; # 結果-> hogepiyofuga # 変数展開はされない my $str = 'unko'; my @arr07 = qw/hoge piyo fuga $str/; say @arr07; # 結果-> hogepiyofuga$str
5. index、個数
配列のindex(要素へのアクセス)と個数についてです。
indexは0からみたいなことは他の言語と同様なので、
こちらも自分的ポイントだけ
# 普通に要素アクセスしてみる my @arr01 = qw / hoge fuga piyo /; say $arr01[0]; say $arr01[1]; say $arr01[2]; # 要素数を超えてアクセスすると途中の要素がundefで初期化される $arr01[5] = 'tekitou'; my $i = 0; foreach( @arr01 ) { say $i; # 結果-> 0〜5まで表示される $i++; } # `$#name`で最後の要素のインデックスが得られる my $arr_num1 = $#arr01; say $arr_num1; # 結果-> 5 # スカラコンテキストで代入すると個数が得られる my $arr_num2 = @arr01; say $arr_num2; # 結果-> 6
6. 代入
こちらはいきなりコードから
# スカラ値に代入する的にリスト値を変数に代入できる my ($a, $b, $c) = ('hoge', 'fuga', 'piyo'); say $a; # 結果-> hoge say $b; # 結果-> fuga say $c; # 結果-> piyo # 右辺が少ないときはundefで初期化される my ($d, $e, $f) = ('hoge', 'fuga'); say $d; # 結果-> hoge say $e; # 結果-> fuga say $f; # 結果-> Use of uninitialized value $f # 左辺が少ないときは捨てられる my ($g, $h) = ('hoge', 'fuga', 'piyo'); say $g; # 結果-> hoge say $h; # 結果-> fuga # 複数の配列も代入できる my @arr01 = (1, 2, 3); my @arr02 = (4, 5); my @arr03 = (@arr01, @arr02); say @arr03; # 結果-> 12345 # カラの配列はシカトされる my @arr04 = (1, 2, 3); my @arr05 = (); my @arr06 = (4, 5); my @arr07 = (@arr04, @arr05, @arr06); my $arr_num1 = @arr07; say @arr07; # 結果-> 12345 say $arr_num1; # 結果-> 5 (6個ではない!) # undefは明示的にセットできる my @arr08 = (@arr04, undef, @arr06); my $arr_num2 = @arr08; say @arr08; # 結果-> 12345(Use of uninitialized value $arr08[3]) say $arr_num2; # 結果-> 6
7. foreach
リストそのものというよりは、
foreachでリストをループさせるときの制御変数について
自分的ポイント
- ループ中の制御変数はリストの要素そのもの
コード
# 制御変数はリストの要素そのもの my @arr = qw/hoge fuga piyo/; foreach( @arr ) { $_ = $_ . 'dayo'; } say @arr; # 結果-> hogedayofugadayopiyodayo
8. コンテキスト
最後にコンテキストについて。
初めてのPerl 第6版でもここが本書の中で最も重要なセクション
と言ってるほどです。
コンテキストについては自分的ポイントよりコードのほうが良いので省きます(手抜きw)
コンテキストとは
式をどのように使うかを表す概念。
perlが式を解析する際には、必ずスカラー値かリスト値のどちらかを期待する。
※今回はスカラーとリストにしぼって説明
コンテキスト例
リストの個数を得る例で説明します。(5. index、個数
の最後でも少し触れたやつ)
my @words = ('hoge', 'fuga', 'piyo'); # コンテキストの違い my @list = @words; # リストコンテキスト my $list_num = @words; # スカラコンテキスト say @list; # 結果-> hogefugapiyo say $list_num; # 結果-> 3
@listと$list_numを初期化しているところがコンテキストの違いです。
右辺が同じ@words
ですが、左辺の形によって式の解釈が変わっています。
コンテキストってこんな感じ。
スカラコンテキスト
perlがスカラとして扱う式です。
わかりにくい説明より見た方が早いので例
my @words = ('hoge', 'fuga', 'piyo'); # 例 my $num = @words; # スカラコンテキスト $words[3] = 'unko'; # スカラコンテキスト if( $words[3] ){ }; # スカラコンテキスト while( $words[4] ){}; # スカラコンテキスト my ($any) = @words; # リストコンテキスト! say $any; # 結果-> hoge
最後のmy ($any)
だけリストコンテキストになります。
他はperlがスカラコンテキストとして解析するってことですね。
リストコンテキスト
こちらもいきなし例
# リストコンテキスト例 my @words = ('hoge', 'fuga', 'piyo'); # リストコンテキスト my ($first, $second) = @words; # リストコンテキスト push @words, 'unko'; # リストコンテキスト foreach my $word ( @words ) { }; # リストコンテキスト print $words[0]; # 密かにこれもリストコンテキスト print "\n";
リストコンテキストはわかりやすいですね。 結構まんまです。
自分的に忘れがちになるのが、最後のprint $words[0];
もリストコンテキストということですかね。
スカラコンテキストの強制
擬似関数slacar
を使うことでスカラを強制できますっていう例
my @words = ('hoge', 'fuga', 'piyo'); # リストコンテキスト # カンマで複数出力 say "this words is : " , @words; # 結果-> this words is hogefugapiyo say "this words is : " , scalar @words; # 結果-> this words is 3 # ドットで連結 say "this words is : " . @words; # 結果-> this words is 3
3つ目のsayのように.
で文字列連結を期待する場合もスカラになります
9. 無名配列での良くある間違い例
こちらは初めてのPerl 第6版に書いてあるわけではないですが
良く見る間違い例です
配列をコピーや代入しようとして間違い
リストのというか無名配列のリファレンスの扱いについての間違いでです
my $words = ['hoge', 'fuga', 'piyo']; # 間違い my @any_words = $words; say $any_words[0]; # 結果-> ARRAY(0x7fa088803ea0) # 正解 my @any_words = @$words; say $any_words[0]; # 結果-> hoge
アロー演算子(->)の有る無しでの間違い
こちらも無名配列とリストの取り扱いについてですね。
my $words = ['hoge', 'fuga', 'piyo']; my @any_words = @$words; # 間違い say $words[0]; # 結果-> エラー(Global symbol "@words" requires...) # 正解 say $words->[0]; # 結果-> hoge # 間違い say $any_words->[0]; # 結果-> エラー(Global symbol "$any_words" requires...) # 正解 say $any_words[0]; # 結果-> hoge
これは実際にはエラーが出て実行できないので適宜直すかコメントして実行してみてください。
簡易的にまとめるとこんな感じですかね。
リスト(配列)は
my @arr
で初期化$arr[0]
で要素取り出し無名配列のリファレンスは
まとめ
ってことで、perlのリスト(配列)について復習してみました。
復習してみても知ってることばっかりなはずなのに
開発中は細かいことでミスってるのにあってるはず
という思考のトラップで
なんでうまくいかないなーと小一時間悩むときありますよね。
そんなときこそこういう初心の復習が大事だと思いました(><)