新人プログラマーが「リーダブルコード」を読んでみた(前編)

お久しぶりです。
いきなりですが、僕は、大学時代にかなりわがままなコードを書いていました。
そんなわがままコードを矯正するために、名著「リーダブルコード」を読んだので、
その感想を書いていきます。

この本の副題は「より良いコードを書くためのシンプルで実践的なテクニック」です。
それでは、早速そのテクニックを見てみましょう!

注)
この記事は、ひたすら読書感想文が続きます。
それでも許せますよ!という人だけ読んでいただければ幸いです。

1. 理解しやすいコード

<重要ポイント>

  • コードは、他の人が見て最短時間で理解できるように書かなくてはならない。
  • 「このコードは理解しやすいだろうか?」と自問自答してから、次のコードを書く。

僕のような新人プログラマーは、コードを書くのが非常に遅いです。
なので「早く終わらさなきゃ!」という気持ちになることが多いです。
しかしそのコードは他の人が見るものなので、理解しにくいコードは他の人の時間を奪います。
もちろん、バグの温床にもなります。
他の人が最短で理解できるコードを、常に意識したいですね。

2. 名前に情報を詰め込む

<重要ポイント>

  • 目的を明快に表す単語を用いて、変数や関数の命名をする。
  • 汎用的であることに意味がある場合以外は、汎用的な命名を避ける。
  • 名前に単位などの情報を付与することで、誤解を生まない分かりやすい命名となる。

この章の内容は、意識することはできれど実践は難しいと感じました。
しかし、できるようにならなくてはいけません。
英単語の語彙を増やせるよう努力します。
オープンソースのプロジェクトを読み、
どのような命名をしているのか勉強するのも良さそうですね!

3. 誤解されない名前

<重要ポイント>

  • 名前を決定する前に、その名前を「このように誤解されないだろうか」と想像する。
  • ある単語に、「ユーザーがどのような期待を持っているか」
  • を考える。

この章は、前章で取り上げられた命名法の、さらに踏み込んだ内容を説明していました。こちらについても、常に他の命名がないかと意識することで、次第に上達していくのかなぁという感想です。

4. 美しさ

<重要ポイント>

  • 複数のコードブロックで同じような処理のとき、コードのシルエットも同じようにする。
  • コードの「列」を揃えることで、コードの概要が理解しやすくなる。
  • ある場所で決めた処理や順序は、他の場所でも同じ順序にする。
  • 空行を駆使し、論理的な段落を作る。
  • 「一貫性」のあるスタイルは、「正しい」スタイルよりも大切。

コードの美しさは非常に重要です。
見にくいコードって誰も触りたくないですよね。
そんなコードを生まないためのテクニックが、この章には詰まっていました。
中でも「一貫性」>「正しい」というのは、意識したことがなかったので、今後注意したいです。

5. コメントすべきことを知る

<重要ポイント>

  • コードからすぐに分かることはコメントに書かない。
  • コメントには、考えの過程や意見など、自分の思考を記述する。
  • 全体像を要約するようなコメントはグッド!
  • 優れたコード > 酷いコード + 優れたコメント

この章は、コードへのコメントについてです。
ここは、非常に耳が痛い章でした。
というのも、私自身、コメントマシーンのようになっていたからです。
思えば、大量のコメントは、自分のコードに自信がないということの表れだったように思います。
今後は「シンプルなコード」+「補足コメント」を意識しようと思います。

6. コメントは正確で簡潔に

<重要ポイント>

  • 曖昧な代名詞の使用を避ける。
  • 関数の正確な動作を書くべきなのか、関数の意図を書くべきなのか考える。
  • 情報密度の高い言葉を選択する。

前章に引き続き、コメントに関する章です。
こちらでは、具体的にどのようなコメントを書くのかというテクニックを紹介していました。
命名法と同じく、常に意識することや、他のコードをよく読むことが大事だと思います。

7. 制御フローを読みやすくする

<重要ポイント>

  • if/else 文では、条件文は肯定形を先に書き、否定形を後に書くようにする。
  • 肯定形が複雑になってしまう場合は、上述の限りでない。
  • 比較の条件を使うときは、変動するものを先に、安定したものを後に書く。
  • 三項演算子は、どうしても使わなければいけないというとき以外は使わない。
  • 条件のネストは、早めに値を返すなどしてできるだけ浅くする。

制御フローをどのように見やすくするかというテクニックが詰まった章です。
大学時代は、比較的複雑なフローを書く機会が多かったので、意識できている内容が多かったです。
もちろん、意識していないこともあったので、それは自分のものにしなくてはならないです。

8. 巨大な式を分割する

<重要ポイント>

  • 「説明変数」を用いて、複雑な式を簡略化する。
  • 複雑なロジックは、ド・モルガンの法則を使ってより簡潔にする。
  • 短く理解しにくいコードよりも、少し長くて明快なコードを書く。

この章では、
① exp->foo->bar
のようなメソッドに次ぐメソッドや、
② (A && !B) || (!A && C)
のような複雑なロジックをどのように簡潔に書くのかという章です。

ちなみに、①は説明変数を用いて簡略化できます。
②は ド・モルガンの法則を使うと、!A || B || A || !C となり、
A または NOT A となります。つまり、いつでも通るみたいな条件文になります。
これらのテクニックは覚えておく必要がありますが、問題は使いどころです。
その判断の目を養わなくてはならないと感じました。

まとめ

今回は、以上です。
各章で、シチュエーションごとのテクニックを紹介していましたが、
共通して伝えていることは、「そのコード大丈夫?もっと見やすくできないの?」
ということです。
この言葉を、常に意識してコードを書かなきゃですね。
残りの章については、また後日記事にしようと思います。

PHPUnitでDeprecatedエラーに止められない方法

テストを書いている中でDeprecatedエラーに阻まれるシーンがあったので、備忘録として記します。

PHPUnit\Framework\Error 内にあるDeprecated.phpを開くとファイル下部に
「 You can disable deprecated-to-exception conversion by setting 」とあるので何か設定を行うと無効にできるようです。

 * <code>
 * PHPUnit_Framework_Error_Deprecated::$enabled = FALSE;
 * </code>

この<code></code>に囲まれた部分を該当するテストに張り付けるだけです。
再度実行するとDeprecatedは表示されますが、処理はそれを無視して続けることができます。

他にも PHPUnit\Framework\Error 内にはNoticeやWarningについての設定方法もあるので同じように設定することが可能です。ですが、根本的な解決方法でないので注意が必要です。

エンジニアのための時間管理術を読んでみました

業務効率改善のために「エンジニアのための時間管理術」を読みました。
感想などを書いていきたいと思います。

呼んでみようと思った理由
タスク管理ツールなどを使ってなんとなくでやっていた時間管理を
一度体系的に学んでベターな時間管理をしたいと考えたから。

感想
タイムマネジメントって難しいと改めて感じた。
今抱えているものだけでなく
急に厳しい期限で新しいタスクが入ってくることがあるというのは
タイムマネジメントを難しくする要因の中で上位だと思う。
1ヶ月先までの期限の仕事を後回しにしていて、
別の優先度が高い作業を始めて急に最優先でやらなければ仕事が入ってきて
後回しにしていた作業もあって地獄を見るなんてのは…考えたくないです。

本書で例えばプログラムを書いている場合に
メールが来ること、
突然話しかけられること、
チャットが来ることなどを
じゃまが入るというどストレートな表現してたのは面白かった。

作業を完了するには中断なしで丸1日、
実際には1ヶ月という言葉も面白かった。
他の人の仕事も実際こんな感じなんだろうと思う。
自分から見て他の人の作業が「その作業もっと早く終わるはずなのに」
というものがあってもその人なりの事情があるのだと感じた。
その事情を把握して自分にできることがあれば手助けしたいし、
逆に自分も事情を説明してどうすれば早くなるかを相談したい。
またじゃまにならないような割り込ませ方も考えたい。
新しい仕事を振る時はこの時間の時にするとか。

実はプログラマ向けの本ではないとばっさり書かれているが、
自分でも当てはまったし、読んだ感じ社会人向けの本として有用だと思う。
完全なプログラマ向けのやつがあるなら読んでみたいと思った。

自分みたいにあまりちゃんと時間管理をやってなかった人が
本書に載っていることを全部やってみるのは困難だと思う。
無理のない範囲で取り入れていきたい。

以下章ごとのまとめ、プチ感想など

1章 タイムマネジメントの原則
原則として以下の6つがある。

  1. タイムマネジメント情報を1つの「データベース」にまとめる
    タスク管理ツールなどを色々使わない。一つにする。
  2. 能力は重要な作業のために温存しておく
    プロジェクトAを行っている場合はそれ以外のことは考えない、忘れる。
    プロジェクトBのことが気がかりな場合、その気がかりをメモしておいて脳では忘れる。
    やっている作業のこと以外は考えない
  3. 日課を定め,それらに従う
  4. 習慣やモットーを養う
  5. 「プロジェクトタイム」の間は集中力を保つ
  6. 日常生活の管理にも,仕事で使用するのと同じツールを使用する
    日常で練習して仕事に活かすのもあり

2章 集中と割り込み
集中しやすい環境を作る。
メーラーは基本的に閉じて2〜3時間おきにみる。
迷ったら捨てる、閉じる。
自分の場合は開きっぱなしが多すぎる。
自分の集中力のピーク時を認識し、その時間に最重要タスクをこなす。
基本はマルチタスクが当たり前だが、
ストレスが溜まっている時、睡眠不足の時は避ける
割り込みされた時は委任することも大事
委任できなかったら諦めて頑張りましょう。

3章 ルーチン
出来るだけ余計なことを考えないようにルーチンは作れるなら作るべき
考えることは重要な仕事に回す。
ただ定期的にルーチンの見直しはやったほうがいいと思う。

4〜7章 サイクルシステム
自分の記憶力を信用しない
サイクルシステムを作成する。

  1. 365日分の作業リスト(作業日誌)
  2. 今日のスケジュール
  3. 約束のカレンダー
  4. メモ(人生目標などを記載)

そして,毎日を以下のサイクルで繰り返す.
・今日のスケジュールを作成する
・今日の作業リストを作成する
・優先順位を付け,スケジュールを調整する
・予定に取り組む
・1日の終わり
・会社を出る
・繰り返す

結構大変そうなので最初は緩く始めてもいいかも

目標を立てないと
「単純に作業をうまく進められるようになるだけ」
になってしまう。
・”何を” 実現したいのか
・”いつ” それを実現したいのか

以下の期間で立てる
・短期(1ヶ月)
・中期(1年)
・長期(5年)

こういうのが苦手なのはなんとかしたい、特に長期。

8章 優先順位
自分で優先順位を決める。
ただ上司が考える優先順位とは異なっているかもしれないのでその辺りは確認する。
自分は今、Aという仕事とBという仕事があって~な理由でAを優先して行うつもりですけどよろしいですか等

9章 ストレスの管理
自分に合ったストレスの管理方法、発散方法を見つける。
自分は体の健康が心の健康につながると思うので運動を継続的に行う。
自分の場合はマッサージはその時は楽になるけど応急処置感があってすぐに戻ってしまう。

10章 電子メールの管理
不必要なメールはどんどん消す。
検索があるとはいえ多いことにいいことはない
メーラーはこの時間に開くなどを決めておく
メールが来たらすぐ返さないといけないことがある場合は難しいけども…
社内チャットツールなども緊急の場合は口頭で伝えてもらうようにお願いして2、3時間おきに見るとかでいいと思う。

11章 時間の浪費
水漏れをしている床を毎回吹くのではなく水漏れしている原因に対処するというのはいい例えだと思った。
根本を解決することに時間を費やす。

仕事上に対しての時間の浪費を減らすのはもちろんだが、
日常生活についても書かれていた。
レンタルビデオ店に行かずNetflixで見ると移動時間が減るなど。
別にそこまで気にしすぎなくてもいいのではと感じたが。
レンタルビデオ店は今では自分も行かないが
書店は実際に足を運びたくなったりするし、
結局 amazonの方が安かったりしてamazonで買うこともある。
ゲームとかもそう。

12章 文書化
文書化はすべきだと思う。
ただし、細かすぎる文書化をすればいいわけではないので注意する。
アップデートが頻繁なサービスの文書化などはしょっちゅう見た目が変わったりするので

13章 自動化
この辺はすべき。
事務的な作業でもpythonとか使って効率化できるとこはしていけるといいなあと思う。

Scala リストに要素を追加する &その時の注意事項

ScalaのSeq型の一つである、List型の宣言は下記のようにします。

var ages = List(42, 61, 29, 64)

リストの末尾に要素を追加する場合には、次のようにします。

ages :+ 10

で、この時の注意なんですが、いかにも ages ってリストに 10 という要素が足されたようになってますが、そうではありません。

object Main extends App {
  var ages = List(42, 61, 29, 64)
  println(s"The oldest person is ${ages.max}")

  ages :+ 10
  println(s"The youngest person is ${ages.min}")

}

上記の出力は次のようになります。

The oldest person is 64
The youngest person is 29

ほげえええ

ages :+ 10 とやったときに、なんと新しいSeqが生まれていて、そこに追加されているのです。元のagesに追加されているわけではないのです。

下記のように変更してみます。

object Main extends App {
  var ages = List(42, 61, 29, 64)
  println(s"The oldest person is ${ages.max}")

  var new_ages = ages :+ 10
  println(s"The youngest person is ${new_ages.min}")

}

出力は次のようになります。

The oldest person is 64
The youngest person is 10

あー、よかった、できたできた。(๑>◡<๑)

Scala IntelliJ sbtでビルドするプロジェクトをインポートする

前回、下記の投稿で新しくプロジェクトを作る場合に、sbtでビルドしたい場合のプロジェクトは作るときに気を付けないといけないよ、という話を書きましたが

既存のプロジェクトをIntelliJで動作させたい場合も気を付けるべきポイントがあるので、書いておきます。

環境は、Windows10 + IntelliJ コミュニティバージョン 2020.1 です。

最初の画面で、「Open or Import」をクリックします。

開いたダイアログでうっかりプロジェクトの入っているフォルダを選んでしまいそうですが、それはダメです。

上記のように、build.sbt ファイルを選んで、

OKをクリックしてください。

そうすると、sbtでビルドするプロジェクトだと認識してくれます。o(>▽<)o

これで、sbt tool windowも、sbt shellウィンドウも見れるようになりました!