2010-07-19 [長年日記]
_ Bundler 0.9.26 を触ってみた
あぁ、快適だ。例え Windows でも画面もキーボードも小さくても、Emacs バインドで書ける喜び*1。
Bundler との出会い
先日、pear packageでアプリの依存ライブラリを管理するようにし始めたわけですが、もとはと言えばこれは jruby-appengine を調べていたときに知った
Bundlerがめっちゃ便利そう
というところからスタートしています。
もともと依存パッケージは管理する必要があると感じていたわけですが、とりあえずリストアップして README 辺りに書いてありゃいいのかなぁとか軟弱なことを思ったりしていました*2。しかし jruby-appengine を調べたときには
- 必要な gem も含めて全部勝手に deploy されてるらしい
- bundle っていう gem がなにやら超絶便利らしい
ということを知り、どうにか勉強しなきゃと思っているうちにまた半年が経っていました*3。
インストールと基本的な使い方
Bundler: The best way to manage Ruby applications
gem install bundler
bundle help
ですね。
Bundler でできること
- 依存している gem package を Gemfile というファイルで管理できる*4
- Gemfile をもとに bundler が download、install を行うことができる
- download した *.gem パッケージを cache することができる ( bundle package )
- install の際には gem server だけでなく、この cache も利用することができる
- local にも remote にも Bundler を入れておくことで、deploy 時に自動的に依存 gem も更新することができる
- Bundler を利用したライブラリの読み込みのサポート ( Bundler.setup )
Bundler: The best way to manage Ruby applications
この辺に書いてあるのですが、group に分けておいた gem package 群を必要に応じて require することができるようです。例えば test 用のライブラリは開発環境でだけ読み込む、といったことを個別に記述することなく Bundler.setup だけで実現できる。らしいです。自分はそこまでたどり着いてはいないのですが。
deploy ツールと連携して remote の gem を管理する
実は当初、bundle package でできる cache/*.gem さえあればいいのかと勘違いしていました。でもそんなことないですよね。そりゃそうだ。実際には
bundler を使って gem をインストールする際に cache/*.gem があれば gem サーバを見にいかなくて済むよ
という話でしかありません。
また、remote での gem のインストールも Bundler によって自動化されるのではなく、
remote にインストールされている Bundler を呼んでくれる deploy ツールによって実現されています。
そりゃそうか。
そりゃそうかの連続。そりゃそうかの連続なんだけど、この仕組みを思いついた人はやっぱり頭いいなぁ。
逆に言うと deploy ツールがない場合は開発環境の準備が多少楽になるよ、程度の意味しかありません。たぶん。まぁそれも重要なんですけど。依存パッケージをいちいち調べたり、動かし始めてからアレがないコレがないという状態になるのはとてもイライラしますから。
Bundler 1.0 へ
ROADMAP というファイルを読むと、今後は 0.10, 1.0 と進んでいくようで、0.9 からは API は変更しない模様。逆に言うと 0.9 の間は変更し放題かな? 実際、0.9.4 と 0.9.5 の間に断絶があるらしいです。
他の環境への応用を考える
Ruby で deploy ツールと言えばもちろん Capistrano 系になるわけですが、これらは基本的に shell アクセスを要求します。repository からコードを取得してサーバを再起動するまで全自動で行います。スバラシイ。
では shell アクセスが不可能な場合はどうしたらよいのでしょう。例えばレンタルサーバでの CGI や PHP 開発では?
PHP の場合は
- include_path さえ通っていれば、ライブラリの読み込みはできる
- include_path は .htaccess からスタートするアプリケーション動作の流れの中で定義できる
- Pear package は pure PHP で書かれていることが保証されており、単に extract しただけで使える
- Pear package は gem のように複数バージョンを管理することはできない
という感じなので、
- 指定の package を取得してきて
- package を extract して
- アプリケーションのコードと一緒に put
できるだけでいいはずです。例えばこの最低限度の機能が実現できれば deploy ツールがなくてもアプリケーションとその依存パッケージを同時に deploy できます。
pecl とか使う場合は build もサーバの再起動も必要になるので話は変わってきますが、星の数ほどあるレンタルスペースベースの小規模 PHP 案件はこれで十分ですし、小規模こそ、この辺りの作業に掛ける手間は減らすべきです*5。
やっぱり PHP にこそ欲しいですねぇ、これ。
参考
2010-07-17 [長年日記]
_ rvmを使ってREEへの移行を考える
Ruby Enterprise Edition が海外では人気らしいというのは知っていたけど、別に今のところ Rails 仕事なんてないしなとか悠長なことを考えていました。
Welcome ― Ruby Enterprise Edition
RHEL クローンでは RubyEE は yum ですぐ使える
そんな中、RHEL 5 クローンな OS では yum で入る Ruby が 1.8.5 で、いやだなぁ、せめて 1.8.6 なら良かったのにと考えていたら以下の記事で
いよいよ RubyGems も RDoc も Ruby 1.8.7 に絞りたいよんと言い始めました。さすがにこれはちょっと困ったなー、どうすっかなーと思っていたところ、先日 Ruby EE ( Enterprise Edition ) が 1.8.7 ベースになっていたことを偶然知り*1、また
で RHEL 5 用に Ruby EE を含むパッケージ群の yum レポジトリが用意されていることも知っていたし、
Twitter / poppen: centosにRubyEEとnginx + pass ...
centosにRubyEEとnginx + passengerをインストールしたでござる
と、普段CentOSを使わない人の動向も知っていたので、間違いなくイケるぞと判断し、
こりゃあ Ruby EE に移行するしかない
と、ようやく思い立ったわけです。うーん前振りが長いな。
yum で RubyEE を入れる作業は省略
End Point のサイトに書いてある通りなので。自分の platform に合う repository データの rpm を入れるだけ。
2010-07-17 現在、i386 向けのものは
ruby-enterprise.i386 : Ruby Enterprise Edition (Release 20090520)
です。
RubyEE 移行への検証環境を rvm で作る
RVM: Ruby Version Manager - RVM Ruby Version Manager - Documentation
問題は RubyEE へすぐ移行できるかどうかです。少ないながらも Ruby のコード資産はあります。一応常用環境が 1.8.[67] なので新たに書いたコードは問題ないと思いますが、1.6 時代から使っているものはさすがに一通り検証してからでないとちょっと怖い。特に 1.8.7 は非互換の部分がちょいちょいあるので、意図せず踏んでいるケースが考えられます。
そうなると一気に yum で Ruby を抜いて Ruby EE を入れて gem を入れ直しておしまい、とはいきません。
どっかに検証環境を作らなきゃ。でも Ruby EE を手軽に入れられる環境は他にないな。
普段使っているプラットフォームは
- OSX 10.5 + Fink Ruby 1.8.6
- Debian 5.0.x + Ruby 1.8.7
- CentOS 5.x + Ruby 1.8.5
で、問題はこの CentOS なわけですが、これを入れ替える前に RubyEE の検証を行いたいわけです。
やりやすいのは Debian に rvm 環境を作って rvm で RubyEE を入れる方法かなー、読んだことあるし。*2
ということで今度は rvm のインストール。
rvm は bash スクリプトで install して動かす
※ Windows ? 知らないっす :-) 適当に VM で Linux 動かせばいいと思います。
入れ方は何通りかあるように見えますが、結局
bash スクリプト群を download して動かす
という方法には変わりありません。shebang に
#! /usr/bin/env bash
と書かれているので *BSD など bash の入ってない環境では先にインストールしてください。
自分が試したのは github から直接 download して動かす方法でしたが、rubygems からインストールしてる人もいるようですし、たぶんどっちでもうまくいきます。というのも、普通にユーザー権限でインストールしていく場合には rvm は
~/.rvm
で完結し、システムに用意されている Ruby と rvm でインストールした Ruby を明確に区別できるからです。そのために login shell の rc ファイルに
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
を追加しろ、と書かれています。
つまり、そういうことです。基本的には rvm で入れる Ruby は他のユーザーには影響しませんし、何もケアしていない場合は shell を変えるだけで使えなくなります。
ビルドに必要なものをパッケージで用意
さて、rvm 自体は bash スクリプト群なので扱いも楽ですが、rvm で Ruby をインストールする作業は結局自分でコンパイルすることに他なりません。少なくとも RubyEE を rvm でインストールする際には以下のものを要求されるようです。
- C Compiler
- C++ Compiler
- make
- patch
- zlib headers
- openssl headers
- readline headers
環境や入れる Ruby のバージョンによって要求されるものは当然違うと思いますが、これらをシステム標準のパッケージでインストールしてしまえば ok です。インストールがうまくいかない場合はカラフルな log を見ればたぶん分かります。実際この記事は log を開いて書いてます。--trace を使えばリアルタイムにも確認できるかもしれません。やってみてないですけど。
rvm でインストールした ruby の使い方
同じです。irb の prompt などは違いますし、インストール済みの gem も違いますが、動かし方は同じです。というか、何を起動しようとしているかによって違います。MRI にない JRuby 独自の動かし方などがあればそれに従います。
基本的な rvm サブコマンド
| rvm use | 利用する Ruby を切り替える |
| rvm use --default | 指定のバージョンをデフォルトの Ruby とする |
use --default を使えばシステム標準の Ruby がなくてもとりあえず開発はできるかもしれませんね。
ちなみに default は
~/.rvm/environment/
以下を見れば分かります。
default -> ~/.rvm/environments/ree-1.8.7-2010.02 ree-1.8.7-2010.02 ree-1.8.7-2010.02@global ruby-1.9.2-rc2 ruby-1.9.2-rc2@global system
こんな風になっています。system が何ともリンクしていないのはたぶん system の Ruby がないからです。
| rvm list | インストール済み Ruby の一覧 |
| rvm list known | インストール可能な Ruby の一覧 |
2010-07-17 時点で Ruby 1.8.6 からしかインストールできないっぽいんですが、もう今のバージョンはそうなんですかね。昔のバージョンはもっと古いものも入れられたみたいですが。
| rvm ruby SCRITPT | 指定の SCRITPT をインストール済みの全 ruby で実行 |
| rvm VERSION,VERSION[, ...] SCTIPY | 指定の SCRITPT を指定の VERSION の ruby で実行 |
| rvm ruby | default の ruby で irb を立ち上げる |
検証対象のコードをインストール済みの ruby で一気に実行することができます。いちいち rvm use で切り替える必要なし。 全 ruby じゃなくてコレとコレで実行したい、という指定もできますが、特定のバージョンでだけ実行することはできないようです*3。
その場合は rvm use して切り替えてから普通に
ruby SCRITPT
で実行すれば済む、ということでしょうね。
sudoして使いたい
Ruby スクリプトを純粋に Web アプリだけに使っているのならあまり関係しないかもしれませんが、システム管理に使っている場合は sudo で権限を変えて実行したい場合がよくあります。しかし、先に書いたように rvm でインストールした Ruby は基本的に自分の常用環境でしか動きません。
そこで rvmsudo というツールが用意されています。
~/.rvm/bin/rvmsudo
これで rvm でインストールした Ruby を sudo で使えます。
特定のディレクトリだけ違うバージョンを使いたい
これ! これめっちゃ便利そう。使い方は簡単、目的のディレクトリに
.rvmrc
というファイルを置き、中に Ruby のバージョンを指定するコマンドを書くだけ。例えば
rvm use 1.9.2
としておくと、この .rvmrc の置いてあるディレクトリ以下だけで Ruby 1.9.2 がデフォルトの Ruby になります。外からこのディレクトリに cd したときに Ruby が切り替わった旨のメッセージも出ます。
info: Using ruby 1.9.2 rc2
これはすごいなぁ。例えば特定の branch は特定のバージョンの Ruby 用です、ということをこのたった一つのファイルだけで明示できる。なんてこった!
※ 脱線しますが、こういうものこそ PHP に欲しいんですよねぇ。いい悪いでなく PHP では中小規模のものを扱うことが多いので、より多くの環境に対応できた方が嬉しいんです。でも基本的に mod_php だと OS ごと仮想化する形の方が結果的に面倒が少ないんです。とは言えやはり大げさなんですよねぇ。別に Apache のバージョンや OS のバージョンに依存してないのに全環境を仮想化しなきゃいけないのは。
まとめ
Ruby 1.9 移行期であり、また複数の Ruby 実装の完成度が急速に上がってきていますし、Ruby で開発を行う人には rvm はとても便利ですね。面倒そうで渋っていたけど、自分のスクリプトの portability も上げていかないといけないので Mac にも入れないとダメだなと思いました。(これ書いている時点ではまだ仮想環境でしか入れてないですけど。)
RubyEE はあえて歩みを遅くしたい場合に有効な選択肢で、RHEL クローンでは簡単にインストールできるのがとてもありがたいです。恐らく RHEL 系は想定以上の歩みの遅さに悩まされると思いますので、RubyEE を基本と考えるくらいでいいのかもしれません。
残った課題は
- rvm で入れた Ruby 自体をシステム標準とする方法
- そもそもこれにメリットがないといけないので、しばらくは放置かな?
- bundler との組み合わせでも大丈夫になったらしい情報が rvm のサイトに書いてあるが、bundler 自体が分かっていない
なんとなく bundler こそ PHP に欲しい機能のはずだと思っているので、時間を見つけて try したいです。
参考
2010-07-11 [長年日記]
_ MetaCon - wtnabe編
MetaCon とは勉強会勉強会のことですが、
直接は関係なくて、勉強会とかについて考えてみた、っていう意味でしかありません。
というわけで、以前からもやもやと考えていた勉強会というか、エンジニアコミュニティについて、モデルを2つ挙げて考え直してみました。目的は、自分の身近な範囲に継続的な、講師 vs お客様という構図ではない何らかの「活動」があったらいいな、です。
モデル1 - asakusa.rb
Asakusa.rbは、東京下町周辺のRuby技術者たちが集まって何かをハックする地域Rubyistコミュニティです。 また、Seattle.rbのように、活動を通して少しでもRubyコミュニティ全体に還元できるようなプロダクトやノウハウ等の成果を残していくことができたらいいなぁ、と考えています。じっさいに、Seattle.rbのdrbrainにどんなふうにやっているのか訊いてみました。
念のため補足しておきますと「下町周辺とか浅草界隈に在住・通勤している人でなければ参加できない」というわけではありません。どなたでも参加は歓迎です。
2008年7月に第1回が開催されて約1年後の第13回くらいから急にペースアップ。記録のない12回に何があったんでしょうか。現在はログや議事録といった名前は付けず、淡々とメールのやりとりが qwik 上に溜まっている感じになっています。実際の活動内容は個々人の日記、あるいはより適切な場所に還元されているようなのですが、まとめページなどがあるわけではないので、詳細はちょっとよく分からないです。
気になる点は以下。
- テーマは最近はもう全体のものはなく参加表明とともに各自のテーマが挙げられている
- 集まり方
- 点呼とかとってるのかな?
- 記録の残し方
- 次回について練ったりしてる? 参加表明とテーマ設定が同時ならこれは不要か。
- いつの時点でどういう経緯で現在の方法に落ち着いたのか?
テーマ設定がすごいです。例えば "RubyKaigi" でもいい。改めて読み直すと asakusa.rb は勉強会じゃないのです。
Asakusa.rbは、東京下町周辺のRuby技術者たちが集まって何かをハックする地域Rubyistコミュニティです。
実はここがものすごくうらやましいところ。というのも北陸には人間が少ないのである特定の言語や環境などにテーマを絞ると参加者の数がぐっと減るか、逆に何の勉強会に出ても「いつものメンツ」のような状態になってしまう。しかも北陸3県をまたいでこの状態。悪く言うつもりはないけど、やっぱ「ちょっとしんどい状態」なのは間違いないと思うんですよ。自分はあんまりあちこち出かけていない方だけど、出てる人は毎週北陸3県を走り回っているような、そんな感じになっています。
というのと、もう一つ、自分の興味はもともと特定の言語や環境ではないので、無理に分かりやすいテーマに絞らなくてもいいのではないかということを以前から感じていました。これに asakusa.rb の活動の流れがとてもよくマッチしているように見えるわけです。
- 特定のネタに縛られる必要もなく
- 何かをハックして
- 成果をアウトプット/還元する
ことが大事なんじゃないか。それがごく自然に、淡々と回っているところが asakusa.rb のとてもステキなところだと思います。
モデル2 - toRuby
toRuby は Rubyist の第2の聖地と言っていいのではないかというくらい大切にされている印象があります。少なくとも有名な Rubyist たちが喜んで、あるいは緊張をもって登壇してくれる、とても特別な地域 Ruby 勉強会。目標とするのはおこがましいとさえ言えます。RegionalRubyKaigi も 2010-07 現在で2回開催されています。
ここで気になっているのは内容や熱さもさることながら、
- 公民館ベースという運営方法
実は、特に金沢では勉強会に積極的である程度のスペースを提供してくれそうな会社がないので、会場の確保にいつもちょっと苦慮しています。(富山、福井の方が話は早かったりする。)
- 北陸は基本的に車社会
- 貸会議室などはやはり街が充実している
- 街中になると駐車場が少なく駐車料金もバカにならない
小規模でもある程度キャッチーで集客が見込めそうなら ITビジネスプラザ武蔵を使うことが最近は増えてきている印象ですが、地味なものはちょっと躊躇があります。
中規模以上のセミナーなどになると高等教育機関の協力を得やすいので、その場合は会場、駐車場は問題なくなりますが、その規模のものを連続して開催するのはそうそうできるものではありません。
ということで目をつけたのがこの toRuby 方式。これに目をつけてからいろいろ下調べをしている最中です。今のところ近江町交流プラザが場所と値段でいちばんいいかなという印象ですね。
金沢市の中央公民館は利用料無料で借りられるんだけど、街中にあり、かつ駐車場がない。生涯学習センターも同様。近江町も本来は駐車場には苦労するのですが、いちば館の駐車場は最近 17:00 以降無料になったので平日やるなら狙い目かなと思っています。ネット予約ができないという弱点はあるものの、建物も新しくてきれいだし、いろいろ遊べるんじゃないかと期待はあります。感触を得たのは
くまでもわかる 文系のためのプロジェクト・マネージメント紹介セミナー – アートグミ-ギャラリー
これに参加したからというのもあります。
金沢の市街地に限定せずにエリアを広げるともう少し見つかるのかもしれませんが、まだそこまでは調べられてはいません。少なくとも鞍月エリアにはめぼしいものはなさげです。金沢外ということになると、自分は公共系のものは借りる資格がありません。
まとめ
最も短く書くと
- 金沢近郊で
- 公民館系、安い公共スペースを基本に*1
- 何かをハックする
集まりが定期的にできたらいいな、と考えています。
何かやりたいことはあるんだけど既存の勉強会は今ひとつテーマがしっくりこなかったという方はいらっしゃいませんか。やり方はよく言われる勉強会だけじゃないはずです。なんかもっと手を動かしたい、もっと成果をアウトプットしていきたい、という思いがあるなら、それを形にしませんか。
とは言え、Asakusa.rb のように Ruby 縛りでは恐らく金沢近郊では回りませんし、漠然とエンジニアとしてしまうとテーマがバラバラすぎて集まる意味が薄れてしまいます。今悩んでいるのはこの「大きなテーマ」の部分です。
個人的には「管理」方面に惹かれています。システム管理、Issue Tracking, プロセスやプロジェクトのマネージメントなどです。ハードウェア方面は疎いです。しかし、これでもだいぶ広いですね。まぁ、もうずっと抱えているものなので焦ってもいないです。とりあえず自分のために整理し直してみたという感じです。一緒にやりたいという人はもちろん大歓迎です。まずは一緒に悩んでください。嘘です。悩むのはあまり生産的ではありません。一緒に考えてください。小さな成果でも、出し続けられればいいなと思っています。
これは、自分の個人の活動を支える最大のポイントでもあります。小さくても続いていることが大事。たぶんきっとね。自分の出せる最大サイズのかめはめ波がたいした大きさではないことは学習済みです。
*1 人数が極端に少なければ別に場所はどこでもいいですが
2010-07-01 [長年日記]
_ Rubyのautosplitの結果は$FというグローバルなArrayに入る
いや知らなかった。
$ ruby --help Usage: ruby [switches] [--] [programfile] [arguments] -0[octal] specify record separator (\0, if no argument) -a autosplit mode with -n or -p (splits $_ into $F) -c check syntax only -Cdirectory cd to directory, before executing your script -d set debugging flags (set $DEBUG to true) -e 'command' one line of script. Several -e's allowed. Omit [programfile] -Fpattern split() pattern for autosplit (-a)
(snip
「awk でもいいんだけど Ruby が標準で持ってるメソッドを使えばもっと楽にできる処理」がたぶんあったんだと思うけど、なんか急に Ruby の autosplit を使って処理してみようと思い立った。*1
で、使ってみたら split された結果がどこに入っているのか分からなくて困った。awk の代わりに使おうと思っているのでてっきり split した結果は $1, $2, $3, ... に入る、
help の $F という表記はそういう意味なんだと勝手に思い込んでしまっていた。
つまり、F は 1, 2, 3, ... に置き換えられるものなんだと。でも違った。
本当に $F という変数ができていて、しかも zero origin の Array だった。
まぁ確かに split は split であって back reference じゃないし、String#split の挙動と合っているので自然なんだけどね。awk脳の恐怖っ。
※ その後、結局 autosplit はやめて普通に自前で回して自前で split して自前で処理した。
*1 実際にこの日記を書いているのは2週間近く経ってからなので、理由はもう覚えていない