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

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

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

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

こういうコードを読みやすくするにはどうすればいいでしょうか?
というようなことを語るスレ。需要ありますかね?
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はだめだね。値を書き換えてるから。
2014/11/19(水) 13:29:08.73ID:xQuvo0yG
>>214
> ちなみに複数行にわたる時はどうします?

三項演算子でも見やすく書ける。

場合によってはハッシュを使う。
Perlで書くけど、

my $value = {
 key1 => 'value1',
 key2 => 'value2',
 key3 => 'value3',
}->{$key} || 'other';
2014/11/19(水) 20:19:45.26ID:eeZRz+g3
>>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
218214
垢版 |
2014/11/20(木) 00:50:43.10ID:dK3PPRDP
最初の話しとはズレるんですが、宣言と同時に初期化し、それ以降の代入を極力避ける
というスタイルをC/C++で言い換えると、積極的に const をつける という事になりますかね。
変数をなるべく const 宣言するというのは、キーワードconstが目印になって宣言箇所がすぐにわかるので
個人的にも好きですね。ただ関数の非ポインタ引数にconstをつけるのは煩わしく思いますが。
2014/11/20(木) 00:55:42.04ID:8SWsMjHc
それより条件式の比較演算子の省略と条件式内での関数呼び出しをやめてほしい
2014/11/20(木) 11:12:42.88ID:nwROesTX
>>219
それは十分シンプルで十分意味がわかるならば問題ないよ。

いるんだよね。ルールを守ることが目的になってる奴って。

× 書き方を統一しようとする
○ わかりやすいように書く

わかりやすいならば、どんな書き方だっていいんだよ。
どうせ書き方なんて些細な事なんだし。
2014/11/20(木) 11:40:07.19ID:jeSKdYmy
まあ比較演算子の省略はわかればいいんだけど
if文の条件式で関数呼ばれると単にデバッグが面倒なんだよね
これは別の問題か
2014/11/20(木) 17:57:21.94ID:B4HwyTzw
えっ
2014/11/20(木) 18:25:29.28ID:d0Ca/Au6
if (func()) { }

ではなく

result = func();
if (result) { }

こういうこと?
2014/11/20(木) 18:35:58.57ID:d0Ca/Au6
比較演算子を省略しないとこうか
result = func();
if (result == true) { }

真偽値だったら省略したくなるな〜俺は
2014/11/21(金) 10:27:03.29ID:09t/alwf
そうそう
C言語って既定の真偽値型ないし
2014/11/21(金) 10:53:54.88ID:09t/alwf
ごめんやっぱリーダーブル関係ないね
2014/11/21(金) 13:24:31.65ID:Y2Jui1fN
Cだったら
if (result == true) はダメでしょ。resultが非0かつ非1だったときに困る。
if (result != false) にしないと。
結局真偽値判定は比較演算子使わない方がいいんでない?
2014/11/21(金) 13:47:31.12ID:18AXju9B
真偽値を直接返す関数を作らなければいいのかな
2014/11/21(金) 14:12:52.15ID:Mc3QBWVu
変数名をresultではなく、 doneやcompleteのように状態を表す言葉にすればいい。
if (done) { }
2014/11/21(金) 14:14:08.05ID:biiemfBm
if (expr == TRUE) とか書くのは馬鹿げている、とcomp.lang.c FAQの回答にもある。
http://c-faq.com/bool/bool2.html 単に if (expr) と書くべき。
2014/11/22(土) 03:29:01.87ID:CZJjmAQJ
真偽値の場合、doneかisDoneにするかで迷う時がある。
2014/11/22(土) 04:07:44.39ID:FS7ceVya
結局どーんすんの
2014/11/22(土) 05:06:36.83ID:CZJjmAQJ
たまにいずどーんにすんの
2014/11/22(土) 11:35:45.69ID:HicAMECL
いやexprは関係演算子以外から導くべきではない、って話だろ
2014/11/22(土) 16:46:09.25ID:jgE9Y6q3
if(variable == undefined)
236デフォルトの名無しさん
垢版 |
2014/11/22(土) 19:28:06.50ID:Le0NeUvk
職場のスパゲティソースのメトリクス値がやばすぎるんで

今度大幅に直そうという話はあがったものの
全く手がついてないんだけど

どういうふうに課員を指導したらいいんだろう
2014/11/22(土) 22:08:19.55ID:6LKk2FqN
同値変形のやり方を練習させろよ
2014/11/22(土) 22:09:52.26ID:+O+q8SCA
それは、どうちて?
239デフォルトの名無しさん
垢版 |
2014/11/23(日) 08:18:15.22ID:zrTQYxev
>>220
こーいう人ってなんなん?

分かりやすいだけがルールじゃないし、
分かりやすい定義が曖昧だから、ルール作って
こーいう意識もってやりましょうってのがルールなのになんで勝手なことするの
2014/11/23(日) 08:46:26.24ID:hspGDGDv
そういう人が言う「分かりやすいコード」って
基本的に誤解しやすいコードが多い
2014/11/23(日) 08:59:26.38ID:DxJUdIe1
>>200がプロだって前提で言うと、
>>200みたいな意見は研究所出身の人に多いね。

で、そういう人の書いたコードは、実際にモノに組み込んで
テストすると大量のバグが露見する(机上、単体テストはOKて言ってたにもかかわらず!)
2014/11/23(日) 09:00:06.86ID:DxJUdIe1
失礼、>>200ではなく>>220でした。
2014/11/23(日) 09:16:30.23ID:rJ+2DU/G
>>242
それはルールを守らずに,独自のわかりやすい方法で書いたからってこと?
2014/11/23(日) 09:34:54.26ID:0xPoVd9P
一貫性の欠いたフレームワークなんて作られた日には使えたもんじゃないだろ
2014/11/23(日) 11:55:45.10ID:c84onc2P
独自のわかりやすいコードっていうのを見てみたいわw

わかりやすいコードっていうのは、独自じゃない。
多くが○○スタイルみたいな言い方で呼ばれてる。
もちろんいろんなスタイルがあって、わかりやすいスタイルというのは
一つではないが、わかりやすいという点では共通してる。

わかりやすいのに、バグがでまくるとか矛盾してるってw
2014/11/23(日) 12:50:11.85ID:Pyfj4pkz
C言語で
#ifdef DEBUG
printf(var);
#endif
が1つの関数に頻出するコードは非常に読みにくい

今やらされてる組織内独自のフレームワークのコード
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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