オブジェクト思考や、MVCなど、プログラムをする時はこうすべきだ!というのを散々他人から押し付けられてきたが、正直自分で書きたいプログラムを書くのがストレスも貯まらないし、非常に生産性も上がることを、独立してから強く感じた。
そして、そうした時に、今まで以上にキレイなプログラムを書かねばならないと、心に強く誓った・・・
そんな唯我独尊状態の今の心境なのだが、returnについて、感慨深い思考に陥ったので、少しまとめてみたいと考えた。
returnは必ず書くもの?
そもそもreturnって何?というプログラマではない人は、今回は置いてけぼりにします。
setとgetぐらいの理解をしている人を対象にしたいと思います。
※この時点で意味不明と思っている人は、
dotinstallの「javascript入門」を見るといいでしょう。
少し話がそれましたが、そもそも関数を作った時にreturn文って作らないとイケないかどうかでいうとどちらなんでしょう?
C言語をやると、なんとなく「returnって絶対に書いたほうがいいな・・・」と思いますが、JavascriptやPHPなどを使っていると、「必要な時だけでいんじゃね?」という感じですよね。
以前、プログラム初心者セミナーに行った時は、その時の講師が「必ず書きましょう」と言っていたので、それを聞いてから実は今までずっと、「書かなきゃいけないんだ・・・」と少し戸惑っていました。
結論としては、人によって書く人もいれば、書かない人もいる・・・でいいのではないかと考えました。
ただし、ここでいう書かない人というのは、ちゃんと理由があって書かないというレベルの事でしょう。
基本的にreturn 0;とでも書いたほうがよほど良いことは十分理解してます。
そもそも、何故必ず書かないと行けないかと言うと、関数を実行した時に、「ちゃんと実行できたよ」という返答をしてあげるだけで、プログラムを実行しながら、簡単な検証も行えるという理にかなった構成になっていくので、「投げっぱなしの関数って有り得ない」というのがセミナーで聞いた内容でした。
う〜〜ん筋が通ってる。しかも、なんかクオリティ高そうだ・・・
まじでこれはいいかもしれないと感じたので、その意見に賛同したのだけれど、書かない人も、「必要最低限で効率的に行えたほうが、プログラムとしてはキレイ」と聞くと、これはこれで、筋が通ってる。
結局、筋が通っている意見を持っていればどっちでもいいという事にしました。
ただし、筋が通ってない場合は、必ず書きましょうね。
返す値は、オブジェクトも可?
今度は、returnの書き方で、インタプリタ系を使っていると本当に適当に書けてしまうので、逆に怖くなってきますが、1つの関数で2つ以上のreturnを書いてしまうという場合、有りか無しか考えてみましょう。
ケース1
function hoge($a){
if($a == 1){
return 1;
}
else{
return 0;
}
}
所謂こんな書き方ですね。
if文により、returnを出し分けているんですが、上記であればさほど問題にならなそうにもみえます。
ケース2
function hoge($a){
$res = 0;
if($a == 1){
$res = 1;
}
else{
$res = 0;
}
return $res;
}
次に、returnを1つにしたものがコレになりますが、上記と比べて、他のプログラマからこんな意見をいただきました。
行数が多くなるので、短い方がいい。
変数が増えるので、メモリ効率が悪いのでは?
変数の初期値があるので、elseがいらない。
3つ目の意見は、書き方により違うかもしれませんが、だけどreturnは1つのほうがいいという意見の方が多いのは何故でしょう?
ケース3
function hoge($a){
return ($a == 1)?1:0;
}
三項演算子などを使って効率的に書いてみるといいのかも・・・1行でできてキレイに書けますね。
でも、そもそも「三項演算子書かないほうがいい問題」というのもあるので、これはかなりの飛び技と思ったほうがいいかも。
ケース4
function hoge($a){
$res = 0;
if($a == 1){
$res = 1;
}
return $res;
}
とりあえず、変数の初期値を活かしてelseを取ってみたバージョンですが、なんだかこれも気持ち悪い書き方ですね。
個人的結論
とにかく、returnが複数あるのは気持ち悪いが、キレイに書きたいという気持ちも分からなくもない。
なので、ケース2を採用していくことにします。
※他にいい書き方あれば教えてください。
ネストを深くしてはいけない
if文をどんどん階層化していく事はソースをどんどん汚くしていっていると考えたほうがいい。
今回のケースは$aと$bがどちらも1の場合にのみtrue(1)を返す仕様です。
ケース1
function hoge($a,$b){
$res = 0;
if($a == 1){
if($b == 1){
$res = 1;
}
else{
$res = 0;
}
}
else{
if($b == 1){
$res = 0;
}
else{
$res = 0;
}
}
return $res;
}
ケース2
function hoge($a,$b){
$res = 0;
if($a == 1 && $b == 1){
$res = 1;
else{
$res = 0;
}
return $res;
}
考えるまでもない・・・
ケース1を書くようでは、初心者レベルと言う事がよくわかります。
returnというよりは、いかにネストを抑えるかという事なのですが、これも、ちゃんとreturnにどうやって繋げるかという事で意識する必要があります。
オブジェクトで返してもいい?
javascriptやphpはとにかくなんでもありの言語です。
コンパイル言語は、大体が、returnの型もちゃんと指定しないと、コンパイル時にエラーになるので、そんなに大それたreturn値を使うことは無いのですが、インタプリタは本当に大胆です。
だってjavascriptだけで考えると、objectって、なんでもアリの型で、やり方によってはfunctionごとreturnするという荒業もできてしまいますからね。
まずはケースを見てください。
jsonで返す
function hoge(a){
var res = {};
if(a == 1){
res = { key:"hoge" , val:1 };
else{
res = { key:"hoge" , val:0 };
}
return res;
}
内容はともかく、オブジェクトを返すのは非常に便利なんですが、慣れていない人が見たら、きっと困惑するでしょうね。
でも、これはこれで、言語で許容している範囲なので、アリでしょう。
ただし、多言語でのローカライズなどを考えたりする人は、こうした単一言語でしか動かないプログラムは組まないほうがいいかもしれませんね。
結局こういう判断ってその人に委ねるしかなくなるので、その都度プログラマは判断をしなければいけません。
自分の思考をちゃんと持つという事がいかに大事なのかを非常によく考えさせられました。
さあ、次はifでも考えるとするか・・・