こんにちは!
西新宿から大久保までノンストップウォーキングしてお眠なちょこひです。

例えるなら、小学生の頃の2コマ続きの水泳授業の後のような、心地よい眠気。
現実は豪雨と強風の中ビッチョビチョになりながら歩いただけです。
今日も(いつも通り)たくさん眠れそう。


三項演算子って?

今日は春から学び始めたPHPの三項演算子の話をするためだけに
眠い目をこすりながら執筆しています。

三項演算子は、プログラミングの世界では有名ですよね。
条件分岐の手法でよく用いられています。

知らない方のためにちょこっと説明してみます。

「Aさんの名前が太郎くんならTaro、次郎くんならJiro、それ以外ならSaburoと出力する」
というプログラミングを組むとしましょう。

Javaで考えてみると、以下のようになります。

16/06/14追記
Javaで文字列の==はよくないんでした・・・epuals()ですね。
一応動くは動くのですが、あとから修正するかもしれません。



if(aName == "太郎") {			//もし太郎だったら
	System.out.print("Taro");	//Taroと出力
} else if(aName == "次郎") {		//もし次郎だったら
	System.out.print("Jiro");	//Jiroと出力
} else {				//それ以外は
	System.out.print("Saburo");	//Saburoと出力
} 



プログラミングを全く知らない方でも、
なんとなく仕組みがわかるのではないでしょうか。


イコールが2つ続いていますが、これは情報の世界では等号として扱われています


(`・д・´) 「じゃあイコール1つはなんなんだよ!」

イコール一つの場合は、
右辺のものを左辺のものに代入」という意味になります。
等しくありません。代入です。


以下をご覧ください。 
number = number + 1;	


数学者「等しくねえよなーに言ってんだこいつ」
プログラマ「numberは1増えるのか〜 numberが1なら2になるな


こんな感じ。


プログラマ「number って2回書くのだるい…」
で、生まれたのが以下の書き方。


number += 1;	


どんどん短くなってますね。
これも、numberに1を足したものをnumberに代入する、という意味です。


話が逸れましたが、つまり何が言いたいのかっていうと
プログラマはとおおおおおおおおってもめんどくさがりなので
何でもかんでも短く書きたがるんです。


最初の太郎さんたちのコードを見てみましょう。

if(aName == "太郎") {			//もし太郎だったら
	System.out.print("Taro");	//Taroと出力
} else if(aName == "次郎") {		//もし次郎だったら
	System.out.print("Jiro");	//Jiroと出力
} else {				//それ以外は
	System.out.print("Saburo");	//Saburoと出力
} 

プログラマ「なげーよ!!!(゚Д゚)ゴルァ!!」


もちろん、もっと短く書く方法が存在します。 
その一つが三項演算子です。


ふー!導入ながかったあ!!!

 
三項演算子はすごい


ひっぱりましたが、実際に三項演算子を使ってみましょう。

if(aName == "太郎") {			//もし太郎だったら
	System.out.print("Taro");	//Taroと出力
} else if(aName == "次郎") {		//もし次郎だったら
	System.out.print("Jiro");	//Jiroと出力
} else {				//それ以外は
	System.out.print("Saburo");	//Saburoと出力
} 

これが、 
String name = aName == "太郎" ? "Taro" : aName == "次郎" ? "Jiro" : "Saburo";	//条件分岐
System.out.print(name);								//出力命令

こうなる。

('A`) 「わかんねえ」

こちらも解説してみます。 

Stringは、nameには文字列が入るよ!と指定しています。あんま気にしなくていいです。

aName == "太郎" の部分は、イコール2つなので「Aさんの名前は太郎だ!」と言ってます。
これは正しいor誤り の2パターンになりますね。
正しい場合は、?のすぐ後の"Taro"がnameに代入されます。
誤りの場合は、:の後に進みます

すると、「Aさんの名前は次郎だ!」と言ってます。これも2パターンになりますね。
正しい場合は、?のすぐ後の"Jiro"がnameに代入され、
誤りの場合は"Saburo"が代入されます。

やってることは同じなのに、書く量が全然違いますね。
三項演算子はプログラマにモッテモテ。
これが、三項演算子はすごい理由です。

まとめると、

example = a == b ? a : b;

aとbが等しいならexampleにはaが、
等しくないならexampleにはbが代入される、
これが三項演算子です。

 
PHPの三項演算子

では、PHPでも同じ三項演算子を書いてみましょう。
ちょっとだけ書式が違うのですが、書いてあることは一緒です。

$name = $aName == "太郎" ? "Taro" : $aName == "次郎" ? "Jiro" : "Saburo";
echo $name;

書けた。
echoは出力命令です。

さて、aNameを太郎にして動かしてみると・・・


(`・д・´) 「Jiroになった」


・・・次郎だと?


 (`・д・´) 「Jiroになった」


・・・花子なら?


  (`・д・´) 「Saburoになった」



花子がSaburoになったことは放っておいて、 
太郎くん消失事件が発生しました。

太郎くんはどこに行ったのか?
もしかしてPHPは太郎くんに親を殺された恨みがあるのか?
もしかしてPHPは太郎の文字列に反応して正常に動かなくなるバグがあるのか?
もしかしてPHPは問答無用で私のコードを受け付けないのか?
もしかしてPHPは三項演算子使えない?


(・∀・)「仕様がちがうだけやで」 


Javaを始めとする他の言語の大多数は、
三項演算子の動きは同じです。
太郎くんたちの例で言うなら、nameはTaro、Jiro、Saburoの3通りになります。

PHPは、それがちょっと違って、
nameはJiroとSaburoの2通りになってしまうようで。 

具体的にいうと、
$aName == "太郎" 〜 == "次郎"
の部分が正しい場合は"Jiro"に、誤りの場合は"Saburo"になる、らしい。

$name = ($aName == "太郎" ? "Taro" : ($aName == "次郎" ? "Jiro" : "Saburo"));
echo $name;

かっこによって優先順位を変えてあげると、
ちゃんと太郎くんは戻ってきてくれました。
よかったね、太郎くん。


・・・花子ちゃんがSaburoになってる問題は知りません。
わたしわるくない。


まとめ


さて、いつになく真面目な文になりました。
眠い時の方が真面目にかける仕様なわたし。意味がわかりません。

一応PHPの仕様を読んでみたのですが、
そもそもPHPでは三項演算子の入れ子(太郎くんたちのまさにあれ)は
推奨されていないようです。

確かに条件分岐が多いなら他の書き方を使ったほうが
可読性はあるかもしれませんね。

この問題に直面した時はPHPだけ仕様が違うことに
全く解せていませんでした。
激おこぷんぷんまるでした(古い)

いっこいっこ確認しながら勉強を進めていこうと思います。


とりあえず今日は眠い!お家帰って寝るんだー!!!



ちょこひ