はてなでコードを書くときに気をつけていること ― 2011年12月18日 14時37分
こんにちは、はてなでアプリケーションエンジニアをしている nanto_vi です。この記事は Hatena::Staff Advent Calendar 2011 の一環として書いています。Advent Calendar の会場ははてなブログとなっていますが、主催の antipop さんに尋ねたところ何でもよいというような返答があったのでここで書きます。
はじめに謝っておきますが、この記事ははてなとほとんど関係がありません。タイトルに「はてな」と入っているのは Advent Calendar の要件を満たすための目くらましあり、内容はといえばはてなのノウハウでもなんでもない、私が最近個人的に心がけていることです。ごめんなさい。
できれば明示的に
業務で書くコードは複数人により読み書きされメンテナンスされるので、わかりやすさが重要になってきます。わかりやすさを保つためには暗黙的に行われる操作を減らし、明示的にコードに表した方がよいと感じます。たとえば、Perl では、
use Encode;
# encode_utf8 関数は Encode モジュールで定義されている
my $octets = encode_utf8 $string;
のようにモジュール読み込み時に自動的に関数をインポートすることができますが、それよりも、
use Encode qw/encode_utf8/;
my $octets = encode_utf8 $string;
のようにインポートする関数を明示的に指定したほうが、その関数がどこで定義されているのかわかりやすいでしょう。
個人的には、関数や変数の名前で grep をかけてその定義(外部で定義されている場合は宣言)を探し出せることが、「明示的」であるための最低線ではないかと思います。
入力には正規化を、出力には符号化を
アプリケーションを作るうえで入出力の扱いは避けて通れません。入力元はユーザーだったりバッチ処理スクリプトの引数だったり、出力先はユーザーだったりデータベースサーバーだったりしますが、いずれにおいても入力には正規化処理を、出力には符号化処理を、それぞれ施すことになります。
正規化は一般に不可逆です。空白文字類をすべてスペースに置換した後はもともとスペース以外の空白文字が含まれていたのかわかりませんし、数値「42」を生み出した入力は "42" でも "42.0" でも、はたまた "0x2A" でもありえます。
符号化は一般に可逆です。あるデータをユーザーのもとへ送り届けるのに、そのデータを HTML のテキストとして扱えるよう一部文字を文字参照の形に符号化し、その HTML ソース全体を文字符号化方式 UTF-8 をもって符号化し、さらには HTTP メッセージに、TCP のセッションに、IP のパケットにと符号化を重ねていきますが、それらすべては符号化規則を逆に適用することで元の形式へ復元できます。
たとえば HTML として解析され、その結果が JavaScript の文字列として、HTML として、URI としてと順に解析されるデータを Template-Toolkit で出力する場合、解析の逆順でそれぞの形式に応じた符号化を施す必要があります。
<script type="text/javascript">
document.write('<a href="/search?q=[% word | uri | html | js %]">検索<\/a>');
</script>
script 要素の内容は CDATA 型であり文字参照は解決されないので、最後に html フィルタをかけることはしません。また、そもそもこのような多重にフィルタをかける事態は避けたほうが賢明でしょう。
入出力いずれにおいても、データがどういう形式で扱われるのかを意識し、それに応じた正規化処理または符号化処理を施すことで、意図しない入力が致命的な挙動を引き起こすこともある程度は防げるのではないかと考えます。
LiveCoding #6 の 2 ― 2009年07月19日 23時40分
OSC Kansai に出た帰りに satzz 君に電話したら、ちょうど LiveCoding #6 をやっているとのことだったのでその足で寄ってきました。前回も第 6 回だった気がするのは何かの間違いでしょうか。
LiveCoding とはプログラミングの実演と実況を楽しみましょうというイベントで、出てくる言語も C から PHP まで色とりどり。まともとは思えないテクニックも多々披露されたわけですが、中でも驚愕だったのが ujihisa さんが書いた Ruby のコード、
def fib n, x = (n < 2) ? n : fib(n - 1) + fib(n - 2)
x
end
fib 10 # => 55
Ruby ではデフォルト引数内で再帰呼び出しができるだなんてちっとも知りませんでした。
飛び入り LiveCoder も大歓迎といわれ、その特典である参加費 (お寿司 + カレー代 + etc.) キャッシュバックを目当てに手を挙げたのですが、ネタが思い浮かばず、bit.ly API の存在を教えてもらって「Web ページ閲覧中にリンク先が bit.ly 経由で何回クリックされたかを表示する Greasemonkey スクリプト」を作ることにしました。
Greasemonkey スクリプトでは let を使えないのについ let と打ってしまって var と打ち直したり、Greasemonkey と bit.ly と wedata の API リファレンスを読みふけったり、E4X で構築した要素を手っ取り早く使うために innerHTML を使おうと思ったら、そもそも要素を作成する必要がないことがわかって単なるテキストを innerHTML に代入する羽目になったり、それならとテキストノードを直接生成するように書き換えたりしているうちに制限時間 20 分はあっという間に過ぎ、45 分かけてどうにか動くものができるという有様。動くのは LDRize 対応サイトのみ、利用するには Firefox 3.5 以上と bit.ly のアカウントが必要です。
その場で cho45 が「こういうときは JSDeferred を使えば」とプッシュしていた気がするので、後日 JSDeferred を使って書き直してみました。JSDeferred をうまいこと使えているかは不明ですが。
ちなみに Greasemonkey スクリプトで let が使えないというのは、Components.utils.evalInSandbox で JavaScript のバージョンが指定できないという制限によるものです。この仕様は Firefox 3.5 で改善され、適切なバージョンを指定すればサンドボックス内でも let、yield を使えるようになりましたが、Greasemonkey 側はまだ対応していません。
コーディングが終わった後はまったり過ごしていましたが、JSDeferred のロゴを作れば女子高生の間で JSDeferred が流行るんじゃないかという話になったため、実際に作ってみました。secondlife さんに「何この 5 秒で描いたような」と dis られましたが、30 秒はかかっています。JSDeferred のトップページにもこのロゴを貼り付けたので、ナウなヤングにバカウケ間違い無しですね。
それと、Gist で Greasemonkey スクリプトを管理しようという話を聞きますが、皆さん具体的にどうやって管理しているんでしょうか? とりあえず Greasemonkey スクリプトを書いた後、gisty で投稿してそれを git remote で引っ張ってきてとやったのですが、これでいいのかよくわかりません (環境は Cygwin + Meadow)。
$ cd FIREFOX_PROFILE_DIR $ cd gm_scripts/bitly_referred/ $ ls bitly_referred.user.js $ gisty post bitly_referred.user.js Initialized empty Git repository in GISTY_DIR/149553/.git/ $ git init $ git remote add origin git@gist.github.com:149553.git $ git pull origin master $ cat > .gitignore * !*.user.js $ meadoww bitly_referred.user.js $ git add . $ git commit -m "Rewrite with JSDeferred" $ git push
セキュリティ & プログラミングキャンプ・キャラバン 2008 京都 ― 2009年02月11日 16時54分
セキュリティ & プログラミングキャンプ・キャラバン 2008 京都に行ってきました。セキュリティ & プログラミングキャンプとは、IT 分野において優秀な若者の発掘・育成を目的として、22 歳以下の学生を対象に毎年夏に行われている合宿 (参加費無料) です。中学生の参加者もおり、普段はなかなかできないコンピュータの話題で盛り上がるそうです。
キャラバンはキャンプの紹介のためのイベントで、プログラミングとセキュリティに関する講義や昨年のキャンプの様子の公開などがありました。詳しい内容については「セキュリティ&プログラミングキャンプキャラバン2008 レポート - y_tsuda's blog - s21g」やそこからとだれるページ、はてなブックマークで「caravan2008」タグをつけられたページなどを参照してください。
個人的に印象に残ったのは、「セキュリティ & プログラミングキャンプの選考に受かるコツは?」という質問に対する回答です。絶対的なコツはないという前置きの下で、自分から情報発信をすること、活動が見えないと評価ができないという話でした。キャンプの選考に限らず、IT 分野において情報の発信は非常に重要だと思います。
私の場合、WEB+DB PRESS に連載を持たせていただいたり、はてなインターンに参加させていただいたりということがありました。こうした機会を得られたのは、ちょうど Ajax ブームが起きて JavaScript に注目が集まったという「タイミングがよかった」面もありますが、ひとつ確実にいえるのは、このブログを書いていなければそのような機会はなかったということです。
現在個人が情報発信する場として代表的なのはブログですが、ブログでは何かすごいことを書かないといけないというようなことはまったくありません。わからないなら何がわからないのか書けばいいのです。勉強会に行こうという話もありましたが、勉強会に行って何が楽しかったかブログに書くだけでもずいぶん違うと思います。私自身は筆不精でついついブログの更新が滞りがちなのですが (^^;)、そうしたブログを読んでいくのは楽しいし、新たな気づきが得られることもたくさんあります。
そのほかキャラバンでは、セキュリティ & プログラミングキャンプは 22 歳以下だけど、大学院生も参加できる IT Keys という取り組みもあるという話、脆弱性を報告したが製造者から「仕様です」と言われたときに、引き下がって愚痴るのではなく製造者やコミュニティに働きかけて悪い仕様を良い仕様に変えていこうという話がありました。
全体を通して主催者側のキャンプにかける意気込みが伝わってきて、若年層にはぜひキャンプに参加してほしいと感じました。同じ志を持った同年代の人たちと知り合えるというだけでも刺激的な体験になると思います。また、このような取り組みが今後も継続していけるよう、自分にできることがあれば積極的に協力していきたいです。
最後に、勉強会に行こうという話があったといいましたが、現在私が参加している主な勉強会に、関西の JavaScript 勉強会 Kanasan.JS と SICP 読書会 (こちらは最近タイミングが合わずご無沙汰していますが) があります。Kanasan.JS の方はこの 2 月 22 日 (日曜日) に Greasemonkey チュートリアル読書会が開かれるので、お近くにお住まいの方はぜひ参加してみませんか。午前中には同会場で Haskell 勉強会 実践編も開かれます。
第 7 回アルゴリズムイントロダクション輪講会資料 ― 2008年12月04日 23時08分
すでにニュースでも伝えられている通り、12 月 1 日に第 7 回アルゴリズムイントロダクション輪講会がありました。今回の担当は私だったので、その発表資料を公開します。
「どうせ後から Web で公開するんだから、PDF とか見るのに手間がかかるものは使ってられないよね。やっぱ時代は XML 複合文書でしょ!」と、数式を表現するのに MathML を使いまくったら、なぜか Firefox 以外ではまともに表示されなくなってしまいました。ホスト言語が XHTML なので、IE にいたっては地の文の表示すらできません。
とは言っても MathML の仕様書を斜め読みしただけなので、適切でないマークアップが結構含まれています。本当は図も SVG で表現したかったのですが、いろいろと余裕がなかったのであきらめました。資料が 3 つ (本番では補足を除く 2 つ) の文書に分かれているのは、Firefox で MathML の要素数が一定数を越えると、文字揃えが効かなくなるというバグに遭遇したためです。
なお、MathML の記述に当たっては以下を参考にしました。
ちなみに私は今のところ風邪の症状は出ていないようです。
はてなインターンを終えて ― 2008年09月24日 21時25分
先に書いたように 8 月は株式会社はてなのサマーインターンシップに参加していました。もう第 2 回も終わろうかというころですが、遅まきながら私の場合についてまとめたい思います。
インターン生の 1 日
「インターン生の」とつけましたが、特に後半 2 週間は何らかのチームに参加しての開発だったのであまり社員と変わらないかと思います。就業時間は 10 時から 19 時となっており、朝は東京オフィスとビデオでつないだ全体ミーティングから始まります。ここでは前日のリリース報告やはてな社に関する活動報告、当日の予定確認があります。その後はチームミーティングで、チーム (数人) の各員が前日の作業内容、当日の作業予定を報告します。私が配属されたキーワードチームには近藤社長も所属しており、社長自ら各自の報告に質問や感想をはさむことも多々ありました。これらのミーティングは不必要に長引くのを避けるためかすべて立ったままで行われ、時間は合わせて 30 ~ 50 分ほどでした。キーワードチームは人数が多めだったため、ややチームミーティングの時間が長かったかもしれません。
ミーティングが終わると開発に移ります。インターン生は基本的に二人一組でチームに配属されるので、配属後しばらくは相方の ninjinkun とのペアプログラミングが中心でした。後の方になるとリリース予定日に追われて二人が別の作業を進めることも増えてきました。私はインターン生だったのでミーティング後はひたすら開発、一区切りついたら、あるいは行き詰ったら社員を訪ねて、サーバーでの確認やアドバイスを求めるという感じでした。社員の人は単純な開発作業に加えて、サーバー調整のためにインフラ・運用チームの人とのミーティングなど、小さなミーティングをいくつかこなしていたようです。
お昼は 13 時からで、週 3 回はオフィスランチが出ます。オフィスランチがないときもご飯だけは炊いてもらえ、別途お弁当屋さんからおかずだけ買って一緒に食べることもできます。炊き立てのご飯が食べられることによる開発意欲の向上は目覚しいものがあり、私などは「初日に来たときは今にも死にそうなくらい顔色が悪かったが、毎日オフィスランチを食べているうちにどんどん顔色が良くなっていった」(伊藤直也氏談) と言われるほどでした。ランチ後もお昼休みはゆったり過ごすことができ、私の場合は社内に転がっているクッションでお昼寝することもしばしばでした。
午後も開発は続きますが、ここで重要なのがフリードリンク・フリースナックです。パイの実やチョコボールといった甘いものをつまむことで脳に糖分を補給し、万全の状態で開発に臨むことができるのです。私はもっぱら緑茶 (ハトムギ茶系のお茶がなかったので) とチョコレート菓子で午後を乗り切っていました。と、ここまで書いて思い出したのですが、ドリンクやお菓子の種類はリクエストもできます (必ずかなえられるとは限りませんが)。十六茶や爽健美茶がほしければそうリクエストすればよかったんですね。
夜は大体 20 ~ 21 時くらいまで残っていました。オフィスランチが残っていればそれを夜食にすることもあります。私はそのまま家に帰ることが多かったですが、インターン生同士 (+ α) でインドカレーやラーメンを食べに行ったり、銭湯に行ったりもしました。
インターンに参加して
このインターンで、これまであまり経験がなかったサーバーサイドでのプログラミングとチームによる開発を体験することができました。成果であるランキング機能については ninjinkun の記事も参照してください。チームの皆さんに助けられつつ、自分がチームに、会社に、ひいては社会に少しでも貢献できたかもしれないと考えると、インターンに参加して本当によかったです。おかげでよりいっそうプログラミングを楽しいと思えるようになりました。
また、会社は顔が見える人たちだけで回っているのではないということも実感しました。はてなのエンジニアといえば伊藤直也さんや田中慎司さんが有名ですが、それ以外にも多くの有能なエンジニアによって各サービスは支えられており、さらにエンジニア以外のスタッフも一体となってはてなは成り立っているということがダイレクトに伝わってきました。
ほかの会社を知らないので比較はできませんが、ユーザーにじかに使ってもらえるサービスを Web 上で提供したいというときに、はてなは開発者にとって素晴しい環境を提供してくれる場所であると思います。
![[図: リンク先へのクリック回数を表示する Greasemonkey スクリプト]](http://www.ne.jp/asahi/nanto/moon/2009/07/19/bitly-referred-s.png)
最近のコメント