ペアプログラミングの時代

1年ほど前、ペアプログラミングについてのエントリとか読んでいたが、当時はまだまだそのパワーを理解できなかった。
が、フレームワーク導入や開発環境の工夫でそろそろいけるんじゃないかと思って、こないだのプロジェクトでペアプログラミングをやってみた。

やっとまともなペアプログラミングを体験したので、思った事を書いておく

どんな感じでやんの?

  • プログラマ2人で1台のPC、1台のキーボードで開発は行う。
  • キリの良いところか20-30分交代ぐらいでキーボード担当を切り替える。
  • リサーチ用に1台ノートPCがあると便利かもしれない。キーボード担当してない人が触る用の。
  • キーボード担当を「コーダー」、見てる奴を「ウォッチャー」と呼ぶことにする。

三人寄らなくても文殊の知恵

  • 2人が同一のスキルレベルでないとしても、お互いをフォローできるので、アウトプットとしてのコーディングのレベルは高くなる。
  • アルゴリズムの妥当性やパフォーマンスについて知識を交換しあいながら行えるので、大変勉強になる。
  • OJTでやるのに大変よろしいかもしれない。

工数が無駄じゃね?

  • マネージャ的立場からみると、別々に作業するより工数が倍必要なように見えるが、実はそうでもない。
  • いまどきのフレームワークコーディングの場合、キーボードを叩くよりマニュアルやAPI Docを眺めている時間の方がはるかに長いケースがほとんどだ。
  • また、仕様を逐次討議していくことで仕様認識の一致や、穴の発見などが行えるので、最終的なアウトプットに対しての工数は2人でやっても1人でやってもほとんどかわらない。そして成果物のレベルは明らかに高い。

工数のコントロール

  • ビジネスコーディングの場合、完璧を目指すより要求仕様に対して妥当かどうかの判断が常につきまとうので、自己満足的なコーディングに手数をかけないようになる。
  • 一人でやってるとハマりがちなスパイラルにおちいらないのも良いところ。

ケアレスミスの予防

  • コーダーとウォッチャーのの立場の違いなのか、ウォッチャーでいると、プログラムや仕様を俯瞰的に見られるのでミスを発見しやすい。
  • typoからアルゴリズムミスまで見抜けるので、ウォッチャーはしっかりとコーダーが何やってるかを見ておく必要がある。

気が散らない

  • そういう環境をきちんと整える事も重要だが(例えば電話の取次ぎを一時拒否とか)、やってる最中にmixiやらtwitterやらtumblrの誘惑に負ける事が無いので作業自体がとても進む。
  • お互いに監視してるようなもんだからwこれはいいと思った。僕たち意思が弱いんで><

時間を区切る

  • 見られながらのコーディングは何かと疲れるので、適宜休憩を挟んで行うほうが良い。
  • 休憩タイミングはあらかじめ決めておくと良い。
  • あと、明確に当日の達成目標をあらかじめ決めておいて、終わったらペアを解いてそれぞれの作業に戻る(または即帰る)つもりでいると良い。ダラダラやってしまいがちなので、目標の見える化は必須といえる。

ペア☆プロがいいので〜す♪→結論

その他にもペア作業でやったほうがいいんじゃないかと思うのがいろいろある。
今後のビジネスワークフロー構築時に検討しようとオモタ。

数字を3桁区切りにするjavascript

PHPで言うところのnumber_format()関数が無いので自作してみた。
勢いでワンライナーで書いてみた。

var n=123456789;
n.toString().split("").reverse().eachSlice(3,function(a){ return a.reverse().join("") }).reverse().join(",");

正規表現でなんかこうカッコよくできそうな気もするが、もうちょっと研究してみる。

0.9.6->0.10.3アップデート

いつのまにかportsも0.10.3になってたので、運用サーバでついに決行。
インストールそのものは簡単に完了。
TOCが動かなくなっていたが0.10用を引っ張ってきて

python setup.py bdist_egg
python setup.py install

であっさり完了。

TracBlogPluginをインストールしようとしたら「'NoneType' object has no attribute 'group'」とか出た。
よくわからんのでいろいろportupgradeしてみたが直らない。
なんとなくsetuptoolsのせいな気がしたので

python ez_setup.py -U setuptools

やったら直りましたとさ。

Form.serializeメソッドの第二パラメータ

Ajaxリクエストを投げるときにクラスでラッパーしちゃったので、メソッドへの受け渡しをオブジェクトでやりたいんだが、Form.serializeメソッドは、ご丁寧にURLエンコードしたパラメータを全部つなげた上で返してくれてしまう。
でも、俺はオブジェクトで欲しいんだよぅ!と思って自分で書いたりしたんだが、RADIOとかCHECKBOXの場合を考慮すると結構面倒なコーディングになる事が発覚。

そこで、いろいろhogeった結果、邦訳されたprototype.jsのドキュメントには書いてなかったんだけど、本家のAPI Docsを見てみたら、あるじゃないですか。

  API=new hogeAPI;
  pars=Object.extend({ 'handle' : 'register' },  Form.serialize('hogeform',true) ); /* 第二パラメータをtrueで投げる */
  API.Request( pars );

こんな感じにすると、parsにForm値をHash化したものにさらに勝手にパラメータを追加してAjaxリクエストに投げられるようになりましたとさ。

prototype.jsは抜かりねぇなぁ(・∀・;)

メソッドに動的にアクセスしたい

引き続きオワタcheckboxネタで、みかぽんからQAが出たネタを。
if文でメソッドをハンドリングしたい時なんかに使う手だが、変数に入っている文字列値をメソッドとしてコールしたい場合、phpなんかだと

  $method=($state)?"print":"store";
  $this->$method; /* $this->print() か$this->store()がコールされる*/

で済むわけだが、javascriptの場合、

  method=(state)?'print':'store';
  this.method(); /* methodがコールされてしまう */
  or
  this.method; /* methodというメソッドのfunctionオブジェクトをさしてしまう */

とかでこのままではダメ。では、どうするかっていうと配列へのアクセスのように[]でくくる。

  this[method](); /* methodが評価される */

NackyのオワタjQuery版を勝手に添削すると

    $(this).click(function(){
        (this.checked)?$(this).parent().find(".owataface").show():$(this).parent().find(".owataface").hide();
    });
    ↓
    $(this).click(function(){
        $(this).parent().find(".owataface")[(this.checked)?'show':'hide')]();
    });

と書くことができる。「this.hoge()」と「this['hoge']()」は等価なのですね。
動的にメソッド指定するときにいろいろラクである。

おわたCHECKBOX俺版

NackyがオワタCHECKBOXとか面白いの作ってやがるので対抗してみた。
コンセプトはHTMLをjavascriptで汚染しない。

<label for="c1"><input type="checkbox" id="c1"/>ちぇっくぼっくす1</label><br />
<label for="c2"><input type="checkbox" id="c2"/>ちぇっくぼっくす2</label><br />
<label for="c3"><input type="checkbox" id="c3"/>ちぇっくぼっくす3</label><br />

<script language="JavaScript" type="text/javascript">
    /* 属性セレクタでinput type="checkbox"を全部引っ張る */
    window.onload=function(){
    $$("input[type=checkbox]").each(function(e){
        /* spanエレメント作成してオワタいれる */
        (span=document.createElement('span')).innerHTML='> \(^o^)/'; 
        
        /* onclickをbindAsEventListener()でセット。一緒にspanを渡しちゃう evtはダミーね */
        (e.onclick=function(evt,owata){  
            $(owata)[(this.checked)?'show':'hide']();
        }.bindAsEventListener(e,span))(); 
        /* Ff対策に一発実行しとく(F5でフォーム値リセットされないし) */

        e.parentNode.appendChild(span); /* labalノードにspan追加 */
    });
    }
</script>
  • $$()はクソ便利だけど、重いらしいので対象が多そうなときは他の方法でコレクションしる。しかし、なぜかIEでも属性セレクタ記述が動作するのがハッピー。
  • spanの追加位置が気に入らなければ、eから辿れるどっかに入れてちょ。
  • bindAsEventListenerの2番目以降のパラメータが便利すぐる。ただしe.checkedとか渡したりしてはダメ。
  • hide()とshow()の条件演算子はやりすぎな気がする。toggle()使いたいところだが、ロード時にcheckedが不確定だからヤメた。
  • (this.checked)?$(owata).show():$(owata).hide();って書くのがちょっとダサい感じがした。
  • ↑で$()使ってんのはElementオブジェクトに変換しないとIEでhide/showできんから。IE死ねばいいのに。

実行はこちら

  • 追記。window.onloadでくくらないと、チェックした後F5で挙動おかしくなるっぽwww