tuneoの日記: このスクリプトを書いたやつを出せ!! 31
日記 by
tuneo
弊社を辞めて競合他社に転職したので出ませんがw
1.条件Aが真であれば処理1を実行する
2.条件Aが偽で条件Bが真であれば処理2を実行する
3.条件A, Bが偽で条件Cが真であれば処理3を実行する
4.条件A, B, Cが偽であれば処理4を実行する
という一連の処理を書くのに、else ifとかelifとかがある言語ではフツーはこう書きますよね。
if 条件A {
処理1
}
elif 条件B {
処理2
}
elif 条件C {
処理3
}
else {
処理4
}
くだんの大先輩はこう書きました。
if 条件A {
処理1
}
else {
if 条件B {
処理2
}
else {
if 条件C {
処理3
}
else {
処理4
}
}
}
……いくらなんでもコレはない(ドン引き
ちなみにこのスクリプト、よせばいいのにド下手くそな実行の排他制御をやっているのですが(何がド下手ってロックの取得がこれっぽっちもアトミックじゃない点がド下手)、スクリプト実行中に異常終了したり、予期しない停電・フリーズ・リブートが発生すると「スクリプト実行中」フラグを立てっぱなしのまま放り投げるので、以後は復帰しても何もしなくなるあたりが実にナイスです。
……そんな腐れスクリプトが動く腐れシステムを一切メンテナンスせず、俺が手を入れるまで5年間も使い続けた弊社も弊社なんですけどねwww
正直、こういう邪悪なコードを書く人間は本邦のイット業界に破門状を回して永久追放したほうが世のため人のためだと思いました。今日はそんな一日でした。
もーすぐ襲来するプログラミング教育 (スコア:2)
# このレベルの条件分岐は、先ずちゃんと動くことが大事なので、どちらでもおkかと。個人的には、無論ネストが少ない前者派。
Re:もーすぐ襲来するプログラミング教育 (スコア:2)
30年以上前のパソコン内蔵BASICじゃあるまいし。
IF~THEN~ELSE~♪ ああ、懐かしい。
Re:もーすぐ襲来するプログラミング教育 (スコア:2)
後者の書き方が絶対悪かというと場合によってはそうではないような。
仕様書に箇条書きみたいなめんどくさい書き方がされてたらその通り書くほうがあとで他人が仕様と照合するときやりやすいし仕様変更対応も楽だとか。
ただ単にそういう複雑でネストの深い条件分岐の仕事が多かった先輩なんだろねと思うだけ。
教科書的には日記の通りなんだけどさ。
Re:もーすぐ襲来するプログラミング教育 (スコア:2)
私もネストの量、と言う意味で前者派ではありますが
「非アトミックなロック」とかと比べてそこまでアレだとはおもいませんね
# むしろ else if より if ごとに return したい派
> 脳なし教師が「前者は出題の論理に忠実ぢゃなゐ」とか宣って×付けそーな典型
ものすごくありそうですなぁ…
Re:もーすぐ襲来するプログラミング教育 (スコア:2)
> # むしろ else if より if ごとに return したい派
私もこれがいい。
Re:もーすぐ襲来するプログラミング教育 (スコア:2)
異常系では良い(むしろ積極的にreturn)が、正常系では後刻に何か後処理を追加された時に、該処理を撒くにせよ、return止めるにせよ、都合が悪いかと。
Re:もーすぐ襲来するプログラミング教育 (スコア:2)
なるほど適材適所ですね。
どこでも異常系を書いている時間が長いとか640x480とかの狭い画面で書いてた時期もあったのでreturnするほうが都合が良かったのかも。今は画面が広くなってエディタも良くなったからみやすくなりましたね。
Re:もーすぐ襲来するプログラミング教育 (スコア:1)
最後に共通の処理をする場合どうするんでしょうね。各々のreturnの手前に書くのでしょうか。
Re:もーすぐ襲来するプログラミング教育 (スコア:2)
この分岐自体を関数に分離するとかですかね。
その共通処理は関数コールの後ろに。
かんがえるのもめんどくさいので (スコア:2)
//こういうかんじので
bool do_exec_1 = A;
bool do_exec_2 = !A && B;
bool do_exec_3 = !A && !B && C;
bool do_exec_4 = !A && !B && !C;
if (do_exec_1) 処理1();
if (do_exec_2) 処理2();
if (do_exec_3) 処理3();
if (do_exec_4) 処理4();
誰が書いた以前に、デプロイされる前にレビューが… (スコア:1)
周囲の従来からの関係者の誰一人として問題点が人と指摘しないのだろうなあ。
腐れシステムというのはコンピュータのシステムではなくそれを取り巻く
人の側という仮面ライダー他でもおなじみの敵は人間という類型。
elifを知らずに彼は育った~♪ (スコア:1)
他人との共同作業や連携を考えない場合は、動けばいいんだし。
彼の書いたコードを洗い直す作業が勃発しそう。
春に新人さんが入ってきたらOJT代わりにやらせてみても良さげ。
Re:elifを知らずに彼は育った~♪ (スコア:2)
Re:elifを知らずに彼は育った~♪ (スコア:1)
sed -e 's/あまり/ほとんど/'
よほどのことがない限り他人の拵えたコードをわざわざ覗く人はいないし、ましてやそれに注文を付けて直すのはよほどの酔狂とみられていますorz。
Re:elifを知らずに彼は育った~♪ (スコア:2)
それはそれとして,ネストは必要以外は使わない,というのは基本のキだと思うんだ。
ぶっちゃけ自分でも何書いてたかわからなくなるじゃん。
興に乗って書き殴ったルーチンは,覚えてるウチに読み砕いて簡素化するようにしてる。
そうするとですね,長年にわたって流用が効くコードになるんだな,これが。
異種言語間でも比較的スムーズに移植できるし。
とくに,Apple系はコロコロ変わるんで,この当たり前のことが致命的になるんだな。
コードの簡素化をする際も,こんな無駄なネストがあると,ついさっき書いたものでも可読性が悪いです罠。
Re:elifを知らずに彼は育った~♪ (スコア:1)
>それはそれとして,ネストは必要以外は使わない,というのは基本のキだと思うんだ。
>ぶっちゃけ自分でも何書いてたかわからなくなるじゃん。
思いつきだけで書きなぐっているときはよくそうなってて、後から見て自分でも???ってなってます。
その手のは、時間置いて見直して整理して書き直すとびっくりするくらい短くなる。
Re:elifを知らずに彼は育った~♪ (スコア:1)
しんじん?知らない言葉ですね。最近はやりの食べ物の名前ですか?
似たようなので (スコア:1)
if (A) {
}
else if (!A && B) {
}
else if (!A && !B && C) {
}
else if (!A && !B && !C) {
}
条件はもっと複数だったけど、こんな感じのを見たことがありますよ。
なんて仕様書に忠実なコード!と騒然としましたが、初見で条件が解りやすいからアリでしょ、
ってことでレビュー通しちゃいました。(まぁ、注釈付けましたけど
# もしかしたらコンパイラが勝手に最適化してくれるかもしれないし。
そうかぁ? (スコア:1)
林晴比古さんのプログラミングスタイルブックでは後者が推奨されていたはず。
例えば変数Aの範囲が0未満、0以上10未満、10以上のように分岐する場合は拡張switch文として else if を使用すべきだが、変数Aの判定と変数Bの判定があるならif文が2回出現すべきだ、という主張だったと思います。
今回の例で、条件Aが正の場合の処理に条件Bによる振り分けを追加する場合を考えると、コードの対称性から考えても正条件・負条件でブロックが分かれている方が妥当だと言えます。
あと、たとえば条件Bとか条件Cとかが負条件だった場合、どのような条件でどの処理が実行されるか、どちらが直感的に判るか考えてみる必要があると思います。
(負条件のelseって段階でどうかとは思うけど)
Re:そうかぁ? (スコア:1)
今回のケースは測定値に対してA,B,Cの条件が成り立つか検査して、真だったらそれぞれ対応した処理をする、というコードなのでif ~ elif ~ elseで書く方が望ましいと考えてます。
なお、上記の日記の疑似コードは俺がインデントした状態なのでそれなりに見れた代物ですが、現物は以下のようにブロックのインデントがめちゃくちゃで、しかもシェルスクリプトなので、以下のようになります。
末尾のインデントレベルが同一なfiの連発を見た時は唖然としましたともさ。
場合によっては俺。 (スコア:1)
条件によってはそういう書き方する。
例えば、条件Aが性別、条件Bが年齢だとしたら、
if (性別 == 男性){
男性の処理
}else if (年齢 >= 20){
成年女性の処理
}else{
未成年女性の処理
}
じゃなくて、
if (性別 == 男性){
男性の処理
}else{
if (年齢 >= 20){
成年女性の処理
}else{
未成年女性の処理
}
}
みたいに書くと思う。
Re:場合によっては俺。 (スコア:2)
Re:場合によっては俺。 (スコア:1)
そういう場合は俺もifをネストさして書きますが、今回の大先輩のスクリプトはシステムの状態を表すとある値に対して条件に該当したら対応する処理を行う、というパターンなのでelifを使わないのはどうかなぁと。
Re:場合によっては俺。 (スコア:1)
もし数百万回まわるループの底にあったとしたら、一番生起確率の高い条件の場合の分岐が最小になるように書くよね。可読性犠牲にしてでも。
Re:場合によっては俺。 (スコア:2)
可読性ばっかいってるなオレ。
条件演算子で (スコア:1)
条件A ? 処理1() :
条件B ? 処理2() :
条件C ? 処理3() :
処理4;
こう書けますよね、
って思ったら何故かPHPでは条件演算子が左結合なのでこれはダメなのだとか。
あとデバッガでステップ実行させたいとき、条件部分がステップで見れないからダメって話も。
Re:条件演算子で (スコア:2)
デバッガで見づらいので断念したことあります
Re:条件演算子で (スコア:2)
Re:条件演算子で (スコア:1)
はい、移植性度外視です。
コメにも書きましたがPHPで評順順が違ったり、tuneo氏のご指摘のようにそもそも該当する演算子がない言語もあります。
Re:条件演算子で (スコア:1)
世間には条件演算子がある言語ばかりだと思わないことです(有名どころだとPythonにはありません)。
Re:条件演算子で (スコア:1)
そうなんですよねー。
個人的には if(条件式, 処理1, 処理2) のような関数形式が好きです。VB.Netとか。
カッコ必須なので上の例のようには書けませんが。