リーダブルコーディング技術スレ

■ このスレッドは過去ログ倉庫に格納されています
2013/10/11(金) 01:06:21.56
リーダブルコードとは

・読みやすさ、理解しやすさを追及したコードのことです
・読みやすいということはメンテナンス性も高いということです。
・理解しやすいコードはコードレビューも楽になります。
・理解しやすいコードはバグも少なくなります。
・短いほうが優れていることが多いですが、必ずしも短いほうがいいとは限りません。

俺ルール
・書き方の勝負であり、言語の勝負をしないでください。
・標準、非標準に限らずライブラリを使いましょう。
・なければ自分で関数を作りましょう。関数はなるべく汎用的に。

こういうコードを読みやすくするにはどうすればいいでしょうか?
というようなことを語るスレ。需要ありますかね?
2013/10/23(水) 22:31:00.52
>>115
Javaの話として解釈する
ぱっと見て意味はわかるし良いと思う
所属しているクラス名がHogeなら、考え直した方がいいかも
117デフォルトの名無しさん
垢版 |
2013/10/23(水) 22:34:24.51
動的型付け言語の場合。
クラスがHogeであっても、getHogeってした方がいいよ。

なぜなら、getだけじゃ何からのgetか分からないから。
近くでnewしていれば簡単だが、関数の外から
渡されてきたらあちこちのコードを読まないとわからない。

しかも一つ見つけたら、それで正しいとは限らない。
もしかしたら見つけたのとは別のクラスも渡しているかもしれない。
2013/10/23(水) 22:52:48.88
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
2013/10/23(水) 22:54:38.49
「リーダブルコード」的には、getHogeはオススメされていない。
・属性値を得るだけの軽い処理とまぎらわしい
・明確じゃない(ほかの動詞を使うべき)
120デフォルトの名無しさん
垢版 |
2013/10/23(水) 22:58:55.35
内部処理を意識させないために
getでいいのでは?

内部処理がどうなっているか不明なのだから
軽いかどうかなんてわかり用がないし
変わることだってだろう?

そこに何かの想定をしてはいけないだけの話。
2013/10/23(水) 23:02:09.66
>>120が英語が出来ないだけの話
リーダブルコードの意味をもう一度考えたほうがいい
2013/10/23(水) 23:09:46.14
Foo.getHoge(); と書くと「FooがHogeをgetする」になってしまう罠。

仮にこれを「FooからHogeをgetする」と読むのならば、
if( Foo.isHoge() ) を 「もしFooがHogeなら」と読めなくなる。
2013/10/23(水) 23:16:32.20
そのロジックはこじつけすぎ
慣習には従うべき
124122
垢版 |
2013/10/23(水) 23:19:31.79
間違えてUCCで書いてもうた…orz
でもまぁ標準ライブラリでもよく考えるとおかしなのがあるから、あまり気にせずとも良い気も。
2013/10/23(水) 23:20:41.94
>>115
定数オーダーの処理ならget,setって言っていいイメージでいます。
2013/10/23(水) 23:31:43.97
話が逸れるけど関数名だけに拘るのではなく、戻り値や引数の型その他を含むシグネチャ全体に気を使った方が良いかと。
特にC/C++なんかだとconstの有無はネーミングと同じ位気を使って欲しい。
うまく使えば読みやすくなるし。
2013/10/23(水) 23:31:45.03
そのHogePathの出どころによるよね
DBから探してくるならfindHogePathとかsearchForHogePath
コンポーネントをいくつか組み合わせて作るならcomposeHogePath
どこかに設定してあるのをちゃちゃっと取ってくるだけならgetHogePath
処理の中身がわかる名前がいいと思うよ
2013/10/24(木) 01:34:22.78
>>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がたまたまそう読めるからといって、だからなに?
他は違う読み方をすればいいだけじゃない。
ってことだな。
2013/10/24(木) 01:49:19.21
>>128
RubyではFoo.newなんだが(;^ω^)
2013/10/24(木) 03:46:48.68
>>129
だから>>122はおかしいってことでしょ
2013/10/24(木) 07:03:23.93
>>129
それは一文字でも短くタイプするとかいう変な宗教だろう
リーダブルとは真逆
2013/10/24(木) 09:16:09.11
Foo.new と new Foo の違いは、前者がメタオブジェクト(Classのインスタンス)の
インスタンスメソッドの呼び出しであるのに対し、後者がnewという前置演算子による
演算子式である、という意味の違いが構文の違いになっているに過ぎず、
リーダビリティとは全く何の関係もない。

それを「一文字でも短くタイプするとかいう変な宗教」とか考える奴の脳味噌が変。
2013/10/24(木) 09:45:45.73
言いたい事をほぼ>>132が言ってくれたから話が早いw
2013/10/24(木) 10:17:04.85
>>131
一文字でも短くタイプするとかいう変な宗教とは、
Foo()
と書くリーダブブルとは真逆な某言語のことだろw
2013/10/24(木) 10:18:18.30
>>134
俺 Python スレとシャワートイレ板で有名コテやってるかあんまり怒らせないほうがいいよ
2013/10/24(木) 10:56:44.27
>>134
これ一番分かりやすいな
2013/10/24(木) 12:52:43.82
その言語において、コンストラクタが普通の関数と同じものなら、それで問題ない。

プログラミング言語は、計算のための意味論を持った、形式言語である、という前提を外した
議論からは、何も生まれないよ。
2013/10/24(木) 21:30:48.46
>>134
Perlは Foo だけでいけるよ。
2013/10/24(木) 21:33:14.24
>>134
なんでリーダブルとは間逆なの?

極端に短く書いたらリーダブルじゃなくなるけど、
適度に短いのはリーダブルだよね?
2013/10/24(木) 21:41:37.23
>>134みたいな馬鹿に賛同する奴は
本当に馬鹿なんだろうなって
心の底から思うよ。
2013/10/24(木) 21:52:44.97
というより、ちょっと前から一人おかしい子が紛れ込んでる希ガスw
知ったようなことを言いたいんだ、ということだけ分かる。
2013/10/24(木) 22:02:24.23
こんな感じで分かり易いコード書けるよー、的な話題になると、
気の利いたコード書けない低脳が、そんなの関数化するから関係無いと言い出し、
その結果、関数名とか変数名とか、あとメソッド呼び出しでの括弧省略とか、
そういう下らない議論になる

読んでないけど、このスレもそんな感じですか?
2013/10/24(木) 22:05:39.81
あぁ、お前が読んでないことが2行目でわかったよw
さっさと自分のスレに帰って、
そいつに泣かされてこい。
2013/10/24(木) 22:08:26.25
自分のスレとか言い出したら
病気ですよ
2013/10/24(木) 22:11:41.26
>>144
2013/10/24(木) 22:12:24.79
あ、馬鹿にしたことに気づいてないのかw
2013/10/24(木) 22:25:41.04
自分のスレって何だ?
148デフォルトの名無しさん
垢版 |
2013/10/24(木) 22:30:08.34
三人称単数ならgetsだろ藁()
小学生かお前ら核爆()
2013/10/24(木) 22:40:56.38
>148
メンバからの呼び出しの場合
2013/10/24(木) 23:07:37.25
>>139
new Foo や Foo.new は「適度に短い」からリーダブルだよ
なぜなら、new というキーワードによって、単なるメソッド呼び出しと
コンストラクタ呼び出しを一目で見分けられる、
つまりコードリーディングを配慮した言語設計だと言える

それに対して、Foo() は「極端に短い」からアンリーダブルだね
なぜなら、前後の文脈を確認しなければ、それがメソッド呼び出しなのか
コンストラクタ呼び出しなのかが区別できない
つまりコードリーディングを無視した
「一文字でも短くタイプするとかいう変な宗教(>>131)」に従った言語設計だと言える

たとえば、f() というコードは一見するとメソッド(または関数)呼び出しに見える
しかし、その前の文脈に f = Foo があれば、f() の意味はコンストラクタ呼び出しになる
もしも、これが new f または f.new であれば迷うこと無くコンストラクタであると判断できる
2013/10/24(木) 23:09:12.24
> それに対して、Foo() は「極端に短い」からアンリーダブルだね

なんで? Foo()という関数は読みづらいか?
2013/10/24(木) 23:10:31.80
ていうか、何でコンストラクタと普通の関数を区別する必要があるの?
馬鹿なの?
2013/10/24(木) 23:11:09.04
メソッドとかコンストラクタと言ってる時点で
わかってないやつじゃないか。

このスレで言う、リーダブルとは
技術の低いやつに合わせることではないって
話と同じことだな。
2013/10/24(木) 23:11:54.80
newFoo = Fooって書けばよくね???
2013/10/24(木) 23:18:11.87
アホがアホのフリをする必要は無いぞ。
156デフォルトの名無しさん
垢版 |
2013/10/24(木) 23:31:48.54
そもそもオブジェクト指向とかゴミだろ藁()
OCaml最高!!
2013/10/24(木) 23:37:35.84
Objective Caml ........
2013/10/24(木) 23:38:57.24
第一級のモジュールができて
完全にオワコンになったOCamlのO
2013/10/24(木) 23:40:51.03
一時のブームに流されたばかりに.....
2013/10/24(木) 23:41:59.24
おまえら、ここは言語の勝負するスレじゃないぞ
2013/10/24(木) 23:47:53.68
if !flag vs. unless flag 派のたたかいはまだですか
2013/10/24(木) 23:50:39.18
論理的にはどちらか一方あればいいけど、
読むことを考えれば、両方できる方がいい。
2013/10/24(木) 23:51:21.06
のってやろう
俺は!を見逃すという凡ミスでハマったゴミクソ野郎なので
unless派だ
2013/10/24(木) 23:52:16.44
実装は同じになるけど、英語の意味は違うよ
だから両方ある方がいい
2013/10/25(金) 01:24:29.19
if not でいいじゃん
2013/10/25(金) 10:07:22.11
条件式は明示的に比較演算子を記述すること
2013/10/25(金) 10:22:07.23
俺みたいな雑魚が until と unless を間違えるから、どちらかを別の単語にすべきだ。
2013/10/25(金) 11:01:11.16
if修飾子が好き。
条件の文字をxで置き換えて書くと

next if xxxxxx
next if xxxxxxxxxxxx
next if xxx

と揃っていて美しい。一瞬でこの一群の目的が分かる。
旧来の方法だと、

if (xxxxxx) next
if (xxxxxxxxxxxx) next
if (xxx) next

こうなって、この一群が同一の目的を持ってることがスグには分からない。
2013/10/25(金) 11:35:26.92
>>168
すみません。このnextっていうのは何のことですか?
2013/10/25(金) 11:45:26.35
>>163
そう言うやつはそのうち unless !flag と書いてはまるので、俺は unless いらない派
2013/10/25(金) 11:49:51.98
>>169
C で言うところの continue じゃね?
perl とかが next だったような気がする。
2013/10/25(金) 11:56:20.11
>>168
同じ目的ならor条件にしろ
2013/10/25(金) 12:31:03.71
一人だけ周回遅れな発言してるなぁ…
2013/10/25(金) 20:13:24.30
条件によりオプショナルなら前置
null対策などで仕方なく条件を付けるのなら後置

みたいに書いたりしないか
2013/10/25(金) 23:00:46.24
>>168
こうすりゃいいやん

if (xxxxxx)      next
if (xxxxxxxxxxxx)  next
if (xxx)         next
2013/10/25(金) 23:24:53.78
変数宣言でそれやってるやついるな。
2013/10/26(土) 00:49:23.99
変なタイプミスした行をあぶりだすのに、それがいいときもある。
状況しだい。
2013/10/26(土) 12:52:26.30
getterでretunr文の位置合わせるのはやりすぎ?
2013/10/26(土) 12:59:11.00
そういうタイプミスをみつけやすくしたいという意味?
2013/10/26(土) 16:11:57.24
int getSpamSpamSpam() {return spam;}
int getHam() {return ham;}
int getEggEggEgg() {return egg;}

int getSpamSpamSpam() {return spam;}
int getHam() {return ham;}
int getEggEggEgg() {return egg;}

下のほうが見やすい気がするけど,同僚からは不評
2013/10/26(土) 16:15:01.79
スペース纏められてたw
2013/10/26(土) 16:17:35.98
int getSpamSpamSpam(){return spam;}
int getHam() {return ham;}
int getEggEggEgg() {return egg;}

int getSpamSpamSpam() {return spam;}
int getHam()        {return ham;}
int getEggEggEgg()     {return egg;}

こんな感じか?
2013/10/26(土) 16:25:30.69
ふつうの等幅フォントのエディタで書いてコピペしてくれた方が、
navi2chでは見やすいんだが
2013/10/26(土) 21:25:49.66
名前と括弧の間にスペースを入れて整形するのは変かな?
2013/10/26(土) 22:35:48.73
2013/10/26(土) 23:00:18.20
変かどうかっていうのは、オープンソース、
それも有名で多くの人が参加しているようなものの
コードをみればいいだけ。

こういうのは考えるのではなく、調べて答えを見つけようぜ。
2013/10/26(土) 23:03:48.33

イテレータならものによっては改行とスペース入れてそろえる
2013/12/03(火) 11:00:09.00
>>182
もっと名前の長い関数を追加することになったら面倒だろ
2013/12/04(水) 01:09:35.65
関数の中身を見比べる必要がある時点でおかしいだろと思った
2013/12/05(木) 07:45:11.65
達人プログラマでも同じようなインデントしてたし
>>182はそこまで変ではないのでは?
2013/12/06(金) 01:25:03.50
見た目云々より、エディタの矩形選択とかを活かせるメリットの方が大きい気が。
2013/12/29(日) 23:04:49.03
クラスの中のある関数をつかうために
あらかじめいくつかの要素をsetしておかないといけないという設計はよくない?
setしないで関数を呼び出したときには例外を出す感じ

コンストラクタにいれてしまったほうがいいんだろうか?
2013/12/29(日) 23:06:02.09
>>192
うん。
何か気に入らないの?
2013/12/29(日) 23:59:47.76
>>193
コンストラクタの引数に不正な値をいれたときの処理が気になる
コンストラクタの中で例外だすのってありだっけ?
そうするとインスタンス生成してから使うところをtryで囲まないといけないし
2013/12/30(月) 00:03:01.47
>>194
ありだよ。

「tryで囲まないといけない」ってのも疑わしいが、それがほんとだとしても
「setしないで関数を呼び出したときには例外を出す」ってしたときと何が違うんだ?
2013/12/30(月) 00:20:47.15
try {
____a = A()
____a.set(something)
____a.do_something()
}

a = A()
try {
____a.set(something)
}
a.do_something()
の違いだと思ってる
コンストラクタで例外がでるとそのクラスのインスタンスを使うところ
すべてtryで囲まないといけなくない?
2013/12/30(月) 00:21:24.74
a = Noen
try{
____a = A()
}
a.do_something()
にしろってこと?
2013/12/30(月) 01:20:49.83
>>196-197
それでいいんじゃね?

ごく狭い範囲をtryで囲むみたいなレアケースの見た目(いずれにしても残念)を
なんでそんなに気にしてるのか知らんけど。
2013/12/30(月) 02:04:19.44
FactoryMethodパターンもいいかも。

これだったら、値を解析して正しい値だったらクラスを生成して返し、
不正だったらnullか、ヌルオブジェクトパターンでダミーのオブジェクトを返してやるとか色々出来るから。

A create(int youso)
{
if(yousoが正常) return new A(youso);
else return null;
}

class A
{
int _a;
A(int youso) { _a = youso; }
}
2013/12/30(月) 09:03:57.73
>>198
コンストラクタに例外がある場合の書き方がよくわからなかった

>>199
こういう方法もあるのか
参考になります
2013/12/30(月) 11:04:11.99
デザパタの目的はいくつかあるだろうが、
その中で「カタログ化」だの「パターンに名前をつけて共有」だの、
さもそれこそがおいしいという論調には疑問だね。

>>199を見ろよ。何がFactoryMethodパターンだ。
ただのファクトリメソッドじゃねーか。
「インスタンス化をサブクラスに任せる」っていう点を押さえて理解できてない。
2014/04/10(木) 09:43:21.89ID:VcyeIpim
>>191
これ
203拳聖ピストン矢口
垢版 |
2014/11/13(木) 23:50:19.89ID:yHSquATN
【注目】チョー気持ちいい!
やっぱセクロスするならアイドルっしょ 超有名アイドルグループ所属の美少女が衝撃のAVデビュー
アイドルは裏切らないっ!!

https://www.youtube.com/watch?v=XmP1TRsAe88
2014/11/15(土) 06:53:16.50ID:6Z/ZPh8x
>>190
変更コストがつらくなってこない?
読みやすさでは>>182も好きなんだけど
2014/11/15(土) 14:58:16.01ID:/lNofN3M
>>204
変更コストって言っても
getterでかつ今までの関数名より長いときにしか起こらないし,そこまで気にしなくていいのでは?
1分もかからないっしょ
2014/11/15(土) 16:17:34.44ID:lm0Ap3/W
変更コストよりも
変更したい箇所以外に、並列されてるだけで関係ない行まで修正が発生するのは気持ち悪いと感じる
1行の修正のはずなのにdiffとると何行も出たり まあオプションで消せるけど
2014/11/16(日) 07:07:37.48ID:fuIgZytk
それでタイポして余計なバグが増えて…
ってなったから>>182みたいに揃えるのは止めたなぁ
見栄えだけなら揃えるのが好きだけど
2014/11/16(日) 08:15:35.42ID:fuIgZytk
見栄え→読みやすさ
2014/11/16(日) 08:30:50.35ID:EKSPBw73
returnの位置を揃えるのとタイポは本質的には関係ないじゃね?
2014/11/17(月) 10:22:10.98ID:vQHrlZj+
alignみたいなやつで気軽にガンガン揃えられるような環境ができればいいのだろうか
2014/11/19(水) 00:13:58.01ID:GN47sEav
自分は次の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);
}
2014/11/19(水) 00:41:55.06ID:eeZRz+g3
>>211
hash = data.empty() ? INVALID_HASH : ComputeHash(data);
213デフォルトの名無しさん
垢版 |
2014/11/19(水) 05:42:14.41ID:3mSy2rZk
hash = INVALID_HASH;
hash = ComputeHash(data) if (! data.empty());
2014/11/19(水) 12:53:45.74ID:GN47sEav
>>212
なるほど、代入が1命令で済むなら参考演算子の方が見やすいですよね。
ちなみに複数行にわたる時はどうします?

>> 213
説明不足でした、C言語を想定していました。
ちなみにこの書き方だと、同じ変数に対する代入が二つ連続しているだけのように(ぱっと見)見えませんか?
1行目の代入って無駄じゃね? と一瞬思わせてからの2行目、みたいな。
2014/11/19(水) 13:24:54.27ID:xQuvo0yG
俺は>>212じゃないけど、

> なるほど、代入が1命令で済むなら参考演算子の方が見やすいですよね。
代入が1命令というより、代入した後は変数の値を変更しないためだな。
変数は代入文とともに宣言し、その後は変更してはならない。
関数型言語の考え方よ。

なので>>213はだめだね。値を書き換えてるから。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況