多言語に親しむ
Ian Bicking の記事を翻訳してくれてたのを見かけた。あとで読もうとなおざりになってた ...
その一節にこんなのがあった。
不思議なことに、プログラマが数日や数ヵ月で新たな言語を身につける方法が話題になるのをよく耳にします。プログラマの知識は、(この例のように)別の言語に応用可能だと考えられているようですが、私は疑問を感じます。独善的な意見でしょうが、こう考える人たちは何かをマスターすることの実際を分かっていないのかもしれません。もちろん新たな言語や環境をモノにするのに、また1万時間をかける必要はないでしょう。それでも確実に数千時間は必要ですし、何年もかかることです。私自身はようやくそのレベルに近づいたと感じています。
Pythonにサヨナラを - HackerNews翻訳してみた
私の周りにはプログラミング言語の仕様を抽象化して語る人がいて、この賛否を一般論として明確にするのは難しい。プログラミングに限らず、言語そのものを抽象化して捉えられる人は、その本質を見抜くのが抜群に速い気がする。もしかしたらプログラミングのセンスというのはそういうのを指しているのかもしれない。もちろんプログラミングの素養というのは、知識によるものや文化的な要素もあるし、実際に頭で分かってるからといって実装できるというわけでもない。論理や設計と実装は別ものだし、コーディングはさらに属人的になる傾向がある。
さて、そういった前置きは置いておいて、私自身は Ian Bicking の意見に賛成だ。以前、転職の面接でこんなことを聞かれたことがあった。
新しくプログラミング言語を習得するのにどのぐらいかかりますか?
この質問には前提が何もないので「習得」というのが何を指すのかは受け取った人によって異なるだろう。私は「2年ぐらいですかね」と答えたら「2年もかかるんですか」と返された。
当時は5年ぐらいプログラマーをしてきた経験から答えていた。感覚的に「習得」という言葉をこんな風に捉えていた。
- 分からないことがあったときに何を (どこを) 調べれば良いかを知っている
- 他人のツールやライブラリを修正してパッチを送ったりできる
- スクラッチからツールやライブラリの設計ができる
- 自分で作ったものをパッケージングして公開できる
- 開発コミュニティに参加して、その文化を理解している
このぐらいできたら、この言語を使って開発してますと言ってもいいかなと考えていた。一節によると、プログラミング言語の開発環境が無償で配布されるようになったのは Java 以降らしい。インターネットの普及とも関連するのだろうけど、それ以前の古参プログラマーにとってはライブラリを公開したり、開発コミュニティに参加するというのは当たり前ではないかもしれない。
いまの職場で Java を使い始めて1年半ぐらい経つけど、実際のところ、この項目の半分にも満たない。たぶん私はプログラミング言語の習得が遅い、まぁセンスがないのだろう。そろそろ自分で Java のツールやライブラリをスクラッチから書いてみたいと思ってはいるけど、そこまでやる気がなかったり、Java の開発コミュニティにも参加してなかったりする。
技術力の高い人が周りに多いが、OSS のライブラリやツールを使っていて、コミュニティにフィードバックしない人が意外といるんだなというのも分かってきた。私はもともと OSS がやりたい派で SIer から転身してきた方だからこの感覚は自分の方が一般よりズレてるのかもしれない。業務系の開発の人は、普段の業務に忙しくてそこまでのモチベーションはないのが普通かもしれない。実際、私も SIer にいた頃は業務に忙殺されて OSS にコントリビュートしようなんて考えすらなかった。
確かに BTS に既存チケットがないかを調べて登録するのも面倒だし、パッチを書いても reject されることもままある。パッチの approve は自身の技術力の客観的評価に良いと思う。というのは、その対象コードの空気を読まないと、まともなパッチは書けないし、その文化を理解しないとその修正は取り込まれない。何となくだけど、そういうのを1つずつ積み重ねていくうちに自分の目指すプログラマーのキャリアができるような気がしている。これは人それぞれだ。
Web 系の開発の人たちの方が OSS の開発やコントリビュートに活発なのは、Web の技術が業務系の開発においては、まだまだ応用範囲が限定的だし、世の中の業務を全てを Web 化するにはもう少し時間がかかるんだろう。Web 系の開発の人たちは Web の世界で起こってることが全てだけど、業務系の開発の人たちは Web でこんなのが流行ってるから使ってみようぜといった感じ。とはいえ、permissive ライセンスの隆盛にもあるように業務系にも OSS の利用が高まっているからこの感覚は徐々に Web 系の人たちと同じものになっていくと思う。そして、正にクラウド化が拍車をかけてる。
話がずれてきたので戻す。
慣れた Python と慣れてない Java でコーディングしていて、何が違うのかというのをよく考えたりする。最近ちょっと分かったことがある。格好よく言うと、Python で設計するときは未来のことも考えながらコードを書いてる。
- 後からこんな要望がくるかもしれない
- 当初はこういう設計方針だったけど、それが変わるかもしれない
- この処理の影響範囲はここで局所化しておく
- 低レベルと高レベルの api を設けておく
- 依存関係を意識して、安定したコードと安定してないコードを明確に分ける
ある程度、未来にどんなことが起こっても大きな変更や工数がかからないように作ってる。実際、本当にそうであるかどうかは置いておいて、そういう自信をもって設計している。いわば、設計原則をその言語の文化に則って明確にするということだ。これをもっと昇華させると哲学的になるんだろうと思うけど、そこまでは至っていない。それは Python という言語に慣れ親しんだところからの、設計や実装の経験からできることだ。
そして、私がプログラミングで一番重要視しているのは保守性だと思う。それは最初に就いたお仕事がシステム運用で、運用のしんどさを経験したせいかもしれない。きれいなコードを書こうと思うのも、テストを書こうと思うのも、リファクタリングしたくなるのも、保守性を高めたいからだ。
理想としては
write once, no update.
なコードを書きたい。
いまの職場では数十万行というコードベース (Java) に対して、修正したり拡張したりしていると意図しないバグにたくさん遭遇する。それは良くないことだけど実におもしろい。いや、他人のコードだとおもしろいけど、自分のコードだと悔しい。でも、そのバグをきっかけにコードを読む、そして関連部分の仕様を理解する。こういう設計/実装をすると、こういうときにバグが発生するんだと学ぶ。CTO が良いプログラムとは分割統治であり、それを実現するキーワードの1つがインターフェースだと言ってるのを何度も読んだが、ある程度の規模のコードベースがあって、その意味が理解できた。
バグを埋め込むのは、自分のプロダクトに対する理解度が足りないことも大きいが、自分よりも経験や技術力の高い先輩や上司をみていても結構なバグを埋め込む。誤解を恐れずに言えば、プログラマーの技術力に関係なく、いじったコードに対するバグを埋め込む量というのはある一定の割合に収束するのかもしれない。そう仮定すると、どうすればバグの埋め込まずにコードを修正できるかという問いの答えに技術力はあまり関係ないんじゃないかとも思う。
世の中に出回っているベストプラクティスは上辺のきれいなところだけ。もちろん学ぶ意義はあるけど、それはほんの入り口に過ぎない。現実のプロダクト品質のコードはもっと複雑で根が深い。単に言語仕様を理解しているだけでは駄目だ。そのヒントは、他人が書いた Python のコードをレビューするときに感じることでもあった。コードレビューでは設計そのものを否定しにくい。このコードで動くし、間違ってないけど、全体としてしっくりこないというときがある。コードに一貫性がなかったり、設計原則が伝わってこないときだ。動くコードを前にして全体的に書き直してとは言いにくいからまぁ大丈夫ですと言う。他人のコードじゃなくても、自分が過去に書いたコードを見直すときにも似たような感覚がある。
その差はどこにあるのか。設計なのか、経験なのか、文化なのか。あるときは分からなかったものが、どうしていまは分かるのか。この認識のズレや違いを明確に意識できれば、いまよりも言語の習得を速められるかもしれない。
また話がずれてきたので戻す。
最近、Ruby のコードをちょくちょく書いてる。スクリプト言語は Python (とシェルスクリプト) ができれば十分だからと、あえて同じ適用領域の他言語は避けてきた。社内には Rubyist の方が多く、Ruby ツールも多い。Rspec でテストを書いたりもしている。自分が関わる業務のプログラムが読めなかったり、書けなかったりするのはストレスなので、結局 Ruby も学ぶことにした。
公式ドキュメントと Ruby Styleguide をみてツールを作った後に、初めての Ruby を読んだところ、よく分かってなかったことや疑問に思ったことが解きほぐされて、この書籍は凄く良かった。まだ手習い程度のことしか分かってないけど、コードを書いていて Python よりも Ruby の方がおもしろいと思う。(Python と比べて) 言語仕様は複雑だから、そういうのを調べたり学んだりするのも楽しい。プログラマーの格好良くコーディングしてやろうみたいなところを良い意味で刺激していると思う。
Ruby のコードを書いてみると一貫しなくても良いんだよとばかりに自由気ままに書ける。全てが式で値が返ってくると便利だし、余分なコードも減るけど、調子にのると返り値を誤解したりコードを修正したときにはまる。簡単にクロージャーをブロックで書けてしまうからコードの様相が散らばる。定義済みクラスへのメソッド追加や特異メソッドはそんなことやっていいんだ!?って感じ。でも、やれることが違うと発想も変わってきて、いろんな設計の違いに触れることができそうな気がする。そういう他と違うということ自体がやっぱりおもしろい。
取りとめがなくなってきた、まとめる。
昔、ある人がこんなことを言っていた。
素人にソフトウェアを開発させるな。プロの開発者だけが設計して開発しろ。
そうなんだろうけど、現実の職場では何割かの素人も開発している。自分もあるときはその1人だ。そして、素人がプロになるための方法もこれしかない。決して座学だけでプロの開発者になれない。
1. まず動くものを作る
2. きれいなコードを書く
3. テストを書く
4. リファクタリングする
5. 設計を見直す
そうだ。先週、同僚と Go について井戸端会議してたんだけど、某ブログに Go 始めてましたとか載ってて、始まってたんだと驚いてる。でも、機会があればやってみたい!
クレーム対応
サポートの問い合わせも trac のチケットに登録されるようになっている。開発者も問い合わせに対する技術的な仕様や対応方法をコンサルの担当者へ伝える必要があるので、日々問い合わせチケットに目は通すようにしてる。
その中でお客さんが怒りだして上司連れて報告に来いみたいな展開になっていた。やり取りしているうちに徐々にやりたいことがプロダクトから離れていって、担当者がのらりくらりとしているうちに癪に障ったようだ。客観的にみてどちらが悪いというよりは本質からどんどんずれていって、話がちぐはぐになっていった感じだった。
サービス業なのでお客さんが怒ることはちょくちょくある事だけど、その後の社内のコメントのやり取りが興味深かった。そのクレームに対応していた担当者を責めることもなく、それぞれ個々人の考えや、どうすれば良かったのかといったアドバイスなどが寄せられた。普段コメントしない人たちも一言入れたりして、みんなチケット読んでるんだなーって思った。是非はともかく、担当者としてはお客さんを怒らせてしまったわけだから多少なりともショックはあるだろうと思う。そんなときに周りがフォローしてるのを見て良いことだなと何気に思った。稀なことだから単に興味を引いただけかもしれないけど。
少し昔のことを思い出した。私も昔、SIer で流通業向けのサポートをやっていた。SIer の技術レベルは低かったし、お客さんのリテラシーはもっと低かった。電話で怒鳴られることもあったし、クレームを上司や先輩に報告しても、上司や先輩からも怒られることもあった。
(報告はもちろんするけど) どうせ怒られるんだから、自分一人で何とかするしかないというのが自然とその職場の雰囲気だったし、なるべく他所のトラブルには関わらないようにしようという感じもあった。あるとき同僚が「本当の意味でみんな誰も信用していない」といったのが、妙に納得感があって笑えたぐらいだ。
若いときにそういう欺瞞は結構がっかりするもので、業務へのモチベーションや周りに対するチームワークにも影響を与えると思う。その SIer では基幹システムの運用という SLA もいまの職場よりはずっと高かったために厳しかったというのも考慮する必要はある。それでも、いまの職場と比べて、業務への取り組み方やチームの在り方で見劣りするものがあったように思う。
マッチョだけが生き残る職場ではなく、人を育てるというか、勝手に育つような職場にはそれなりの理由があるようにちょっと思った。
trac 移行作業
開発の谷間なので今週は主に trac の移行作業をやっていた。
前年度からのタスクに 0.12 から 1.0 へ移行をすると断言しながら、1年近く放置してきたというひどいことをしてる。全ての情報は trac で一元管理するという原則のもと、trac が社内インフラとして重要な位置付けになっている。ダウンタイム無くアップグレードするのに準備の工数が大きく、影響度の大きさから消極的になってた。
それでも先月からようやく少しずつ前に進み始めて3つあるプロジェクトのうち2つを移行できた。この作業と同時に mod_wsgi を embeded モードから daemon モードに変更して、それぞれのプロジェクトを独自にメンテできるようになった。さらに同僚に手伝ってもらって solr を使った TracAdvancedSearchPlugin の全文検索も試験的に導入できる段階になった。
チケットのユーザー定義ステータスを扱えなかったので修正して pull request を送ったらすぐに取り込んでくれた。ちゃんとメンテしてくれてるから安心してこのプラグインを推奨できる。おそらく12月は時間ないだろうけど、次は2月頃に余裕があれば、trac 移行の経緯や全文検索の導入をまとめられれば良いなぁ。やる気次第か。
今日はもう1つ。丁寧な pull request が来ていたのでレビューしていた。
1年以上触ってないので、コードも忘れてて、diff だけ見ても分からなくてじっくりレビューした。テストデータに大きなリストを渡すときにリテラルで記述するのではなく、オプションから生成できるように、もう一段階抽象化する仕組みを作ってくれた。なるほどなぁとその意図に感心して、コードも既存の実装の空気を読んできれいに実装してくれてたのでなるほどなぁとまた感心した。
現実の応用例として、wikipedia:同値関係 を表すテストコードを書いてくれたけど、これはちょっと理解できなかった ...
xls ドキュメントの差分チェック
今日はコードフリーズだった。
と言っても開発に追われていたわけではなく、昨日から xls のドキュメントの更新をしていた。ドキュメントの内容と trunk のスキーマの差分を調査して更新していたのだけど、これが結構時間かかって次リリースにも少し持ち越した。
その過程で差分チェックの簡単なツールも作ってみた。あとは xls から比較したい内容をテキスト抽出できれば良い。今回は時間がないから手作業で取り出した。
試しに xls のテキスト抽出には Gnumeric パッケージに付いてる ssconvert コマンドを使ってみた。対象ファイルが説明資料なので必要な部分だけテキスト抽出するのは一工夫が必要そうだ。というか、抽出したテキストを見たらこれは無理かなと今回は諦めた。
- サーバ上でPDFやオフィス文書からテキストを抜き出す方法あれこれ - ククログ(2010-08-02)
- http://xmodulo.com/2012/06/how-to-convert-xlsx-files-to-xls-or-csv.html
trunk との差分チェックも手作業を介するのと、バージョン管理で差分も見れないし、ドキュメントを更新していて、いまどき xls でのドキュメント管理をやめるべきだろうとも思い始めた。とはいえ、ユーザーに渡す資料なのである程度、見やすい資料にしたいというのもあり悩ましいところ。
開発者の視点:
- trunk との差分を自動チェックしたい
- 定期的にチェックツールを実行して (差分を) 都度メンテしたい
- 過不足がない内容を保証
テスターの視点:
- 更新内容が適切かどうかを自動テストしたい
- テスト期間中にテストが通れば良い
- テストが落ちない内容を保証
校正者の視点:
- 更新内容が分かりやすいかどうかをチェックしたい
- ドキュメントをリリースする前に確認したい
- ユーザーが誤解しない内容を保証
ユーザーの視点:
- 知りたいことが分かりやすい資料がほしい
- 作業する前に仕様を確認したい
- 目的が達成できればそれで良い
視点を変えてみると、それぞれ求めるものは違うのかもなぁ。
Red5 の RPM パッケージング
2013-01-31 - forest nook で Red5 の RPM パッケージングについてコントリビュートしていた。
ちょっと間延びしてしまったけど、必要な spec ファイルとドキュメントのコントリビュートが完了した。やり方としてはイシュー登録してやり取りするだけ。
これらの成果物は以下にある。
Red5 は業務のプロダクトにも試験的に取り入れている。今後も業務で関わっていくだろうからコミュニティとの関係や空気を読むことには少し気を遣っていこうと考えている。最近 1.0 リリースが出たばかりにしては、あまり盛り上がってないし、やや閉鎖的なコミュニティにもみえる。Java のコミュニティってそんなもんなのかなぁ。
メンテナンスリリースした
TracCronPlugin 0.3.1
もともとのチケットで要望だしてから約1ヶ月ほどかかった。
- #10802 (Reminder task for ticket deadline) – Trac Hacks - Plugins Macros etc.
- wiki/TracCronPlugin#Ticketdeadlinetask
最初のベータ実装を終えて簡単なドキュメントを書いた。
Python 2.4 でも (たぶん) 動くようにしてリリースした。ちゃんと検証してないけど、スモークテストとユニットテストは通ってる。
残課題もいろいろある。いまは手が回らないのでしばらく置いておく。
- メールのテンプレート修正
- メール内容の国際化
- 期限を過ぎた後の処理をどうするか
もともとあった不具合のチケットも3件ほど残ってる、内容はまだ調べてない。
ソースも trac-hacks の Subversion から bitbucket へ移行した。要望があれば pull request もらえると嬉しいな。
メンテナーになった
TracCronPlugin
元の開発者の Thierry Bressure 氏とコンタクトが取れたのでメンテナーを申し出たら快く受諾してくれた。
AdoptingHacks – Trac Hacks - Plugins Macros etc. というプロセスがあって、この流れに従ってメンテナーになれる。他にも "needsadoption" というタグが付いてるプラグインがメンテナー募集中みたい。詳細は別途ブログにまとめたいけど、リクエストを出して
メーリングリストでやり取りして
すぐメンテナーになれた。
本来は TracCronPlugin の機能拡張をしたかっただけなんだけど、せっかくメンテナーになったのでもう少しがんばる。まずは以下のところから手をつける。
- モダンなパッケージング
- 一貫したコーディングスタイル
- テストの実装
メインリポジトリは trac-hacks の Subversion にしつつ、開発リポジトリは bitbucket を使いたい。Subversion から bitbucket への移行はすぐにできた。git-svn があるんだから、きっと hg-svn もあるんだろうと思う。
今週から来週にかけて新しいバージョンをリリースしたい。