トップ 最新 追記

2011-01-02 [長年日記]

_ Simplenote + ViewSourceWith を安全に使うにはとにかく new file で

普段 Simplenote には Notational Velocity で書いてるし、その方が速くていいんだけど、エディタでキチっと書きたい場合もある。そういう場合は Firefox で Web UI を開いて ViewSourceWith を使うようにしている。

しかしこれがちょっと曲者。というのも、他のサイトでは起きない現象が起きる。それは

何回か同じ文書を ViewSourceWith で編集していると新しい内容が破棄されることがある

というもの。

なんで起きるのかはよく分からないんだけど、二回目以降の編集で

[ Open new file ] [ Cancel ] [ Overwrite file ]

と聞かれたら、

とにかく new file を選ぶ

ことで回避できることが分かった。

Tags: Web

2011-01-05 [長年日記]

_ wkhtmltopdf で Ajax コンテンツを撮影する

なにするものぞ

wkhtmltopdf - Project Hosting on Google Code

  • WebKit
  • Qt

を利用して、コマンドラインで Web ページのレンダリング結果を PDF や画像に変換できるツールです。

今回試したのは static link の OSX(386) 版 0.10.0 beta 4 です。

wkhtmltopdf と wkhtmltoimage ができてた

以前知ったときに、おぉこれはいいなと思ったのですが、うまく撮れるサイトと撮れないサイトがあってちょっと置いておくかーと思っていました。試したバージョンはよく覚えてません。

今回、この中に wkhtmltoimage という文字を見つけたのでこっちを試してみたところ、一部文字組みに凝っているところなどは wkhtmltopdf よりレイアウトの再現性がよいみたいです。*1とは言え、PDF なら文書構造も文字情報も保持されるので、テキストベースの再利用性を考えれば wkhtmltopdf の方がいいわけです。

画像さえ撮れればいい場合は wkhtmltoimage で

--format png

などとした方が劣化もなくてきれいです。

ただし全体の見た目はフォントも影響するので、やはり Linux で作るより Mac で作った方がきれいです。

delay を設定すれば Ajax も ok

例えば bijin-tokei(金沢版)official website / Japanese Ver. なんかは肝心の画像の load が遅延実行されるのでそのまま実行しても悲しいことになります。

でも手元の環境では

--javascript-delay 15000

で撮ることができました。たぶんネットワーク環境にもよるので、この数値は一般化できないと思います。

エラー処理

サーバに繋がって 404 が返って来る場合は exit status は 2 になるけど動作は止まらず、スクリーンショット(?)自体も撮れますが、サーバ自体の response がない場合には abort してしまいます。

これは

--load-error-handling

で回避します。これを skip か ignore にすれば大丈夫。( default はabort. ) skip と ignore の違いはよく分かっていません。skip しても ignore しても何かが render されます。

ライセンス

wkhtmltopdf, wkhtmltoimage の実行バイナリのライセンスは GPL v3 or later になります。ただし、libwkhtmltox の部分は LGPL v3 のようです。libwkhtmltox っていうのも以前はなかったのですが、今後はこれをコアにしてアプリや操作は自分で好きなの作ってよ、みたいな展開があるのかも。そうなると面白いですね。

*1 PDF に文字情報として残したうえでレイアウトを凝ろうとすると苦労するのは通常のドキュメントでも一緒ですよね。


2011-01-07 [長年日記]

_ crontabの書き換えミス防止にWheneverを使おうとして失敗

crontab -e で自分用 reminder

sleep 300 && growlnotify -s -m 'どん兵衛'

てなことも普段やっているんだけど、経過時間ではなく時刻指定で alert を上げてほしいこともよくある。タスクに名前の付くものは Remember the Milk を使っているんだけど、そこまででもない小さなものは cronteb -e して自分用の crontab にそのまま書いてしまうこともある。

crontab の設定ミスに気づかない

ところがこの crontab の設定を時々間違える。致命的な文法ミスなら crontab -e で開いたエディタを終了したときにチェックが走って怒られるんだけど、そういうレベルでは見つからないミスをする。

また、/etc/crontab のレベルなら何度も確認をするのでミスがあってもすぐに見つかる。しかし crontab -e のレベルではそこまで確認しないのでミスがあってもなんとなくスルーしてしまう。

そこでチェックツールか何かないかと思ったけど、見つからないので反対の方向に考えてみた。

Whenever を試してみたものの

crontab の記法だからミスしてしまうので、crontab 以外のもっと分かりやすい記法で書いて crontab に変換すればいい。そういやそんな発想の Whenever っていう Gem があった。

javan/whenever - GitHub

Whenever は crontab を書き換えることもできるのだけど、今回はシステムの crontab ではなくあくまで個人のものなので、

Whenever::Output::Cron.new

を直接呼んでみることにした。例えばこんな感じ。

irb> Whenever::Output::Cron.new( 'sun', 'echo', '10:00' ).output
=> "0 10 * * 0 echo"

なんかちょっと使いにくい。

もうちょっと簡単にできないかと思い、Whenevrer が時刻指定の parse に使っている Chronic を読んでみた。

mojombo/chronic - GitHub

けど、Chronic 自体はほんとに parse しかしてない。crontab 形式に format するのは Whenever の仕事。

で、Whenever の中で parser を探すと、どうも頑なに frequency を設定しようとしている。つまり、

単純な reminder にはオーバースペック

らしいということが分かった。

結局、未だに何一つ変わってない。うーん。本格的に欲しくなったら DateTime.parse ベースでシンプルなやつを自分で書いた方がいいかもしんない。


2011-01-09 [長年日記]

_ Stub と Mock の違いが分かってきた気がする

mock という言葉だけは知っていたが、実際に mock を作って使ったことはなかった。いよいよ mock を使わないとなぁと思い始めたところで mock は stub じゃないと聞こえてきた。えー。stub ってなんだろう。

今回は RR ( Double Ruby ) の v 1.0.2 を試しながら stub と mock の違いを学んだ話。

btakita/rr - GitHub

stub

例えば RR では

stub( object ).method_name { return_value }

という書き方で object の method を stub 化したものが得られる。戻り値が、ではなく object そのものが stub 化している。

object.method_name      # => return_value
object.method_name( 1 ) # => return_value

この object の .method を呼ぶと規定通りの return_value が返る。引数を指定せずに stub 化したのでどう呼んでも同じ値が返る。*1

特定の引数に対して stub を設定する場合は

stub( object ).method_name( arg ) { return_value }

という書き方になる。この場合は arg 以外の引数を与えた場合には動作しない。

ある Klass クラス のオブジェクトすべてを stub 化したい場合は以下のようにする。

stub.instance_of( Klass ).method_name { return_value }

で、これを利用して何らかの動作をするオブジェクトをテストする。stub 化した object を直接テストすることも可能だけど、それはやっても意味ないよね。あくまで stub 化した object を「使う」オブジェクトのテスト用だろう。最もよくあるのは I/O を担うオブジェクトを stub 化することでテストに必要な準備を減らし、テストのスローダウンを避けるといった用途になる。あるいは未実装の機能を呼び出したり外部 API へのアクセスをなくすとか。

スタブは主に生成したりコントロールしたりするのに手間がかかるオブジェクトをもみ消す [stub out] のに使われる。典型的なのはデータベース接続だろう。[手間のかかるオブジェクトを"もみ消す"ので、] 結果としてスタブを見かけるのは、ほとんどの場合、システムの外部との境界や、システム内の複雑なオブジェクトの塊のあたりだったりすることになる。スタブは、実際のオブジェクトと代替できるようインターフェースの実装をし、実際のメソッドをシンプルな [テスト用に] 準備されたデータを使うメソッドで置き換えることで作られる。

ということは stub で覚えてしまおうとしないで stub out で覚えるべきなんだな。

まとめ

RR では

  • 引数を(与えずに|与えて) stub 化
  • 戻り値を(与えずに|与えて) stub 化
  • (クラス|特定のオブジェクト|あるクラスの全インスタンス) の stub 化

を組み合わせて使える。

用途に応じて使い分けるといい。

例えば Rails の Model を stub 化する場合はある id の場合に nil が、ある id の場合にはインスタンスが返るようにしておくとそれっぽく Controller をテストできる。*2

mock

mock は stub に似ているが expectation を object に加えることができる。mock を作っておいて呼ばないテストは失敗する。つまり mock は所定のメソッドがちゃんと呼ばれているかどうかをテストするために使う。値も返せるので返る値を使った他のテストも行える。ただし戻り値を利用したテスト*3を重視するなら stub を使えということらしい。

stub の場合と同じく RR では

mock( object ).method_name { return_value }

で mock を定義する。上の場合は method は引数を受け取らない。受け取れない。

mock( object ).method( 1 ) { return_value }

の形で定義すれば引数として 1 を受け取ることができるようになる。

イメージとしては mock オブジェクト自身がテスト主体となるような感じか。RR の場合は RR.verify を呼ぶことで、定義した mock が想定通りに実行されていない場合に例外を投げてくれる。

例えば上の定義にしたがって RR.verify を実行する場合、object.method( 1 ) が 2回呼び出されたらエラーになる。何回読んでもよい mock にしたい場合は

mock( object ).method( 1 ).times(any_times) { return_value }

のように記述する。

mock( object ).method(anything).times(any_times) { return_value }

とすれば引数には何でも与えることができる。ただしこの場合は一つ。二つの場合は

mock( object ).method(anything, anything).times(any_times) { return_value }

になる。

また、すべてのインスタンスを mock 化したい場合は

mock.instance_of(Klass).method_name

になるが、この場合もメソッドは1回しか呼ぶことを想定していない形になるので、

mock.instance_of(Klass).method_name.times(any_times)

にするとあらゆるオブジェクトが何回呼ばれても大丈夫になる。

※ ただし1回しか呼ばれないことを想定しているなら、当然この場合は mock としての要件を満たしていない。

mock ライブラリはテスト対象の object を受け取り、mock 自体が、テストしたい振る舞いが object に存在し、正しく呼び出されているかどうかを確認する機能を提供している。(つまり BDD で言う matcher もこの mock ライブラリが用意する。)それ以外の使い方も「一応」できるように return_value の定義もできるが、これは半分おまけのようなものと考えればいいのかな。

感想

mock, mock と言ってきたけど、自分の求めていたものは stub あるいは fake なのだなと思い始めている。少なくとも「呼び出され方」などは今までテスト可能だと思ったことすらなかった。恥ずかしながら。

mock の使いどころはもう少し考えるとしてまずは stub をきちんと使えるようになろうと思う。これは mock の使いどころがまだよく分かっていないためでもあるけど、

RR は明らかに stub 定義の方が簡単

という辺りに、そういう「意図」がこのツールにあると思えるからでもある。

参考

*1 return_value は必ず定義しなければいけないわけではない。その場合は予想通り nil が返る。

*2 ただし本当にうまく活用するためには scope を使って検索条件をシンプルなメソッドのようにしておいてそれを stub out する、という手間が要る。ここら辺の扱いが上手くなると開発効率はだいぶ高くなるはず。

*3 これを mock と stub の違いを説明する際には「状態中心のテスト」と呼ぶ


2011-01-10 [長年日記]

_ レガシーコードをライブで扱う際のポイント試案

twitter で TDDBC Hokuriku (2010) のレガシーコード改善を Coding Dojo で行った際の Ruby チームは比較的うまくいってたけど、あれって○○な流れだっけ的な話をしているうちに気になってることをまとめておこうと思い立ったので、できるだけ書き出してみる。

何かのきっかけになれば嬉しい。

素材(レガシーコード)のポイント

  1. まず動くこと
  2. 触ったことがあること*1
  3. ある程度でいいので機能別に書かれていること
    • オブジェクト指向であるとなお良い(使える技が増える)
  4. 小規模であること
    • ただし完全に単機能だと余地が少ないのでテストを足しにくい
    • 外部 API 依存しまくりの場合は単なるレガシーコード改善とはまた別なテクニックの習得に繋がってよいかも
  5. 自動実行できるテストがないこと :-)

1 については「えっ」て思うかもしれないけど、放置してるものは依存ライブラリの関係や、そもそも動かし方がよく分からない(覚えてない)など、動かないことがよくあるので、素材を事前に用意できるならこの部分をチェックしてあるとだいぶ話が早い。

文字列処理、数値処理などテストしやすい機能が独立していると改善は早いけど、あまりきれいに分離されていると分離するまでに使える技をおみまいできないので、悩ましいところかも。

ただライブで扱う際はどうしても時間的制約が大きいのであまりに難しい題材を扱うのはまず無理だと思う。

事前準備のポイント

素材を用意する人は

  • コードの読み込み
  • 動作テスト

を入念に行っておくのがオススメ。

特に自分で書いたわけではない(オープンソースなどの)レガシーコードを相手にするのは難易度高めなので事前準備が大切になってくる。

この部分は TDD の知識の有無、経験値は関係なく準備できる。古典的な「読ん」で「動かす」でよい。できれば「こうしたい」という要求が挙げられるとよいけれど、それがイベント内で達成可能なゴールになるとは限らない。

これはそういうもんだと思っておくとあまりガッカリしないで済む。なんでもそうだと思うけど、達成可能なゴールの設定にはある程度経験が必要。

レガシーコード改善手順を復習

レガシーコードをレガシーコードでなくすこと自体が目的ということはそれほど多くないと思う。継続してメンテナンスが必要だけど修正ポイントを見つるのが大変、リグレッションテストのコストが大きすぎて大変、てゆーか影響範囲が判断不能、といった事情があるはず。

そこでテストを付加していくわけだけど、その手順を書き起こすと大きく三つ、

  1. テスティングフレームワークに載せる
  2. characterization test から徐々に TDD を回す
  3. 修正、機能追加やリファクタリングを目指す

に分けられると思う。

サイボウズの記事のようにユニットテストよりも Selenium レベルのテストを重視するという方針ならそもそも話が変わってきてしまうんだけど、基本的には TDD を回すと言った場合はある程度「ユニットテスト可能」な状態を指すと思うし、Selenium 重視になるとテストデータの投入の自動化とかそもそも Web アプリじゃなかったらどうするのとか、クリアすべき課題がさらに増えてしまうので、ユニットテストを付加していく方向で考える方がイベント時の手順として汎用的に使えるだろう。

レガシーコード改善チーム編成のポイント

レガシーコードの改善をイベントでやろうとする場合、

  • ペア以上の人数で一つの素材に取り組むチームを作る*2

そのチーム内に

  • TDD に慣れている人*3
  • コードに習熟している人

の両方を置く

という形がベストだと思う。どちらが欠けてもイベントの限られた時間内でゴールに到達するのは難しくなるだろう。

理想的には上に挙げた人が一人ずつのペアを作れると最も速度が出て効果的に学習できるのだが、そんなに大量に TDD エキスパートが揃うとは思えないので、チーム内に一人ずつを目指すのがよいと思う。

ゴールは素材とイベントの規模とチーム編成次第

さて準備が整ったところでレガシーコード改善に実際に取り組むわけだけど、個人的には先に挙げた 3つのどのステップをゴールに設定してもよいのではないかと考えている。

どこをテスティングフレームワークに載せるのか

レガシーコードすべてを一度にテストに載せるのは多くの場合で無理なので、特にどの部分をテストして、修正、機能追加、リファクタリングに結びつけるかを考える。この際、ややこしい依存がいくつもある部分を選んだ場合はテストハーネスに載せるまでの苦労を実践的に味わえる。

現実の「どうにかしたい」レガシーコードの中にはそういうとてもややこしいことになってしまっているものも数多くあると思う。とにかく片っ端からそうしたコードをやっつけていきたいので、まずはここを強化したいと考え、あえてテスト開始の難しい素材でやるという選択もアリだと思う。

というかそういう素材しか見つからない場合だってあり得る。その場合はテスト可能な状態を作るだけでも良しする判断もあるんじゃないか。2〜3時間から半日程度の規模ならここまでで終えてしまうケースも増えると思う。

例えばコンストラクタが頑張りすぎてて依存オブジェクトが多い場合はまず依存オブジェクトを初期化する処理をそれぞれ別メソッドに分ける、外部のライブラリをあちこちで呼んでいる場合は wrapper にまとめる*4、本当に果たすべき一つの責務を見つけ出す、継承してテスト用クラスで override して依存を分離する、など身につけたいテクニックはたくさんあるわけだが、多くの場合、一時的にはコードが膨らんでしまうし、この作業に掛かる時間を事前に読み切るのは難しい。

逆にすべてを体験したい場合には

ややこしい依存のないコード、あるいは依存を分離しやすいコードを選ぶ

ことになる。

もう一つ、テスティングフレームワークに載せる部分は修正、機能追加、リファクタリングを行う部分なので、2番目以降のステップに繋げやすいという要素も重要になってくる。

例えば機能としては独立しているのでテスティングフレームワークに載せるのは比較的容易だが、外部あるいはブラックボックスの API 呼び出しだらけとかメソッドがちゃんと入出力を持つ関数として機能せずに副作用だらけで動くようなものは TDD の入門素材としてはあまり適していない。(無理じゃないけど。)

TDDBC Hokuriku 2日目の Coding Dojo Ruby チーム は比較的うまくレガシーコードの改善が進んだのだが、このときの決め手の一つは t_wada

「パーサがありますね! パーサいいですね! パーサにしましょう!」

だったと思う。この決断は TDD への習熟から生まれてきたものだろう。

characterization test から徐々に TDD を回す

レガシーコードはテストコードのないコードなので、当然機械的に確認可能な仕様が存在しない。仕様書はあるかもしれないが、それが現在の動作と合っている保証はない。そこでまず現状把握のためのテストを書く。これを Characterization Test と呼ぶ(『レガシーコード改善ガイド』第13章)。テストするのはもちろん変更を加えたい部分とその周辺。

これがすんなりうまく行くようならしめたもの。その後の修正、機能追加、リファクタリングに集中できる。

しかしたぶんそんなにうまくいかない。そのメソッドが想定通り動く条件をすぐに満たせるかどうかが分からない。インスタンス生成はうまくいってもメソッドの呼び出し時にはいきなり例外が上がる可能性もある。また、目的のメソッドは副作用を基本にしたメソッドかもしれない。そうなると検出用変数の追加など、テストなしで加えなければいけない変更が出てくるかもしれない。

目的のメソッドをテストできるようになったらようやくそこがスタート地点。境界値など一般的なテストを書いて仕様を確認していく。

「現場」においてはこの段階は次のステップへの繋ぎなのでゴールにはならないのだけれど、これもイベントにおいては状況次第かなと思う。次のステップへ進むために遠回り(目的とは異なるメソッドのテストや stub out など)が必要な場合も考えられる。そうなってしまうとどこでその遠回りが終わるかの予想が難しいこともあり得る。

修正、機能追加、リファクタリングを目指す

修正、機能追加を行うためにはその部分をテストでガードしましょうというのが TDD の基本である。(それ以外の部分もガードできないと本当はダメだけど、そこは置いておく。)ということでガードできたところからプロダクトコードをいじり始める。ただし、レガシーコードをいじる場合、

影響範囲が閉じていて簡単に変更できるなんて平和なことは少なく

  • 影響範囲は小さいがメソッドは巨大で if や case の嵐
  • 一つのメソッドで多くのインスタンス変数やメソッドを呼び出している

なんてことがザラにある。要するに

レガシーコードはクラスやメソッドの仕事が多すぎる傾向にある。

方針としては

仕事(責務)を一つに減らすことが理想

と言えるが、これは恐らくそれほど簡単には実現できない。つまり、リファクタリングをゴールにする場合は結構時間が掛かることを覚悟しなければいけない。

だから修正や機能追加をゴールにする方が時間設計上は楽だと思う。

それでもリファクタリングしたいという場合、「リファクタリングのための準備」くらいで我慢しなければいけないこともあり得ると覚悟しておこう。例えば

  • 不要なコードは削除する
  • メソッド丸ごと別クラスに分離する
  • if, case の嵐は実際の処理を別メソッドに分けて、override できるようにする

など。

上の文字だけを見ると単純な話のように見えるけど、これはこれでちゃんと準備して施術する必要があり、かつ効果は予想以上に大きい。場合分けすると複雑で長くなってしまうコードも、override を前提にすれば個々の処理はそれほどでもない場合は多いし、独立クラスに追い出してしまうと結果的にコードの長さが長くなったとしても、可読性が高く短い処理に分割しやすくなる。

また試行リファクタリングも効果的。これは実際には捨ててしまうことを前提に理想的なコードを組んでみることで、クラスやメソッドが本来果たすべき責務を明らかにするために行う。ただしこれを踏まえて作業できるとは限らない。非常に根の深い問題を抱えている場合は試行リファクタリングで見つけたような気がした理想的な状態をいったん捨てて*5、地道に取りかかれるところだけを作業しなければいけないこともあり得る。実際にできあがったコードだけを成果として捉えてしまうとこれはとても寂しいが

できないことが分かる

ことも成果である。

まとめ

個人的には TDD のキモの一つは依存の分離だと思う。テストしにくい依存はどんどん分離してテスト対象の動作に集中して回転を上げていく。これができるからこそ TDD はリズムが良く、小さなミスの発見、小さな設計変更、小さな達成をくり返すことができる。

これはレガシーコードを相手にする際により大きな意味を持つ。レガシーコード特有の問題ではないが、レガシーコードは往々にしてブロック*6が大きすぎ、それぞれの責務が曖昧で名前もぼんやりしている傾向にあり、依存ライブラリを含めて本番と同じ動かし方しか想定していないので分離の難しい傾向にある。だから TDD で書き始めたコードよりも

大胆な依存分離テクニックと発想、そのための調査

が大事になってくる。

自分にはそれほど多くのレガシーコード改善経験があるわけではないが、レガシーコードとの戦いに有用な依存分離テクニックは伝統的なオブジェクト指向の教科書的な方針とぶつかることがあることは知っている。しかし多くの場合で教科書を補足する原則には反していない。つまり、実はオブジェクト指向の周辺知識がとても有効な武器になる。

レガシーコードとの戦いはつらい。だがレガシーコードを切り刻んで TDD 可能なコードに改善する作業も楽ではない。これは総力戦だと思う。レガシーコード改善のためには TDD への習熟も必要だし虫食いの知識を補強する必要もある。そしてこれをイベントで扱う場合は「楽しかった!」「勉強になった!」と簡単に言えないケースも想定しておくことが大切だと思う。

最後のまとめの発表では「ここまでしかできなかった」という気持ちにならないこと。「この課題はここが難しかったがここまで進むことができた」と締めくくろう。

あ、『レガシーコード改善ガイド』はオススメですよ。これを読むと

勇気が手に入る。

諦めていたレガシーコードともう一度戦ってみようと思える。同時に、何が大事なのか、捨ててよいものは何かを考える契機にもなるし、戦って負けてもそれはそれで別な方法で再戦しようと思えるようになる。

自分が段階的なゴール、段階的な成果を前提にこのエントリを書いているのもこの本と TDDBC Hokuriku (2010) の影響だと思う。

ありがとう。

参考

*1 読むだけでなく、ここをこうしたい、と思える程度にはコードをいじったことがないとテストを付加して何を行うのかが見えてこない

*2 一人で学ぶよりその方が早い

*3 できればレガシーコード改善の経験のある人

*4 この場合は元のレガシーコードにはまず触らず、wrapper だけを独立して TDD で作り、のちにこの wrapper と統合するのがよいだろう。

*5 つまり書き上げたコードだけでなく理想的な設計と思えた形も両方捨てる

*6 if, case, メソッド、クラスなどなど


2011-01-12 [長年日記]

_ Gitのbranch付きbundleの扱いがよく分からない

まとめ

まるごと rsync して解決してしまったので分からないままです><

たぶん clone --mirror でうまくいくみたい。

これまでは一直線 master のみの bundle しか扱ったことがない

bundle を使って何をしているかというと目的は大きく二つあって、

  1. 開発者以外の作業スペースのガード
  2. 開発環境のバックアップ

開発だけではサイト、サービスは完成しない。デザインする人もいれば内容を作り込む人もいる。それらの人の作業は残念ながら古き悪しきファイル共有ベースで行っているので、いつどんな事故が起きるとも限らない。そこで開発環境のコードと bundle を使って同期させている。せいぜい日に 1, 2度、手動だが何もしていないことに比べれば安心感は絶大。*1

もう一つのバックアップについては git の command をたくさん覚えるより repository 丸ごとパッケージにできてそこから復元できる bundle で十分かなということで一石二鳥だと思って bundle を作っている。

また職場での git の使い方は git + svn ( git-svn じゃなくて別々に使う ) が中心で、ほとんど branch は使わずにやってきた。svn 側で branch を切って作業を始めるので git 側はバックアップ以上の意味があまりないのだ。

branch 付き bundle は意外に面倒くさい

git を使い始めて2年以上経っているのに今さら branch 付きの bundle を試してみた。今回はいつものガード目的ではなくゼロから作業できる Rails 関係のコードを branch も使いながら git に突っ込んでいる。これをいくつかの環境で正しく動くかどうかを確認しようってわけ。

まず今まで通り

$ git bundle create {FILE} HEAD

してみた。でもこれだと current branch しか bundle に入らないうえに branch の情報が残らないみたい。こんな感じ。

$ git clone {FILE}
$ cd {FILE}
$ git branch
* (no branch)

branch の情報がさっぱり残ってない。

$ git bundle create {FILE} HEAD --branches

とすればよいのかと思ったが、この場合も

$ git branch
* master

としか表示されない。topic branch で作業していたのに、master branch しかないことになっている。

$ git bundle create {FILE} --all --branches

として bundle を作ると少し変わる。この場合は

$ git clone {FILE}
$ cd {FILE}
$ git branch
warning: Duplicated ref: refs/remotes/origin/branch1
warning: Duplicated ref: refs/remotes/origin/master
* master

と表示される。うむむ? branch があることは分かっているみたいなんだけど、実際には branch として fetch できていない。のかな?

--mirror 付きで clone すればいいのかな?

[2011-02-12 追記]

bundle の話は Pro Git にも書かれておらず、なかなか情報が見つからない。役に立ちそうなのはこれかな?

git - Backup of github repo - Stack Overflow

なるほど --mirror や --bare 付きで clone するのか。

$ git branch
warning: Duplicated ref: refs/heads/branch1
warning: Duplicated ref: refs/heads/master
  branch1
* master

duplicated ref な warining は出るが、ちゃんと branch の情報を保持したまま clone できたようだ。とりあえずこんな感じかなぁ?

もっと分かる人いたら教えてください。

cf.

Tags: Git

*1 開発用の repository は svn なので git や hg を併用することで「違い」をそのまま吸収できるメリットもある。


2011-01-15 [長年日記]

_ Google Chrome で RTM の priority を変更できなかった話

まとめ

LDRize のために入れていた Chrome KeyconfigType-ahead-find が悪さしていた。

Chrome Keyconfig

オプションで 1 などダイレクトに入力する数字にタブ移動の機能が割り当てられている。この数字は RTM で priority の設定に使われているので、思い切ってこの設定は削除した。

Type Ahead Find

Type Ahead Find は Ctrl + F や Cmd + F を入力しなくてもページ内のリンクを検索してすぐ遷移できるように入れてるんだけど、どうもこれがリンクじゃない 1 を拾ってるみたい。

仕方ないので

http://www.rememberthemilk.com/home/*
https://www.rememberthemilk.com/home/*

を blacklist に入れて対処した。

Tags: Google Web

2011-01-18 [長年日記]

_ Typusのcsv downloadがセミコロン区切りな件

以前も紹介した Typus は 3.0.3 相当のバージョン以降*1 CSV で DB の内容を download する機能が動いているんだけど、これがなぜかセミコロン区切りになっている。

lib/typus/controller/format.rb
    def generate_csv
       fields = @resource.typus_fields_for(:csv)

       filename = Rails.
                    root.
                    join("tmp",
                         "export-#{@resource.to_resource}-#{Time.zone.now.to_s(:number)}.csv")

       options = { :conditions => @conditions, :batch_size => 1000 }

       ::FasterCSV.open(filename, 'w', :col_sep => ';') do |csv|
   ...

(v. 3.0.6 で確認)

こ、これは。完全に決め打ちじゃないか。

セミコロン区切りの CSV なんて聞いたことねーよ、と思ったけど、これ OOo では正常に開くことができる。というかむしろ OOo 的にはデフォルトがセミコロンらしいという話も。

どっちでもいいけど field separator くらいは指定させてほしいなぁ。

[2011-01-20 追記] typus を gem 版 3.0.2 から github 版に置き換えたらせっかく用意してあった _t() って I18n 関係の便利メソッドがなくなった。便利だったんだけどな。

Tags: Rails Ruby

*1 3.0.3 の release はない


2011-01-19 [長年日記]

_ sendmailのforwardで忘れもの

すっかり忘れていた。

  • 少なくとも CentOS では webmaster -> root の alias があるので webmaster アカウントで cron を動かしても webmaster 宛にはメールは来ない
  • /etc/aliases をいじったら newaliases を実行しないといけない
  • ~USER/.forward は 0600 で

shlauncher を使ってこの辺のメールを投げるような処理もまとめていった方がいいかもなぁ。

Tags: Sysadmin Mail

2011-01-20 [長年日記]

_ Chromeが問答無用で閉じちゃうのがちょっと困る

Firefox から Chrome に移行してほとんどの機能は標準のものや拡張でどうにかなってるんだけど、一つだけ解決してなかった要望が

複数のタブ、ウィンドウを開いてる場合だけ終了時に確認を入れてほしい

だった。どうやって探したらいいかもよく分かってなかったんだけど、見つけた。

Confirm Close - Google Chrome 拡張機能ギャラリー

入れた。

快適。

Tags: Google Web

2011-01-21 [長年日記]

_ 改めてRubyとbundlerとオープンクラスとgithubに感謝

Railsで初めてモンキーパッチを当てたときに変に感動して連投したtweetより。

11/01/20 10:43 Railsの中身がよく分かってないのでどこで対処すべきかうま
               く判断できない。でも Ruby だからなんとかなるだろうと読
               んで踏み出したし、実際なんとかなった。オープンクラス最
               高。
11/01/20 10:44 Ruby + githubの組み合わせがとてもよい。モンキーパッチで
               対処できるし、最悪本家へのフィードバックが届かなくても
               github的な意味でforkしてしまえばよい。
11/01/20 10:48 加えてbundlerがステキ。bundlerでforkしたrepository見に
               いくようにすればアプリ側は何も気にする必要がない。
11/01/20 10:49 PHP + svnのライブラリでパッチ投げて無視された(内容云々
               じゃなくてもうメンテ継続してない)ことが何回かあるけど、
               この場合面倒くさい。モンキーパッチも作りにくいし、fork
               も面倒。bundlerのような仕組みもないのでライブラリをこっ
               そり差し替えたりするのが手間。
11/01/20 10:57 Railsもまぁいろいろあるんだろうけど、自分はやっぱRubyの
               方がしっくりくるな。http://bit.ly/hxmmTb 「Lisperは臆病
               なんです。」とても強く響いている。実は。

いっぱい書こうと思えば書ける話なんだけど、膨らみすぎるのでそのままにしておく。

Lisp:よくある正解

Ruby は Lisp だなんてことを言うつもりはないし、そんなことが言えるほど Ruby も Lisp も分かっているとは思っていない。でもこの言葉は自分の中でとてもしっくりきている。

そういう状況において、「どんなに汚くても、打てる手段がある」というのは 何物にも替え難い救いなのです。というより、そういう予想外の事態に対して エスケープポッドが備えられていない処理系を使うなんて恐くて出来ません。 Lisperは臆病なんです。

例えばオープンクラスでない言語 + github などの fork 上等なリポジトリホスティングを使っていないライブラリやフレームワーク*1を採用してしまった場合、後から「しまった」と思ってもどうにもならない。

ある程度 Ruby を使える自信があるなら、それは下手な「実績」なんかより Ruby を採用する理由として十分だ。今なら以前より強くこれを言える。

LL だから、OSS だから、だけじゃないんだよな。

Tags: Rails Ruby

*1 PHP + sf.net とか


2011-01-22 [長年日記]

_ Mashup Seminar in FUKUI 2011 に参加してきた

Mashup Seminar in FUKUI 2011 | アップグレードふくい

道中すごい雪に当たったけど、なんとか無事に行って来れた。

アップグレードふくいに初参加

場所は福井県産業情報センタービル。初めて行ったけどこの辺はソフトパークふくいと言っていろんな企業、施設が並んでる。結構立派な建物で、会場もなかなか広かった。ぱっと見でパソコン開いてる人は1, 2割くらいで、年齢層は広め。女性も少ないながらもいたのは普段の勉強会と違うところか。*1

アップグレードふくいはこのような催しの総称のようなもので、定期的に行われている。財団法人で新しいことを試みながらこれだけ継続しているのは北陸ではアップグレードふくいくらいじゃなかろうか。少なくとも石川ではコミュニティベースのもの以外は IT 系はまったく注力されていない。この違いはなんだろう。

感想

内容は紹介のページに譲るとして感想を。

Mashup Award 6をふりかえって

全体的に MA6 の可能性や熱さ、ゆるさは伝わったけれども、具体的に参加のためにこんなことをするといいよ!って話があったらもっとよかったかも。

特に今回の最優秀賞が EmiriSystem っていうのは心理的なハードルの高さがハンパないので。

EmiriSystem

いちばん上からいちばん下まですべて一人で開発、運営している EmiriSystem の全貌の話。

10年掛けてるとは言え、普通の人には時間的にここまでのものを作るのは不可能だと思う。よくよく聞いているともともと関係ない分野と言え研究開発が仕事だったり、グラフィックデザインにも興味があったとのことで、EmiriSystem そのものが直接仕事に活かせなくても何らかの形で生きているんだと思う。

単なる Mashup というレベルは完全に越えている。

印象に残ったのは今後の課題。継続性、専門性、品質。

1PACと世界の最近の事例から今後について

「透明化する境界線」というタイトルは話を聞くまで今ひとつピンとこなかったんだけど、なんというか、圧倒的だった。なんだこれ。Web の話は多くないですというかほとんどないというか。Web は「ソーシャル」という意味ぐらいしかなくなってきている。

いや、正しいのかもしれない。もともと Web の目的なんてシンプルなものだったし実装もシンプルなものだった。我々の日常の様々な活動は当然 Web では完結しないし、Web だけにこだわる意味もあまりないのかもしれない。それだけプラットフォームとして成熟したと言えるのかも。

そして「Web"上"」という「枠」も要らないのかもしれない。繋がり方はそれぞれで、HTTP は使っているかもしれないし Flash などの技術も使っているかもしれないけど、結果として我々人間とのインターフェイスはもはや Web と意識されていない、そんな世界に近づいている気がした。

Rails とか言ってる場合じゃないのか。いやまぁ、今回はフロントエンド中心の話だからね。バックエンドの話はまた別。

印象に残ったのは「会社としてできることの枠を広げる」というテクニカルディレクターの役割と、「新しいことに挑戦するのにデメリットはない」という言葉。

あと、普通にフィードバックとかアフォードとか言葉が出てきたけど、自分の足下を見てどれだけ通じるだろうという不安も感じた。

FITEA とコンペ報告

福井情報技術者協会[FITEA]

勉強会やってるよ、発表側になると勉強になっていいよ、具体的にはこんな感じだよ、という話と、学生さんのコンペの発表。

Twitter / @S Jun-ichi: FITEAはおっさんになりたい若い技術者を求めていま ...

いや、それどうなの。

まぁ若い人もおっさんも一緒に頑張りましょうということで。

まとめ

Mashup Awards は興味はありながらも参加がかなわぬまま何年か経ってしまっている。そのまとめが聞けるならと、けっこう軽い気持ちで参加して、かなり内職する気まんまんだったんだけど、かなり間違っていたことを痛感した。

MA が、というよりは自分の意識の問題というか、あえて偏らせていたとはいえ、だいぶ「今」が分からなくなっていることを感じた。視点の違いでありアプローチの違いであり、可能性の違い。

自分は SIer でないにも関わらず最近はかなり SIer 的なスキルを自分に要求するようになっている。それは「結局システムの会社でない限りは社内の人間もお客様のような存在にならざるを得ないシーンが多いから」だ。SIer の課題を分かっているわけではないし、SIer によく聞く非効率的な制約もそれほどない環境ではあるが、「本来できるはずのことができていない」という感覚は強い。それを解決するための一つの方法として自分に SIer 的なものを求めている。

一方で、今自分に求めているやり方は、「失敗を減らし確実に前に進めるためには有効」だが「何か新しいものを生み出す」という意味ではたぶんベストではないと思う。そのこととそのために大切なことを、このセミナーでいくらか感じ取れたのではないかと勝手に感じている。

こういうのは、文字じゃ伝わらないんだよなー。

Tags: 日々

*1 北陸はコミュニティベースよりも「公」の色があった方が女性参加者が増える印象。というか女性のコミュニティとは分断してるのかもしれない。


2011-01-23 [長年日記]

_ Kanazawa.sysadmin を考えてみる

先週(1/17)、ぼそっと kanazawa.sysadmin と twitter に流したら良好な反応があったので、ちょっと遅くなってしまったけどアイディアを吐き出してみる。

対象

専門として、あるいはたまたまシステム管理的なことをやっている人

  • ホスティング企業勤務
  • いわゆる企業の情シス
  • いろいろなものを納入する業者(事務系でもセットアップやメンテくらいやるよね)
  • ショップの人
  • たまたま周りより詳しい学生
  • なんとなく興味ある人

てゆーか、システム管理ってなんだろう?*1 風呂敷を広げてみたら自分もよく分かっていなかった感じ。

レベル不問。

内容

  • サーバ管理の困った/こんな工夫してます
  • クライアント管理の困った/こんな工夫してます
  • その他業務支援の困った/こんな工夫してます
  • デバイス、ネットワーク周りの困った/こんな工夫してます
  • こんなユーザー企業が好き/いやだ
  • こんな納入業者が好き/いやだ
  • sysadmin の自負/悲哀
  • ほか

たぶんまだまだあるんだと思うけど。

パターン

方法もいくつかあるような気がする。大きく分けるとこんな感じ?

  1. 洗い出し、ブレインストーミング(発散系)
  2. 調査、読書、ハック(絞り込み系)
  3. まとめ

いずれかを行ったり来たりするような感じになるんじゃないかな。

会場

恐らく小規模で地味にいくと思うので、金沢では

  • ITビジネスプラザ武蔵
  • 近江町交流プラザ
  • 勤労者プラザ

辺りの会議室を使わせてもらうのがお手軽でいいんじゃないかと思っている。

電源、ネットワーク周りの設備を考えるとITビジネスプラザ、そこにこだわらない、例えば本を基本にしたり持ち寄った資料でディスカッションをベースにするのであれば、近江町交流プラザや勤労者プラザの方がたぶん安くあがる。近江町は平日の遅い時間なら駐車場無料なのもポイント。

とりあえず第0回は

  • 内容はどれでもよい
  • 発散系で以下のように考えると合計 2.5h ちょっと短いか?
    • 中くらいのネタ ( 30m )
    • LT ( 15 ( + 5 ) x 3 )
    • アンカンファレンス的なディスカッション ( 1h )

人数次第なのでまずはどれだけ広報できるかと、「客寄せ」のネタが揃うかどうかがポイントかな。ある程度頭数が揃ったらディスカッションでいろいろ探れるんじゃないかと思う。

あるいは

  • 完全に kanazawa.js 方式にして各自が自由に自分のやりたいことをやる

という手もあるんだけど、js のようにキャッチーで明らかに需要のある分野でもないというか、分野が広すぎるのでさすがに躊躇してしまう。この方式で行けそうかどうかは第0回次第な気もする。

いつやる

時間が短くなりそうなら平日にやっちゃう手もあるんだけど、平日の勉強会って自分でも参加の可否が読みにくいので厳しいのかなぁ。あと遠方からの参加は難しくなるね、当然だけど。

でも週末は大きくて魅力的なイベントが多いのであえて外して平日の方が地味で良いかも? もうそろそろ勉強したい人はみんな時間埋まってきてるよね。週末は割と魅力的なイベントが多いし、家族サービス大事にしたい人はあまり週末の長い時間を割きたくないでしょう。

週末やるならあんまり短い時間はどうかなってちょっと思ってしまったりするんだけど、とりあえず第0回は週末の方が都合合わせやすいかな?

サイトどうしよう

kanazawa.js は facebook や tumblr を基本にしていてイマドキな感じ。ML が必要だとこの構成だけじゃアレだけど、必要ないならこんなんでもいいのか。どっちも自分はほとんど使ってないからよく分かってないけど、見せたい情報にフォーカスさせるのはこういう方法の方がやりやすいのかもしれない。

qwik.jp も使ってみたいと言えば使ってみたい。asakusa.rb リスペクトというか。ただ、未だに何ができるのか自分でもよく分かっていない。

Google Groups はイマイチな気がする。ML しか考えてないならいいけど、ページの記述やらなんやらがどーにも。あんまりやる気ないみたいだし。

github + github pages ってのは技術的に面白そうだけど、テキスト情報以外はあんまりお手軽じゃないよね。うーん。まぁそれも sysadmin ぽいと言えばぽいけど。

*1 自分の中では「何でも屋」の一言で片付けちゃってるけど。

本日のツッコミ(全1件) [ツッコミを入れる]

_ ゆういちろう [kanazawa.sysadmin 賛成。是非やりたいですね。 まとまった時間を取ってハックする時間が取れない..]


2011-01-24 [長年日記]

_ iGoogleガジェット + 何か

wtnabe 11/01/22 22:37 Google Chrome 拡張の RTM のようなものが Firefox
にも欲しいなぁ
wtnabe 11/01/22 22:45 おぉ、サイドバーで開くこれがまさに Google
Chrome 拡張で開いてるやつか。なるほど。
wtnabe 11/01/22 22:47 ブックマークツールバーから外に出すのは無理なのか
wtnabe 11/01/22 23:09 結構この iGoogle ガジェットを使う方式いいな。

って思った。

cf.

iGoogle って使ってないからあまり意識したことがなかった。

Tags: Web

2011-01-27 [長年日記]

_ 今さらab以外のテストツール調べた

ふと twitter 上に httperf という文字がよぎったので、はてなんだべと調べていたらこれが見つかった。

Programing Bible:Webの負荷テストに使えるフリーソフトウェア (1/2) - ITmedia エンタープライズ

で、感想としては

  • 普段使いなら ab でいいかな
  • より複雑で実際の環境に近いテストは Siege がよさげ
    • Siege 入れられない環境とか ab 入ってない環境は httperf がよさげ

という感じかな。httperf は流行ってるらしいけど ab から積極的に乗り換えるほどでもないように見えた。もちろん Apache をインストールしていない環境の場合は話は変わってくると思うけど*1

Siege

proxy で URL 収集ができる。収集した URL からランダムにマルチスレッドでリクエストを投げるので、より実際の環境に近いテストができる。らしい。

パッケージ有無
fink NO
CentOS YES
Debian YES
MacPorts YES

httperf

パッケージ有無
fink YES
CentOS YES
Debian YES
MacPorts YES

参考

上の記事は日本語訳は sf.jp が元記事で、さらにオリジナルは linux.com らしい。これだけリンクしとけば情報源としてどれかは生き残るだろう。

Tags: Web

*1 Apache 1.3系が信用できないとかいう話になるとそれはもう残念ですねとしか言いようがない。


2011-01-30 [長年日記]

_ iPod touch用H.264ムービー出力設定メモ

いつも以前どうやったのか覚えてないのでメモ。

iPod touch のスペック的には

iPod touch (2nd generation) - Technical Specifications

にあるように

  • 1.5Mbps ( H.264 LC ) / 2.5Mbps ( H.264 ) 640x480

までってなってるんだけど、まぁだいたい

  • 1Mbps 480x320 ( 480x288 )
  • H.264 ( baseline )
  • 128kpbs AAC-LC ( 44.1KHz )

くらいにしておこうかなと思う。H.264 の profile を baseline のみにしておかないと 2nd ( 2008 ) で再生できないので注意が必要。

素材用はなんか 853x480 ( 720x480 ) で 3Mbps にしてあった。これは iMovie のメニューの [ ムービーを書き出す ] の [ 大 ( 960x540) ] とは違うらしい。どこから出てきたんだろう。

こいつらをいずれも multi pass で。

Tags: Movie iPod