PHPエンジニアがPerl入門した時に知っておきたいこと
はじめまして。オークファン開発部の山本です。
主にaucfan.com本体サイトの開発を担当しております。
私はPHPエンジニアとして弊社に入社したのですが、
入社早々、いきなりPerlを担当してくれとの指示があり、
それ以来、PHP&Perlエンジニアとして各言語のプロジェクトに携わってまいりました。
そこで、PHPエンジニアだった私がPerlを修得するまでに躓いた点をいくつか挙げていこうかと思います。
(とはいえ、PHPからPerlに行く方はなかなかおられないかと思いますが。。。)
- my って何?
-Perlのソースを見てまず目についたのは変数の前にやたら「my」がある。まぁ直感的にlocal変数のような概念なのかと解決はするものの、
Perlを書いていくとPHPの名残からかこのmyを使うべきところで忘れがちになる。(グローバル変数を書く機会は少ないので実質myを必要とすることが多い)
※myとは別にlocalという宣言でダイナミックスコープ変数になるのでその違いに注意 - subって何?
-myの次に目につくのがこの「sub」。調べてみると、サブルーチンの「sub」ということらしい。これもPHPでいうfunctionの概念かなと直感的に理解できるのですが、引数の受け口がない。
更に、subの次の行には変数に「shift」を代入していたり「@_」を複数の変数に代入していたりと、PHPでは見慣れない記述がある。
1234567sub example{my $ex = shift;...}
123456function example($ex){...}
1234567sub example{my ( $ex1, $ex2, $ex3, $ex4 ) = @_;...}
123456function example($ex1, $ex2, $ex3, $ex4 ){...}
また、「shift」や「@_」はそれぞれ下記の記述で同じ動きになる
1234567sub example{my ( $ex1, $ex2, $ex3, $ex4 ) = @_;...}
12345678910sub example{my $ex1 = shift;my $ex2 = shift;my $ex3 = shift;my $ex4 = shift;...}
※Perlはこういった同じ動きをするのに書き方が様々存在する言語という印象。それが初心者に混乱を招き、とっつきづらい言語とさせているのではないかと個人的に思う。。 - Perlには連想配列が。。ない。。。
-厳密にはPHPで言う連想配列のようなものはあります。それはハッシュという配列構造で、PHPの連想配列のように配列キーに文字列が入る。それに対し、数値キーのものをPerlでは配列と呼ぶようです。
一見、それであるなら解決ではないか?と思うのだが、問題なのはハッシュと配列で書き方が違うこと。
12345678910# ハッシュmy %ex_hash = ( 'ex_key' => 'hash_val' );# 配列my @ex_array = ('array_val');# 出力print $ex_hash{'ex_key'}; # hash_valprint $ex_array[0]; # array_val
定義時にハッシュと配列で「%」と「@」とで違いがあり、更にその値を使用する時はどちらも「$」から始まる。
更に更に、使用する時のハッシュと配列でキーの括弧が「{‘ex_key’}」と「[0]」で違う。
ちなみにPHPでは↓
1234567// Perlで言う配列とハッシュがPHPでは1つの配列に共存できる$ex_array = array( 'array_val1', 'array_key' => 'array_val2' );// 出力echo $ex_array[0]; // array_val1echo $ex_array['array_key']; // array_val2 - eqとneって何?
-if文等の条件文はPHPとPerlに限らずどの言語でもたいてい存在する。
Perlの場合、その条件分の書き方が少し変わっている。
まずPHPの例から↓
123456789$ex = 1;if($ex == 1) {echo $ex; // 1}$ex = 'a';if($ex == 'a') {echo $ex; // a}
123456789my $ex = 1;if($ex == 1) {print $ex; # 1}$ex = 'a';if($ex eq 'a') {print $ex; # a}
これはイコールの「eq」なのである。じゃ、ノットイコールはnqかな?と思うとそれは「ne」↓
12345678my $ex = 'a';if($ex eq 'a') {print $ex; # a}if($ex ne 'b') {print $ex; # a}
直感的に「eq」と「ne」が対局の比較演算子ということがわかりづらい。
さらにPHPエンジニアとしてはこれはいつもの癖で「==」や「!=」で書いてしまい、
Perlもそれをエラーとしてキャッチしないため、ドバドバっとコードを書いた後、思ったように動かず、
とても悩んだことがある。↓
1234567891011121314my $ex = 'a';my $return = '';if($ex == 1) {$return = 'b'; # ここは通らない} else {$return = 'c'; # cに書き換え}if($return == 'b') {$return = ''; # 空にする}print $return; # (空が出力される)
エラーとして止まらず動いてしまう。。それが何よりも怖い。。。
一つ目のif文は正しい条件文で、$exの値が’a’なので、else文へ入る。
ここまでは想定通りの動き。問題はその次のif文。
これは文字列を比較しなければならないのに、「==」で数値比較をしてしまっている。
これはPHPで言うtrueとfalseを比較しているようなもので$returnに文字列が入っているので1、
更に比較しているものも文字列なので1。
つまりif(1 == 1)という比較をしていることになるのです。
ということで、PHPで全く同じコードを書いても結果が変わってしまうわけです↓
1234567891011121314$ex = 'a';$return = '';if($ex == 1) {$return = 'b'; // ここは通らない} else {$return = 'c'; // cに書き換え}if($return == 'b') {$return = ''; // 空にする}echo $return; // cPHPエンジニアがPerl入門した時に最も注意しなければいけないのがここだと私は思います!
さてここまでツラツラと書いてきましたが、まだまだ言い足りないことはあります。
しかしキリがないので、今回は一旦ここまでにしておきたいと思います。
ここまで読んでくださり、ありがとうございました。