先日、札幌Ruby会議2012のプログラムが決定しました。クリアコードからは以下の2件が採択されました。
他にも興味深い話がたくさん採択されています。札幌Ruby会議2012は9月14日-16日に開催されるので、興味のある人はそのあたりの予定を空けておくとよいでしょう。
それでは、秋に札幌で会えることを楽しみにしています。
これまで、ククログの記事には特にライセンスを設定していませんでした。そのため、ククログの記事をコピーしたり変更したり再配布したりするためにはクリアコードに許可を求める必要がありました*1。
しかし、それでは記事を再利用したりする敷居が高くなるため、Wikipediaと同じCC BY-SA 3.0*2とGFDL(バージョンなし、変更不可部分なし、表表紙テキストなし、裏表紙テキストなし)*3のデュアルライセンスにし、クリアコードに明示的に許可を求めなくてもライセンスの範囲内で自由に利用できるようにしました。これにより、ククログの記事を以下のように利用できます。
CC BY-SA 3.0の「原著作者のクレジット」およびGFDLの「著作者」の表記は以下のいずれかを使ってください。
Wikipediaと同様のライセンスとしたので、ククログ固有の不明点はそれほど多くないはずですが、不明点がある場合はお問い合わせフォームからご連絡ください。
クリアコードが開発に関わっているソフトウェアと同じように、ククログの記事も自由に利用できるようにしました。この記事と同様の内容はライセンスページにも用意しています。もし、ククログに有用な記事があったら、ぜひ自由に利用してください。
ただし、特定の記事でこのライセンスを適用できないことがある場合は、その記事内*4で「この記事のライセンスは○○です。」と明記します。ライセンスに関する記述には注意してください。
2012.6.7に logaling-command のEmacs用のフロントエンドプログラム logalimacs 1.0.0 をリリースしました。 Emacsのキーボードショートカットでlogaling-commandを利用できます。
logaling-commandは翻訳作業に欠かせない訳語の確認や選定をサポートする CUI ツールです。 対訳用語集を簡単に作成、編集、検索することができます。
登録したキーボードショートカットを押すことでカーソル位置にある単語を logaling-commandで検索(lookup)しツールチップやバッファに表示します。
以前はpopup.elの機能でツールチップで表示する機能を利用していましたが、 今回のバージョンアップでpopup.elのポップアップを多階層表示する機能を 利用するようにしました。 候補に注釈があった場合、C-fを押すことで注釈を表示できます。
下の画像の2段目の”猫科の動物”が注釈の部分です。
ポップアップ時のツールチップの幅を現在のバッファの幅の最大か 自動かを選択できるようにしました。 デフォルトでは自動になっています
logaling-commandの--dictionaryオプションに対応しました。 これはloga lookup時のオプションで edict や gene95 といった辞書をインポートして使用している場合など、 訳語からも検索できたり、設定している言語コードとは異なる対訳用語集からも検索をしたい場合に設定します。 --dictionary オプションを使用すると、原文だけではなく、訳文からも検索を行い、完全マッチしたものから順に結果出力します。 検索の優先度は、"原文の完全一致 > 原文の部分一致 > 訳文の完全一致 > 訳文の部分一致"となっています。 利用方法としては.emacsなどの設定ファイルにloga-use-dictionary-option変数をtに設定するとlookup時の検索結果が--dictionaryオプションを利用した物になります。 (インストール方法の項で具体的な設定方法を書いています。)
バッファ表示と、ポップアップ表示する時にviスタイルの移動方法の"j"、"k"で候補を上下に移動できるようになりました。 "p"、"n"で移動する方法も残っています。
詳しいlogaling-commandの設定やインストールの説明はlogalimacsの チュートリアルページ で紹介しています。
logaling-commandは既にインストール済みでEmacsにlogalimacsを入れる方用に簡単に導入方法を説明します。 ※既にlogalimacsを利用している場合はgit pullでlogalimacsを最新版にして 以下の設定の"お好みで設定してください"の部分をお好みで追加してください
GitHubからclone
$ cd ~/.emacs.d/ $ git clone https://github.com/logaling/logalimacs.git
logalimacsに関する設定を~/.emacs.d/init.elに以下を追加します。
;;; logalimacsディレクトリへのロードパスを通す ;; ~/.emacs.d/package/logalimacs/logalimacs.elが存在する場合 (add-to-list 'load-path "~/.emacs.d/package/logalimacs") ;;; keybinds (global-set-key (kbd "C-:") 'loga-lookup-in-popup) ;;; お好みで設定してください ;; lookupに--dictionaryオプションを利用する場合 (setq loga-use-dictionary-option t) ;; :autoがデフォルトでカーソル位置の近くにポップアップ ;; :maxにするとbuffer一杯までpopupをのばし行の最初から表示します (setq loga-popup-output-type :max)
注: 記事中の「解説」の部分のライセンスは「Creative Commons 表示 - 非営利 - 継承」です。「解説」は「クリアコード」(「ClearCode Inc.」)によって変更されています。変更前の原著作者は「オライリー・ジャパン」です。「Creative Commons 表示 - 非営利 - 継承」なので再配布や変更や翻訳などはライセンスに従って自由に行えますが、営利目的で利用することはできません。
The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (Theory in Practice)(Dustin Boswell/Trevor Foucher)の翻訳である「リーダブルコード」が今月(2012年6月23日)発売されます。すでに予約できるようです。
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
オライリージャパン
¥ 2,592
本書の内容は原書の紹介記事を参照してください。
日本語版の訳者は角さんです。これまでの訳書と同様にとても読みやすく訳されています。翻訳なので読みにくいのでは…と心配する必要はありません。良いコードを書きたい人なら読んでみるべきです。
日本語版にはクリアコードの須藤が書いた「解説」が付いています。これは原書にはない内容で、日本語版のために新規に書かれた文章です。「解説」をできるだけ自由に利用できるように、編集の方*1にお願いして「解説」のライセンスは「Creative Commons 表示 - 非営利 - 継承」にしてもらいました。そのため、ククログに少し変更したバージョンを紹介できることになりました。ありがとうございます。
「リーダブルコード」の「解説」の少し変更したところとライセンスについて少し解説します。
以下の「リーダブルコード」の「解説」は書籍に載っているバージョンから以下のように変更されています。
これは、先日、訳者の角さんと話したときに次のような話を聞いたためです*2。
タイトルは「読みやすいコード」ではなく、あえて「リーダブルコード」にした。これは「リーダブルコード」という聞きなれない言葉にすることで、読んだ人に「リーダブルコード」というものについて注意して欲しいからだ。今のプログラマーは普通に「リファクタリング」という言葉を使っていて、「コードをよくすること」がより当たり前になっている。それと同じように、読みやすくないコードを見たら「それリーダブルじゃないよね」とか読みやすいコードを見たら「これリーダブルコードでいいね!」というようなことが自然に言われるようになって、「読みやすいコード」がより当たり前になるといい。
これは応援したくなる話だったので、「解説」の中の「読みやすい」・「読みやすいコード」と書かれている部分は「リーダブル」・「リーダブルコード」としてあります。変更前のものは日本語版を参照してください。
このように、以下の「解説」は日本語版の「解説」を変更して再配布したものになります。元の「解説」のライセンスは「Creative Commons 表示 - 非営利 - 継承」で原著作者は「オライリー・ジャパン」です。そのため、この変更された「解説」のライセンスも「Creative Commons 表示 - 非営利 - 継承」になります。変更された「解説」の原著作者は「クリアコード」(「ClearCode Inc.」)です。
それでは、「リーダブルコード」の「解説」です。9ページ分なのでそこそこ長いです。
須藤 功平
読んでみていかがだっただろうか。プログラマにとってとても大切な「リーダブルコード」を書くということを「理解しやすく」伝えていたはずだ。
本書は元の英語も読みやすく書かれている。少し英語を読める人なら原書でも読めるだろう。そんな原書のいいところをしっかりと残して読みやすい日本語にしたのが訳者の角さんだ。角さんは本書以外にもソフトウェア関連の訳書が数冊あり、どれも読みやすい日本語になっている。角さんの訳の特徴は、読みやすい日本語と時折はさんでくる(わかる人にはわかるくらいのちょっと)有名な言葉だ。本書を読んでニヤリとした人もいたのではないだろうか。やわらかい言い回しでまじめな話をしながら時折ユーモアあふれる挿絵をはさむ本書の訳者として、角さんはまさにうってつけの存在だ。
読みやすい日本語だし、技術的に難しい内容でもないので、サクサク読めただろう。でも、難しくない内容だからといって軽視していいわけじゃない。本書に書いてあることはとても大切なことだ。あなたがこれからプログラマとして信頼してもらえるコードを書くかどうかは本書に書いてあることを身につけるかどうかにかかっていると言ってもいい。もし身につけていないなら、少なくとも私は信頼しない。
そんな本書の内容を身につけて、自然にリーダブルコードを書けるようになるための3つのステップを紹介しよう。
まず、実際にリーダブルコードを書く。はじめはうまくいかないだろうが、本書を読み返しながら意識してリーダブルコードを書く。リーダブルコードを書けるようになってきたら、「リーダブルコードを書くことが当たり前」にする。リーダブルじゃないコードなんてありえない。そんな状況だ。そんな状況でリーダブルじゃないコードが入ってきたら、どうしたらリーダブルになるかをリーダブルコードで伝える。「リーダブルコードとはこう書くんだよ。」そういうことをリーダブルコードで伝えるんだ。ここまでくれば、自然にリーダブルコードを書けるようになっているだろう。
さぁ、それぞれのステップの具体的なやり方を紹介しよう。
まず 1 つめのステップは、実際にやるということだ。
当たり前だけどこれはとても大事なことだ。(本書の内容も当たり前だけどとても大事なことだったね。)本書の内容を実践して、これから書くコードはリーダブルコードにしよう。実際にやるとはじめて気づくことがたくさんある。
まず、内容を活かす場所がぜんぜんないって思うだろう。でも、それはあなたの書いたコードがすでにリーダブルだからじゃない。単に「気づかない」からだ。本書を読んでいるときは次々と出てくる小さなコードを読みながら「たしかにここはそう変えた方がいいな。ふむふむ。」なんて読んでいただろう。読みながらあなたが「ふむふむ」言っていられたのは著者がわかりやすく書いてくれていたからだ。でも、実際のコードにはそういうヒントはない。著者のヒントがないんだから、実際のコードを読んでいるときは見逃してしまうだろう。それが自分が書いている真っ最中のコードならなおさらだ。読む側の視点じゃなくて書く側の視点でコードを見ているんだから。
ウソだと思うなら新しくリーダブルコードを書いて私にコードを見せてみるといい*3。リーダブルコードになっているかどうか、よっぽど気にして書かないと何かしらツッコミが入るだろう。もちろん、イジワルするつもりじゃないから、リーダブルコードだったらちゃんと「すばらしい!」とコメントするつもりだ。
今、さらっと私に見せてみるといいなんて書いたけど、自分が書いたコードを人に読んでもらうということは、リーダブルコードを書くためのとてもいい機会になる。本書の中で、「他の人がこのコードを読んでどう思うか」ということを何度も気にしていたのを覚えているだろうか。
だから、読む人は私じゃなくたっていい。仲間と一緒にコードを書いているなら、仲間に見てもらうのがいいだろう。でも、そのときは「気になるところがあったら遠慮せずに言ってくれ!」と念を押すことを忘れずに。同じコードを触っている仲間なら多少理解しづらいコードがあってもなんとなくわかってしまう。そうすると、本当はリーダブルじゃないコードなのに気づいてもらえないかもしれない。
できれば、仲間にも本書を読んでもらって、どうすればリーダブルコードになるかを共有しておくのがいい。仲間と一緒に実践できるとなおいい。仲間と一緒に始めれば、「今のコードはリーダブルだね!」といった話や「今のコードをこう変えればもっとリーダブルになると思うんだけどどうだろう?」といった話ができる。そうなったらより楽しみながら「リーダブルコード」を書けるようになる。まわりにいるすごいプログラマにも意見を聞いてみるといいだろう。「このコードで○○をリーダブルにできなかったんですが、なにかいいアイディアがあったら教えてもらえませんか?」
あなたがリーダブルコードを書こうとしていることがみんなに伝われば、「ここ、もう少しリーダブルにならないかな?」といったフィードバックが増えるだろう。そうすると、あなたの書くコードはどんどんリーダブルになっていくはずだ。(ただし、あなたが素直にフィードバックを聞ければ、だ。自分がリーダブルだと思って書いたコードをリーダブルじゃないと言われるのはつらいことだけど、別にあなたを攻撃しようとしているわけじゃないので落ち着いて素直に聞いてみよう。)
自然にリーダブルコードを書けるようになるための1つめのステップは、実際にやるということだ。はじめはどこをよくすればいいかを見つけることが難しい。本書を読み返したり、仲間にコードを読んでもらったりしながら自分で「気付ける」ようになって欲しい。リーダブルじゃないことに気付いたら、リーダブルにする方法は本書に書いてある。ここはそんなに難しい話じゃないはずだ。自分で自分のコードのリーダブルじゃないところに「気付ける」ようになれば、リーダブルコードも書けるようになっているだろう。そうなったら次のステップへの準備はできている。さぁ、次のステップへ進もう!
次のステップは当たり前にするということだ。
1つめのステップであなたが新しく書くコードはリーダブルになっている。そうすると、既存のコードのリーダブルじゃないところがちらほら目につくようになる。目の前のそれらのコードをリーダブルにしようと意気込んでいることだろう。それはとてもすばらしいことだ!だが注意して欲しいことがある。それは、一時の頑張りだけではリーダブルコードにはならないということだ。もし、それを忘れてしまうとせっかくの意気込みが消えてしまう。それはとてももったいないことだ。
あなたが既存のコードを直し始めたとしよう。でも、仲間たちはその間も新しいコードを書いている。それらのコードはリーダブルコードではないかもしれない。自分だけがリーダブルコードを書いているという状況はとてもつらい。他の人がコードを書くたびにリーダブルじゃないコードが入ってくる。掃除しているそばからゴミを捨てられているような感覚だ。まずは新しく書くコードがリーダブルコードだけになるようにしよう。既存のコードを直すことはそれまでガマンして欲しい。
具体的には、これからあなたが触るコードはリーダブルコードにしていく。まず、新しく書くコードはリーダブルコードで書こう。これはもうできているはずだ。でも、できているからといって油断してはいけない。まだ意識しないとリーダブルコードを書けない状態だから、気を抜くとリーダブルじゃないコードを書いてしまう。気を付けて。
さらに、他の人が新しく書いたコードについても同じくリーダブルコードにしていく。リーダブルじゃないコードだったらその人と相談してリーダブルコードにしよう。既存のコードはそのコードを変更するときにリーダブルコードにしていこう。やり方はわかるはずだ。理解するまでに時間がかかる書き方だったらどうする?名前が曖昧だったらどうする?ピンとこなかったら本書をもう一度読み直してみよう。本書で丁寧に説明している。
これを続けてリーダブルコードを書くことを当たり前なことにしよう。誰かがリーダブルじゃないコードを書いたら、「ここ、少しリーダブルじゃないよね?」と指摘する人がいるのが自然な状態だ。そうなれば習慣になったといえる。ここまできたら既存のコードをリーダブルにするやり方を考え始めてもいいだろう。(ただし、1年かけてリーダブルにするというようなやり方がでてきたら危険な合図だ。そのやり方をもっと小さく分割したりできないか考えてみるべきだ。ただ、この話題は本書の範囲を超えるのでまたの機会に。)
本書で説明しているリーダブルコードを書くための方法は小さな基本的なことばかりだ。ソフトウェア全体をキレイにまとめるパターンなんかではない。1つの方法ではコードが少しキレイになるだけだ。しかし、これらの方法をコード全体に適用していけばコード全体がキレイなリーダブルコードになる。一時的にコードをリーダブルにしようというスタイルではなく、継続してコードをリーダブルにしようというスタイルでコードを書いて欲しい。
明日、あなたが読むコードは今日まであなた(と仲間たち)が書いたコードだ。明日、見たくないコードを見なくてもすむようにするには、今日、リーダブルコードを書くことだ。
リーダブルコードを書くということはたまに思い出してやることではない。習慣にして常に実践することなんだ。それを忘れないで欲しい。それが実践できれば明日もずっとその先も楽しくコードを書けるはずだ。
リーダブルコードが当たり前の世界へようこそ。さぁ、次のステップへ進もう!
最後のステップはコードで伝えるということだ。
リーダブルコードが当たり前になったら、その先なんてないと思うかもしれない。だって、みんながリーダブルコードを書いているんだから。これ以上なにを求めると言うんだ。
でも、あなたには仲間が増える。それは若い子だったり新人だったりするかもしれない。新しい仲間は本書を読む前のあなたと同じだ。最後のステップでは新しい仲間を手伝って、新しい仲間もリーダブルコードを書くことが当たり前になれるようにする。ちょうど本書の著者があなたにやってくれたように。
本書はたくさんの人に伝えられるように一般的な例を使って書かれている。それでもわかりやすく書かれているが、実際に自分たちが触るコードを使って説明した方がより実感がわくし、納得もしやすい。新しい仲間にどうすればリーダブルコードになるかを伝えるために自分たちが書いているソフトウェアを使おう。自分たちのソフトウェアをリーダブルコードで書くことで、どうすればリーダブルコードになるかを伝えるんだ。
ソフトウェアはコードの変更の積み重ねで作られている。それを管理するためのソフトウェアが Git や Subversion などのバージョン管理システムだ。もちろんあなたも使っているはずだ。まだ使っていないなら急いで使えるようになろう!リーダブルコードを書こうと試行錯誤するときにとても役立つ。仲間とコードを共有することにも便利だ。
よし、バージョン管理システムは用意できたね。それでは、コミットメールも用意しよう。コミットメールとはバージョン管理システムに変更を追加(コミット)したときに送られる通知メールのことだ。コミットした人は誰か、どんな変更だったかの説明なんかが書かれている。これを読めばどんな変更が入ったか、雰囲気がわかる。具体的な変更点(diff)は入ったり入らなかったりする。私はdiffも入れることを強くオススメする。diffもあるとどのようにコードが変更されたかまですぐに確認できる。diffを入れないとgit log -pやsvn diff、Webブラウザでリポジトリブラウザを開くなどの追加のひと手間が必要になる。コードを読むための敷居はできるだけ低くする。これはとても大事なことだ。コードを読むことが面倒になると、「どうせ誰も読まないって!」となってしまう。これでは「どうしてリーダブルコードを書かなきゃいけないの?」に逆戻りだ。
diff入りのコミットメールは仲間みんなに届くようにしよう。はじめは誰もあなたのdiffを読んでくれないかもしれない。ここであきらめちゃダメだ。まずはあなたが仲間のdiffを読もう。diffを読んで、リーダブルじゃないコードがあったら教えてあげよう。diffにはコード全体ではなく変更箇所の周辺しか含まれていない。「diffだけ読んでリーダブルかわかるわけないじゃん!」と思うだろう。でも、diffだけ読んでもリーダブルなコードにしないといけないんだ。もちろん、diffだけでその周辺のロジックまで正しいかどうかはわからないことの方が多いだろう。それでもdiffだけでリーダブルなコードを書いているかどうかはわかるんだ。
本書の内容を気にして書かれているコードはdiffになってもリーダブルだ。小さなdiffの中だけでtmpという変数名を使っているならそれは本当に一時的な変数なんだろう。このようなコードは適切な名前がついていてリーダブルだ。でも、大きなdiffの中でtmpという変数名を使っているなら要注意だ。単にいい名前をつけなかっただけかもしれない。思い出して欲しい。本書の中でたくさんのサンプルコードが出てきた。それらのほとんどは10行未満のコードだった。でも、そのコードを読んで、リーダブルコードとそうじゃないコードがどう違うかが伝わったはずだ。だったらdiffを読んだってわかるはずだ。
まずはあなたがdiffを読んで仲間にフィードバックしよう。「こうすればもっとリーダブルになるんじゃないかな?」それを続けていれば仲間もあなたのdiffを読んでくれるようになるはずだ。あなたがコミットするときはリーダブルなdiffになるようにコミットしよう。仲間のdiffを読んでいたあなたはどういうdiffがリーダブルかはわかっているはずだ。
わかりやすい目安はこうだ。1つのdiffに1つのことを。もし、あなたが本書中のコードをリーダブルにする方法でコードを変更したときは、1つの方法ごとにコミットすること。「2.1 明確な単語を選ぶ」と「4.4 縦の線をまっすぐにする」を一緒にコミットしてはいけない。「2.1 明確な単語を選ぶ」で1回、「4.4 縦の線をまっすぐにする」でもう1回コミットするんだ。そう、「11章 一度に1つのことを」だ。
他の人がリーダブルじゃないコードをコミットしたら、「こうすればもっとリーダブルになるんじゃないか」というコードをコミットしよう。そして、「今コミットしたように変更するともっとリーダブルになると思うんだけどどうかな?」と声をかけてみよう。ただし、他の人のコードに手を入れるというのが「当たり前」の文化でない環境の場合はいきなりやると角が立つかもしれない。(バージョン管理システムを使っているならコードを共有する文化は根付いていると思うけど!)その場合は、まずは「このあたりのコードを整理していい?」と事前に確認してからやるのもいいだろう。
これは私が「添削コミット」と呼んでいるものだ。「添削」だと上から目線のイメージがあるので「提案コミット」と呼ぶほうがいいかもしれない。
どうして最後のステップで「添削コミット」をオススメしているのか。それは、添削コミットではまさに「リーダブルコード」になっていなければいけないからだ。「添削コミット」はコードで自分が意図していることを伝えるということだ。伝えるためには他の人が理解しやすいコードでなければいけない。これはまさに本書で言っていることだ。
本書はリーダブルコードの書き方をわかりやすく伝えている。どうしてわかりやすいのか。それは、「どうしてこの書き方がいいのか」という「理由」だけでなく、そのための「具体的な書き方」という「方法」も一緒に伝えているからだ。たとえ「理由」だけがわかってもそれを実現するための「方法」がわからなければ実践できない。例えば、「関数を理解しやすくなるのでいい名前をつけましょう」だけでは実践できない。「いい名前」だけでは抽象的すぎて人それぞれの「いい名前」になってしまう。
添削コミットではリーダブルコードにするための「具体的な書き方」がコミットの内容そのものになる。コミットメッセージにはどうしてこの書き方の方がリーダブルなのかの「理由」を書く。こうすることで本書でやっているような伝え方を実現できる。修正しているので実際にコードがよくなるし、具体的な実例をつけてよりリーダブルなコードを伝えることができるので、ぜひやってみて欲しい。
もちろん、添削コミットをする前にその人にも本書を読んでおいてもらうといいだろう。リーダブルコードについて、より伝わりやすくなるはずだ。
自然にリーダブルコードを書けるようになるための最後のステップは、コードで伝えるというだ。これまでのステップではあなたがリーダブルコードを書けるようになることを重視していた。最後のステップではあなたがリーダブルコードを伝えられるようになることを重視する。あなたの意図をコードで伝えられるなら、それは本当にリーダブルコードになっているということだ。
あなたがリーダブルコードを伝えるためには、自分たちが書いているソフトウェアで伝えるのが一番わかりやすい。一般的な例題で伝えるよりもピンとくる。自分たちのソフトウェアを材料にするために、みんながより自然にコードを読む環境を作る。その方法としてdiffを共有する。diffをただ流すだけにしてはいけない。まずあなたがdiffを読んでそこからリーダブルじゃないところを見つける。そして、その改善案をコードで伝える。リーダブルコードで伝える。具体的な改善案とリーダブルになる理由でリーダブルコードを伝えるという方法は本書で著者たちが使っていた方法だ。今度はあなたがリーダブルコードを伝える番だ。
解説として、本書の内容を身につけて自然にリーダブルコードを書けるようになるための3つのステップを紹介した。3つめのステップまでいけば「リーダブルコードを書かないなんてありえない!」となる。そうなったら著者が本書の最初で書いていたようなことが現実になる。
君はきっと優秀なプログラマになれるはずだ。自分の仕事に誇りを持ち、周囲のみんなが喜んで使ってくれるような、バグの少ないコードを作り出せるようになる。
私はリーダブルじゃないコードを書く人とは一緒にコードを書きたくない。私がリーダブルじゃないコードを触るときは、まず、見た目を直してリーダブルにする。そう、本書の「第I部 表面上の改善」に相当することだ。本書を読んで「わかってるな!」と思ったところは、まず「第I部 表面上の改善」を持ってきているところだった。
あなたも本書の内容を活用して、リーダブルコードを書くプログラマとなってくれることを期待している。
リーダブルコードを書いて、自分が書いたコードを忘れてしまっても問題ないようにして欲しい。リーダブルコードを書こう。忘れてもいいコードを書こう。
「自分が書いたコードってどのくらい覚えているんですか?」
「ほとんど覚えていないですよ。」
「直すときどうするんですか?わからなくなってるじゃないですか。」
「忘れても見たら簡単にわかるように書いておくんですよ。」
須藤 功平(すとう こうへい)
フリーソフトウェアプログラマで、株式会社クリアコード代表取締役(2代目)。社名の命名者でもある。社名の由来は「キレイなコード」。その名の通りキレイなコードを書く会社であろうという意図を込めている。最近は自分がどうやってキレイなコードを書いているかを他の人にうまく伝えるにはどうしたらよいかに興味がある。他に興味があることは立派じゃない盆栽を種から育てること。訳者の角さんと初めて話したのは2005-08-27のLLDNが終わった後のロフトプラスワン前。訳者の角さんと編集の高さんも所属しているたいやき部の部長としても活躍中。
以上が「リーダブルコード」の「解説」です。リーダブルなコードに興味のある人は読んでみてください。
解説中にでてきた添削コミットの例を紹介しておきます。Cutterのコミット4ded23dに対応するのは1429aa1...dd6a37fのコミットです。見なおしてみると、「どうしてコミット後の方がよいのか」という理由は1回しか書いていませんね。
コミットにコメントするということに関連しますが、「クリアコードのプログラマーがあなたのコミットにコメントする」という新しいサービスを検討しています。まだ検討を始めたばかりで、実現しないかもしれないのですが、興味のある方はお問い合せフォームからご連絡ください。実現するしないに関わらず、検討後、その結果どうなったかをご連絡します。
2015年3月6日に実践リーダブルコードというセミナーを開催します。この解説で説明している「自然にリーダブルコードを書けるようになる」方法を身につけられるセミナーです。自然にリーダブルコードを書けるチームを目指している方はご利用ください。
*1 訳者まえがきの謝辞にある通り編集はオライリー・ジャパンの高さん。
*2 こんな内容だったというだけで一字一句同じではありません。多少誇張しているかもしれませんが、そのときは角さんが修正してくれるはずです。
*3 連絡先はkou@clear-code.com。もし、Rubyのコードなら、るびま編集部に送ってもいいだろう。コードを添削する企画があるのでそこでコードを読んでくれるはずだ。Rubyist Magazine - るびま magazine@jp.rubyist.net
2012.6.7に1.0.0をリリースしたばかりですがMermaladeからMELPAにリポジトリサイトを変更したのでお知らせします。
logaling-command のEmacs用のフロントエンドプログラム logalimacs 1.0.1 をリリースしました。 Emacsのキーボードショートカットでlogaling-commandを利用できます。
logaling-commandは翻訳作業に欠かせない訳語の確認や選定をサポートする CUI ツールです。 対訳用語集を簡単に作成、編集、検索することができます。
以前はMermaladeというリポジトリサイトを利用していましたが、 最近はメンテナンスされていないようでアップロードできませんでした。 そのため今回のアップデートで 他のEmacsリポジトリサイトのMELPAに変更しました。 ちなみにMELPAは最新のmasterを持ってきて日付をバージョン替わりにします。 なのでMELPAにしておけばEmacs-Lispのパッケージ職人の方は masterにpushするだけで最新のものをアップロードしたことになります *1。
'max
の様なシンボル記法も対応しましたpopup表示の時の幅を最大にするか自動にするかの設定変数ですが、:max
より'max
の表記のほうが見慣れている方もいるのでどちらでも設定できるようにしました。
M-x loga-lookup-in-buffer
コマンドでバッファに翻訳候補を表示して
画面移動できますが、入力した文字がミニバッファに表示されていました。
ミニバッファに出力しないように修正しました。
今回のリリースでMermaladeからMELPAにリポジトリサイトが変更になりました。 今まではEmacs23ユーザーの方には、GitHubからのcloneと.emacsなどへの設定で インストールして頂いていたのですが、 今までアナウンスしていなかったので、この機会にpackage.elを導入してlogalimacsをインストールする方法を紹介したいと思います。 (Emacs24は標準添付なのでpackage.elの導入の説明は、Emacs23のユーザー用です)
package.elを~/.emacs.d/package23/以下にダウンロードする例です 作成するディレクトリは適宜変更してください。
$ makedir -p ~/.emacs.d/package23 $ cd ~/.emacs.d/package23 $ wget http://repo.or.cz/w/emacs.git/blob_plain/1a0a666f941c99882093d7bd08ced15033bc3f0c:/lisp/emacs-lisp/package.el
上記を行うと~/.emacs.d/package23ディレクトリの下にpackage.elが作成されるはずです。
package.elはEmacs23用とEmacs24用で違うので Emacs24になった時には必要なくなるので条件分岐しています。
;;; Emacs24未満の場合だけEmacs23用のpackage.elを読み込む (when (version< emacs-version "24.0.0") (load "~/.emacs.d/package23/package")) ;;; リポジトリにMELPAを追加 (add-to-list 'package-archives ("melpa" . "http://melpa.milkbox.net/packages/")) ;;; package.elの設定 ;; インストールするディレクトリを指定(お好みで) (setq package-user-dir "インストールされるディレクトリ") ;; インストールしたパッケージにロードパスを通してロードする (package-initialize) ;;; logalimacsの設定 ;; keybinds (global-set-key (kbd "M-g M-i") 'loga-interactive-command) (global-set-key (kbd "M-g M-l") 'loga-lookup-at-manually) (global-set-key (kbd "M-g M-a") 'loga-add) (global-set-key (kbd "C-:") 'loga-lookup-in-popup) ;; 以下はお好みで設定してください ;; lookupに--dictionaryオプションを利用する場合 (setq loga-use-dictionary-option t) ;; :autoがデフォルトでカーソル位置の近くにpopup ;; :maxにするとbuffer一杯までpopupをのばし行の最初から表示します ;; Version: 1.0.1から'maxの様なシンボル記法も対応しました (setq loga-popup-output-type 'max)
詳しいlogaling-commandの設定やインストールの説明はlogalimacsの チュートリアルページ で紹介しています。
M-x list-packages
コマンドでインストールM-x list-packages
コマンドを実行すると
現在登録しているリポジトリサイトから候補を表示します。
C-s
でlogalimacsを検索してみてください。
"logalimacs 20120611 ~~~~"
のような行がみつかるので
この行にカーソルをあわせて"i"
を押してください。
行のはじめに"I"
というマークがつくので、
"x"
を押してインストールを実行してください。
これで
(setq package-user-dir "インストールされるディレクトリ")
で指定したディレクトリか~/.emacs.d/elpaの下にインストールされます。
もし既にlogalimacsをGitHub経由でインストールしていて、load
関数やrequire
関数で
読み込んでいた場合、正常にインストールされない場合があります。
この場合はそのload
関数や、require
関数を消してEmacsを再起動してから試してみてください。
無事インストールできれば、
C-:
でポップアップを表示できるはずです。
以上で本日リリースのlogalimacs 1.0.1の紹介を終わります。
2012/6/10にEmacs24.1も正式にリリースされましたので、
M-x list-packsges
を試すついでにlogalimacsもインストールしてみてはいかがでしょうか?
*1 MELPAの由来:Milkypostman's ELPA or Milkypostman's Experimental Lisp Package Repository
クリアコードは、例年、日本Ruby会議をスポンサーとして後援していましたが、札幌Ruby会議2012もPlatinumスポンサーとして後援します。
さて、Platinumスポンサーになると札幌Ruby会議2012本編の参加チケット(懇親会は含まない)を3枚もらえるのですが、それを3枚とも希望者に譲ります。(クリアコードから参加する人は全員発表者として参加するので、すでにチケットを持っており、スポンサー用のチケットを使う必要がない。)
応募方法などは日本Ruby会議2011でえにしテックさんが北海道の学生さん1名を招待したときの方法のように以下の通りとします。
株式会社クリアコードは、札幌Ruby会議2012の本編チケットを3名に提供します。(懇親会チケットや会場までの交通費や宿泊費などは各自で別途用意してください。)
応募多数の場合は厳正な選考を行い、当選者は@_clear_codeおよびククログにて発表いたします。
奮ってご応募ください。
わかりやすいコードを書くことはソフトウェア開発において大切なことです。では、具体的にわかりやすいコードとはどんなものでしょうか?その観点はいろいろなものがあります。その中で今回は名前のつけ方に着目します。
ソフトウェア開発において、名前をつける作業というのは絶えず発生します。メソッド名、変数名、クラス名、ファイル名などなど。名前をつける機会を挙げたらキリがありません。では、そもそもなぜ名前は必要なのでしょうか?
それはソフトウェアに限らず言えることですが、複数のモノを区別したいためです。例えば、まったく違う処理をする別々のメソッドに同じ名前をつけたらソフトウェアは正しく動きません。それを防ぐためにそれぞれのメソッドにちゃんと名前をつける必要があります。それぞれのモノにそれぞれ違う名前をつけて区別できなければソフトウェアはそもそも動きません。
名前をつける作業が必要な理由はもう一つあります。それは、わかりやすくするためです。区別できる名前でさえあれば、確かにソフトウェアは動きますが、それではいけません。名前が被らなければどんな名前をつけてもいいわけではありません。対象を的確に表しているわかりやすい名前をつける必要があります。
ソフトウェア開発において、名前をつける作業には次のようなものがあります。
これらの作業の中で名前がつけられる対象の種類はかなり違いますが、名前をつけるという点では共通しています。これらの作業では、大なり小なりのコードに名前をつけている作業に他なりません。名前をつける時、開発者は、ソフトウェアの特定部分のコードに対して名前をつけます。
これらの作業をまとめて「コードに名前をつける」という名前をつけることにします。今回の記事ではどのようにコードに名前をつけたら、コードがわかりやすくなるかについて説明します。
コードに名前をつける時、略した名前をつけるという慣習が存在しています。略した名前というのは、自然言語の言葉を短くした、そのソフトウェア内だけで使われている独自の名前のことです。例えば「manager
」から「mgr
」という名前に略すことです。ローカル変数に言葉の先頭1文字だけの名前をつけたりすることも当てはまります。
たしかにこの慣習は広く用いられていますが、コードをわかりにくくする悪い慣習です。極力避ける必要があります。
開発者は略した名前が含まれているコードを読む度に必ず頭の中で元の言葉に読み直しています。人の脳は生物的にそのような読み直しがとても不得意です。視覚情報の再処理は、人の脳にとって負荷が高いからです。
その負荷が高い処理を避けるために、シンタックスハイライトでコードに色をつけ、開発者がラクができるようにしています。他にも、普通のdiffではなくUnified Formatになっているdiffが広く採用されているのも、視覚的に縦に変更が揃えられていたほうがラクだからです。そのように開発者がラクをしている中で、名前をつける際にわざわざ略して人の脳に負荷を高めるのは合理的ではありません。
略した名前をつける時だけ発生する問題があります。さまざまな略し方があるなかで、どう略すか、どう略したかで悩んでしまう問題です。たとえばcontrol
の場合ctr
と略したり、ctrl
と略したりする場合があります。environment
はenv
と略したりenviron
と略したりする場合があります。
また、略した名前よりも略されていない元々の言葉の方が、キーボードで入力し慣れているので、効率よく入力できます。
名前を略したものにするということは、名前から推測できるはずの情報を意図的に削っているということです。これはコードを部分的に読むときにわかりにくくします。具体的にわかりにくい例をあげてみましょう。例えば次のコードを読んだときに、処理内容を読み取れるでしょうか?
悪い例:
1 |
convert(downloaded_archive.first_mtrl) |
ダウンロードされたアーカイブの中にある、最初のmtrl
を変換しているということまではわかりますが、mtrl
が何かがわかりません。読んだ時につまづいてしまい非常にモヤモヤします。しまいにはmtrl
が何を意味しているのかを考え始めてしまいコードを読むという本来の作業から脱線してしまいます。
mtrl
が何のことだかわからなくて、まだまだモヤモヤしていますか?答えは、material
です。
つまりは、上のコードがしているのは、「ダウンロードされたアーカイブの中にある、最初の資料を変換する」です。すっきりしたでしょう?このようにモヤモヤさせないようなコードはとても大切です。
以下のように略さず名前をつけるとわかりやすいコードになります。
良い例:
1 |
convert(downloaded_archive.first_material) |
ソフトウェア開発において、かつてのgoto
やグローバル変数が、今や悪しき文化となったように、略した名前も過去の遺物となるべきです。これからソフトウェアを開発をする際、その慣習に引きずられないように注意する必要があります。そもそも、コードはプログラミング言語と呼ばれる言語の一種です。自然言語が文章中で言葉を略さないように、名前を略さないほうが、むしろ自然であり、つけるべき名前であると言えます。
名前がつけられていない長いコードはわかりにくいです。
悪い例:
1 2 3 4 5 6 7 8 9 10 11 12 |
def hexdump(data) data.bytes.each_slice(16).collect do |bytes| bytes.each_slice(8).collect do |half| half.collect do |byte| "%02x" % byte end.join(" ") end.join(" ").ljust(3*16+1) + " " + bytes.collect do |byte| (0x20..0x7e).include?(byte) ? byte.chr : "." end.join end.join("\n") end |
実行例:
irb(main):013:0> puts(hexdump(Random.new.bytes(100))) d5 c4 e1 ad db 87 28 50 d6 17 1b 91 74 6b bb 7d ......(P....tk.} 7c a5 c9 48 1e f7 ed 4b 69 2c cc 6a e6 18 c8 f0 |..H...Ki,.j.... 04 ff 9d 47 19 29 57 5a 4e 11 35 5d ca 03 db a6 ...G.)WZN.5].... a8 c3 ff 40 1d 41 37 a5 f1 fb 72 59 b7 fd da b8 ...@.A7...rY.... 58 37 ba 66 5a 2c f7 75 0d fe 82 c6 4c 58 14 c4 X7.fZ,.u....LX.. 16 78 59 29 c8 11 2b 63 02 23 0c 73 e9 e2 bc bc .xY)..+c.#.s.... a5 62 84 1c .b.. = > nil
メソッドに的確に名前がついているおかげで、データを16進数形式でダンプすることはすぐにわかります。ですが、実装がどうなっているのかがわかりにくいです。例えば16進数とAscii文字の間に区切り文字として|
を入れたいことを想定してみましょう。悪い例だと名前がつけられていないために、やりたいことは小さい修正なはずなのに、どこをどう変更したらいいのかを知るために全てのコードを理解しなければなりません。
長いコードに名前がつけられていないということは、名前がつけられ抽象化されたより小さいコードに分かれていないということです。どこを変更したらいいのかがわかりにくくなっている理由は、「16進数の部分」を表現しているモノと「Ascii文字の部分」を表現しているモノに対応するコードに名前がつけられていないためです。それらのモノに対応するコードに名前をつけてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
def hexdump(data) data.bytes.each_slice(16).collect do |bytes| hex = dump_to_hex(bytes) ascii = dump_to_ascii(bytes) hex.ljust(3*16+1) + " " + ascii end.join("\n") end def dump_to_hex(bytes) bytes.each_slice(8).collect do |half| half.collect do |byte| "%02x" % byte end.join(" ") end.join(" ") end def dump_to_ascii(bytes) bytes.collect do |byte| (0x20..0x7e).include?(byte) ? byte.chr : "." end.join end |
これだけでもだいぶhexdump
はわかりやすくなったはずです。区切り文字を|
にするにはどこを変更すればいいのかすぐにわかります。
もう少しだけコードに名前をつけてみましょう。hexdump
はdata
と呼ばれるバイト列を受け取り、16進数形式のダンプに変換してその結果を返しています。変換する際には、受け取ったバイト列を小分けにして順番に取り出しながらダンプ結果の各行へと変換しています。その小分けにされたバイト列はbytes
という名前になっていますが、data
とbytes
はほぼ同義語でありわかりにくいです。その小分けにされたバイト列に的確に名前をつけましょう。data
が小分けされたバイト列をchunk
という名前にします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
def hexdump(data) dump_each_chunk(data) do |chunk| hex = dump_to_hex(chunk) ascii = dump_to_ascii(chunk) hex.ljust(3*16+1) + " " + ascii end.join("\n") end def dump_each_chunk(data) data.bytes.each_slice(16).collect do |chunk| yield(chunk) end end def dump_to_hex(chunk) chunk.each_slice(8).collect do |half_chunk| half_chunk.collect do |byte| "%02x" % byte end.join(" ") end.join(" ") end def dump_to_ascii(chunk) chunk.collect do |byte| (0x20..0x7e).include?(byte) ? byte.chr : "." end.join end |
こうすることで、最初に複数のメソッドにhexdump
を分けた上で、変数の関係をdata => chunk (=> half_chunk) => byte
と的確に名前をつけ、よりわかりやすくなりました。
このように長いコードには部分部分に的確に名前をつけるとわかりやすくなります。
ソフトウェアを変更する時、コードの名前からどこを変更すればいいのかを読み取ります。そして関係していると読み取ったコードを変更してあとは大丈夫だと思ってしまいます。しかし、もし他にも変更しなければならないコードがあるとすれば変更漏れということになり、バグなどの原因となります。同じコードは1つにまとめ、1つだけの名前をつけると、わかりやすくなります。
抽象的でいまいちピンとこないことでしょう。例で説明します。例えば次のコードがあったとします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
def error_message "use one of following modes: download, upload" end def change_mode(mode) mode = mode.to_sym raise error_message unless modes.include?(mode) send(mode) end def modes [ :download, :upload, ] end def download # ... end def upload # ... end |
ここに新たにmonitor
モードを追加するとします。具体的には、次のようにmodes
メソッドを変更し、monitor
メソッドを追加します。
1 2 3 4 5 6 7 8 9 10 11 |
def modes [ :download, :upload, :monitor, ] end def monitor # ... end |
これだけではバグがあります。すぐにわかるでしょうか?次のようにerror_message
メソッドも変更しなければならないのです。
1 2 3 |
def error_message "use one of following modes: download, upload, monitor" end |
なので、monitor
を追加する前から次のようにコードが書かれていることが望ましいです。
1 2 3 |
def error_message "use one of following modes: #{modes.join(", ")}" end |
そもそもこれはなぜバグと認識できるのでしょうか?それは開発者の視点からは、ヘルプメッセージから出力されるモードと実際にサポートされているモードは同じであるという認識があるからです。ここで注意してほしいのが開発者の視点からはこの2つの場面でのモードは同じモノを指し示しています。ですがコード上ではその同じのモノが2箇所のコードに対応しています。これがバグの原因となります。繰り返しになりますが、開発者が認識しているモノとコードは1対1で対応しているとわかりやすいです。
ここで仮定を変えてみます。monitor
は隠しモードでエラーメッセージには含めたくないとします。そうなるとerror_message
を修正する必要は無いので、最初の変更だけでバグが無いことになります。
しかしわかりやすいコードという観点からは問題があります。別の開発者が読んだとき、error_message
を修正したほうがいいと思うかもしれません。
monitor
の追加でモノとコードの関係がずれているからです。ヘルプメッセージから出力されるモードと実際にサポートされているモードとは別々のモノであるという認識があるからです。それを次のようにコードから読み取れるようにするとわかりやすくなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
def error_messge "use one of following modes: #{normal_modes.join(", ")}" end def modes normal_modes + hidden_modes end def normal_modes [ :download, :upload, ] end def hidden_modes [ :monitor, ] end |
こうすれば、あとから読んだときに、error_message
にmonitor
が無いのはたまたま抜けていたバグではなくて隠しモードとして扱っているためだから、ということが的確に読み取れます。
今回はコードの名前のつけ方を通して、コードをわかりやすくする方法を説明しました。
具体的には、略した名前をつけず、名前をつけるのをサボらず、同じコードには同じ名前をつけるとわかりやすくなるということを説明しました。
groonga 2.0.4が6月29日にリリースされました。そのリリースの変更点の1つとして新しい実行ファイルであるgroonga-httpd
が追加されました。
今回はgroonga-httpd
について説明するとともに、簡単に特長を紹介します。
groonga-httpd
についてgroongaには、groonga
という実行ファイルが含まれています。groonga-httpd
はgroonga
と関連しているので、まずはgroonga
について説明します。
groonga
を使うことで、ローカルにあるgroongaのデータベースファイルに対してテーブル作成、レコード追加、全文検索などの処理を行うことができます。その他にもgroonga
はサーバーモードとして実行することもでき、リモートからも同様にテーブル作成、レコード追加、全文検索などの処理を行うことが可能です。リモートとの通信には、HTTPか独自プロトコルであるGQTPを利用します。
groonga-httpd
はそのgroonga
のHTTPでのサーバーモードの代わりとして利用できるものです。
groonga
のHTTPサーバーの実装は独自なものですが、groonga-httpd
はnginxを使っています。そのためnginxの特長がそのままgroonga-httpd
にも当てはまります。具体的には、高性能であること、nginxモジュールで様々な機能が提供されていること、HTTPの仕様にしっかり準拠していることなどが挙げられます。
groonga-httpd
の詳細については、groongaのドキュメントを参照してください。
上で説明したように、groonga-httpd
でのみサポートされている機能としてHTTPのKeep-Aliveがあります。Keep-Aliveを有効にすることでクエリごとの接続、切断処理が省略され性能が向上します。そのことを確認してみましょう。
まず、groonga-httpdのドキュメントに書いてあるようにgroonga-httpd
をセットアップします。
そのあと、次のようにab
でKeep-Aliveの無効の時と有効の時とで性能を測定してみます。
Keep-Aliveが無効の時:
$ ab -c 100 -n 100000 'http://0.0.0.0:10041/d/status' Requests per second: 15135.00 [#/sec] (mean) Time per request: 6.607 [ms] (mean) Time per request: 0.066 [ms] (mean, across all concurrent requests)
Keep-Aliveが有効の時:
$ ab -c 100 -n 100000 -k 'http://0.0.0.0:10041/d/status' Requests per second: 23285.10 [#/sec] (mean) Time per request: 4.295 [ms] (mean) Time per request: 0.043 [ms] (mean, across all concurrent requests)
無効の時と比べ、有効にした時は、Requests per secondから約1.5倍の性能向上が確認できます。
groonga
のHTTPサーバーに対しても同様に性能を測定してみます。
Keep-Aliveが無効の時:
$ ab -c 100 -n 100000 'http://0.0.0.0:10041/d/status' Requests per second: 20933.84 [#/sec] (mean) Time per request: 4.777 [ms] (mean) Time per request: 0.048 [ms] (mean, across all concurrent requests)
Keep-Aliveが有効の時:
$ ab -c 100 -n 100000 -k 'http://0.0.0.0:10041/d/status' Requests per second: 20683.93 [#/sec] (mean) Time per request: 4.835 [ms] (mean) Time per request: 0.048 [ms] (mean, across all concurrent requests)
groonga
のHTTPサーバーはKeep-Aliveに対応していないので、有意義な性能差は確認できません。
今回の性能測定の結果はHTTPの通信処理だけの性能差ということになり、クエリの処理全体でみると性能差は縮まります。しかし今回のリリースではnginxとgroongaを組み合わせた最初のリリースです。さらなる性能向上や機能追加はこれからということになっていますのでご期待ください。
groonga 2.0.4で新しく追加されたgroonga-httpd
について簡単に紹介しました。