Murga

個人的に言いたいコト・主張・気持ち。

自分がコードを書く時に気を付けていること

ふと思い立って、自分がコードを書く時に気を付けていること・心がけていることを振り返ってみた。

大きなくくりでいうと、こんなところ。

  • 読みやすいこと (インデントや名前など、表面的なところ)
  • 改修しやすいこと (ある意味での「読みやすい」こと)
  • 冪等性・何度繰り返しても同じように動くこと
  • 処理内容を追跡できるログを出力する

以下、それぞれの内容についての細かな話を書いてみる。

表面的な読みやすさとして心がけていること

例えばこんなところ。

  • インデントを正しく付ける
  • ケースを揃える
  • 変数名・関数名などの品詞が適切である (英文として自然に読めるように)

「インデントをきちんと付けたり、名前を考えたりすると、作業速度が落ちるから、急いでいる時は適当にやる」という人がいるが、その認識は間違いだと断言する。そんな人は汚くてミスのあるコードを作ってしまった時に、読み解くコストが余計にかかり、正しいモノを提出できるまでに時間がかかることだろう。

まず、その程度のことで「作業速度が落ちる」ことの方が問題。キーボード操作が遅くてインデントごときに手間取ったり、頭が悪くて命名がヘタクソだったりして、そうした作業に時間がかかってたり負担を感じていたりすることの方を直さないといけない。平たくいえばバカだから遅ぇんだよ頭良くなれ。

自分はタイピング速度が速いからインデントを正しく付ける作業に時間がかからないし、命名も瞬時に妥当なモノが付けられる。その結果最初からキレイなコードが書けるから、もしバグがあってもすぐに見つけて修正できて、結果的に短時間で済む。

表面的なコーディングスタイルなんかが不揃いだと、中身を読み解く以前の段階のコードリーディングにかかるコストが増える。中身がすんなり入ってこなくて、勘違いしたりしやすくなる。そうしたノイズを減らして中身に注視してもらうために、表面的なところは特に驚き最小の原則を心がける。

「品詞」の意識も大事。変数は名詞、関数は動詞、ぐらいのことはまだいいが、目的語にあたる内容を関数名で示すか、それとも引数名で示すか。クラス名は主語にあたるので、クラスの分割粒度が正しくないと英文法として不自然になったりする。他にも、配列の変数は複数形で書き、For-Each で要素を取り出した時は単数形で書く、とか。

改修のしやすさとして心がけていること

例えばこんなところ。

  • 変数名・関数名などから処理内容を読み取りやすくする
    • 勝手に省略した単語を使ったりしない
  • 影響範囲を調べやすくする
    • 同じモノは同じ文字列で記述する
  • 修正された時にバージョン管理ツールでの差分がキレイに出やすくする

自分が書いたコードが、いつか誰か他の人に直される時のことを考えてコードを書いている。コードを直すためにはまず中身を読んでもらうことになるので、それが何をしているコードなのか、読み取りやすくなるよう工夫している。

影響範囲を調べたりする時は、コード全体を grep したりすると思うので、grep でヒットしやすくなるよう、同じモノは同じ文字列で名前を付けてやる。getItem()addData() とが同じ Book というリソースを扱っている、みたいな調べにくい命名を避ける。

また、修正された時に、Git で行単位の差分がキレイに見えることを狙って、処理ごとに行を分けて書いてみたりしている。複数の変換処理を経てデータを返却する関数を作ったとして、「追加要件によっては、この変換処理の間にさらなる変換処理を追加するかもしれない」と思ったら、その処理と処理の間を開けておいてやる。といった感じ。

冪等性を心がける

冪等性とは、同じ操作を何度繰り返しても同じ結果が得られる、ということ。

SQL なんかでいうと、INSERT 文を発行するコードは、そのまま2回目も実行すると、データが既に登録されているので、INSERT できずにエラーになる。コレを回避するとしたら、例えば UPSERT 文を使うようにするとか、SQL を投げるアプリ側でエラーハンドリングするなどして、その関数の実行結果としては、何度叩いても同じ状態にすることが望ましい。

シェルスクリプトでいうと、echo HOGE >> とリダイレクトで追記するような処理は、何も考えずに実装してしまうと、実行した回数だけ同じ文字列が追記されることになる。冪等性を考慮するのであれば、その文字列を追記する必要があるかどうかを事前にチェックする必要があるだろう。

REST API における PUT メソッドなどでも、このようなことが言われたりする。Ansible という構成管理ツールは冪等性を保つために、「実行しなくて良い処理は再実行しない」ように動くことで、結果的に設定される内容が同一に保たれる。

追跡可能なログを出力する

契約プログラミングの考え方でいくと、ある関数は、

  • 事前条件:処理を始める前に、前提条件をチェックする
  • 事後条件:処理をした後に、あるべき結果になっているかチェックする
  • 普遍条件:処理の前後で変化してはいけない部分をチェックする

という、3つの条件が守られていることを、アサーション等で確認する必要がある。

ログ設計についても、この3つの情報を出力するようにしておくと、問い合わせや障害が発生した時に、その処理をトレースしやすくなる。

シェルスクリプトでいうと、例えば、あるファイルの文字列を置換する、1つの処理があったとする。

sed -i 's/hoge/fuga/' ~/example.txt

sed は置換対象がなくても、終了コードは 0 で、思ったとおりに置換できたのかどうかが一見分かりにくい。

契約プログラミングとして強制力を持たせるなら、置換後の文字列が存在するかどうかで grep し、なければエラーとする、といった形で対応する。これはこれで実装するワケだが、同時に、「処理前はどうだったか」「処理後はどうなったか」というログも残しておくと良いだろう。

# 事前チェック : 「hoge」が含まれているかどうか
grep 'hoge' ~/example.txt

# 置換処理
sed -i 's/hoge/fuga/' ~/example.txt

# 事後チェック : 「hoge」が含まれていないこと
grep 'hoge' ~/example.txt
# 事後チェック : 置換した「fuga」が含まれていること
grep 'fuga' ~/example.txt

前後に追加した grep コマンドによって、事前・事後の状態がログに残ることになる。コレがあれば、この当時はどういう風に何が起こったかを追跡できるだろう。

全ての箇所に実装するのは大仰だと感じるかもしれない。チェックのための処理も、それだけ処理コストがかかるので、過剰なロギングは性能低下を招く恐れすらある。だから「チェック・ログ出力すべき箇所」と「しなくてもよさそうな箇所」を見極める必要はあるが、迷った時はログ出力しておいた方が、追跡しやすいだろう。

処理内容を正確にトレースできないと、障害調査に膨大な時間がかかり、確証が持てないと調査結果の信頼性も落ちることになる。そうした時間的コストと比べたら、ちょっとしたチェック処理を実装するコストと、それを都度実施するマシンの処理コストをとった方が良い場合は多いだろう。

以上

自分が当たり前にやっていることでも全然できない人が多いので、書いてみた次第。実装者である自分を信用しないからこそ、堅牢で信頼できるコードが書けるようになる。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

  • 作者: Dustin Boswell,Trevor Foucher,須藤功平,角征典
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2012/06/23
  • メディア: 単行本(ソフトカバー)
  • 購入: 68人 クリック: 1,802回
  • この商品を含むブログ (140件) を見る

…やっぱりリーダブルコードに行き着く。この本を読んだことがあるか否かで、ハッキリ別れる。

自分がムカつくネット上の話題の特徴

ストレスを操るメンタル強化術

ストレスを操るメンタル強化術

僕は神経質で HSP なところがある。

痴漢がどうしたとかセクハラがどうしたとか安倍政権がどうしたとかアメリカ韓国との関係がどうしたとか、そういうニュースをネット上で目にするだけでイライラしてしまう。俺はその痴漢セクハラ事件の関係者でもなければ、自覚している特定の政治思想も持っていない。自分には関係のない話なのに、その話題が耳に入ってくること自体が、うるさくて、イライラしてしまう。

ただ、そういうニュース全てがイライラするワケではなく、政治的な動向が一つも気にならないワケでもない。ニュースは知っておかないといけないよなーとは思うし、池上彰の番組や中田敦彦の動画を聞きかじる程度のことは行っている。そこで語られている政治的な思想はどうあれ、その人の切り口によればそういう話なのだ、というのを知るのは、楽しいし大事なことだと思う。

では、自分がイライラする多くの話題と、その中でもイライラせずに見ていられる動画や記事との違いはどこにあるのか。自分は何にイライラしているのか、それを探ってみようと思う。

感情的な話し方は一発シャットアウト

自分は何かをキャンペーンされる時に、感情的な接し方をされると一気に興味を失う。

  • 「〜〜が可哀想だと思わない?」
  • 「〜〜は酷いですよね!?」
  • 「あなたも同じことをされたらムカつきませんか?」

こういう語り口の記事は即閉じする。

確かに、自分も同じ目には遭いたくないと思ったり、ひでぇことするなぁーと同意したりする気持ちも、なくはない。が、それをどうにかしたいと思っている話者が、そんな稚拙な感想・論法で迫ってきてるところが頭に来るのだ。

反対意見を想像していない主張は聞く気にならない

「○○が××なのはおかしい」という主張を掲げた本人が、反論を想定していない文章は、考察が甘いと感じて読む気をなくす。

今あるモノを批判して別のモノを推奨するのであれば、その前に「今あるモノ」がどうして選ばれているのか、それをよくよく考えてほしい。その上で、自分が提案するモノがそれよりも勝る点、劣る点を述べてほしい。

その人の主張が以下のようにまとまっているなら、多少は読むに値すると思う。

  • 自分は、○○については「××」であるべきだと思うが、現状は「△△」になっている
  • なぜ「△△」が現状取り入れられているのか、もっともらしい理由を考えてみる ← ココが重要
  • 以上のとおり、一定の理由で「△△」に優位性があることは理解できたが、それでも「××」を取り入れるべきだ
  • なぜなら「××」は「△△」よりもココとココが勝っているからだ
  • 「××」に切り替えることで、「△△」よりも劣る点はココだが、ココについては別途「☆☆」を組み合わせれば、現状維持できる ← ココも重要

今あるモノを廃止することによる悪影響にまで意識が及んでいて、そこに対する対策まで打ち出せているととても良い。

現実的な実現可能性を考慮していない主張は寝言と同じ

例えば、

  • 「〜〜病が自己負担なのはおかしい、今すぐ無償化するべきだ」

こんな主張。

なぜ今それが自己負担なのか、という経緯や理由を全く考慮していない文章は、上述のとおり読む気に値しないが、さらにその先の主張が荒唐無稽で実現可能性が低いモノは、結局のところ自分の感情だけで、自分が困ってるから何とかしてほしいと思ってるだけだろ?と思う。

上の例だと、「無償化すべき」と言っているが、無償化するのがどれだけ不可能に近いことなのか、を考えるべきである。

  • 一般的に、その病気に疾患する可能性が極めて低く、医療整備や制度の維持費が合わなさすぎる
    • 国がやることは慈善事業ではないので、あまりにも採算が取れない施策は打てない
    • 仮にその施策を実現したとして、維持費がかさみすぎて、他の病気の人のケアが行き届かなくなったらどうする?といった想像もしてほしい
  • その病気と偽って不当に薬を処方してもらう人が後を絶たない場合とか
    • 安易にその施策を実現した場合に悪用されるリスクなどを考えているかどうか
    • 本当に欲しい人に薬が行き渡らないとか、残念な結果になるとも限らない

こうしたことを少しでも考えたか?ということ。考えてなさそうな文章は、イラッとする。

比較しても意味のないモノを比較しているのは感情論

  • 「○○病は保険適用なのに、××病は自己負担なのはおかしい」
  • 「タバコは合法なのに、ドラッグが違法なのはおかしい」

これらって、正しい比較対象なのだろうか?比較することに意味があるのだろうか?

なんとなく近いカテゴリにあるモノを列挙して、「(ドラッグを吸いたいのに) 自分が許されないのは不当だ」と言いたいだけだろ。

まったくロジカルでなく、聞くに堪えない。

比較しても意味のないモノとは比較せず、そのモノだけ論じろ。

調査不足

  • 「〜〜という生物が保護されていない!もっと保護すべきだ!」

気持ちは分からんでもないが、よく調べてみろ。

  • 既に行政や非営利団体が保護のための施策を打っている
    • そのおかげで個体数はむしろ増えている、など

主張が若干ズレていて、「既存の施策だけではこのように足りない、もっとこうするべきだ」という言い方なら分かる。でも、「何もされていない」は間違い。

もっと穏やかに言えないのか?

  • 「〜〜はおかしい!こうあるべきだ!ムキーー!」

ってツイートするんじゃなくてさ、

  • 「〜〜なのは素人目に見て違和感があるんだけど、どういう理由でそうなのだろう?○○が選ばれていない理由は何だろうか?」

と書けないもんかねぇ。

素人が感じる違和感のほとんどは、専門家が長年考えに考えて出した最善策であることが多い。そして、素人が考える対案のほとんどは、専門家が既に考え尽くして否定してきた「劣った考え」だ。素人の観測範囲で分かるレベルのことを、頭の良い人達が考えていないワケがない。そしてお前らはことごとく素人なので、大抵の場合において口を出すべきでない。

「自分はあれが間違いだと思う!!」ではなく、「自分が間違っているんだろうけど、どうにも納得いっていないから、理由を知りたい」という姿勢でないと、専門家に論破されて恥ずかしい目に遭うだろう。

悪口ほど直接伝えて現状を変えろ

日常生活で何かイラッとした、悲しかった、という話は、ネットで陰口のように書き捨てない方が良い。代わりに、本人に直接言った方が良い。

ネットで言っても、当人には届かないから、当人はいつまで経っても同じことを繰り返す。そしてネットに書いた側は「自分は何度も言ってるのに」という感覚だけが強まり、余計にイライラする。ネットに書けば書くほど、自分が歪んでいく。周りとの距離は離れ、誰からも理解されなくなっていく。

そうなるくらいなら、直接「あなたのこういう行為に迷惑してます、やめてください」と伝えた方が良いだろう。相手に理解力があれば分かって止めてもらえるし、止めてもらえない場合でも周りの理解は得られたり、法的措置など次の手に出やすい。

自分の意志で、自分の生活を変える気があるのか。あるならネットにくだらない陰口なんか書いてないで本人に言え。自分を変えるつもりがないなら、いつまでも同じことを繰り返して落ちていけばいい。あんたの書き込みを見てイラッとした人達はあなたをブロックして終わりだ。あんたなんか存在しないモノとしてこれからも生きていく。皆から無視されて終わりだ。

思考の整理のために、誰にも見られていない非公開の日記に書き殴る、といった行動をとるのは理解できるが、「私はイラッとしました!私の感情って合ってますよね!?」と周りに意見を求めるな。自分の感情ぐらい自分で整理しろ。そしてそれを雑に補強してつまらない「議論モドキ」の記事を書くのはいい加減にしろ。そんなノイズはクソの役にも立たないし全く賛同できないから一発ブロックだ。二度と視界に入れんなボケ。

自分の感情を守るために、非論理的な話題はブロック

つーワケで、自分はこのようにしょーもないネット上のノイズにイライラしてしまう神経質人間なので、そんな人間が自分を保つためには、ノイズは除去、ブロックするしかないのである。

そして、自分が何をノイズだと感じるかというと、総じてロジカルでない、感情的で分析や降雪に欠けた話題が嫌いなのだ。それは僕の根源に、「不満があるなら自分で変えようとしろ」という思いがあるからなのだろう。

これは恵まれている人間の言い分だろうか?不満を垂れるだけで本当に何も出来ない人達の方が、世間には多いのだろうか?

弱者がどれだけいるのか、彼らがどれだけ弱い存在なのか、ということにも僕は全く興味がなくて、負ける奴は負けてろと思ってるので、やはりコレ以上話題にするつもりがない。マシになってから俺の視界の前に現れてくれ。それまでは消えてろ。

DHC セントジョーンズワート 30日分

DHC セントジョーンズワート 30日分