ukstudio

ブログをWordPressからmiddlemanに移行しました

今まで当ブログはWordPressでブログを書いていたけれど、今回middlemanを使うことにした。特になにかが気に入ってmiddlemanを選んだわけでもないのだけど、しばらくはこれで運用してみようと思う。

運用はGithub Pageで行なうことにした。これで今まで中途半端に保持していたVPSを解約することができる。最近はIRCを全然使ってないからいいけど、なんかの機会に使うようになったらtiarraとかをどう運用するか考えなくちゃいけないなぁ。

デザインやその他足りない機能は追々増やしていこうとおもいます。とりあえずRSSだけは用意した。

validates :foo_id, :presence => trueを追う

チームメンバーから「validates_presence_of :user_idはそのuser_idが存在するか確かめてくれる」という情報を得て、そんな隠れ仕様あんの?とおもってちょっと調べてみた。 結論だけまず言うと
validates :user_id, :presence => true
validates_presence_of :user_id
ではなく、
validates :user, :presence => true
validates_presence_of :user, :presence => true
の用に関連名を指定するとそれっぽい動作をしなくもない。 とりあえずコードを追うとpresence系のバリデーション自体はActiveModel::Validations::PresenceValidatorで定義されている。
module ActiveModel
  # == Active Model Presence Validator
  module Validations
    class PresenceValidator < EachValidator
      def validate(record)
        record.errors.add_on_blank(attributes, options)
次にadd_on_blankを見てみる。
# File activemodel/lib/active_model/errors.rb, line 251
def add_on_blank(attributes, options = {})
  [attributes].flatten.each do |attribute|
    value = @base.send(:read_attribute_for_validation, attribute)
    add(attribute, :blank, options) if value.blank?
  end
end
add_on_blankメソッドはattributesの内容を走査してblankだったらerrorsに追加してるんだろうなーというのが読み取れる。じゃあ実際に値を取ってきてるであろう:read_attribute_for_validationは何なのだろう。api.rubyonrails.orgで検索してもヒットしない。仕方ないからgitリポジトリをgrepして探す。そうすると以下の様なコードがみつかる。
# activemodel/lib/active_model/validations.rb line 327
alias :read_attribute_for_validation :send
つまりただのsend。なので
validates :user_id, :presence => true
というコードは
instance.send(:send, :user_id)
となり、結局は普通に指定した属性の値を見るに過ぎない。 で、最初の話に戻るが
validates :user_id, :presence => true
は普通にuser_idの値がblank?かどうかだけを見るので実際にそのuser_idでUserが存在するかチェックはしない。
validates :user, :presence => true
はどうかというと、instance.userがnilの状態でinstance.userを呼び出すとinstance.user_idでUserを取りにいく。そこでUserが存在しなければ[]が返ってくるのでblank?がtrueとなりこのバリデーションは失敗する。
instance = Model.new
instance.user_id = 111111111
instance.valid? #=> false
  User Load (3.4ms)  SELECT "users".* FROM "users" WHERE ""."id" = 111111111 LIMIT 1
なので、このケースに限って言えばそのIDのレコードが存在するか確認する動作をしている。とは言え、あくまでisntance.userの値を見るだけなので
instance = Model.new
instance.user = User.new
instance.valid? #=> true
この様に直接値を入れてしまえばDBにselect文はなげない。 なので、そういう動作をすることもあるだけで厳密にはそのIDのレコードが存在を確かめているわけではない。

GentooでCDをリッピングして聞く

メモ CDをwavで一旦取り込んでflacに変換。
$ sudo emerge cdrtools
$ sudo emerge flac
$ cdda2wav -H -B
$ find . -name "*.wav" -print0 | xargs -0 flac
# /etc/security/limits.conf
@audio - rtprio 99
@audio - memlock unlimited
@audio - nice -10
# /etc/portage/package.use
media-sound/aqualung alsa cdda cddb ffmpeg flac mp3 oss wavpack jack
media-sound/jack-audio-connection-kit alsa
# mplayer で聞く
$ mplayer *
# aqualung & jackで聞く
$ sudo emerge aqualung
$ sudo emerge jack-audio-connection-kit
$ jackd -R -d alsa
$ aqualung -o jack --auto
正直、JACKで何が変わってるのかよーわからん。

TDDカンファレンスでLTしてきたのでその補足

4月の6日のTDDカンファレンスに参加&LT発表してきた。参加といっても遅刻していったのでほとんど話を聞けていないのだけれど。 とりあえず資料はこちら。読み直してみたら途中の話の飛躍がこれはひどい。当日もかなり短い発表の上に色々内容を省いてしまったので色々と補足しておく。(当日聞いていただいた方に申し訳ないし、あまりこういうのはよくないね。パブリックスピーカー読んででなおします。) 今回の内容の発端は「TDDはテストではない」という言葉の暴力性というか、言い切りに何となく違和感を感じていたのがきっかけ。もちろん、誤解されたくないという意味では言い切るのは大事なんだろうけどちょっとだけ暴力的に感じる。暴力的に感じる理由は資料にも書いてあるけど、実際TDDで書いたユニットテストはテスト資産として流用している。それは副産物的なものかもしれないけれど、TDDの効果としては大きいんだから言い切っちゃうのはどうなんだろうという感じ。 その上で動詞と名詞のテストという観点で考えると案外すっきりするんじゃないのってを思いついた。でも結局のところTDDで書いたユニットテストだけじゃ足りないのは皆わかってるんだから、TDDが何なのかに拘ってないで必要だと思うこと足りないことやればいいんじゃないの?という結論になったのが資料の最後の方。こうして文章にしてみると、動詞と名詞のテストってのは上手いこと言えた気がしたから資料にいれたけど話の流れとしては変だしいれなくてもよかったかも。 まとめると「定義にこだわってないで必要だと思うことをやろう」です。名詞動詞とか「TDDはテストではない」という言葉の暴力性とか自分で言っておいて何だけど結構どうでもいい。「TDDはテストを目的としていないからテスト手法ではない」とか「TDDはいくらかテスト手法的な部分もあるのだからその断言はおかしい」とかつい議論しがちだけど、そんなことよりお互いにTDDだけでは足りない部分があるのはわかってるんだから、そこを考えようよってことです。

結婚いたしました

この度4月1日付けで結婚いたしました。 Facebookには届出を出した時点で結婚したことを書いたんですが、たくさんのイイネ!とおめでとうのお言葉ありがとうございます。書類をだしただけで特に何もかわっていないので今だに結婚した自覚がないんですが、そのうち自覚するものなんでしょうか。 今のところ式は予定していないので、近いうちにパーティ的なことはしたいなと考えています。その時は改めて近しい皆様にはご招待させていただきます。 以上、簡単ではありますが結婚のご報告でした。 See also ukstudioの欲しいものリスト 新婚なのでなんかくださいリスト

ruby勉強会@spicelife

@holygrailに何か話してよと頼まれたので適当に話してきた。 資料 なんか当日、話す時に使った資料は古いやつだったみたい。どおりで何か違和感があると思った。 うっかり対象者を初めてのRubyを読んだ人ぐらいを対象にしてたけど全然そんなことなかった。「define_methodをsendで呼び出すとわかると思うんですけど」「まずはsendがわからないんじゃない?」みたいな。結構早口だったし、資料も大分内容が薄いので大半の人はわからなかったかも。大変申し訳ない。 なんか初心者向けの勉強会って難しくて、当然入門本以上の話だと参加者が理解できない。かと言って、入門書の内容をするなら入門書読めばいいし。Railsの作法も最近僕自身はあまり気にしていない(というかそれなりに長いので割と感覚に近い感じになってきた)ので、作法ってなんだっけなって感じになってしまった。とりあえずRESTは重要だよなーと思いつつも、Webを支える技術を読めばいいしなーとも思うし。そんな感じで色々と迷走した結果がさきほどの資料です。 今思うと、もうちょい別のアプローチもあったかなぁという気はする。これは対象者と話す内容を見誤った僕のミスだなぁ。あとは勉強会直前、結構忙しかったんだよね。忙しい時はやっぱり勉強会とか引き受けちゃダメだなぁ。申し訳ない。 とりあえずこの間話した内容を理解するためのリソースは提示してあるので、やる気ある人は頑張ってください。既に資料から僕のアフィから買ってくれた人どうもありがとう。

勉強会とかで話す時のモチベーション

  • その勉強会やコミュニティから得たものがあるので、恩返ししたい
  • 主催者もしくは声をかけてくれた人にお世話になったことがあるので恩返ししたい
  • 勉強会の目的・主旨に賛同し、何らかの協力をしたい
  • たまたま自分が自主的に調べていた・勉強していた話題だった
  • 営業活動になりそう
  • 資料作りの時間を含めた上で、ある程度満足できる謝礼・報酬がでる
ぐだぐだ言ったけど、最終的には気分である。

rails3でprimary keyとforeign keyをbig intにする

以下は、PostgreSQLの例。
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:primary_key] = 'bigserial primary key' 
外部キーの場合、t.references :userとか書いてると、ActiveRecord側でintegerがハードコーディングされているのでlimitオプションを付けるしかなさそう。
t.references :user, :limit => 8

LVMを使っているKVMのディスクイメージの容量を追加する

KVMのディスクイメージの容量を増やしたのでメモ。

イメージファイルの拡張

まずはイメージのフォーマットを確認する。qemu-imgのinfoでわかる。
$ qemu-img info vm.img
今回はqcow2になっていたのでrawに変換する。
$ qemu-img convert -f qcow2 vm.img -O raw vm.raw
ddのseekを使って末尾に領域を追加する。10GBのイメージに5GB追加するならこんな感じ。
$ dd if=/dev/zero ov=vm.raw bs=1G count=5 seek=10
フォーマットを元に戻す。
$ qemu-img convert -f raw vm.raw -O qcow2 vm.img

仮想マシンのパーティションの修正

その後、イメージを立ち上げてパーティションを修正する。今回のパーティションは/dev/hda1がboot、/dev/hda2がlvmになっていたので/dev/hda2の方を修正する。
$ fdisk /dev/hda
> d
> 2 # /dev/hda2を一旦削除
> n
> p
> 2
> Enter
> Enter # /dev/hda2を作りなおす。デフォルトでサイズが拡大するはず。
> t
> 2
> 8e # /dev/hda2のパーティションタイプをLVMにする
> w
> q # 書きこんで終了
$ reboot

ボリュームの追加

$ vgextend VolGroup00 /dev/sda2
$ lvextend -L +5GB /dev/VolGroup00/LogVol00
$ resize2fs /dev/VolGroup00/LogVol00
思い出しながら書いてるから細かいところで違うかもしれないけど、だいたいこんな感じで容量の追加が完了。

Gentooデビューしました

メインの開発マシンのOSをUbuntuからGentooにしました。Gentooにした理由は割となんとなくだけど、強いて言うならGentooいいよっていう人の気持ちを知りたいのと、あとPortageは割と好きだからかな。Ubuntuに不満があったわけでもない。Unityは好きじゃないけど、どうせXMonad使うし。 インストールは第2回 Gentoo Linux インストール講習会 : ATNDに参加したおかげで起動するまでは割とすんなり(Thanks @ursm, @kenchan)。Funtooもいれて、実際起動するところまでは持っていったけど無線LANの設定とかがGentooのドキュメント通りじゃなくて混乱したので今回はやめた。 Gentooのインストールは色々と勉強になった。パーティション切るのも中学生の時に本に従ってLinuxいれた時以来だし、GRUBに至っては触ったことなかったし。ほかにもカーネルやXとかの設定とか、普段は動くものがすぐそこにあるだけだから意外に知らないのよね。 とりあえず今はXfce4 + XMonadの環境を作った。XMonad単体の方がいいんだけど、PDFリーダとかメッセンジャーとか何使ったらいいかわからなかったからとりあえずXfce4を使うようにした。GNOME3いれようとしたけど挫折。 そんなわけでしばらくはGentoo生活を送ります。

IPv6 Hackathonに参加してきた

この間のLL PlanetsでIPv6 Hackathonとやらに参加してきた。Ruby組は僕と @sugamasao と @takano32 の3人でチーム組んだ。

RailsはIPv6でも大丈夫っぽい

大丈夫っぽいっていうのは軽くさわった程度なので断言できるほどでもないため。IPv6でRailsを立ち上げたかったら上記のように--bを指定すれば大丈夫です。
rails server --b="::"  -p 3000
Unicornの場合もオプションで大丈夫。
unicorn_rails -l '[::]:3000'
あとはApacheは対応してるし一応なんとかなるのではないか。Nginxとかthinは調べてないのでわからないです。あとMySQLはIPv6に対応していないらしいけど、データベースはWebサーバから見えれば大丈夫だし何とかなるでしょう。きっと。

github.comやrubygems.orgはAAAAレコードがない

digコマンド叩けばわかるけど、みんな大好きgithub.comとrubygems.orgにはAAAAレコードがありません。ということで、IPv6オンリーな環境だと使えないと思うのでトンネル掘るなりなんなりの対応が必要っぽい。

今回作ったもの

ネタアプリを作っただけなので実装としてはそんなにおもしろいものでもないかな。 ひとつは、twitterの発言ひとつに対してIPv6のアドレスをひとつ割り振って、そのIPv6にリクエストがきたらそれに対応するtwitterの発言を表示させるというもの。ただのアドレスの無駄遣いですね。 あと1時間ぐらい僕の時間があまったので、その1時間でIPv6アドレスをキーとするストレージっぽいものを作った。あるIPv6に対してPOSTするとbodyの内容が保存されて、GETすると保存された内容が取得できるみたいな。更新はPUTだろっていう話もあったけど、時間が足りなかったのでした。 発表資料がそのうち公開されると思います。 Lightweight Language Planets : 公開資料

Net::HTTPとURI

そのストレージのテストをするのにRubyでNet::HTTPとURIを使って画像をPOSTするコードを書いた。その時にちょっとハマったことがあるので説明しておく。 IPv6は:を使ってアドレスを区切るので、ポート部とわけるために[]を使うことがある。そのアドレスをURI.parseしたあとにURI::HTTP#hostで値を取得すると[]が残ったままになり、Net::HTTPは[]があるとどうやらダメっぽくてエラーがでる。パッと見コードに何も問題がなさそうに見えるので知っておかないとハマる人はハマりそう。実際に僕はハマりました。 で、たまたまURI::HTTP#hostnameというメソッドがみつけてこっちは[]を取り除く。このURI::HTTP#hostnameはるりまを見るとどこにも乗ってなくて、挙動の違いはバグかとも思ったりしたんだけどどうやら違うみたい。 Rubyのuri/generic.rbを見ると以下のように書いてあった。
# Since IPv6 addresses are wrapped by brackets in URIs, # this method returns IPv6 addresses wrapped by brackets. # This form is not appropriate to pass socket methods such as TCPSocket.open. # If unwrapped host names are required, use "hostname" method. # # URI("http://[::1]/bar/baz").host #=> "[::1]" # URI("http://[::1]/bar/baz").hostname #=> "::1"
ということで、hostnameメソッドを使いましょうという話でした。

TDDBC 東京 1.6でサポートスタッフをやってきました

TDD Boot Camp 東京 1.6にRubyのサポートスタッフとして参加してきた。 当初の予定ではあくまでサポートなのでペアプロには参加しない予定だったけど、Rubyのグループが5人で人数が奇数になってしまったので急遽ペアプロに参加することにした。 この辺は@t_wadaさんや主催の@pocketberserkerさんとも相談してペアとトリオのふたつに分けるっていう話もあったけれど、僕が「せっかくだからペアプロして帰ってもらいたい」と思ったので若干の迷いはあれどペアプロに参加することにしたのでした。Ruby組は@takahashimさんや@1syoさん、@kwappaさんたちが参加されていて彼らなら付きっ切りでサポートしなくても大丈夫そうというのも理由のひとつ。 コードレビューを見た感じだと一応はうまくいったんじゃないかなと思う。特に@1syoさんと@takahashimさんのペア(ダブル高橋!)は積極的に質問をしてくれたので、僕としても教えがいがあった(えらそう)。ただ、質問を受けると僕の方のペアプロが一時的に中断してしまうし、僕としても頭の切り替えが結構大変だったので出来ることならやはり参加者同士でペアが組めるといいんだろうなぁ。理想を言うと全部のペアをスタッフ+参加者にすることなんだろうけど、あまり現実的じゃなさそう。 今回、最初に僕とペアを組んだ方が(お名前を聞くのを忘れてしまった...)モダンなテストの書き方を知りたいと言うので、ある程度xUnit的なテストの書き方でペアプロを進めた後、がっつりRSpec的な書き方にリファクタリングするということをやってみた。他のペアもRSpecは初期のit "なんちゃらかんちゃら"の書き方をされていたので、コードレビュー時に共有できたのはよかったのかな。RSpecの書き方については言っちゃいけないということはないだろうから言っちゃうけどそのうちるびまの方に書く予定なのでお楽しみに。 Ruby組は全体的にTDDのサイクル自体はできていた感じで、内容としてはテストの書き方にフォーカスが移っていたように感じる。例えば、標準出力が絡むテストのやり方とか、システム時刻が絡むテストのやり方とかdescribe/contextの切り方とか。多分、TDDBCも回数が増えていくにつれ、こういう人達がどんどん増えてくると思うからTDDBCの次の道をしめせるといいんじゃないかと思った。参考図書はいくつかあるけど、例えばxUTPとかTDDBCからのジャンプアップがヘビーすぎるなぁという気もする。(もちろんいきなりあれを全部読めという話でもないんだけれど) 話は変わって当日のお題を再度ひとりで実装してみたので、コードを公開しておきます。 ukstudio/tddbc1.6 - GitHub あまりじっくり書いたって感じでもないので仕様漏れとかありそうだけど、テストコードの書き方の参考にはなるかと思います。@bleisさんみたいに細かに解説しようと思ったけど気力がないのでした。 そういえば今回のスタッフも若手が多いな。@bleisさんと俺が86世代、@kyonn_mmさんと@pocketberserkerさんがひとつだかふたつだか年下だっけ? 同世代の人が頑張ってるのはとても刺激になります。 最後に、主催の@pocketberserkerさん、講演をしてくださった@t_wadaさんをはじめ、スタッフの方々どうもお疲れ様でした。参加者のみなさま、どうもありがとうございました。 特に@pocketberserkerさんは佐賀の人なのにもかかわらず東京でTDDBC主催とか、そのパワフルさを見習いたい感じです。本当にお疲れ様でした。 おまけ

BDDについて自分なりにまとめてみた

BDDという言葉も割と人によって指すものが違うようなので「俺の中でのBDDはこうだよ」って内容のエントリ。別に絶対的なものでもないと思うので参考までに

結論から

とりあえず結論だけ知りたい人向けに。

  • BDDにはふたつの種類がある
  • 1. TDDの言い換えのBDD(開発寄り)
  • 2. ATDD(受け入れテスト)でのBDD(ユーザ寄り)

振る舞い

BDDは振る舞い駆動開発と言われたりするように、テストという言葉のかわりに振る舞いという言葉を使う。日本語的には仕様と言うほうがわかりやすいかもしれない。多分、BDDのイメージが掴みにくいのはこの振る舞いという言葉にあると思う。と言うのも振る舞いと言うのは、人の立場よって変わるからだ。例えば、プログラマがあるクラスを実装している時に言う振る舞いはそのクラスのメソッドとかの仕様になる。逆にユーザレベルの人が言う振る舞いはアプリケーションの要件・動作を言うだろう。 つまり、BDDという言葉はTDDからATDDの両方にかかるので文脈によって指すものがかわってくる。この辺は@t_wadaさんの言う「誰のためのテストか」を考える方がわかりやすいだろう。

TDDの別名としてのBDD

TDDにかかるBDD、つまりプログラマの為のBDDについて説明する。そもそもBDDという言葉が生まれた背景にはTDDに対する誤解がある。いわゆる「TDDのテストはテストじゃないよ」ってやつ。その誤解を避けるために生まれたのがBDD。多分「誤解を避ける」というのもあまり適切な表現ではない。と言うのもこの表現だとTDDを実践していない人の誤解を避けるために生まれた印象をうける 実際はテストという言葉を使うことでTDDを実践する(しようとする)プログラマ自身にもよくない影響がある。例えばTDDの場合先にテストコードを書くので当然テストを書くときにテスト対象が存在しない。これは不自然だ。テスト対象がないことで、TDDに慣れていない人は「何をテストすればいいの?」と思うことも少なくない。

BDDではテストという言葉の変わりに振る舞いという言葉を使うと先程書いた。振る舞いという言葉を使うことで、テストという言葉から受ける違和感はなくなる。テスト対象が存在しなうちにテストを書くのは不自然だけど、なにかを実装する前に振る舞い(仕様)を決めるのは自然だ。 また、振る舞いに着目することでより良い設計ができるようになる。少なくとも僕はそう感じている。TDDでも先にテストコードを書くのでインターフェースに注意を向けることができるが、BDDの語彙を使うことでより実装と振る舞いを分離して考えられるからだと思う。

とは言え結局のところやることはTDDと変わらない。はたから見たら、TDDをしているのかBDDをしているのか区別つかないだろう。なのでここでひとつめの結論BDDはTDDの言い換えになる。もちろん使う言葉が違いプログラマに与える影響が違う以上、厳密にはTDDとBDDは違うものなのかもしれない。けれど個人的にはそこまでTDDとBDDの違いに厳密性を求めてないし、求める必要もないと思うので、プログラマ視点で見たときはほぼ同じという結論。

ATDDとBDD

ATDDはAcceptance Test Driven Developmentの略でAcceptance Testというのは受け入れテストのこと。TDDのよりレイヤの高いものだと思えばいい。Growing Object-Oriented Software, Guided by Testの画像がわかりやすいので拝借。

ATDDのひとつのサイクルでひとつの受け入れテストが完了し、それを繰り返すことでアプリケーションを実装していく。受け入れテストはどちらかと言えば顧客のためのテスト。受け入れという名の通り、このテストがパスすればその機能は実装が完了したとわかり、顧客の立場からすると要件が正しく実装されていること、進捗が管理しやすいなどの利点がある。

これとBDDに何が関係するのかと言うと、上で書いたようにBDDの振る舞いはユーザレベルで見たときはアプリケーションの要件・動作を指す。顧客は大抵の場合、ユーザレベルなのでこの場合での振る舞いは受け入れ条件となり得る。つまり、ATDDをBDDでやることは可能と言える。ATDDをBDDでやるメリットは、BDDでは振る舞いの言葉を使うのでより顧客・ユーザに近い言葉で受け入れテストを記述できるようになる(例:cucumberの日本語での記述とか)。

これがふたつめの結論のATDDでのBDD

ちなみにATDD自体も結構あやふやなやつで、何をテストするのかは受け入れ基準による。もし受け入れ基準が「とあるクラスに正しくメソッドが実装されていること」だとしたらどうなるか。これはややこしいけれど、ATDDのサイクルとTDDのサイクルの距離が大分近くなると思う。場合によってはTDDで書いたテストコードがそのまま受け入れ基準となり得ることもある。それでもTDDとATDDは目的が違うのでその辺は意識した方がいい。

Outside-In

BDDは上で説明したように、コンテキストで「振る舞い」が指すものが変わる。とは言え、根源となる思想はあってそのひとつがOutside-In。Outside-Inと言うのは外側から見た振る舞いを軸に内部を作りこんでいくということ。人によって見る位置が違うので「外側」がどこか変わってくる。プログラマならメソッドやクラスの外だし、ユーザならアプリケーションの外側。なので、BDDがなにかを一言で答えるとしたら振る舞いに着目して、それを軸に内側を作りこんでいくことになるのかなぁ。

再び結論

長々と書いて逆に混乱してきた人もいるかもしれないのでさくっとまとめ。

  • 結局は'誰が'、'誰の為に'、'何を'テストしているのかが重要である
  • TDDはDeveloper Testing。つまり僕達のためのもの。
  • ATDDはCustomer Testing。つまり顧客のためのもの。
  • BDDは振る舞いに着目する。状況・目的によって「振る舞い」が指すものが変わる。それに合わせて語彙も変わる。

なんちゃらDDはいっぱいあって、しかもそれらが色々な軸で交わったりしてすごいややこしい。TDD/BDD/ATDDと誰かが言った時は、大抵の場合暗黙のコンテキストがあるのでそこに気をつけよう。わからなかったら聞こう。「それは誰の為のテストで何をテストしているんですか?」

個人的にはBDDという言葉を使わないのは誰の為のテストかわかりづらいから。なので大体の場合はTDDとATDDのふたつを使うことが多い。BDDが僕達にくれたものは大きいけれど、その知見はTDD/ATDDに十分反映されている(もしくはされつつある)ので、普通にTDD/ATDDと言えばいいじゃないかって意見。BDDって言葉を使うとややこしくなるので僕は使いません。

おまえの言うBDDは間違ってる!!という人は突っ込みいただけるとありがたいです。

See also

mongodb + node.js を軽く試した

mongodbのインストール

$ sudo aptitude install mongodb
$ mkdir /path/to/data
$ mongod --dbpath /path/to/data

mongooseのインストール

$ npm install -g mongoose
node.jsでmongodb扱うのに他にもライブラリあるみたいだけど、とりあえずnpmでサクッと使えるmongooseを使ってみる。

サンプル

軽く試しただけなので、詳細は LearnBoost/mongoose - GitHub を参照。 実行するとmongodbの中身はこんな感じ。
> db.users.find()
{ "_id" : ObjectId("4dce0fb5bad67a145c000001"), "name" : "AKAMATSU Yuki", "age" : 24 }
印象としてはActiveRecordっぽいというかORMっぽいというか。mongodb自体をそんなに触ってないからこのアプローチが正しいのかどうかはわからないけど、馴染みやすくはある。

duostackでnode.jsアプリを動かすまで

node.jsのインストール

何はともあれnode.jsのインストール。aptではなくgithubからリポジトリをcloneしてmakeした。最近はapt以外のものは$HOME/localに入れるルールでやってるのでnode.jsも同様に。node.jsをsudoで入れると結構ハマるみたいな話を聞くので特に理由がなければaptとかで入れるか$HOME以下に入れるのがよさそう。
$ git clone git://github.com/joyent/node.git
$ cd node
$ ./configure --prefix=$HOME/local
$ make
$ make install
$ which node
/home/ukstuido/local/bin/node

npmのインストール

duostackを使うのにnpmが必要なのでnpmもインストール。curl使う方じゃなくてmakeしてインストールした。curl ... | sh の形式があまり好きじゃない程度の理由。
$ git clone git://github.com/isaacs/npm.git
$ cd npm
$ make install
$ which npm
/home/ukstudio/local/bin/npm
npmがインストールされる場所は特に指定しなくても$HOME/localに入った。node.jsの位置でも見てるんだろうか。よくわからない。

duostackのインストール

あらかじめ、Duostackのアカウントは取っておくこと。結構すぐ登録確認メールが来る。 duostackのインストールは-gオプションを付けないとnode_modulesディレクトリがカレントディレクトリに出来る。最初-gオプションを知らなくて困惑した。
$ npm install -g duostack
$ which duostack
/home/ukstudio/local/bin/duostack

アプリの作成とデプロイ

ここまで来るとDuostack · Docs: Quick Start Guideに従うだけでOK。 適当なディレクトリを作ってそこにserver.jsを置く。
$ mkdir sample
$ cd sample
$ vim server.js
git initしてやる。
$ git init
$ git add .
$ git commit -m 'init'
duostackコマンドでアプリケーションを登録。ここで指定したアプリ名がそのままドメインになる。
$ duostack create ukstudio
$ git push duostack master
無事にpushできればURLが表示されているはずなのでブラウザで確認する。今回の例だとhttp://ukstudio.duostack.net/になる。 こんな感じでduostackでnode.jsアプリを動かすところまで試してみた。herokuとかもそうだけど、こうサクッとアプリが動かせる環境があるのはうれしい。 次はnode.js + CoffeeScriptとか、もうちょっとアプリらしいアプリを作ってみようかな。

追記: duostackでCoffeeScriptを動かす

CoffeeScriptからコンパイルしたJavaScriptを乗せるんじゃなくて、CoffeeScriptそのものを乗せる方法。server.jsは必要っぽいのでそこからrequireする形にした。CoffeeScriptはアプリの中にインストールしておく。 これで一応動くことは動く。
$ npm install coffee-script

Vimをソースからビルド

aptで入れたvimのrubyインターフェースのバージョンが1.8.6なのが気にいらなくてvimをソースからビルドした。
$ hg clone https://vim.googlecode.com/hg/ vim
$ hg update vim73

$ cd vim
$ ./configure --enable-multibyte --prefix=$HOME/local --enable-rubyinterp
これでOK。aptで入れたvimも一応残しておきたかったのでprefixで$HOME以下にビルドするようにした。Rubyインターフェースはrvmで入れた1.9.2を見るようになっていたのでとりあえずよしとする。何でrvmの奴を見にいったのかはよくわからない。

CoffeeScript + QUnitでTDD環境作ったよ

Rails3.1からCoffeeScriptがデフォルトで入ってるとかなんとかで、とりあえずCoffeeScriptだけで少し触ってみた。とりあえずQUnit自体もCoffeeScriptで書けるようなTDD環境を作ってみた。 とりあえず、UbuntuにCoffeeScriptをインストールするわけだけどaptの方が古いしせっかくだから最新のを触るかと思ったのでgithubからCoffeeScriptとnode.jsのリポジトリをcloneしてインストール。
$ git clone git://github.com/joyent/node.git 
$ cd node
$ ./configure
$ make
$ sudo make install
$ node -v
v0.5.0-pre
$ git clone git://github.com/jashkenas/coffee-script.git
$ cd coffee-script
$ sudo bin/cake install
$ coffee -v
CoffeeScript version 1.1.0-pre
ディレクトリ構成はこんな感じ。coffeeにCoffeeScriptに入れて生成されたJavaScriptはsrcにいれるルール。test/index.htmlはQUnitの結果を見るため。test/qunitはずばりQUnitそのもの。
./coffee/hello.coffee
./src/hello.js
./test/index.html
./test/qunit/qunit.css
./test/qunit/qunit.js
./test/coffee/test-hello.coffee
./test/src/test-hello.js
CoffeeScriptは-wでファイルの変更を監視してコンパイルしなおすことができるので,以下の用に実行しておけばそれぞれ変更があったらコンパイルしてくれる。CoffeeScriptはデフォルトでfunction(){}();で囲って外部からアクセスできなくなるので,-bを付けてトップレベルにJavaScriptを生成するようにする。
$ coffee -w -b -o src/ -c coffee
$ coffee -w -b -o test/src -c test/coffee
これでテストコードもしくは本体のコードを修正すれば勝手にコンパイルするのでtest/index.htmlを見ればよい。後はもうちょい頑張ってブラウザを勝手にリロードするか,Rhinoとか使えばindex.htmlを用意しなくてもCUIでテスト結果をみれそう。 一式は以下のgistに置いた。(Qunitはライセンス見てないので外してある) CoffeeScript+QUnit — Gist

大江戸Ruby会議01で発表してきました

昨日は大江戸Ruby会議という名のasakusa.rbの生活発表会があったので、普段の生活で考えてることを発表してきた。ちなみに実はasakusa.rbの参加回数はそんなに多くなかったりする。当日のスライドと動画はこちら。KaigiFreaksは仕事がはやくてすごい。いつもありがとうございます! 大江戸Ruby会議01 on Vimeo この発表について何か僕にもの申したい人がいたら@ukstudioかy.akamatsu[at]ukstudio.jpまで頂けるとありがたいです。 発表内容についてちょこっとだけ書いておこうかな。パブリックスピーカーの告白で言う「講演家がこう話せばよかったと思うスピーチ」にあたる部分。 タイトルに戦略ってあるけど、正直そもそもそういったものがあるのかよくわからない。CIとかは環境の話だし、TDDとかリファクタリングとかはスキルだしでそれらが「戦略」かと言われると違う気がする。 結局のところ、継続的に改善していくしかないと思うんだよなぁ。そうなると後はもう手を動かすか動かさないかの話になる。そんなことを考えたら終始「熱意を持って頑張って」みたいな話になってしまった。これはこれで妙に好評だったけど(母数80ぐらいのうちサンプリング5ぐらい)。ちなみに熱意がなくとも仕事だと割り切って手を動かしてももちろんいいと思います。 で、手を動かす前提となるとClean Codeを保てるかは個々の設計能力に依存してくる。そういうわけでRubyでClean Codeってどう実現するんだろうね?というところをSOLID原則を取り出して話をしたつもり。 終わった後に@t_wadaさんからRubyConfで似た話をした人がいるから動画を見た方がいいと言われ、今日twitterで動画を教えてもらった。 SOLID Ruby - Jim Weirich - Ruby Conference 2009 資料も豪快にgithubにあがっていて、こっちは@kakutaniさんに教えてもらった。お二人共ありがとうございます。 jimweirich/presentation_solid_ruby - GitHub まだ資料をざっと見ただけなんだけど、僕より全然良くできてるので皆さんこっちを見るといいです。まだまだ精進が足りない。 Rubyらしい設計って色々とまだ手探りなんだけど、参考になったのはRubyによるデザインパターンとかリファクタリング:Rubyエディションあたりかなぁ。 後はJavaだけど、Clean CodeとかAmazon.co.jp: アジャイルソフトウェア開発の奥義とか。両方とも結構ヘビーな本だけど勉強になる。 大江戸Ruby会議の全体的な感想は他のWeb日記力の高い人におまかせしたいと思うのでそちらをどうぞ。と言うのも、発表が最後の方だったので会議中ずっとそわそわしてたため、文章にまとめられるほどまだ消化できてないのだ。この辺はなかなか難しいところだけど、あの空気感の一旦を担えた(と思いたい)と言うことでよしとする。 最後に。発起人の@a_matsudaさん、実行委員長の@kakutaniさんを始め、スタッフ、発表者、参加者のみなさん、どうもありがとうございました!

近況

個人事業主になりました

この間の確定申告の際に、個人事業主届けを出してきた。去年は出さずに1年働いていたけど、今年は確定申告を青にしたのでそのついでに。届出の提出はすごいあっけなくて、改めて個人事業主なんてそんな大層なものじゃないなーと思った。 屋号は「UKSTUDIO」にした。屋号を取ったから何が変わるってわけでもないけど、本名とukstudioっていうIDの間にある溝を埋めるぐらいの意味はあるかな。

4月下旬からスケールアウトでお仕事

@yamazさんからお声がかかって、4月下旬からスケールアウトで働くことになった。正社員ではなく1年の契約です。 一応、別の仕事も請けることは可能だけど最初から複数の仕事をまわせる気がしないし当分はお仕事の依頼は請けられないと思います。あしからず。 「パフォーマンスを出してください」と言われたので頑張りたいと思います。よろしくお願いします。

TDDBC福岡に参加してきた

福岡TDDBCに参加してきた。今回で3回目の参加(1回目は東京、2回目は東北)。 3回は割と多めの参加回数だと思うけど、参加者層が地域によって違ったり、当然ペアプロする相手も違うわけでいつも違う刺激をもらってる。 今回は@mzpさんが参加するとのことなので普段使ってるRubyではなくOCamlで参加。OCaml組は2ペア(4人)いて、1日目の前半を@suerさん、1日目の後半と2日目を@mzpさんとペアを組んでやった。OCamlは初心者もいいところなので2人には大分お世話になりました。どうもありがとうございます。 コンパイルが必要な言語でTDDをやるとコンパイルがテンポを崩しがちなんだけれど、OMakeが結構よく出来ていてautotestみたいなことも出来るし、その辺は特に不自由ない感じ。OCamlの型付けの強さはなかなか慣れないけれど、コンパイルが通った時点で型の間違いがないって言うのは割と安心かも。 慣れない言語でTDDをやって一番実感したのは、普段Rubyの時は「こういうインターフェースで使いたい」と振る舞いの視点からテストケースを考えられるのに、OCamlだと「今回正規表現が必要そうだけどOCamlだとどうやるの?」といった具合で先に実装の詳細について考えはじめてしまうこと。本来は実装は置いておいてテストケースを考えるべきなのについつい実装の方を考えてしまった。 ただ、言語を習得していく過程でTDDが出来ないかと言うとそんなことはないとも思う。ペアプロの時はたまたま僕にとってオーバーペースだっただけで、落ち着いてbaby stepで刻んでいけば逆に習得しやすくなるかもしれない。今回はRubyと同じテンポでやろうとした俺のミスだなー。 後、ここ最近新しい言語を習得できないなーと思っていたけどこういうイベントで挑戦するのは悪くない。普段だとついついRubyに逃げちゃうんだけど、ペアプロだと逃げようがない。あとは@mzpさんのコードを書くところを横でみれたのは大きいと思う。こう書くのかーって発見がいっぱいあった。 2日目の休憩時間に@mzpさんがAsakusaSatelliteのテストコードを修正していて、RSpecで書かれていたので「ここはこう書けるよ」「こうした方がRSpecっぽいよ」と横で口出ししていたら@mzpさんと@suerさんにRSpecの魅力が伝わったようでよかった。 ここ最近、RSpecに興味はあるけどどう書いたらいいかわからないみたいな話を良くきく。構文だけだったらドキュメントみればいいんだけど、それをどう活用するのかみたいな話はなかなかまとまってないからかな。結構需要がありそうなのでそのうちるびまあたりに寄稿してみようかな。最近やっとletの使い方が見えてきたよ。 そう言えば、今回は結構若い人が多かった気がする。@mzpさんは1つ上らしいし、@bleisさんは同い年だった。主催の@pocketfberserkerさんも年下。講師の1人の@akinekoさんは俺より1つ2つ年下だったと思うし(年上だそうです)。こういうイベントで同世代や自分より若い人がいるとなんかうれしいなー。 今回のTDDBCもなかなか刺激的で楽しかった。次のTDDBCもいくつか開催決まってるっぽいし、今回で動きだす地域もあるみたいだし楽しみ。 最後に、主催の@pocketfberserkerさんを始め、今回のTDDBCの運営に携わっていた方々、どうもありがとうございました! Togetter - 「TDD Boot Camp福岡」