リーダブルコーディング技術スレ
■ このスレッドは過去ログ倉庫に格納されています
リーダブルコードとは ・読みやすさ、理解しやすさを追及したコードのことです ・読みやすいということはメンテナンス性も高いということです。 ・理解しやすいコードはコードレビューも楽になります。 ・理解しやすいコードはバグも少なくなります。 ・短いほうが優れていることが多いですが、必ずしも短いほうがいいとは限りません。 俺ルール ・書き方の勝負であり、言語の勝負をしないでください。 ・標準、非標準に限らずライブラリを使いましょう。 ・なければ自分で関数を作りましょう。関数はなるべく汎用的に。 こういうコードを読みやすくするにはどうすればいいでしょうか? というようなことを語るスレ。需要ありますかね? コスト感も癖にテストテスト叫ぶガキはまずリーダブルなコード書けてから言えといいたい 最近、メインのコードから汎用的なコードを関数化していって 汎用的なコードはまあテストするが、 そうするとメインのコードが凄くシンプルになって、 それをテストするって意味あるのか?って思えてきた。 むしろテストしにくいコードをテストしなくて済むように 複雑なものを極力追いだすというか。そんな感じ。 テストコード自体にもリーダブルさは必要だからなぁ。 リーダブルなコードを書けない人間がテストコードを書いても ごみの集まりにしかならない。 テストのメンテナンスが大変になるだけ。 >>1 汎用的なコードの羅列は読みにくい。コードはできるだけ個別的に書くべき。 ライブラリの使用も極力避けるべき。 テストが面倒だから、テストしやすいコードを書くと簡潔になるな。 同じテストを繰り返したくないから、DRYの原則を守るようになってたり。 >>7 pure Prolog は書き手が書いたことだけが真であって、 読み手との間で誤解の生じる余地がありません。 組込述語(ライブラリ)が無いのですから、個別的であり、 書き手と読み手の間の抽象能力の差から生じる不理解が 生じません。 このスレッドは天才チンパンジー「アイちゃん」が 言語訓練のために立てたものです。 アイと研究員とのやり取りに利用するスレッドなので、 関係者以外は書きこまないで下さい。 京都大学霊長類研究所 >>9 問題はそれがリーダブルかどうかです。 試しにライブラリも関数も使わずにMySQLに接続して select文を発行するコードを書いてみてくれませんか? リーダブルコードというのは 実用的でなければなりません。 例えばPerlでは要素が重複しないリストを返す関数はないわけ。 言語仕様だけで実装すればこんなふうになるけど、 my %count; @array = grep( !$count{$_}++, @array ) ; 見ての通り明らかに、リーダブルではない。 List::MoreUtilsという有名なライブラリには これをやってくれる関数がある @array = uniq @array; こっちの方が明らかにリーダブル。 実際の開発において、ライブラリを使わずに実装するなんてことは 腐った現場以外ありえない話なので、 リーダブルが目的の現実的な開発ではList::MoreUtilsのuniqを 使うという選択が一番正解なわけだよ。 >>11 pure Prologではなく普通のPrologですが、 http://nojiriko.asia/prolog/fukakusa_no_shoushou_1_1.html のようなコードを念頭に置いています。 あなたが意識されているのは読みやすさではなく実用性ではありませんか。 さすがにPrologからMySQLへのインターフェイスはないと思いますが、あれば、 mysql :: かやうに(_かやうに), のように質問することになるのでしょう。 >>13 だから実用性を考えないリーダブルに意味は無いんだって。 読んだってたかが知れてる量だとリーダブルにする意味は無いだろ。 何百、何千行にもなるような実用レベルのコードを 読みやすく構築するのがリーダブルの目標 実用レベルではMySQLを使うのは当たり前の話で それをライブラリを使わないで書いてもリーダブルといったのはお前じゃんか。 こちとら何百、何千行もあるコードを数行に収めることを目標にしてるんだ。 だから当然ライブラリを使うし、ライブラリを作る他ないだろ。 リーダブルはあくまで実用性を念頭に置いて考えなさい。 サンプル程度の短いコードの話なんて要らないのよ。 >>13 横レスする もしもそのリンク先コードがリーダブルであると主張するならば、 同サイトのPrologで書かれたクイックソートのコード: http://nojiriko.asia/prolog/quick_sort.html よりも、以下のコードのほうがリーダブルであることを認めねばならない クイックソート [] = [] クイックソート (中心軸:残りのリスト) = クイックソート 中心軸未満の部分リスト ++ 中心軸:(クイックソート 中心軸以上の部分リスト) ここで (中心軸未満の部分リスト, 中心軸以上の部分リスト) = リストを分割 (< 中心軸) 残りのリスト リストを分割 関数_f = foldr 関数_g ([], []) ここで 関数_g X (部分リスト_Y, 部分リスト_Z) = もし 関数_F x ならば (X:部分リスト_Y, 部分リスト_Z) さもなくば (部分リスト_Y, X:部分リスト_Z) なお、ここでは以下を仮定した(関数型言語Haskellを元にする)架空の言語を想定している ・識別子として日本語文字(UTF-8等)が利用できる ・予約語「where」の代わりに「ここで」が利用できる ・構文「if ... then ... else ....」の代わりに「もし .... ならば .... さもなくば ....」が利用できる クイックソートのコードがリーダブルかなんてどうでもよくね? qsort() これが一番リーダブルだ。 そう難しいロジックは関数に隠蔽してしまう。 >>16 関数抽象を言い出せば、あらゆるプログラムなんて、 program() これが一番リーダブルだ、ってことになる つまり>>16 は、何も言明していないに等しい まったくだw もし>>17 みたいなのがあったら、それは一つの関数で 何でもやってるリーダブルではないコードになってるだろうな。 リーダブルってのはバランス感覚が重要。 何を関数にして、何を関数にしないか。その見極めが重要。 優れた技術者は関数を汎用的なものにして 一度作ればメンテナンスを不要なレベルにする。 アプリのライフサイクルにおいて、修正が必要な箇所を極力減らす。 それがリーダブルなコードになる。 ソート関数なんてアプリの機能が変わったとしても、 一度作ればメンテナンする必要は殆ど無い。 だから関数にする。これがバランス感覚というもの。 >>17 みたいなのは、結局program()の中をメンテナンスする 必要があるわけでなにも解決していない。 それが真実とすると、整数のソート関数を作った後、文字列のソートをしたくなる。 そんな時、テンプレートが使えると理想的。 結果、C++のような変態言語が実は理想なのか?ってなってしまう。 >>20 うん、各型ににおいて最速のコードを 生成するならC++が理想的だよ? 別にそこまでパフォーマンスが必要ないなら、 比較関数さえ入れ替え可能にしておけば どんな型にでも対応できるけど。 void*はリーダブルコードなのか?とか新たな疑問がわいてくる。 void*でリーダブルかどうかなんて分かるわけがないだろ。 そもそも型であり、コードでないのだから リーダブル”コード”の範疇外だ。 そういうレベルまで下りてくると、関数名を適切に付けましょうとか その程度の話になってくる。 ちなみに俺はfunction_10000()まであと少しだが、十分リーダブル。 >>24 重要な事なんだがねぇ。 関数の名前、関数の引数。関数の使い方。 これらがリーダブルコードの大きなカギ。 いかにメンテナンスが必要なコードを シンプルにかつ柔軟にかけるようにするかを 提供するライブラリの構築は極めて重要な作業。 コメントを適切につけましょう。 関数名を適切につけましょう。 当たり前の事をきちんとやりましょう。 以上でスレ終わり。 そういう勘所わかんねえガキがすぐ喚き立てるからな。はてなダイアリーwとかツイッターwでな。滅びろガキ共 まず、コードってのは二種類に分かれる。 アプリの仕様の変化によって メンテナンスが必要なコードと そうでないコード。 メンテナンスが必要でないコードの例として フレームワークやライブラリがある。 アプリってのは何千行、何万行ものコードから なりたっている。そのうちメンテナンスが必要なコードを 極力減らすのがリーダブルコードの重要な点。 メンテナンスが必要ないコードは汎用的であり一度覚えればよく、 中身を見る必要はないか一度だけ見れば良い。 見る必要がないコードが多ければ、コードレビューも楽になる。 見なくて良いコードを増やして、 見なくてはいけないコードを減らしていくのが 大規模アプリをリーダブルにするコツ。 >>28 ひとつひとつのツイートをシングルクォートで囲み最後にピリオドを 付ければ、全部 Prolog プログラム。 ピコーン! 関数に分ければ読む必要ないからリーダブル! program() ソートが必要な場合、sort()に切り分ける。 関数名をわかりやすくsortにしておく。 ここ重要。 中身は知る必要なし。 一目で何をやってるかわかるリーダブルの完成。 引数なし戻り値なしの関数の占める割合を見ればわかる >>34 お、それに気づいたか 引数なし戻り値なしの関数が 多いものは読みにくいコードであることが多い。 >>15 Haskell風コードの方が当然リーダブルのように思うが、違うのか? インスタンス変数を直接触る関数は自分で書いてて分かりづらいなって思ったからやめた 関数にすると処理があちこちに飛んで見難くなる。 だから関数を使うな。 というとんでもない意見があるが、 100%間違っているというわけでもない。 それは関数=サブルーチンになっている場合。 コードが長いからという理由だけでその一部分を関数 (という名のサブルーチン)にした所でコードは読みやすくはならない。 なぜなら、関数の中まで読まないと何をやっているかわからないから。 ではなくて、関数というのは中を読まなくてもわかるようにするべき。 標準ライブラリの関数とか通常の開発で中を読むことはまずない。 中を読まなくていいということは、その分読む量が減るということ。 サブルーチンにした場合、その中を読まなくていいということはまずないので、 結局、あちこちに飛んで見難くなるだけ。 正しい関数の作り方を知らないからこうなる。 1箇所からしか呼ばれないものは関数化しない、という方針は、そんなに間違ってもいないが、 絶対でもないぞ。 極端な話、初見では少々読みづらいコードになったとしても、上位レイヤと下位レイヤに 分けて実装しないと、あとあと全体の構造がメンテ不能になったりすることもある。 >>42 レイヤ分けも「中を読まなくていいようにする」行為の一つだよ。 正しいレイヤ分けをしていれば、引数と戻り値のみがわかっていれば そのレイヤで何を行うのかわかってるので、中のコードを読む必要がなくなる。 関数にするときは、中を読まなくていいように なっているかどうかを意識しよう。 中を読まないといけない状態では リーダブルにはならないことが多い。 標準ライブラリ関数のソースは読まないけど、ドキュメントは読まないと使えないよね >>41 のいう"正しい関数の作り方"をすれば、それすらも必要ないの? それとも、コメント書いとけっていうことを、わざわざ長文にして書いたの? >>44 ドキュメント≒コメントな。 同じようにコメントがあったとしても、 コードを毎回のように読まなくてはいけないものと コードを(初回レビュー以外)読まなくても大丈夫なもの 二通り有るだろ? コードを読まなくても大丈夫なものは、 標準ライブラリの関数などのように、 それ自体の役目が小さくサブルーチン(処理のまとまり)ではなく しっかりと関数になっているもの。 サブルーチン(処理のまとまり)なんかだとコメントが有ったとしても 結局コードを読まないと、具体的なことは何もわからない。 どんな時だって、コメントがあれば問題解決するわけじゃないんだよ。 関数の中を毎度毎度読んでるようなら、 それは関数ではなくサブルーチンになっているということさ。 そういうのを減らせと言ってる。 >>45 >コードを毎回のように読まなくてはいけないものと >コードを(初回レビュー以外)読まなくても大丈夫なもの >二通り有るだろ? コメントでカバーできないような関数にはするなっていうこと? >>46 読まないといけないコードを減らして 読まなくても良いコードに置き換えろということ。 読まなくても良いコードの割合が増えれば それだけコードレビューの時間も減る。 コメントでカバーとかそういう発想をそもそもしていない。 コメントがなくてもコードでわかるのであれば、コメントすら不要。 コメントを書きたくなる時点で、コードがリーダブルでないという証拠でしかない。 つまりは なでしこで書かれたプログラムが 一番リーダブルなんじゃね? 関数名と言うのは、巧いコードだと処理の概要を物語るコメントとしても機能する。 例えば void BubbleSort( int *p, int n ) という関数が何をするのかは容易に推測できる。 (ただしこんな名前でクィックソートしてるなら糞コードだが。) 一方、下手なコードだと関数名は単なる識別子としてしか機能しない。 内部で何をやっているかは関数内のコードやコメント、ドキュメントを追う必要がある。 例えば void HogeMoge() という関数が何をするのかは中身を見なければまず分からない。 と書いてみる。 他人のコードを読む難しさは、”作者が暗黙にイメージしてる図”を推論することの難しさにある。 f(x+d) - f(x) / d 作者自身は「これは微分するためだ」という暗黙のイメージがあるので簡単に理解できる。 一方、他人はコードのみから「これは微分が目的か?」と推論する必要がある。 コードを推論だけで読むには、作者と同等かそれ以上のコードを書けるだけの基礎が必要となる。 これら推論を補助するには、ホワイトボードによる図説が有効である。 イメージ図が有ると無いとではコード理解の難易度が大幅に変わる。 >>51 それこそ、 >>26 が言っている関数名の付け方の問題で、 関数名を xxxを微分する() にすれば良い。微分という 概念なら共有できるのだとすれば。 問題はこのように概念化、言語化できない(し難い)アルゴリズムの 場合、関数名では解決できないケースがあること。 ・・・ 問題は、アルゴリズムと呼ばれているものの中には、 このような概念化、言語化できない(し難い)ものが あり、この場合は関数名では解決できない。・・ですね。 「微分ってなに?」って奴に対してリーダブルにするにはどうすればいいかってことが問題になるな >>54 それはそれで「こういう処理を微分と呼びます」でいいんじゃないの 例え新たな用語であろうと、それに対しての厳密かつ具体的な処理が示されて「こういう処理をそう呼ぶんだな」と思えないなら プログラマとしては、数学以外の分野でもかなり困ることになるぞ >>54 それは勉強すればいいことなので微分のままでいいよ。 リーダブルというのは知識不足を補うためにあるんじゃない。 会社特有の知識とか、会社やめたら無駄になるようなものは 覚える必要はまずないから、それに関するドキュメントが必要。 でも世間一般の知識は、勉強しろの一言で終わり。 それが技術力ってものだからね。 技術者である以上、自分には技術がないのでわかりません。は恥だと思え。 俺にはわからんから高度な書き方をするな。みたいなことを言ってる奴は 技術力ねぇんだなと思えばいい。自分より技術の低いやつに合わせる必要ない。 足を引っ張ってる奴が悪い。 道具が使えるだけの奴は三流。 技術・知識も使いこなせて二流。 人も使いこなせてこそ一流。 ここまでオライリーの「リーダブルコード」への言及なし。 この本のいいとこ悪いとこの話題とか、 もっと深い議論があるスレを期待した俺がバカ。 >>59 お前がすればいいじゃん。 他人任せなのはやめろ。 自分から行動しろ。 >>57 それでは足を引っ張られる一方だろ。 自分が楽をするためには どんな馬鹿にでも判るようなやり方を使って どんな馬鹿をも楽に使えるような環境を整えるしかない。 >>61 馬鹿は切り捨てるか育てるしかない。 技術者は技術があるもののことだ。 素人を基準にしてどうする? 自分が楽をしたいんだろう? 馬鹿用のやり方で楽になるわけがないだろう。 そうそう、リーダブルというのは プロがプロのために読みやすいコードとはという話であって、 馬鹿でもわかるコードのことではない。 関数さえ理解できない馬鹿がいるんだしな。 だからそいうヤツのことを考えるのは リーダブルとは無関係。 ”リーダブルではないが”馬鹿用に仕方なく書いている。 という状態になるだけ。 馬鹿なんて言葉が出てくる時点でどうかと思うけどね。 馬鹿は切って捨てろというのは同意したいところだが、あまり理想が高すぎると誰もついて来なくなる。 そもそも原著からして「シンプルで実践的」を掲げてるわけで。 >>68 > 「シンプルで実践的」 って、馬鹿^H^Hプログラミング初心者に迎合しろって意味ではないだろ 思うにコードを読むのにごく一部の天才しか知らない・理解できないような知識を要したり、 ごく一部の馬鹿の為に特別なルールが設けられているなどの背景についての理解を要するのは どちらもリーダブルではない罠。 一般的なPGの大多数が、予備知識を一切持たずにすんなり読めるコードこそリーダブルと言うべきではなかろうか。 > 思うにコードを読むのにごく一部の天才しか知らない・理解できないような知識を要したり なんでそんなのを使うと思うんだ? プログラミング言語が備えている機能を 普通に使ってるだけだぞ? えとさ、例えばプロの技術者が、自分の使っている道具を 使いこなせてないとしたらどう思うよ? > 予備知識を一切持たずにすんなり読めるコード そんなものはない。 技術職なんだから技術がない人間が 読めるわけ無いだろ。 反対に言えば、技術職なんだから 素人が出来ないことをできるようになれよ。 お前が言うPGの大多数って馬鹿のことだろう? 具体的に言えば、入社一年未満レベル。 違うのか? 本物のプログラマが普通に読めるレベルなら プログラミング言語の機能はどれを使っても 読めるはずだが。 >71-72 最後に「一般的なPGの大多数が」と書いてるのに、何故そんな解釈するのさ。 言語が備えている機能を普通に使っているコードが読めないレベルが一般的で大多数だとでも? だとしたら他を見下しすぎ。 あと「予備知識を持たずに」とは書いたけど、「勉強せずに」とは書いてないからね? 例えば余程難解な代物でも無い限り(この条件を見落とさな用に!)、コメントに「〜参照」とでも書いておくだけでも 予備知識を持たずに読めるコードになるでしょ。 >74 >本物のプログラマが普通に読めるレベルなら >プログラミング言語の機能はどれを使っても >読めるはずだが。 アセンブラでフルスクラッチできるレベルなんでしょうなぁ。 トグルスィッチでミスせず入力しきった真のPGも居ますが。 一般的なPGの大多数がどの程度のものを指しているのかしらないけど、 例えば、プロジェクトがオープンソースプロジェクトで 多くの人が参加しているとしよう。 その予備知識を一切持たずにすんなり読めるコードに 書き換えましょうと提案して通るレベルならいいよ。 まあ少数の初心者のために書きなおすことはないだろうね。 >>74 PGの大多数が入社一年未満レベル? なに言ってんの? ユニバーサルデザインの考え方だな。 より一般的な、説明が不要な方法で実装したほうが、 結局はみんなが幸せよ。 例えば売掛買掛とかいう概念にしがみついてんのは、 自分の立場を守ろうとする老害よ。 専門性に逃げ込むような輩は先細っていくよ。 おいおい、みんな結局同じことを言ってるぞ。 リーダブルコードというのは、 初心者プログラマでも読めるレベルで書くことじゃない。 プロがプロとして読みやすいコードを書くということだ。 言語の機能には時として使わないほうがいいとされる機能もあるが、 そういうものないのなら、すべて使って良い機能だ。 言語の機能を知らないのは、初心者が頑張って技術をつけろという話であって 初心者のレベルに下げようということではない。 だろ? >>79 > より一般的な、説明が不要な方法で実装したほうが、 より一般的な、説明が不要な方法ってなんだよ? 俺らは技術者だぜ。 技術的な方法で実装するのは問題ない。 わからないのは技術が低いからなだけだろう? そもそも「初心者」っていう言葉を使ってるの一人だけっぽいが…。 我田引水っ子が混じってる気がするから気持ちよく話に参加できない。 どんな技術でも使うことに正当な理由があれば使うし、 使うべきでは無いという正当な理由があれば使わないよ。 ただ「周りがわからないから使わない」は 正当な理由にはなりえないな。妥協した理由だ。 >>83 なるほど。正当な理由と 妥協した理由ね。 つまりはリーダブルコードの話をする時 正当な理由のみで語るべきということ。 そこに妥協した理由を持ってきてはいけない。 妥協したいならお前の周りだけ妥協すればいいだけじゃん。 技術のなさを恥じながら妥協しておけよ。 >79 >より一般的な、説明が不要な方法で実装したほうが、結局はみんなが幸せよ。 この「説明が不要」と言うのはうまい表現かもね。 専門知識・用語を駆使して「説明を省く」のとはちょっと違う。 >>85 具体的に言ってよ。 専門知識・用語を使えば簡単なのに、 使わないほうがいい例を プログラミング技術の話でたとえてみて。 >>81 > より一般的な、説明が不要な方法ってなんだよ? 分からないの? それは技術が低いから? >>87 いいから説明しろよ。 みんなエスパーじゃないんだからさ。 お前の考えだろ? >>89 くだらない煽りはいらん。 さっさと寝てろ。 説明を求められて説明できない人って 何のために意見を言ったんだろうかね。 >86 >専門知識・用語を使えば簡単なのに、使わないほうがいい例 例えばC++ではないC言語で、「オブジェクト」という単語が出てきたとしよう。 本当にCをよく理解しているならそれが何を意味してるのか分かると思うが、 なまじC++等を知ってるプログラマを混乱させる元になる。 > 例えばC++ではないC言語で、「オブジェクト」という単語が出てきたとしよう。 その場合それは専門用語ではない。 誰かが勝手に作った用語だろう? そういう人こそちゃんと勉強して 正しい専門用語を使えと思うんだが? >>63-65 合ってるだろ、leaderぶる話で 関数型言語であるような、mapとかfilterとかは、 知らないと読めない典型だけど、いったん知ってしまえば とても便利だよね これがリーダブルなのかそうでないのかは 読み手によるとしか答えようがないなあ その言語の典型的な書き方、イディオムは、読めて当然と考えていいんじゃないか? それをはずれた書き方は読むのをストップさせるリーダブルじゃないコードだろ。 イディオムを覚えていない初心者はこの議論の範疇外だよ。 クラス名や関数名、主要変数名に気を使って、ぱっと見ておおまかな処理の流れさえ分かれば、細かい処理はわかりづらくてもコメント打っておけば良いと思っている 公開する範囲にもよると思うが >>97 mapやfilterはものすごく勉強しないと理解できない物? 違うよね。 ちょっと知ればいい程度のものなら、勉強すれば終わりでしょ? そんなものまで、知らないから読めないという人のために 使うかどうか迷うの? ほんの数分の勉強で、これから先ずっと快適になるんだよ。 比べるまでもないことだよね。 >93 >その場合それは専門用語ではない。 >誰かが勝手に作った用語だろう? 手元にあるK&R第2版日本語訳にはこう書いてある。 【付録A(ANSI規格)】 A5 オブジェクトと左辺値 オブジェクトは名前付きのメモリ領域であり、左辺値(lvalue)はオブジェクトを参照する式である。 K&Rをバイブルとする技術者には御馴染み>そのオブジェクト >>93 は頑張って勉強しなきゃな。 K&Rは、もはや参考書でしかないよ。 まずは規格票を読まなきゃ。 >104 「付録A」はその規格について述べてる訳ですが? 解説であって規格票そのものではないし、しかもC99じゃなくてC89のだし。 俺らの世代以上の人なら、K&Rの例の「オブジェクト」について、 少なくとも何度か話題に上がったことは当たり前にあるだろうね。 >106 まともなプログラマなら>102の内容はc99でも通用する記述だと分かるだろ そもそもコードは「キーワードと文法しか知らない」コンパイラに分かるように頭から読んでいけば分かるように書いてある訳で、 どんな糞コードであっても、コンパイルが通るなら言語規格を熟知してる奴には読めるはずである。 すなわち「規格を熟知している奴に読めれば良い」という条件では糞コードを除外できない。 CはそもそもK&RのRのほうが勝手に作った言語だけどなw 結局規格票で確認した奴はいなかった、というオチだろ? 純粋なgetter,setterじゃないのにget〜とかset〜とかは使わない方がいい? 例えば,なんかのファイルのパスを返すような関数があったとして, getHogePath()とかいう関数名はあり? もちろんhogeっていうメンバ変数はないとして >>115 Javaの話として解釈する ぱっと見て意味はわかるし良いと思う 所属しているクラス名がHogeなら、考え直した方がいいかも 動的型付け言語の場合。 クラスがHogeであっても、getHogeってした方がいいよ。 なぜなら、getだけじゃ何からのgetか分からないから。 近くでnewしていれば簡単だが、関数の外から 渡されてきたらあちこちのコードを読まないとわからない。 しかも一つ見つけたら、それで正しいとは限らない。 もしかしたら見つけたのとは別のクラスも渡しているかもしれない。 ISO/IEC 9899:201x Programming languages - C ttp://www.open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf 24ページ目辺り 3.15 object region of data storage in the execution environment, the contents of which can represent values 「リーダブルコード」的には、getHogeはオススメされていない。 ・属性値を得るだけの軽い処理とまぎらわしい ・明確じゃない(ほかの動詞を使うべき) 内部処理を意識させないために getでいいのでは? 内部処理がどうなっているか不明なのだから 軽いかどうかなんてわかり用がないし 変わることだってだろう? そこに何かの想定をしてはいけないだけの話。 >>120 が英語が出来ないだけの話 リーダブルコードの意味をもう一度考えたほうがいい Foo.getHoge(); と書くと「FooがHogeをgetする」になってしまう罠。 仮にこれを「FooからHogeをgetする」と読むのならば、 if( Foo.isHoge() ) を 「もしFooがHogeなら」と読めなくなる。 間違えてUCCで書いてもうた…orz でもまぁ標準ライブラリでもよく考えるとおかしなのがあるから、あまり気にせずとも良い気も。 >>115 定数オーダーの処理ならget,setって言っていいイメージでいます。 話が逸れるけど関数名だけに拘るのではなく、戻り値や引数の型その他を含むシグネチャ全体に気を使った方が良いかと。 特にC/C++なんかだとconstの有無はネーミングと同じ位気を使って欲しい。 うまく使えば読みやすくなるし。 そのHogePathの出どころによるよね DBから探してくるならfindHogePathとかsearchForHogePath コンポーネントをいくつか組み合わせて作るならcomposeHogePath どこかに設定してあるのをちゃちゃっと取ってくるだけならgetHogePath 処理の中身がわかる名前がいいと思うよ >>122 > Foo.getHoge(); と書くと「FooがHogeをgetする」になってしまう罠。 つまりgetは一切使うなってこと? いや違うな。Fooをcreateしてしまう場合は、create Fooだろう? Foo.createだったら、Fooが作成してしまうになってしまう。 いやいやcreateではなく、newだからnew Fooであってるのか。 Foo.newはだめだな。 でもこれはnewだけの話だろう? Array.join(', ')とかどうなるんだ?配列が','でjoinする? 配列をjoinするんじゃないのか? おかしいな。 とりえず俺としての結論は、 Foo.isHogeがたまたまそう読めるからといって、だからなに? 他は違う読み方をすればいいだけじゃない。 ってことだな。 >>128 RubyではFoo.newなんだが(;^ω^) >>129 だから>>122 はおかしいってことでしょ >>129 それは一文字でも短くタイプするとかいう変な宗教だろう リーダブルとは真逆 Foo.new と new Foo の違いは、前者がメタオブジェクト(Classのインスタンス)の インスタンスメソッドの呼び出しであるのに対し、後者がnewという前置演算子による 演算子式である、という意味の違いが構文の違いになっているに過ぎず、 リーダビリティとは全く何の関係もない。 それを「一文字でも短くタイプするとかいう変な宗教」とか考える奴の脳味噌が変。 言いたい事をほぼ>>132 が言ってくれたから話が早いw >>131 一文字でも短くタイプするとかいう変な宗教とは、 Foo() と書くリーダブブルとは真逆な某言語のことだろw >>134 俺 Python スレとシャワートイレ板で有名コテやってるかあんまり怒らせないほうがいいよ その言語において、コンストラクタが普通の関数と同じものなら、それで問題ない。 プログラミング言語は、計算のための意味論を持った、形式言語である、という前提を外した 議論からは、何も生まれないよ。 >>134 なんでリーダブルとは間逆なの? 極端に短く書いたらリーダブルじゃなくなるけど、 適度に短いのはリーダブルだよね? >>134 みたいな馬鹿に賛同する奴は 本当に馬鹿なんだろうなって 心の底から思うよ。 というより、ちょっと前から一人おかしい子が紛れ込んでる希ガスw 知ったようなことを言いたいんだ、ということだけ分かる。 こんな感じで分かり易いコード書けるよー、的な話題になると、 気の利いたコード書けない低脳が、そんなの関数化するから関係無いと言い出し、 その結果、関数名とか変数名とか、あとメソッド呼び出しでの括弧省略とか、 そういう下らない議論になる 読んでないけど、このスレもそんな感じですか? あぁ、お前が読んでないことが2行目でわかったよw さっさと自分のスレに帰って、 そいつに泣かされてこい。 三人称単数ならgetsだろ藁() 小学生かお前ら核爆() >>139 new Foo や Foo.new は「適度に短い」からリーダブルだよ なぜなら、new というキーワードによって、単なるメソッド呼び出しと コンストラクタ呼び出しを一目で見分けられる、 つまりコードリーディングを配慮した言語設計だと言える それに対して、Foo() は「極端に短い」からアンリーダブルだね なぜなら、前後の文脈を確認しなければ、それがメソッド呼び出しなのか コンストラクタ呼び出しなのかが区別できない つまりコードリーディングを無視した 「一文字でも短くタイプするとかいう変な宗教(>>131 )」に従った言語設計だと言える たとえば、f() というコードは一見するとメソッド(または関数)呼び出しに見える しかし、その前の文脈に f = Foo があれば、f() の意味はコンストラクタ呼び出しになる もしも、これが new f または f.new であれば迷うこと無くコンストラクタであると判断できる > それに対して、Foo() は「極端に短い」からアンリーダブルだね なんで? Foo()という関数は読みづらいか? ていうか、何でコンストラクタと普通の関数を区別する必要があるの? 馬鹿なの? メソッドとかコンストラクタと言ってる時点で わかってないやつじゃないか。 このスレで言う、リーダブルとは 技術の低いやつに合わせることではないって 話と同じことだな。 そもそもオブジェクト指向とかゴミだろ藁() OCaml最高!! 第一級のモジュールができて 完全にオワコンになったOCamlのO if !flag vs. unless flag 派のたたかいはまだですか 論理的にはどちらか一方あればいいけど、 読むことを考えれば、両方できる方がいい。 のってやろう 俺は!を見逃すという凡ミスでハマったゴミクソ野郎なので unless派だ 実装は同じになるけど、英語の意味は違うよ だから両方ある方がいい 俺みたいな雑魚が until と unless を間違えるから、どちらかを別の単語にすべきだ。 if修飾子が好き。 条件の文字をxで置き換えて書くと next if xxxxxx next if xxxxxxxxxxxx next if xxx と揃っていて美しい。一瞬でこの一群の目的が分かる。 旧来の方法だと、 if (xxxxxx) next if (xxxxxxxxxxxx) next if (xxx) next こうなって、この一群が同一の目的を持ってることがスグには分からない。 >>168 すみません。このnextっていうのは何のことですか? >>163 そう言うやつはそのうち unless !flag と書いてはまるので、俺は unless いらない派 >>169 C で言うところの continue じゃね? perl とかが next だったような気がする。 条件によりオプショナルなら前置 null対策などで仕方なく条件を付けるのなら後置 みたいに書いたりしないか >>168 こうすりゃいいやん if (xxxxxx) next if (xxxxxxxxxxxx) next if (xxx) next 変なタイプミスした行をあぶりだすのに、それがいいときもある。 状況しだい。 getterでretunr文の位置合わせるのはやりすぎ? そういうタイプミスをみつけやすくしたいという意味? int getSpamSpamSpam() {return spam;} int getHam() {return ham;} int getEggEggEgg() {return egg;} int getSpamSpamSpam() {return spam;} int getHam() {return ham;} int getEggEggEgg() {return egg;} 下のほうが見やすい気がするけど,同僚からは不評 int getSpamSpamSpam(){return spam;} int getHam() {return ham;} int getEggEggEgg() {return egg;} int getSpamSpamSpam() {return spam;} int getHam() {return ham;} int getEggEggEgg() {return egg;} こんな感じか? ふつうの等幅フォントのエディタで書いてコピペしてくれた方が、 navi2chでは見やすいんだが 名前と括弧の間にスペースを入れて整形するのは変かな? 変かどうかっていうのは、オープンソース、 それも有名で多くの人が参加しているようなものの コードをみればいいだけ。 こういうのは考えるのではなく、調べて答えを見つけようぜ。 変 イテレータならものによっては改行とスペース入れてそろえる >>182 もっと名前の長い関数を追加することになったら面倒だろ 関数の中身を見比べる必要がある時点でおかしいだろと思った 達人プログラマでも同じようなインデントしてたし >>182 はそこまで変ではないのでは? 見た目云々より、エディタの矩形選択とかを活かせるメリットの方が大きい気が。 クラスの中のある関数をつかうために あらかじめいくつかの要素をsetしておかないといけないという設計はよくない? setしないで関数を呼び出したときには例外を出す感じ コンストラクタにいれてしまったほうがいいんだろうか? >>193 コンストラクタの引数に不正な値をいれたときの処理が気になる コンストラクタの中で例外だすのってありだっけ? そうするとインスタンス生成してから使うところをtryで囲まないといけないし >>194 ありだよ。 「tryで囲まないといけない」ってのも疑わしいが、それがほんとだとしても 「setしないで関数を呼び出したときには例外を出す」ってしたときと何が違うんだ? try { ____a = A() ____a.set(something) ____a.do_something() } か a = A() try { ____a.set(something) } a.do_something() の違いだと思ってる コンストラクタで例外がでるとそのクラスのインスタンスを使うところ すべてtryで囲まないといけなくない? a = Noen try{ ____a = A() } a.do_something() にしろってこと? >>196-197 それでいいんじゃね? ごく狭い範囲をtryで囲むみたいなレアケースの見た目(いずれにしても残念)を なんでそんなに気にしてるのか知らんけど。 FactoryMethodパターンもいいかも。 これだったら、値を解析して正しい値だったらクラスを生成して返し、 不正だったらnullか、ヌルオブジェクトパターンでダミーのオブジェクトを返してやるとか色々出来るから。 A create(int youso) { if(yousoが正常) return new A(youso); else return null; } class A { int _a; A(int youso) { _a = youso; } } >>198 コンストラクタに例外がある場合の書き方がよくわからなかった >>199 こういう方法もあるのか 参考になります デザパタの目的はいくつかあるだろうが、 その中で「カタログ化」だの「パターンに名前をつけて共有」だの、 さもそれこそがおいしいという論調には疑問だね。 >>199 を見ろよ。何がFactoryMethodパターンだ。 ただのファクトリメソッドじゃねーか。 「インスタンス化をサブクラスに任せる」っていう点を押さえて理解できてない。 【注目】チョー気持ちいい! やっぱセクロスするならアイドルっしょ 超有名アイドルグループ所属の美少女が衝撃のAVデビュー アイドルは裏切らないっ!! https://www.youtube.com/watch?v=XmP1TRsAe88 >>190 変更コストがつらくなってこない? 読みやすさでは>>182 も好きなんだけど >>204 変更コストって言っても getterでかつ今までの関数名より長いときにしか起こらないし,そこまで気にしなくていいのでは? 1分もかからないっしょ 変更コストよりも 変更したい箇所以外に、並列されてるだけで関係ない行まで修正が発生するのは気持ち悪いと感じる 1行の修正のはずなのにdiffとると何行も出たり まあオプションで消せるけど それでタイポして余計なバグが増えて… ってなったから>>182 みたいに揃えるのは止めたなぁ 見栄えだけなら揃えるのが好きだけど returnの位置を揃えるのとタイポは本質的には関係ないじゃね? alignみたいなやつで気軽にガンガン揃えられるような環境ができればいいのだろうか 自分は次の3つを結構その時の気分で描いてしまうのですが、どれかに統一したほうがよいとか、ありますか? こういうのに対するコーディング規約とかも、会社によってはあるんでしょうか? (ちなみに3は否定を使わない事でif文が素直に読めるかな?という理由で条件を逆にしているだけです) 例1 hash = INVALID_HASH; if (! data.empty()) { hash = ComputeHash(data); } 例2 if (! data.empty()) { hash = ComputeHash(data); } else { hash = INVALID_HASH; } 例3 if (data.empty()) { hash = INVALID_HASH; } else { hash = ComputeHash(data); } >>211 hash = data.empty() ? INVALID_HASH : ComputeHash(data); hash = INVALID_HASH; hash = ComputeHash(data) if (! data.empty()); >>212 なるほど、代入が1命令で済むなら参考演算子の方が見やすいですよね。 ちなみに複数行にわたる時はどうします? >> 213 説明不足でした、C言語を想定していました。 ちなみにこの書き方だと、同じ変数に対する代入が二つ連続しているだけのように(ぱっと見)見えませんか? 1行目の代入って無駄じゃね? と一瞬思わせてからの2行目、みたいな。 俺は>>212 じゃないけど、 > なるほど、代入が1命令で済むなら参考演算子の方が見やすいですよね。 代入が1命令というより、代入した後は変数の値を変更しないためだな。 変数は代入文とともに宣言し、その後は変更してはならない。 関数型言語の考え方よ。 なので>>213 はだめだね。値を書き換えてるから。 >>214 > ちなみに複数行にわたる時はどうします? 三項演算子でも見やすく書ける。 場合によってはハッシュを使う。 Perlで書くけど、 my $value = { key1 => 'value1', key2 => 'value2', key3 => 'value3', }->{$key} || 'other'; >>214 >ちなみに複数行にわたる時はどうします? hash = data.empty() ? ( INVALID_HASH ) : ( ComputeHash(data) ) ; 理屈は >>215 、いわゆる参照透明性のことで、 関数型言語や Ruby のような関数型プログラミングに適した言語ならではのコード ・Rubyによる関数型プログラミング http://www.h6.dion.ne.jp/ ~machan/misc/FPwithRuby.html なお Ruby には C と同様な条件演算子(三項演算子)もあるけど、 複数行にわたる場合には if 式を使うのが普通 hash = if data.empty() INVALID_HASH else ComputeHash(data) end 最初の話しとはズレるんですが、宣言と同時に初期化し、それ以降の代入を極力避ける というスタイルをC/C++で言い換えると、積極的に const をつける という事になりますかね。 変数をなるべく const 宣言するというのは、キーワードconstが目印になって宣言箇所がすぐにわかるので 個人的にも好きですね。ただ関数の非ポインタ引数にconstをつけるのは煩わしく思いますが。 それより条件式の比較演算子の省略と条件式内での関数呼び出しをやめてほしい >>219 それは十分シンプルで十分意味がわかるならば問題ないよ。 いるんだよね。ルールを守ることが目的になってる奴って。 × 書き方を統一しようとする ○ わかりやすいように書く わかりやすいならば、どんな書き方だっていいんだよ。 どうせ書き方なんて些細な事なんだし。 まあ比較演算子の省略はわかればいいんだけど if文の条件式で関数呼ばれると単にデバッグが面倒なんだよね これは別の問題か if (func()) { } ではなく result = func(); if (result) { } こういうこと? 比較演算子を省略しないとこうか result = func(); if (result == true) { } 真偽値だったら省略したくなるな〜俺は Cだったら if (result == true) はダメでしょ。resultが非0かつ非1だったときに困る。 if (result != false) にしないと。 結局真偽値判定は比較演算子使わない方がいいんでない? 変数名をresultではなく、 doneやcompleteのように状態を表す言葉にすればいい。 if (done) { } if (expr == TRUE) とか書くのは馬鹿げている、とcomp.lang.c FAQの回答にもある。 http://c-faq.com/bool/bool2.html 単に if (expr) と書くべき。 真偽値の場合、doneかisDoneにするかで迷う時がある。 いやexprは関係演算子以外から導くべきではない、って話だろ if(variable == undefined) 職場のスパゲティソースのメトリクス値がやばすぎるんで 今度大幅に直そうという話はあがったものの 全く手がついてないんだけど どういうふうに課員を指導したらいいんだろう >>220 こーいう人ってなんなん? 分かりやすいだけがルールじゃないし、 分かりやすい定義が曖昧だから、ルール作って こーいう意識もってやりましょうってのがルールなのになんで勝手なことするの そういう人が言う「分かりやすいコード」って 基本的に誤解しやすいコードが多い >>200 がプロだって前提で言うと、 >>200 みたいな意見は研究所出身の人に多いね。 で、そういう人の書いたコードは、実際にモノに組み込んで テストすると大量のバグが露見する(机上、単体テストはOKて言ってたにもかかわらず!) >>242 それはルールを守らずに,独自のわかりやすい方法で書いたからってこと? 一貫性の欠いたフレームワークなんて作られた日には使えたもんじゃないだろ 独自のわかりやすいコードっていうのを見てみたいわw わかりやすいコードっていうのは、独自じゃない。 多くが○○スタイルみたいな言い方で呼ばれてる。 もちろんいろんなスタイルがあって、わかりやすいスタイルというのは 一つではないが、わかりやすいという点では共通してる。 わかりやすいのに、バグがでまくるとか矛盾してるってw C言語で #ifdef DEBUG printf(var); #endif が1つの関数に頻出するコードは非常に読みにくい 今やらされてる組織内独自のフレームワークのコード >>246 プリプロの記法はもうちょっとなんとかならないものか?#if/#ifdef/#endif を一行で書ければいいのだが‥ >>245 本人はわかりやすいつもりで書いてるコードが該当するんじゃね? 省略できるものは全部省略しちゃうとか。 >>248 > 本人はわかりやすいつもりで書いてるコードが該当するんじゃね? > 省略できるものは全部省略しちゃうとか。 だからそれがどんなのかってこと。 例えば、単語を省略して書くのは わかりにくいとされている。 >>246 それ、明らかにわかりにくいコードだよね。 わかりやすいコードとして考えられたのではなく、 単にやっつけ仕事でifdef DEBUGを入れたのだろう。 一般的な仕組み、例えばsyslog当たりを使えば 分かりやすくなるよね。 #ifdef NDEBUG #define DEBUG_ONLY(x) #define RELEASE_ONLY(x) x #else #define DEBUG_ONLY(x) x #define RELEASE_ONLY(x) #endif な〜んかID:c84onc2Pの癇に障ったみたいなので一応補足すると、 別に>>220 みたいな意見を持つ人全員がバグ量産機だなんて言うつもりはないよ。 ただ、プロとして仕事する以上、コーディング規約に沿ったものでなければ 納品できない開発なんてざらにあるんだよね(有名所だとIEC61508とか)。 釈迦に説法かもしれんが、分かり易いとテストし易いは、似てるようで別物。 技術力が充分でないのに「分かり易ければOK」ていう人は往々にして テスト漏れ仕込むってことを愚痴りたかっただけ。>>241 は完全に個人的な経験からくる偏見だな。ごめんね。 プロとか言い訳すんなやw 「コーディング規約に沿ったものでなければ 納品できない」 というのが、理由であって わかりやすくするためではないだろ。 クライアントが望むなら、けばけばしいデザインのサイトだって作るさ。 だがそれは、クライアントの指示でだめなことをしているのであって それが正しいと思ってはいけない。 今ここに、クソなクライアントはいないんだぜ? いや、言い訳じゃなくて、契約の問題ですし。。。常識でしょ? スレタイ読んでね。リーダブルコーディング技術スレ。 リーダブルなコードのための話であって、 契約で〜とかいうのが理由ならそれは無関係だろ。 プロか否か、常識か否か、 これを早々に持ち出す姿勢w >>249 そう書いてあればまだ読みやすいのにひどいコードだよ全く あくまでメンテナンス性最悪なコードの例として出したんだけどね >>253 横からだけど一言多いなんじゃないかな プロとか常識とか言い出す奴は 信用してないわw だってそれ、単なる虎の威を借る狐だもの。 それに、虎ですらないかもしれないしな 俺の信じる、虎さまはこうおっしゃってる。 だから信じなさい。みたいなw 俺が定義するプロはこういうものなんだ。 お前はプロじゃないのか!みたいで どっかの宗教と同じ。お前は(俺らの)神を信じないのか! プロとか常識とかクライアントが決めたこことか無視しようぜ わかりやすいコードとはなにか? これだけで考えよう。 う〜ん、何か余計に癇に障ったみたいだね。 不覚にもスレ違いな話題に誘導されちゃったから、しばらく黙ってるは。 以下↓本来のリーダブルコーディング技術スレ まあ、俺は最初から、わかりやすいコードの 話しかしてないんけどねw ○な書き方、△な書き方、どっちがわかりやすい? の答えに、どちらでもわかりやすい。という答えがあるのは事実 だから複数のコーディング規約が存在するわけで。 書き方を(自分の好きな書き方に)統一すると、気持ちいかも知れないが わかりやすさの点から見れば、どちらでもいいことが多い。 >>246 エディタの置換コマンドで 一行に置換してしまえばいいんじゃないか? >>266 読むぶんには読めるけど書き換えはさせてもらえない なのにコード読まないと処理が理解できないというコード リーダブルと真逆なものを上げることで参考になればいいなと思って > 読むぶんには読めるけど書き換えはさせてもらえない 可愛そうだよね。まあ、社内規則だからw で、ここはリーダブルなのかはどういうことかって話すスレだから 社内規則で変えられないとかはどうでもよくて。 じゃあリーダブルなのはどういうコードかってことで、 意見を集めましょう。 ってもうみんな書いたか? 俺はsyslogって書いた。 デバッグ出力をするために再コンパイルが必要っていうのも 変な話なんだよね。そもそもオプションで指定すればいいと。 デバッグ出力機能を持っている。という所まで仕様。 で、こういう仕様を考える人、そこまで頭が回る人が、いないんだろうね。 只のデバッグプリントなら読み飛ばせばいいだけじゃん リーダブルの真逆てコードの意図が伝わってこないものを言うんじゃない? どうでもいいけど、syslogでデバッグって相当頭悪いか、ぬるい開発だな おいおい、syslogでやるのはデバッグプリントであって デバッグそのものじゃないぞw syslogにあるだろ。プライオリティdebugのことだよ。 http://www.atmarkit.co.jp/ait/articles/0209/07/news002_2.html > プライオリティ(priority) > > priorityは、プログラムが出力するメッセージのうち、ログのレベルの重要度を設定します。 > > priority 内容 > debug デバッグ情報 > info 情報 > notice 通知 > warn 警告 > err 一般的なエラー > crit 致命的なエラー > alert 緊急に対処すべきエラー > emerg システムが落ちるような状態 > 下になるほど重要度が高い なんでこんな基礎的を説明せにゃならんのだw 既に世の中にあるものを使わずに(知らずに) 少ない知識でもやれるぜって考えで オレオレで実装するのも、リーダブルにならない原因の一つだよね。 なぜ、人はアンリーダブルを求めるのでしょうか? 人は生きて、死ぬだけの存在でありながら、 存在するということに意味を持たせ、生と死をより複雑なものにしようとしました。 本来、人は無駄を好む存在です。 オートメーション、自動化、リーダブルなどというものは、 将来、オートメーションにより追いやられた人々により破壊されることが目に見えているのですから、 破壊されるために効率化を豪語し、効率化に勤しむ人々がいることに、 私は含み笑いを抑えることができません。 リーダプルは、時間的にどの程度のスパンで考えるのかな? 読みやすさは主観であり、人により異なる。 全員に対して読みやすさを一定量担保するために、コーディング規約を作る。 デバッグプリント関係は、『CODE COMPLETE』 第八章防御的プログラミングがお勧め。 > 読みやすさは主観であり、人により異なる。 つまり、人によっては、Aという書き方が読みやすく、 別の人は、Bと言う書き方、Cと言う書き方が一番読みやすいということ > 全員に対して読みやすさを一定量担保するために、コーディング規約を作る。 たとえば規約でBという書き方に統一する。 さて、統一することによって、Aという書き方は読みにくということになるのか? Bという書き方は読みにくいということになるのか? もちろん違う。なぜなら、 > 読みやすさは主観であり、人により異なる。 と書いてあるように、人によって、AやCが読みやすいということに変わりはないからだ。 つまりなりが良いたいかというと、 AでもBでもCでも読みやすいことには変わりないということ。 統一するのは、読みにくい書き方を無くすのが目的であり、 読みやすい書き方は複数あるということは真実だし、 読みやすい書き方ならどれでもいいことにかわりはないのである。 だからこそAとCは自分のに取っては一番ではないが それでも読みやすいならばどれでもいいから、その規約に従うのである。 >>220 >× 書き方を統一しようとする >○ わかりやすいように書く 世間に受け入れられているコーディング規約に従うのが一番わかりやすいんだから それ対立軸じゃなくて両方○になるか両方×になるかだろ > 世間に受け入れられているコーディング規約 が複数あることを忘れてない? わかりやすい書き方は一つじゃないんだよ。 >が複数あることを忘れてない? 忘れてない >わかりやすい書き方は一つじゃないんだよ。 もちろん で? >>271 当たり前なことをわざわざ引用付きで語んなよw お前がぬるい開発しかしてないことはよく分かったから >>280 お前、「お前は語るな」と「俺はそう思ってる」の 2つのことしか言ってないぞ。 何か言い返せよw >>279 で?と言われてもな。 最初から言っているように、 わかりやすいコードを書くことが目的であって 書き方を統一することは目的じゃないんだよって話 言い換えると、わかりやすければ統一する理由はない。 本当の目的を忘れるなって話。 >言い換えると、わかりやすければ統一する理由はない。 いや、AとBの両方わかりやすくても、一つの製品にAとBが混在してたら駄目だろ デバッグ出力でsyslogって発想は無いなぁ 最初に批判されてるが #ifdef DEBUG は普通のイディオムだから小さなプログラムなら悪くはないし もう少し大きな規模になってロギングフレームワークを検討しようというなら もっと抽象度の高いレベルでちゃんとしたフレームワークを採用するだろ (C++ならglogとか。言語ごとにあるだろ) >>282 君のコードは分かりにくい。はい。論破。 だから、ルールを決めるんだよ。お分かり? >>283 > いや、AとBの両方わかりやすくても、一つの製品にAとBが混在してたら駄目だろ なんで? それで問題が起きたことなんて無いよ。 どうせコーディング規約なんて誰かが我慢すれば済むようなもんでしょ? 一つに統一することで、他の人が我慢するという横暴(笑)が成り立つんだから。 全員が我慢するか、一部の人だけ除いて我慢するかの違い。 >>285 なんで、世の中で普及してあるコーディング規約の 一つを使ってるのにわかりにくいんだよw 馬鹿じゃないのか? >>284 > デバッグ出力でsyslogって発想は無いなぁ 無いなぁと言われてもね。 ほとんどの有名どころのオープンソースはsyslog でデバッグ出力している。 それが事実じゃね? >なんで? それで問題が起きたことなんて無いよ。 すまんが、2ch で匿名でここから議論する気はないので退散。論破と思うならそれで構わん。 教育しても俺に見返りないし。 はい、論破と思いますよ? 別にわざわざいなくてもいいのに。 このページの「デバッグライト」とか http://www.pro.or.jp/ ~fuji/mybooks/cdiag/cdiag.6.3.html ここでは、DebugPrintというマクロを用意しているわけだが、一度これを用意したら全員がDebugPrintを使わなきゃ意味ない DebugPrintを使ってるコードと#ifdef DEBUGを生で使っているコードが両方存在するのは最悪で。 DebugPrintを用意することで、その定義を変えればデバッグ先をsyslogにしたりできるだろ ところが、生で#ifdef DEBUGされてるコードが残ってたらそこで変更漏れのバグになる DebugPrintなど無くて全員生で書いていれば、変更時には漏れがないように注意するからまだマシ DebugPrintを用意したのに使ってないというのは本当に最悪 これがまず、統一するってことな。 もう一つは、 そもそもこういうDebugPrintみたいなのは車輪の再発明なので 今時こんな「オレオレフレームワーク」を作るのは間抜け (元ページはCopyright 1996) あるものを使うのが普通 >>286 同じものは同じように見えるようにしておかないと、コードレビューしづらい。 コードに手をいれるときにいちいちスタイルどうするか迷うのも無駄。 ・・・コードレビューしないなら問題は起こらない。 まわりと明らかにスタイルの違うコードを混入させて気にしないなら問題は起こらない。 つまりそういうことなんだろうと思ってる。 >>291 > あるものを使うのが普通 だからsyslogだろ? もしかして、syslog(ライブラリ)を使っていれば 標準出力や任意のファイルに出力できるって知らない? >>287 > ほとんどの有名どころのオープンソースはsyslog > でデバッグ出力している。 サーバーソフトだけじゃね? クライアントソフトの例を 10個ぐらいあげてみて ログは異常管理にdebugレベルを含めて使うけど、 開発時のデバッグには使わないかな。 >>294 サーバプログラムだってsyslog決め打ちなんて少ないと思うが。ログ出力先の選択肢の一つとしてsyslogがあるだけだろ。 Apache httpd (http://httpd.apache.org/docs/current/logs.html ) エラーログは普通はファイルに書かれます (通常 Unix システムでは error_log、Windows と OS/2 では error.log)。 Unix システムではエラーを syslog や パイプでプログラムに送る ことができます。 Postgresql (https://www.postgresql.jp/document/9.3/html/runtime-config-logging.html ) PostgreSQLは、stderr、csvlogおよびsyslogを含めて、サーバメッセージのログ取得に対し数種類の方法を提供します。 Tomcat (http://tomcat.apache.org/tomcat-6.0-doc/logging.html ) Logging in Apache Tomcat is implemented with the help of Apache Commons Logging library. 有名どころのオープンソースでログ機能がsyslog決め打ちって何かあるの? >>295 「デバッガを使え」みたいな方法論と、デバッグ出力をどうするかは別だと思うが、そういうこと?どうしてる? >>297 システム運用中に異常処理を行った場合、管理者にその旨を通報する用途でログを使う。 あくまで、システムの一部なので、リリース後でも取り除かれない。 開発時にだけ有効で、リリース時に無効にする用途には使わないかなって話。 開発時のみで使うものだったら ifdefで残したりしねーよ? そういう残してあるコードが じゃまだってのが、話の始まりだろ? >>298 ああ、理解した デバッグエイドとログを完全に別の概念として使い分けるということか プリプロセッサ命令のある言語だと確かにそれがスマートだな、なるほど >>299 > 開発時のみで使うものだったら > ifdefで残したりしねーよ? え゛? ifdefでソースコードに書いて それをずっと保守し続けてるってことは 残す理由があるからそうしてる。 ここまでOK? その残されたコードがじゃまで リーダブルにならくなって困っている。 ここまではOK? ならばifdefなんか使わずに もっとわかりやすいコードにしろって話。 お前はいい加減周りのことも考えて行動や発言できるようになれよ コーディングはそれから >>302 で、具体的な提案もなく、文句言うだけ? で、そこに#ifdefの方がわかりやすい派が現れるんですねわかります ソースとプリプロセッサのインデントが混じって見辛くなるから、俺はしない プリプロセッサのみの部分(define値の切り替えとかerrorとか)だったらインデントしたほうが見やすいと思いインデントしてる ソース内にかかる部分だと309と同じ意見でしてない 基本は#ifがネストしないようにしたいと思ってるけどね プリプロ行はスペースで、コード行はタブでインデントしてる。 見やすくはなるけど、読みやすさに繋がるかどうかはわからない。 #if XXX aaa bbb #endif よりも #if XXX void func() { aaa bbb } #else void func() {} #endif func() ってやっちゃうなあ。これならfunc呼び出し部分についてのインデントに悩まなくてもすむじゃん? しかも条件XXXで切り替わる部分が複数に成った場合でも、定義を一カ所にまとめておける。 関数呼び出しじゃなくてマクロにした方が良くない? リーダブルの観点ではないけれど、関数呼び出しのネストが深くなるのは良くないと思うんだ。 >>313 func の内容が数行ならいいけど、もっと増えると同じ内容を両方に書かないといけなくなる func の型とか引数が変更された時に片方の変更を忘れる とかあるので、俺はやらない >>316 > func の内容が数行ならいいけど、もっと増えると同じ内容を両方に書かないといけなくなる > func の型とか引数が変更された時に片方の変更を忘れる だからこそ>>313 のように書くんでしょ? これなら変更が一箇所にまとまる。 もしこれを、funcを使う場所ごとにに ifで加工としたら、funcを100箇所使っていたら、 100箇所、同じ変更を繰り返さないといけないよね? >>317 ああ、すまん、勘違いしてたわ 変更部分を別関数に切り出すと言うことか > aaa > bbb が元々関数に切り出すような意味のある単位ならわかるけど、処理の途中の一部を切り出したような場合だと関数名も付け辛いし分かりにくくなる あと、単に aaa, bbb って書いてるから違和感ないけど、実際には aaa, bbb で必要とする情報や、逆に変更した情報等のやり取りを引数でやる必要もあるので、結構面倒に思うんだけど 確かOpenSSLも各プラットフォーム毎に #ifdefの嵐でで手が付けられなくなったらしいけど、 こういうのはTemplate Methodパターンみたいなものを使えばいいんだよ。 デバッグ用の関数、またはクラスと リリース用の関数、またはクラスを作って それを使うコードはどちらを使っているか意識する必要がないようにする これぐらい基本だと思うんだが、OpenSSLを見る限り 世の中のレベルってこの程度のものなのかもしれんな。 >>322 こう?関数fにdebug用とrelease用をラップさせんの? f_debug() { } f_release() { } f() { f_debug(); } デバッグ用出力の話なら >>249 で十分テンプレートメソッドパターンと言えるでしょ 呼び出し元のスコープを維持したいからマクロを使うんであって、関数やクラスに分けられるものをマクロで書く奴はいないだろ 『レガシーコード改善ガイド』を読むと、どこにテスト用のフックを 仕掛けるかみたいな話が出てくるからお勧めしとく。 c言語でなるべくグローバル変数を使わない方がいいという事で グローバル変数無しで書き直したら、関数の引数がやたら多くなってしまった。 (´・ω・`) なるべくグローバル変数を使わない でいいんだが、 組み込み系だと、場合によって使っていいかと。 組み込みは仮想メモリが無く、搭載メモリ容量も決まっていて、 各機能それぞれ、どれだけの最大サイズでメモリを使うかなんて 設計段階で確定するものだから、 その最大サイズで最初からグローバルにメモリマップを切っておくべきかと。 動的確保とかだと開放漏れなんていう不具合がありがちだし。 普通にローカル変数ですむようなことまでグローバルにするのは厳禁だけど。 メモリなどの制約があるからやるのであって、 それをするのが常識な業界であっても その目的は「リーダブル」ではないことに注意ね。 >>330 グローバル(スコープの話)と動的確保(メモリー領域の話)をごっちゃにするなよ... 言語の話としては、スコープ(可視範囲)とエクステント(生存期間・寿命)な。 スタックに確保するかヒープに確保するかは、それらの実装の話。 いやあ、結構可読性が変わってくるよ。 動的確保系の処理って、寿命管理にそれなりの設計というかコードを書く必要があるし、 未確保の場合の条件分け処理だとか。 グローバルにすればそういう系のコードが排除出来てすっきりするんで。 今、組み込みで動的確保バリバリのプロジェクトに関わってて。 本来大丈夫なはずの所まで、大量の未確保時の例外処理を入れまくって、 可読性?なにそれ?なソースを相手にしているところww >>335 > グローバルにすればそういう系のコードが排除出来てすっきりするんで。 ごめん、マジで言ってることがわからん >>336 C言語の問題になるが、例外というものがなく エラーは戻り値で返ってくるので、 ちゃんとしたコードを書こうと思ったら原則的に このように書かないといけない。 int ret; ret = printf('Hello'); if (ret < 0) { return ret; } ret = printf('World'); if (ret < 0) { return ret; } >>337 だからグローバル使えばどうすっきりするのかと オブジェクト指向系言語だったらヌルオブジェクト使ってヌルチェックを不要に出来るし、 どのタイミングで動的確保されるかとかはクラスで隠蔽出来るんだが コードで示してくれない? グローバルでもチェックが不要になる訳じゃないよね? ? ポインタをグローバルに持つとかじゃないよ?念のため。 普通に、ごく普通にプリミティブ型やら構造体変数をグローバルに持つだけなんだが。 イメージ的には、様々な動的確保情報を全て確保した状態のヒープを、 最初から固定でグローバルに持っておく、という感じ。で伝わるかな。。 (やべえ何度読み直しても分からねえ…何が分からないのかさえ分からねえ…) >>339 > だからグローバル使えばどうすっきりするのかと グローバルを使えば、メモリ確保が失敗することはない。 つまり、すべてのメモリ確保エラーを 書かないで済む。 やり取りの内容がまだ理解できるレベルではないが 奥がふかいんですねえ やっぱcだけじゃなくjavaあたりもやっといた方がいいのかな >>353 え?? そもそも ID:Znidw3Lc なん? c言語である程度プログラムが大きくなってくると関数の数も増えて来るし どの関数がどの関数を呼び出してるとか色々増えて来ると思うんだけど こういうのってどういう管理が一般的なんだろか >>360 > どの関数がどの関数を呼び出してるとか色々増えて来ると思うんだけど 増えていかないようにモジュール化する > こういうのってどういう管理が一般的なんだろか 増えちゃったとか不幸にもぐちゃぐちゃのソースを解析するなら Doxygen とか、金があるなら Imagix とかで見るとか 関数がある程度増えたら、それを小さく分割するってことを しないからどんどん増えるんだよね。 なんで過去のコードを修正しないのか? 簡単なうちにすぐ手を付けないから、あとから手遅れになるんだけど。 >>363 それは分割の仕方が間違ってる派 正しいやり方は 長い関数があった時、その中で汎用的に使える所をシンプルな関数に 抜き出しながら全体を短くするというやり方。 間違ったやり方だと 長い関数があった時、その一部。例えば前半分と後ろ半分みたいに分けて 汎用的ではない関数(というよりもルーチン)を増やすやり方。 ”見通しが悪くなる" という言葉がうまく表している。 間違ったやり方は、汎用的ではない関数ができるから"見ないといけない" 「処理があちこちにジャンプして見にくい」など言うのはまさにこれが原因 正しいやり方ならは、汎用的でシンプルだから(一度見るだけで)あとは見なくて良くなる。 見るべきコードが減って処理も分割されないので、あちこちにジャンプすることもなく、見通しが良くなる。 >>364 以上、本ばかり読んでてコード書いたことのない自称できるプログラマーの意見でした なかなか難しいところだ脳。 やっぱコード書く前にしっかり設計やってからやるべきなのかね。 趣味だけども >>366 正論だから反論はできないよ 無限の時間と労力かけてでもやれと言う主張だから、役に立たないけどな w このスレの忘年会みたいな軽いノリで、リーダブルじゃない現場コードの晒し合いとか愚痴晒し合いとかしませんか 言語問わずなんでもありで 丁度上司のunreadableコードと戦っててもうね 出所バレない感じに整形したりしてるんですがもうね 再帰関数使いたいけど無名関数じゃ再帰できないようだからしぶしぶprivateメソッド化して細切れになる現象 >>364 ワンストップ・サービス(窓口)のFacadeはどうなる? fA(){ fB();fC();fD(); } >>367 Eclipseのリファクタリングの説明を読むといい >>370 つ Yコンビネータ って全然リーダブルじゃねーか new codeClone[num_of_func] >>368 > 無限の時間と労力かけてでもやれと言う主張だから、役に立たないけどな w なんで無限?w あなたが仕事すると無限の時間がかかるって話?w >>375 > 無限の時間と労力かけてでも > 無限の時間と労力かかるけど 区別できないアホは絡んで来るなよ >>371 > ワンストップ・サービス(窓口)のFacadeはどうなる? その例から何を言いたいのかよくわからないよ。 何か俺が言ったことを勘違いしていそうだから、 勘違いしていそうなところの補足をしておく。 > 間違ったやり方だと > > 長い関数があった時、その一部。例えば前半分と後ろ半分みたいに分けて > 汎用的ではない関数(というよりもルーチン)を増やすやり方。 この前半分と後ろ半分にわける間違ったやり方というのは、 例えば一つの工程をA、Bの二つに分けた時、 Bの内容(引数・戻り値じゃなくて"内容")を見ないと Aが最終的にどうなるかわからないようなもののこと。 Facadeみたいにそれぞれの独立した工程に処理を渡して 引数・戻り値といった最小限の情報だけでやり出来るものは関係ない。 >>376 区別できているかできていないかの前に 質問に答えてよ。 俺は「無限の時間と労力をかけてでもやれ」なんて一言も言っていない。 でもまあ、仕事(作業)するなら時間がかかるのはあたりまえだよ。 (その時間内で)適切なやり方をやれって言っているだけだが どうして無限の時間をかけるって話になったのさ? 「適切なやり方をやれ」って言っただけなのに それを「無限の時間と労力をかけてでもやれ」と勘違いしてしまうのは 「適切なやり方をやったら、俺は無限の時間がかかるんだ。適切なやり方=無限の時間なんだ」って >>368 が言っているようにみえるのは仕方ないでしょw >>377 ようは暗黙にBの事前条件がAの事後条件となるのがダメということかね。 >>364 の「汎用的」がどういうものを指しているのかいまいち意味がつかめなかったが、 条件を明確にするなら汎用/専用関係なくていいんじゃね? >>396 java で何でかんでも定数定義して(カウンタ変数とか!) フォーマッタでぐちゃぐちゃになったソースは見たことある だから正論に反論なんてできないよ 「適切なやり方やればいい」 間違ったことは言ってないからな でも、そんなことは小学生でも言えるわ w >>382 の上司「無限の時間をかけてでも適切なことをやれ!でも給料はいつも通り!」 って言われてるからここで愚痴ってるんでしょ >>382 だから変なのは「無限の時間」って話が出てきた所だけだよ。 正論言ってるんだから、俺が言った内容に反論できないのはわかってるよ。 俺が言った内容ではない話が、どこからできたんだ?って言ってるだけ。 >>384 そんな時間じゃできません と言われたらどう答えるんだ? >>385 誰が誰の立場でできませんっていうんだよ? わけわからんわ。 時間内に出来るかどうかはケースバイケースなんだし、 出来るところまでやればいいだけだろ。 それに技術力を上げれば時間内にできることも多くなるぞ。 何も努力しないでコピペばかりするから技術力も上がらなくなる。 >>385 上司「何言ってるんだ土日があるだろ。ただしそれはお前の能力不足が原因だから残業代は出ないからな。」 >>386 > 誰が誰の立場でできませんっていうんだよ? はあ? 指示を受けた人がその指示を実行する責任を負う立場でだよ。 常識だと思うが。 まあ、常識ないから > 出来るところまでやればいいだけだろ。 なんてことを平気で言えるんだろうな。 >>387 先月すでに土日も使うことにあなたの指示で計画変更されてますが、お忘れでしょうか? ... >>388 上司「俺は土日をつかえなんて指示はしていない。そんな計画を承認したはずもない。 ただお前が業務時間内に間に合わないなら土日や深夜や自宅時間も使わざる負えないだろうということだ。そんなこともわからんのか。」 >>388 > 指示を受けた人がその指示を実行する責任を負う立場でだよ。 つまり俺か? なら出来ますって言えばいいだけじゃないか。 「お前このバグ直せる?」って聞かれた時 出来ますって答えるだろ? あ、もしかして俺なら(上級者なら)時間内にできる仕事を どれだけ時間があっても出来ないって言いたい人なのかな? 俺にはいくら時間があっても仕事できないよって。 まあ、ここいらでリーダブルコーディングの話に戻すか。 仕事が遅い人って見ていると、自分で自分を苦しめてるんだよね。 自分でぐちゃぐちゃなコードを書いて、 正しく動かない、バグが直せないって言ってる。 自分が書いたコードと戦っているわけさw リーダブル、つまり読みやすいコードを書けるように 自分を鍛えれば、自分が書いたコードと戦うことは少なくなっていく。 でも仕事が遅い人って、自分が書いたコードと戦うことに精一杯。 時間がないを言い訳にしてレベルを上げようとしないから、 戦う敵を量産するだけで、更に時間をなくしてる。 コードは読むものなのだが、どうもレベルが低い人にとっては 解析する物になっているようだ。解析した後その謎を片付けないでそのままにして さらにコードを追加するから、書けば書くほど謎が深まっていく だから仕事をするばするほどかかる時間が増えていく。 あ、だから無限の時間って話になるのかw 自作のソフト、ネタ尽きてきたからコードの簡略化してたら5時間くらいたってた クリエイティブじゃないやつはリファクタリングして仕事した気になってる勘違いが多い 匿名通信(Tor、i2p等)ができるファイル共有ソフトBitComet(ビットコメット)みたいな、 BitTorrentがオープンソースで開発されています 言語は何でも大丈夫だそうなので、P2P書きたい!って人居ませんか? Covenantの作者(Lyrise)がそういう人と話したいそうなので、よろしければツイートお願いします https://twitter.com/Lyrise_al ちなみにオイラはCovenantの完成が待ち遠しいプログラミングできないアスペルガーw The Covenant Project 概要 Covenantは、純粋P2Pのファイル共有ソフトです 目的 インターネットにおける権力による抑圧を排除することが最終的な目標です。 そのためにCovenantでは、中央に依存しない、高効率で検索能力の高いファイル共有の機能をユーザーに提供します 特徴 Covenant = Bittorrent + Abstract Network + DHT + (Search = WoT + PoW) 接続は抽象化されているので、I2P, Tor, TCP, Proxy, その他を利用可能です DHTにはKademlia + コネクションプールを使用します UPnPによってポートを解放することができますが、Port0でも利用可能です(接続数は少なくなります) 検索リクエスト、アップロード、ダウンロードなどのすべての通信はDHT的に分散され、特定のサーバーに依存しません 1^ >>58 >道具が使えるだけの奴は三流。 >技術・知識も使いこなせて二流。 >人も使いこなせてこそ一流。 医療系の管理者です。 今更ですが金言だと思いました。 その立場にならんとわからないですね。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.0 2024/04/24 Walang Kapalit ★ | Donguri System Team 5ちゃんねる