223 Software

主に勉強したことなどを記録するログです。 最近はRuby, Railsなどが多め。

開発 - 223 Software

QUnit + QUnit-TAPでJSのTDDをしてみた

JavaScriptでTDDするにはどうすればいいのかな・・・と思い、TDDBCではQUnit + QUnit-TAPが使われていたようなので、とりあえずその環境を整えてみました。

普段rspecを使っている自分としてはrspecっぽく書けるJasmineも気になっているのですが、とりあえずはQUnitを。

インストール

QUnit-TAPはnpmで提供されているので、それで入れるのが簡単そう。globalに入れることもできますが、とりあえずカレントディレクトリのnode_module/に入る以下のコマンドでインストール。

 $ npm install qunit-tap

設定

まずは設定とか必要なモジュールのrequire等を行うtest_helperを作ります。

QUnit-TAPにサンプルでついてくるtest_helper.jsをほぼそのまま、パスのあたりだけ調節して使っています。

exports = module.exports = global;

var tryRequireThese = function() {
  var args = Array.prototype.slice.apply(arguments);
  for(var i=0; i < args.length; i+=1) {
    try {
      return require(args[i]);
    } catch(e) {
      // ignore
    }
  }
  throw new Error("cannot find moduele: " + args);
};

QUnit = require('qunit-tap/vendor/qunit/qunit/qunit.js').QUnit;
var qunitTap = require('qunit-tap').qunitTap;

var sys = tryRequireThese("sys", "system");
for (var i in sys) exports[i] = sys[i];
puts = (typeof sys.puts === 'function') ? sys.puts : sys.print;

qunitTap(QUnit, puts, {noPlan: true});

QUnit.init();
QUnit.config.updateRate = 0;

exports.assert = QUnit;

テストを書いてみる

このへん利点がよくわかっていないのですが、TAPという形式での出力はproveというperl製のコマンドを使って実行するのが便利らしいので、それに従っておこうと思います。

すると、t/というディレクトリ以下にテストファイルを置いておくとproveコマンドが自動的にそのディレクトリ以下のファイルを自動的にテストファイルとして扱ってくれるらしいので、従います。

t/array_test.js

require('../test_helper.js');

QUnit.module('Module Array');
QUnit.test('#length', function() {
  var ary = new Array(5);
  assert.equal(ary.length, 5);
});

QUnit.test('#push', function() {
  var ary = new Array();
  ary.push('first');
  assert.equal(ary.length, 1);

  ary.push(2);
  assert.equal(ary.length, 2);
});

QUnit.test('#concat', function() {
  var ary1 = [1, 2, 3];
  var ary2 = [4, 5, 6];
  var res = ary1.concat(ary2);
  // assert.equal(res, [1, 2, 3, 4, 5, 6]); # => fail
  assert.deepEqual(res, [1, 2, 3, 4, 5, 6]);
});

QUnit.start();

実行してみます。

$ prove -vc --exec=node --ext=.js
t/array_test.js .. 
# module: Module Array
# test: #length
ok 1
# test: #push
ok 2
ok 3
# test: #concat
ok 4
1..4
ok
All tests successful.
Files=1, Tests=4,  0 wallclock secs ( 0.04 usr  0.00 sys +  0.12 cusr  0.01 csys =  0.17 CPU)
Result: PASS

proveコマンドの-vは結果の表示を詳細に、-cは色を付けて、--execはテストコードの実行コマンド、--extはテストコードの拡張子ですね。

ちょっとハマったのが、配列同士をassert.equal()で比較するとfalseになってしまうこと。確かにnodeコマンドのコンソールで[1,2] == [1,2]と打ってもfalseが返ってきます。このへん、JavaScriptの動作としては配列の中身までは比較せずに、同じオブジェクトへの参照を持っているかどうか、ということを比較しているからfalseなのでしょうか。assert.deepEqualを使うことで意図通りのテストができました。

せっかくなのでもう一つテストファイルを足してみます。

t/string_test.js

require('../test_helper.js');

QUnit.module('Module String');
QUnit.test('#match', function() {
  var str = 'test';
  assert.ok(str.match(/te.{2}/));
});

QUnit.test('#split', function() {
  var str = 't,e,s,t';
  assert.deepEqual(str.split(','), ['t', 'e', 's', 't']);
});

QUnit.start();

Greenでした。OKですね。

では、独自に作ったJSをテストすることにします。
テストファーストということで、テストファイルから。

t/calculator_test.js

require('../test_helper.js');
var cal = require('../lib/calculator.js').Calculator;

QUnit.module('Module Calculator');
QUnit.test('#initialize', function() {
  assert.ok(cal);
});

QUnit.start();

この時点でテストを実行すると当然Red。
実装しましょう。

lib/calculator.js

var Calculator = {
};

exports.Calculator = Calculator;

JSのモジュールとか、やったことは無いのですがこんなやり方でいいのかな?とにかくGreenになったので、テストコードを足して失敗になったことを確認した後、実装します。

t/calculator_test.js

QUnit.test('#sum', function() {
  assert.equal(10, cal.sum(5, 5));
  assert.equal(15, cal.sum(5, 5, 5));
});

lib/calculator.js

var Calculator = {
  sum: function() {
    var result = 0;
    for (var i = 0, l = arguments.length; i < l; i++) {
      result += arguments[i];
    }
    return result;
  }
};

GreenになったのでOKのようですね。

自動でテストを実行

やっぱりテストファイルを更新したら自動的に更新されて欲しいですよね。
とりあえずrubyですがguardを使ってみました。

$ gem install guard guard-shell growl rb-fsevent
$ guard init shell

生成されたGuardfileを以下のように書き換えて、lib/, t/以下のファイルが更新されたら自動的にproveコマンドを実行するようにしました。

guard 'shell' do
  watch(%r{lib|t/(.+)\.js}) {|m| `prove -vc --ext=.js --exec=node` }
end

結果、JSとperlとrubyを駆使した(?)面白い環境になりました。
色がつかないのでなんとかしたいのですが、どうすればいいのかよくわからなかったです。

まとめ

今回はnode.jsを使って、簡単なモジュールのテストをしてみました。

一口にJSのテストと言っても、サーバーサイドのJSをテストしたいのか、ブラウザ上のJS(特にDOM操作が入ったりするもの)をテストしたいのか、JS含めたアプリケーションの動き全体をテストしたいのか、そのへんを見極めておかないといったい自分が何をしたいのかを見失ってしまいそうで、要注意ですね。

Rubyを始めたい方向けまとめ(2011年秋版)

最近gitやrubyなど、プログラミング関連のあれこれを教える機会が増えてきました。

今自分が一番使っているプログラミング言語はRubyですが、これをどうやって効率的に学習すればいいのかなぁということを考えてみました。

情報の入手の仕方なども盛り込んで、今後自力で使いこなしていくために必要そうなノウハウをなるべく盛り込んでみました。
これからrubyを学ぼうという方の参考になれば幸いです。

また「これからプログラミングを覚えて何かWebアプリを作ってみたいけれど、とっかかりが見つからない。」という方にとっても何かしらきっかけを与えることができたなら幸いです。

ご注意

  • 僕自身はWeb系のプログラマのため、そちらの分野に偏った内容となっています。
  • この分野の情報はすぐに古くなります。1ヶ月後にはトレンドが全く変わってしまっている可能性がありますので、新しい情報を常に参照するように気をつけてください。(自戒をこめて)

目次

開発環境の構築

まずは開発できる環境を整えたいと思います。

ここでは執筆時点で最もモダンだと僕の考える方法で環境構築をしてみます。

マシンの準備

Windowsでも動きますが、Macユーザーが極端に多いです。特に初級者の場合は教えてくれる人がなるべく多い環境を選ぶ方がいいのでMacをおすすめします。

勉強会で大人気のMacBook Airですが、だいぶ安く買えるようになりました。
ruby系の勉強会に行くと、参加者の9割はMacで、そのうち半数以上がAirということもざらです。

ここから先はMac OS X 10.7 (Lion)の環境を対象にして進めてしまいます。

Xcode

rubyのコンパイルや、一部のライブラリのインストール時に必要になります。
また、データベースなどの開発に必要なミドルウェアのインストールにも使われます。
デフォルトでは入っていませんので、App StoreからXcodeをインストールしてください。(無料です。)

App Storeへのリンク

Homebrew

Homebrew

パッケージ管理システムと呼ばれるソフトウェアの一つで、開発に必要なソフトウェアの管理に使います。

従来はMacPortsが主流だったのですが、今はかなり多くの開発者がHomebrewに移行しています。

ターミナルで以下のように打ち込むことでインストールできます。

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"
バージョン管理

rubyの場合、実質gitがデファクトスタンダードです。GitHub上で開発されているライブラリもたくさんありますし。

Lionの場合、Xcodeをインストールすれば一緒に入るはずです。

コマンドラインでの操作が苦手な方も、GUIのGitクライアントも増えてきましたので安心です。

あとはgit guiとすると、GUIのクライアントが立ち上がると思います。

rubyのインストール

現在最新の安定版のrubyはバージョン1.9.2ですが、まだまだ1.8.7も多い状況です。OS Xに始めから入っているrubyも1.8.7です。
これから何か新しいプログラムを書くのであれば、1.9.2で問題ないと思います。

追記: 先ほど1.9.3がリリースされたらしいので、そっちが最新ですね。ちゃんと確認していないので取り急ぎ。

ちなみにrubyのインタプリタ(ソースコードを解釈して実行してくれるプログラム)にはいくつかの種類があります。

特に理由が無ければMRIを入れておけば間違いないです。

rubyに限らず最近のスクリプト系言語(LL: Lightweight Languageと呼ばれたりする。perlとか、pythonとか、node.jsとか)の開発者の多くは複数のバージョンを切り替えて扱えるようなツールを使っています。

rubyで言うと、以下の2つが主流です。

最近人気が高まってきているのはrbenvの方ですが、まだまだユーザーはrvmの方が多いと思います。
身近に教えてくれる人がいるのなら、その方に合わせてください。
いないようなら、とりあえずはユーザーの多いrvmがいいと思います。

RVM: Ruby Version Manager - Installing RVM のページの"Single-User installations"の手順に従って作業をすれば、それだけでruby 1.9.2を使うモダンな環境が出来上がります。

またrbenv + ruby-buildは僕の個人的なおすすめです。こちらにチャレンジする方は以下のエントリーを参考にしてください。

rbenv + ruby-buildのインストール方法

エディタ

以下のものが人気が高いみたいです。自分に合ったエディタを探してください。

サーバー

Webアプリケーションを作ったとして、それを動作させるサーバーがないと一般公開できません。
幸い、今は無料でアプリケーションを素早く公開することもできるようになりました。

今ruby開発者の間でもっとも広く愛用されているのはherokuです。
gitでpushするだけでアプリケーションを公開でき、無料でもかなり使えますのでまずはこれを使う方向でいいと思います。

サーバー構築ができる方はVPSやIaaSも検討されるといいと思います。
apache or nginx + passengerがお手軽です。

ちなみにこのブログはさくらのVPS にインストールしたapache + passengerで動いています。

おすすめの学習方法

手っ取り早く体系立てて学ぶには本を読むのがいいと思います。rubyの書籍はたくさんありますが、中でもおすすめの2冊を紹介します。

他の言語を学んだことがある方は、「初めてのRuby」がおすすめです。薄い本なのですが、rubyらしい考え方のエッセンスが詰まっています。

rubyの文法や文字列操作、配列、メソッド定義などの基本的な内容に加え、ブロックやメタプログラミングの入り口まで含まれています。

基礎を固めたあとは「メタプログラミングRuby」がおすすめです。

例えばActiveRecordなど、rubyのよく使われるライブラリはメタプログラミング(通称:黒魔術)を駆使して書かれていることが多く、メタプログラミングの知識無しでは使いこなすことが困難です。

あとはせっかくherokuもあるしアプリケーションを書いてみるのがいいのですが、いきなりrailsにいくと覚えることの多さに挫折してしまうかもしれません。
個人的にはまずsinatraで作った簡単なマッシュアップ程度のアプリケーションを公開してみるのが手軽かつ面白いと思います。
例えば以下のようなアプリケーションを作ってみるのはいかがでしょうか?

  • ATNDのイベントを検索するサイト - APIはここ
  • 楽天やYahooショッピング, amazonを横断して商品検索ができるサイト
  • 自分のツイートからURL付きのツイートを抜き出すサイト
  • Instagramに投稿された写真をタグや位置情報をもとに検索するサイト

初級レベルではsinatraだとDBに接続するまでがちょっと難しいので、DBを使う段階になったらrailsやpadrinoに行くといいかもしれません。

DBを使うプログラムの場合、ブログや一行チャット、Todoを作ってみるのが定番だと思います。
ただ、ログインの機能をつけようと思うととたんに難しくなりますので、とりあえずbasic認証とか、認証無しで。

実際、一番いいのは教えてくれる人を早めに見つけることです。
身近でruby勉強会などが開催されていないか、ぜひ探してみてください。
あとはtwitterやfacebookなどで教えてくれる人を探すのもいいかもしれません。

知っておくべきライブラリやフレームワークの軽い紹介

アプリケーションを作ろうとしたとき、必ずしも全機能を自分で実装する必要はありません。すでに色んな種類の定番ライブラリがありますので、その辺をうまく活かしていくのも素早くアプリケーションを作るコツです。

基本編

RubyGems

ライブラリの管理ツールです。1.9以降はruby本体に付属しているので特にインストールせずに使えます。

$ gem search [検索文字列] -r # ライブラリの検索
$ gem install [ライブラリ名]
$ gem update # ライブラリのアップデート
$ gem uninstall [ライブラリ名]

Bundler

これもライブラリの管理ツールですが、アプリケーション固有で必要になるライブラリの管理に使います。
railsをやるときや、herokuにアップロードするアプリケーションを作るときに触れることになります。

簡単に説明すると、Gemfileというファイルにそのアプリケーションを動かすのに必要なライブラリを列挙します。
そしてbundle installコマンドでそれらのライブラリがインストールされます。
そのライブラリはカレントディレクトリ以下の任意のディレクトリにインストールすることができるので、システムにごちゃごちゃとライブラリがインストールされること無く、アプリケーションごとにきれいに管理できるという利点もあります。


rack

直接rackを意識することはあまりないかもしれませんが、sinatraやrailsといったWebアプリケーションフレームワークはこれを利用して作られています。
rackのおかげで、thinやpassenger, unicornなどのどのサーバーを利用してもちゃんとアプリケーションを動かせるわけです。

Webアプリケーションフレームワーク編

Ruby on Rails

言わずと知れた超有名ruby製フレームワーク。これを使いたいがためにrubyを勉強しようという方も多いのではないでしょうか。
簡単なブログ程度ならあっという間に作れるのですが、ちょっと踏み込むと高機能であるが故に覚えることもたくさんあります。

書籍もたくさんありますが、バージョンに気をつけて選んでください。今の段階だとおすすめは以下です。

あと、公式のGuidesは必読です。


Sinatra

非常にシンプルなフレームワークです。

railsで挫折してしまった人もこちらなら十分理解できるくらい覚えることが少なく、とっつきやすいです。

個人的には、これからプログラムを勉強してみたいという人にはこれを一番に推します。Webアプリの仕組みを勉強するのにもとても向いていると思います。
ちなみに次点はレンタルサーバーを借りることを前提としてPHPでしょうか。


Padrino

最近これをテーマとした勉強会も開かれ、勢いがあります。

railsでは大きすぎるし、sinatraではちょっと足りない、そんなニーズに応えるものです。管理画面が作りやすいのも特長ですね。

データベースアクセス編

ActiveRecord

railsの一部のように思われがちですが、単独で使うこともできます。なのでsinatraで利用することなどもできます。


DataMapper

特長はMongoDBやredisなどのNoSQLのアダプタもあることでしょうか。
ruby製の人気CMSであるLokkaでもこのライブラリを使っています。


Sequel

ActiveRecordやDataMapperよりももうちょっと生のSQLに近いAPIのライブラリという印象です。
SQLがわかっていると、とてもわかりやすいAPIだと思います。

cheat sheet


Mongoid

MongoDBを使う際、今一番使われているライブラリだと思います。

ほぼActiveRecordと同じようなAPIが準備されているので、すんなり使い始めることができます。
それでいて、ちゃんとEmbedded DocumentなどのMongoDBの特長も活かせるような作りになっています。


Redis

高機能NoSQLのRedisのアダプタです。

テンプレートエンジン編

ERB

railsのデフォルトのテンプレートエンジンがこれです。
PHPみたいに、HTMLの中にrubyのコードを混ぜて書くことができます。

<div id="profile">
  <div class="left column">
    <div id="date"><%= print_date %></div>
    <div id="address"><%= current_user.address %></div>
  </div>
  <div class="right column">
    <div id="email"><%= current_user.email %></div>
    <div id="bio"><%= current_user.bio %></div>
  </div>
</div>

Haml

慣れると簡潔にHTMLが書けるようになります。階層関係をインデントで表すので、あとからのメンテナンスもしやすいです。

好き嫌いはあると思いますが、僕はこれを使い始めたらhtmlを書くのがめんどくさくなりました。

上のERBのサンプルコードは実はhttp://haml-lang.com/から持ってきたもので、hamlで書くと以下のようになります。

#profile
  .left.column
    #date= print_date
    #address= current_user.address
  .right.column
    #email= current_user.email
    #bio= current_user.bio

Slim

Hamlから記号などを除いたらslimになるイメージです。
Node.jsでよく使われるjadeと似ているので、そっちもやっている人にはおすすめかも。

ちなみに、hamlっぽく#とか.とかを使って書くこともできます。

div id="profile"
  div class="left column"
    div id="date"= print_date
    div id="address"= current_user.address
  div class="right column"
    div id="email"= current_user.email
    div id="bio"= current_user.bio

Sass

CSSをよりスマートに書くための文法です。

Sassでは、hamlみたいにインデントで階層構造を表現するsassという書き方と、従来のCSSとほぼ同じように書けるscssという書き方の2種類があり、rails 3.1から標準でサポートされたのはscssの方です。

セレクタの入れ子ができたり、mix-inという関数みたいな仕組みや、変数をCSS中で使うことができるのが特長です。

同種のものにlessというものもあります。

テストフレームワーク編

rubyはソフトウェアテストの文化がとても深く根付いている言語だと思います。

勉強会などに参加しても必ずテストが話題にのぼるくらいです。テストでよく使われるライブラリのうち、いくつか定番を挙げます。

RSpec

現状、rubyでテストと言ったらこれがデファクトスタンダードのようになっています。うかつに検索すると古いサイトが出てきてしまいますので、これを学ぶには以下のサイトがおすすめです。

"RSpecの写経"と言われたら、上記のサイトのことです。一通りこなすといいと思います。

あとはRSpecのAPIなどは以下を見ましょう。

個人的にはRelishを一番頻繁に見ていて、モックを使おうとしたときにMocksを参照することがたまにある感じです。

追記: 上記、rubydoc.infoへのリンクが2.4.0という古いバージョンへのリンクになっていました。修正しました。


test-unit

他言語のxUnit(PHPUnitとか、JUnitとか)にあたるのがこれです。

ruby 1.8の頃は標準添付でしたが、今は代わりにminitestというのが標準添付となっています。

標準添付ではなくなってからも活発に更新されているようです。


shoulda

shoulda-matcherとshoulda-contextの2つのgemに分かれているのですが、Test::Unitでもcontextを使ってRSpecみたいにテストケースを整理することができたり、rails開発に便利なマッチャー(検証用のメソッド)が提供されていたりします。

僕は使っていないので詳しくわからないのですが、根強いファンがいるようです。


Capybara

ブラウザでの動作をエミュレートしてくれるライブラリです。テストフレームワーク?って感じですが一応ご紹介。

visit '/top'
fill_in_with 'email', :with => 'user@example.com'
fill_in_with 'password', :with => 'password'
click_button 'Login'

こんな感じに書けます。seleniumを使うことにより、実際にFirefoxが立ち上がって動いたりして、なかなか面白いです。


他にもmockのライブラリとかテストデータの作成に便利なライブラリとか色々ありますが、そこまで進む頃にはすでに初心者じゃないと思いますので割愛します。

情報の入手方法

オブジェクト指向スクリプト言語 Ruby リファレンスマニュアル

まずは公式のドキュメントです。

文法などの確認はこちらで。あと、標準添付ライブラリも便利なものがたくさんあるのでどんなものがあるのか、一通り見ておくといいです。


最速Rubyリファレンスマニュアル検索! | るりまサーチ

マニュアルの検索はこちら。


Rubyist Magazine

通称るびま。

Webで発行されているRubyist向け雑誌です。
技術的な情報のみならず、インタビューやエッセイが掲載されていたりもします。


The Ruby Toolbox

人気のあるライブラリを探すことができます。

最近リニューアルされて、カテゴリ検索に加えてキーワード検索もついて使いやすくなりました。

追記: Toolboxを間違ってToolkitって書いてました。ご指摘ありがとうございました。


RubyDoc.info

ライブラリのAPIドキュメントが見られるサイトです。個人的にとても重宝しています。


Ruby5

英語ですが、ruby関連の情報を流しているPodcastです。
英語の勉強を兼ねて通勤中によく聴いています。


RailsCasts

これも英語ですが、railsのスクリーンキャストです。
これもiPhoneに入れて通勤中に見たりしています。


あとは勉強会やコミュニティに参加するようになると、新しい情報や実務に基づいた詳しい情報なども入手することができるようになります。
あとはブログなどで自分からも情報を発信するようにすることで、色んな人とのコミュニケーションができるようになり、結果色んな情報が集まるようになったりもします。

あんまり優良な情報を発信しようと無理に意気込むのではなく、とりあえず自分が試してみたことやうまくいかなかったことなどを気軽にメモるようにしておくと、結構教えてもらえたりします。

コミュニティ/勉強会

ということで、コミュニティや勉強会です。

まずは 地域Rubyの会 を探してみるといいと思います。
まぁ、やっぱり首都圏が多いですよね。

遠方の方は、自分で始めちゃうのが一番いいのかもしれません。あとはオンラインでしょうか・・・。ちょっとオンラインで継続されているコミュニティの例を僕が知らないのでこの辺はよくわかりません。

僕は横浜在住ではないのですが、Yokohama.rbによく参加しています。片道1時間以上かかりますが。

rubyにこだわらずに勉強会に参加してみるのもいいと思います。そこから得られる刺激は他では得難いものですし、人とのつながりが増えていくのはとても楽しいことです。

勉強会を探すなら、IT勉強会カレンダーをチェックです。

あとはTwitter経由で勉強会の情報を得ることが多いので、ブログなどで見かけた活発に活動されている人を片っ端からフォローするのがいいのではないでしょうか。

まとめ

思いついたことをどんどん書いていたら結構長くなってしまいましたが、少しでも参考になりましたら幸いです。
ここに書いたくらいの内容を事前に知っておけば、突然rubyの人の中に放り込まれても話が全く分からなくてぼっちというおそれは無いと思います。

あとはブログ + twitter + githubは現代のWeb系プログラマにとっては必須だと思います。たとえ趣味のプログラムだとしても。

ブログは無料のレンタルブログでかまいません。プログラマにははてなダイアリーが人気です。もうすぐ"はてなブログ"になるそうですが。

勉強会などに行って名刺を交換しても、twitterとかfacebookとかのアカウントが書いていない場合はあんまりその後の交流が持てないことが多いです。
正直、twitterアカウントはメールアドレスよりも重要かもしれません。

ということで、このエントリをきっかけに自分でWebサービスを作ってみようと思う人や勉強会やコミュニティに参加してみようという人、面白いサービスが増えたりすると嬉しいなと思います。

rbenv + ruby-buildのインストール方法

rbenv, TextMateで開発環境をシンプルにしてみたでも書いたrbenvですが、最近rvmからの乗り換え先として検討している方が多いようです。

僕もあれから1ヶ月半ほど継続して使っていますが、特に困ったこともなく快適に使っています。

そこで、2011年10月5日現在の最も簡単だと思われるrbenv + ruby-buildの導入方法を書いてみようと思います。

rbenv, ruby-buildのインストール

$ brew install rbenv
$ brew install ruby-build

Homebrewから入れるのが一番簡単だと思う。

rbenvの設定

.bash_profileに以下のように書きます。

eval "$(rbenv init -)"
source ~/.rbenv/completions/rbenv.bash

if以下はタブ補完のための設定です。シェルでrbenv まで打ってタブキーを打つとサブコマンドが保管されますので便利です。

zshの人は.zshrcへ多分こんな感じ。

eval "$(rbenv init -)"
source ~/.rbenv/completions/rbenv.zsh

rubyのインストール

ここではとりあえず1.9.2-p290を入れてみます。
rbenv installコマンドはruby-buildをインストールすることによって使えるようになります。

$ rbenv install 1.9.2-p290
$ rbenv global 1.9.2-p290
$ rbenv rehash
$ ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.1.0]

新しいバージョンのrubyや、バイナリを提供するgem(sassとか、railsとか)をインストールした後は$ rbenv rehashして下さい。そうしないとコマンドが見つかりません。

ちなみに、$ rbenv installだけ打ってエンターキーを打つとインストールできるバージョンがずらっと表示されます。

また、MacVimを使っている場合など、libruby.dylibが欲しい場合は./configure時に--enable-sharedを指定する必要があります。これは、"CONFIGURE_OPTS"という環境変数に指定することで可能となります。

$ CONFIGURE_OPTS=--enable-shared rbenv install 1.9.2-p290

簡単な使い方

$ rbenv global 1.9.3-rc1 # 使用するrubyのバージョン切り替え
$ rbenv local 1.9.3-rc1 # このディレクトリ以下で使用するrubyのバージョン切り替え
$ rbenv versions # インストールされてるrubyのバージョン一覧
$ rbenv version # 現在有効になっているrubyのバージョン

$ rbenv localするとカレントディレクトリに.rbenv-versionというテキストファイルが作られます。rvmで言う.rvmrcみたいなものですね。

公式リポジトリ

SinatraでWardenを使った認証がテストできなかった件

問題

wardenを使ってsinatraアプリを作っていたのですが、テスト時にwardenのauthenticated?などのメソッドを呼び出す箇所でenv['warden']がnilになっている旨の例外が発生し、うまくテストできませんでした。
これはcapybara-webkitやseleniumドライバを使っても同様でした。

しかし、ブラウザからアクセスするとちゃんとwardenが有効になり、意図通り認証ができます。

やってみたこと

wardenやrack/testのコードを読んだりしてみたのですが、どうにも理由がわかりませんでした。
deviseのTestHelperも見たのですが、今回の件にはあまり大きく関係しないのかなぁという感じで。
埒が明かないので、この件をエントリにまとめて有識者に助けてもらうことを期待し、検証するための小さなアプリを作ってみました。

warden_test

app.rbに、ほとんどのコードを積み込みました。
なんと、こちらのコードでは正しくテストができました。Caypbaraでcapybara-webkitやseleniumドライバを使った時も同様にちゃんと動きました。

解決

わかってみれば単純でした。以下のコードをrackup.ruに書いていたのがいけないのでした。テスト時にwardenがそもそも使われていなかったということですね。

use Warden::Manager do |manager|
  manager.default_strategies :password
  manager.failure_app = Hogehoge::App
end

まとめ

問題の切り分けのためにはちょっと面倒でも手を動かして検証しましょう。

rbenv, TextMateで開発環境をシンプルにしてみた

今までは会社でWindowsでの開発を強いられていたこともあり、Mac専用のソフトを使って開発を行うことに抵抗がありました。
しかし今後は晴れてMacで開発ができるので、思い切って開発環境の整理をしてみました。

方針はとにかくシンプルに。開発環境の構築のハマりすぎないよう、できるだけデフォルトに近い形でやろうと決めました。

zsh -> bash

なるべくデフォルトに近くという考えから。正直あまりzshを活かせていない気がするので。

僕のぬるい使い方ではタブを新しく開けばいいだけの話なので、screenも止めました。

rvm -> rbenv + ruby-build

rvmはとても便利です。
でもgemsetとかの機能を使わず、プロジェクト毎のgemの管理はbundlerで・・・と考えて
よりシンプルなrbenvとruby-buildを組み合わせる方法に乗り換えてみました。

とりあえずは必要なruby 1.9.2のみを入れています。

実行ファイルは .rbenv/shims 以下に置かれるようになっているのですが、次のコマンドを実行しないと使用できません。 自動ではやってくれないみたいなので、bin/に実行ファイルを置くようなgemをインストールしたときは要注意です。

$ rbenv rehash
Powを使っている場合は設定を。

~/.powconfigに以下のように書くと、ちゃんとrbenvで有効になっているrubyを使ってくれます。

export PATH="/Users/[yourname]/.rbenv/shims:/Users/[yourname]/.rbenv/bin:$PATH"

vim -> TextMate

vimのキーバインドに慣れすぎていてTitanium Studioを試したときにかなりのストレスがあったため、
今後のことを考えて普通のキーバインドのエディタを使ってみようと思いました。
RubyやRailsの開発が主なのでTextMateを使ってみることに。

bundleの管理はgit submoduleでやってみています。

少し使ってみた感想・・・やっぱりvimに帰ってしまうかも。
キーバインドの癖というのはなかなか抜けないですよね。

ストレスにならない程度にちょっとずつ使ってみて、だんだんTextMateの便利機能を使いこなせるようにしたい。

プログラマとデザイナでハッカソンした話

@machida さんにお誘いいただき、ハッカソンしてきました。

今回のハッカソンについて

デザイナーの@machidaさんが「プログラマを招いて一緒にハッカソンをやったら楽しそう」という旨の発言をされていて、それに「やりたいです!」と即反応し参加させてもらいました。

そこにさらに@milligrammeさんと@9dさんが加わり、プログラマ2人、デザイナ2人というバランス良い構成になりました。

企画

それぞれ持ち寄ったアイディアを発表し、最終的に@milligrammeさんの作っていたツイートを色やSVGに変換するツールを起点とした「ちょっと便利でおしゃれな」ツールを作ることにしました。

みなさん勉強会などに参加される方なので、勉強会とかイベント関連で使えそうなもの・・・とアイディアを出し合った結果、今回のイベント会場のプロジェクターにハッシュタグで検索した結果を次々と映しだすツールというアイディアになりました。

もともとはデザイナ+プログラマの2人一組で各々ばらばらに開発する予定でしたが、作業量などから今回は4人で一つのシステムを作る方針にしました。

開発手順・役割分担

リモートではなく実際に顔を合わせて開発を行える環境であったため、スケッチブックに書かれたラフから大体のシステムの機能・アーキテクチャを決めました。

あとは主な担当を以下のようにしました。

  • @satococoa
    Sinatraで全体的なscaffoldを作る+クライアント側のプログラミング(CoffeeScript)
  • @milligrammeさん
    ツイートを数値やRGBに変換するモジュール、Twitterから発言を取得するメソッド
  • @9dさん
    デザイン全般
  • @machidaさん
    @9dさんデザインのhaml化、gitやgithubのレクチャーなどの調整役もやってもらいました

この担当分けがなかなかハマって、お互いの作業が衝突することなくスムーズに進めることが出来ました。
@machidaさんのおかげでgithubを使って協働ができたこともかなり作業を効率化してくれました。

そして公開へ

途中お昼休憩は挟んだものの、気づいたらあっという間に21時くらいになっていました。
ちょうど、ひと通り最低限の機能が実装を終えていたのでherokuにアップし、twitterで軽く告知して終わりました。

KPT

僕が思ったKPTをまとめてみます。

KEEP
  • githubを効率的に使えた
  • 企画から公開までを一日でできた
PROBLEM
  • 始めからDBを使うような設計にしておけば、ツイートの取得部分で悩む時間を減らせたかも?
  • お互いの作業に一生懸命で、それぞれの作業の様子をじっくり見られなかった
TRY

成果物

詳しくはgithub上のREADMEをご覧ください。
試してみるには流用が多いハッシュタグだと面白いと思うので、nicovideoとかpixivとかsoundtrackingとかnowplayingとかがおすすめ。

最後に

場所を提供してくださった株式会社シロクロ様はじめ、みなさまどうもありがとうございました。

そして「ひとりでつまらない」と言いつつも「楽しんできてね」と快く送り出してくれた妻にも、ありがとう。

SocketStreamのデモを動かそう

西村賢(@knsmr)さんの記事を読んで、面白そう!と思い、早速デモを動かしてみました。
Rails Hub情報局: Node.jsに強烈に個性的な「SocketStream」が登場!

デモはgithubのリポジトリから3つほどリンクされています。

とりあえず動かしながら、特徴っぽいところを自分なりに書いてみます。
動かし方については、Mac + Homebrewしか想定していません。というか自分の環境しかわかりません。
あと、Node(Node.js), npm, gitは入っている前提で。
他の環境で動かした方はぜひ教えてください。リンクします。

最初にSocketStream自身をグローバルにインストールしておきましょう。

$ npm install socketstream -g

Coffee-Scriptとか、Socket.ioとかもごっそり入ります。

SocketChat

WebSocketを使ったチャット。app/client/app.coffeeからSS.server.app.sendMessageのようにクライアントからサーバーのメソッドを直接呼んでいる(ように書ける)ところがポイントかな?

動かし方

まず、Redisをインストールしていない人はインストール。

$ brew install redis
$ mkdir -p ~/Library/LaunchAgents
$ cp /usr/local/Cellar/redis/2.2.10/io.redis.redis-server.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/io.redis.redis-server.plist

mkdir -p以降は、brew installが終わったときに自動的に案内が出ますので、言われるとおりに従えばOK。

蛇足
バージョンアップのときにも、起動用の.plistをコピーしてlaunchctlやり直す必要がありますが、バージョンアップの時に出る案内を見逃さなければ大丈夫。見逃しても $ brew info redis で再度見られます。 /蛇足

では動かします。

$ git clone https://github.com/addyosmani/socketchat.git
$ cd socketchat
$ npm install
$ mkdir public/assets # directoryが無いよ、って次の手順で言われたので。
$ socketstream s
$ open http://localhost:3000/

はい、終わりです。

ここでherokuにデプロイしようと、小一時間ほど試したのですがちょっとわからなかったのでパス。
具体的には、heroku上で動かすにはprocess.env.PORTでアプリケーションを動かすPORTを取得するのですが、socketstreamではconfig/app.jsonのような.jsonでその辺の設定をするようで、それを動的に取り出す方法がわかりませんでした。

Dashboard

Widgetを設定し、配置できます。APIからWidgetの中身を操作できるようになっています。
APIから操作し、それがリアルタイムにWidgetに反映されるというのがポイント。(多分)

動かし方

MongoDBをいれていない場合は以下。

$ brew install mongodb
$ mkdir -p ~/Library/LaunchAgents
$ cp /usr/local/Cellar/mongodb/1.8.2-x86_64/org.mongodb.mongod.plist ~/Library/LaunchAgents/
$ launchctl load -w ~/Library/LaunchAgents/org.mongodb.mongod.plist

では動かします。

$ git clone https://github.com/paulbjensen/socketstream_dashboard_example
$ cd socketstream_dashboard_example
$ npm install
$ socketesteam s

以上

SocketRacer

レースゲームです。
チャット機能や衝突判定などにのメインロジックにCoffeeScriptを使っているのが売りらしいですが、
すごいんですけれどもsocketstreamならではの売りがちょっとよくわかりませんでした。しっかりソースも追っていません。

見所をどなたか教えてください。

動かし方
$ git clone https://github.com/alz/socketracer.git
$ cd socketracer
$ npm install
$ socketstream s

以上

まとめ

公式のREADMEが充実しているので、ひと通り呼んでサンプル作ってみたいと思います。
対応ブラウザは限定されてしまうかもしれませんが、注目に値するフレームワークではないでしょうか。

CoffeeScriptはじめの一歩

Rails勉強会@東京第63回のあまりのCoffeeScript人気に便乗して。

インストール

CoffeeScriptを動かす、あるいはJavaScriptにコンパイルする方法も色々あるようですが、Node入れてやるのがいいと思うのでその方法で。
Node使う予定の無い人も、きっとそのうち一度はExpressやらSocket.ioやら使うときが来ます。

まずはNode(Node.js)を入れます。MacでHomebrewな人はおめでとうございます。簡単です。

$ brew install node

rubyでいうrvmみたいなものもあるのですが、僕はbrewで十分だと思っています。

引き続き、Node用のライブラリを管理するnpmを入れます。rubyでいうRubyGemsのようなものです。

$ curl http://npmjs.org/install.sh | sh

多分/usr/local/bin/以下にnpmが入ります。そのままcoffee-scriptを入れます。

$ npm install -g coffee-script

オプションの-gをお忘れなく。npmは、デフォルトではカレントディレクトリ以下にnode_modules/というディレクトリを作って、その中にライブラリを入れます。
今回はカレントではなくglobalにインストールするので、-gを付けます。これで/usr/local/bin/coffeeが入ったことと思います。

Hello World

hello_world.coffeeというファイル名で以下のようなスクリプトを作ってください。

console.log 'Hello, world'

jsにコンパイルし、nodeで動かしてみます。

$ coffee -c hello_world.coffee
$ node hello_world.js    # => Hello, world!

また、jsにコンパイルせずに直接動かすこともできます。

$ coffee hello_world.coffee    # => Hello, world!

.coffeeを更新したら自動的にjsにコンパイルする方法

その1 coffeeコマンドの-wオプションを使う。
$ coffee -wc hello_world.coffee  # これでファイルを監視開始
その2 watchrを使う。

参考:Haml+SCSS+CoffeeScriptでモダンな静的ページ制作を

その3 shadow.vimを使う。

参考:Vim-users.jp - Hack #192: 任意の言語で任意のマクロを使う

効率よくCoffeeScriptを勉強する方法

公式サイトを写経するといいと思います。
JavaScriptと違う書き方やキーワードも多くて、なかなか覚えられないですが一度写経してあとはひたすら書くといいのだと思います。

正直なところ、まだCoffeeScriptよりもJavaScriptを直接書く方が楽です。いちいち頭の中にあるjsのコードをCoffeeScriptに翻訳しながら書いている感じです。

Haml+SCSS+CoffeeScriptでモダンな静的ページ制作を

CoffeeScript、流行っていますね。

あとはモダンなRubyistならそろそろ静的ページでさえもHTMLやCSSではなくHaml, SCSSで書きたいと思っていることと思います。

実現方法はあまり難しくありません。要はhaml, scss, coffeeファイルを更新したときに自動的にコマンドを実行してhtml, css, jsにコンパイルしてやればいいだけなので、watchrを使ってちゃちゃっとひな形を作ってみました。

なお、ついでにhttp://www.cdnjs.com/を使ってunderscore.jsとbackbone.jsを読み込んでいます。あとGoogle Libraries APIを使用してjQueryも読み込んでいます。

https://github.com/satococoa/modern_html5_lab

watchr?

watchrとは、ファイルの更新を監視し、任意の処理を実行するためのライブラリです。
例えばautotestのようにファイルの修正時に自動的にテストを実行したり、今回のようにソースファイルの更新時に自動的にコンパイルしたり、という用途で使えます。

$ gem install watchr # インストール
$ vim watchr.rb # 監視対象、処理を書く。ファイル名は別になんでもOK。

watchr.rb

watch('src/(.*)\.haml')   {|md| system("haml -f html5 #{md[0]} prod/#{md[1]}.html") }
watch('src/(.*)\.scss')   {|md| system("sass --scss #{md[0]} prod/#{md[1]}.css")    }
watch('src/(.*)\.coffee') {|md| system("coffee -o prod -c #{md[0]}")                }

$ watchr watchr.rb # 監視開始

もちろんhaml, sass, coffee-scriptが入っていないと動きません。

jsdo.it

先日初めて使ったjsdo.itが面白かったので週末にHTML5の練習も兼ねて遊んでみようかなぁと思ったのですが、久しぶりにHTML+CSS+JavaScriptを書いたら(ちなみにこんな気持ち悪いものができてしまった。http://jsdo.it/satococoa/faces)Haml+SCSS+CoffeeScriptのモダンな環境の簡潔さを実感してしまいました。
そのためローカルでHaml+SCSS+CoffeeScriptで書いたものをjsdo.itに貼り付ける方がいいかなぁと思い、こんなものを作ったのでした。

そういう目的なので、コンテンツのディレクトリ分けなどはしていません。

-webkit-transitionで遊んでみた

@milligrammeさんがgistで面白いことをしていたので、forkして-webkit-transitionで遊んでみました。

ソース:https://gist.github.com/1014379
実行結果:http://dl.dropbox.com/u/142643/stars4.html
↑そのうち消すかも

HTML, CSS, JavaScriptに分解してjsdo.itに置いた
http://jsdo.it/satococoa/stars

ちなみにhamlで書かれていたので、それをwatchrを使ってstars.hamlが更新されると同時にhtmlを生成するようにしています。

$ gem install watchr
$ watchr hamler.rb # これで更新の待機状態になる

アニメーションは単純に-webkit-transitionを使っているだけです。
これだけで簡単にアニメーションができるなんて素晴らしいですね。