xargsメモ

xargsはよくfindと組み合わせて一括処理したりするのに使うけど、失敗すると大ダメージを受けるのでお勉強。

プログラムを指定しないとecho

xargsにプログラムを指定しないとechoが使われるのでどんな感じに渡されるのか確認できる。

$ ls -l
total 0
-rw-r--r--  1 pasela  staff     0B  1 22 17:11 foo
-rw-r--r--  1 pasela  staff     0B  1 22 17:11 bar
-rw-r--r--  1 pasela  staff     0B  1 22 17:11 baz

$ ls | xargs
foo bar baz

NUL(\0)区切りで受ける

xargsはデフォルトではホワイトスペースで区切るので、たとえば"Foo Bar"というような空白を含むファイルがあるときに普通に実行すると残念なことになる。

$ ls -l
total 0
-rw-r--r--  1 pasela  staff     0B  1 22 17:11 Foo Bar
-rw-r--r--  1 pasela  staff     0B  1 22 17:11 baz

$ find . type -f -print | xargs rm
rm: ./Foo: No such file or directory
rm: Bar: No such file or directory

これはこんな感じの3引数として渡される。

rm "./Foo" "Bar" "baz"

これを避けるにはリストを\0区切りで出力して、受ける方も\0区切りで受けるとよい。
findのほうは-print0を使うと\0区切りで出力してくれ、xargsは-0で入力を\0区切りとして受け取れる。

$ find . type -f -print0 | xargs -0 rm

これはこんな感じの2引数として渡される。

rm "./Foo Bar" "baz"


ちなみにGNU版の場合は-d delimで他にも任意のデリミタを指定することができる。

実行コマンドを表示する

-tを指定すると実行するコマンドを表示してくれる。

$ ls | xargs -t
/bin/echo bar baz foo
bar baz foo

表示した上で実行もするので、dry run的な確認には使えない。勘違いしないように。
ログとして残したい場合なんかにいいかも?

実行するかどうか確認する

-pを指定するとコマンド実行毎に実行するかどうか確認してくる。yで実行、それ以外でスキップ。

$ ls | xargs -p
/bin/echo bar baz foo?...y
bar baz foo

入力n行ごとに実行する

-L 数字で指定行数ごとにコマンドを実行させられる。

$ ls | xargs -L 1 -t
/bin/echo bar
bar
/bin/echo baz
baz
/bin/echo foo
foo

$ ls | xargs -L 2 -t
/bin/echo bar baz
bar baz
/bin/echo foo
foo

引数n個ごとに実行する

-n 数字で指定個数の引数ごとにコマンドを実行させられる。

$ ls | xargs -n 1 -t
/bin/echo bar
bar
/bin/echo baz
baz
/bin/echo foo
foo

$ ls | xargs -n 2 -t
/bin/echo bar baz
bar baz
/bin/echo foo
foo

ん、-Lとの違いがわからない?
ではこうやって1行の入力にしてみると違いがわかるはず。

$ echo "foo bar baz" | xargs -n 1 -t
/bin/echo foo
foo
/bin/echo bar
bar
/bin/echo baz
baz

$ echo "foo bar baz" | xargs -L 1 -t
/bin/echo foo bar baz
foo bar baz

-nのほうはホワイトスペースで3つに区切られた上で、1つずつ実行されている。
-Lのほうは1行の入力ずつ実行されている。

置換文字列で挿入する

普通はxargsに渡したコマンドの最後にxargsが引数を追加して実行されるが、cpやmvみたいにコマンドラインの途中の位置に挿入して欲しい場合は-I repstrが使える。

普通にやると……

$ ls | xargs -t cp /path/to/dest_dir
cp /path/to/dest_dir bar baz foo
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
       cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory

こんな感じのコマンドラインで実行されてしまうが、-Iを使うと……

$ ls | xargs -I % -t cp % /path/to/dest_dir
cp bar /path/to/dest_dir
cp baz /path/to/dest_dir
cp foo /path/to/dest_dir

このように-Iで指定した文字列のところを置換して処理してくれる。

BSDの場合)もうちょっと賢く

上記のは見てのように自動的に-L 1として処理されてしまうので効率があまりよくない。
ここはcp bar baz foo /path/to/dest_dirってなってほしいよね?
こういう場合、BSD版なら-J repstrを使うとよい。

$ ls | xargs -J % -t cp % /path/to/dest_dir
cp bar baz foo /path/to/dest_dir
GNU coreutilsの場合(2013-03-05追記)

GNU版のcpやmv等の場合、--target-directoryというdestinationを指定するオプションがあるので、-Iを使わずに次のようにすることもできる。

$ ls | xargs -t cp --target-directory=/path/to/dest_dir
cp --target-directory=/path/to/dest_dir bar baz foo

通常、引数の最後となるdestinationをオプションで手前に持ってくることができる。

複数プロセスで並列に実行する

-P 数字を使うと指定したプロセス数で並列実行してくれる。デフォルトは1。

例えばこんな感じのURLリストがあったとして……

$ cat urls.txt
http://www.google.co.jp/
http://www.yahoo.co.jp/
http://www.goo.ne.jp/

こんな感じで実行すると普通は1つずつ実行される。

$ cat urls.txt | xargs -n 1 -t curl >/dev/null
curl http://www.google.co.jp/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 12352    0 12352    0     0   130k      0 --:--:-- --:--:-- --:--:--  177k
curl http://www.yahoo.co.jp/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 25694    0 25694    0     0  53247      0 --:--:-- --:--:-- --:--:--  253k
curl http://www.goo.ne.jp/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 64743    0 64743    0     0   630k      0 --:--:-- --:--:-- --:--:--  916k

-Pを指定してやるとこれを並列に実行して一気にダウンロードできる。

$ cat urls.txt | xargs -n 1 -P 3 -t curl >/dev/null
curl http://www.google.co.jp/
curl http://www.yahoo.co.jp/
curl http://www.goo.ne.jp/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 12340    0 12340    0     0   127k      0 --:--:-- --:--:-- --:--:--  191k
100 64796    0 64796    0     0   590k      0 --:--:-- --:--:-- --:--:--  832k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 25703    0 25703    0     0  59137      0 --:--:-- --:--:-- --:--:--  522k

Webカラー名を一覧表示するunite source作ってみた

vimにもカラーピッカーみたいなプラグインはいくつかあって、自分はcolorsel.vimとかColorV.vimを使っていたんだけど、ColorVのカラーリストがなんとなく気に入らなかったので、uniteのソースとして自作してみることにした。


unite-webcolorname
https://github.com/pasela/unite-webcolorname


こんな感じで色を選択して挿入したりコピーしたりできる。


Vim script自体もあんまり書いたことないしuniteのsourceも作ったことなかったので、あちこちのsource plugin見ながらなんとか作ってみたよ。
シンタックスハイライトの例がほとんどなかったのと、ハイライトの目的がちょっと普通じゃないので試行錯誤が必要だったけど、こんな感じに綺麗にできた。


選択中の項目が白くなっちゃうのがちょっと残念だけど、まぁ仕方ないかな?
カーソル下のcandidateから色取ってCursorLineを逐一書き換えるという方法も浮かんだけどそもそもできるのかわからないし、選択中の項目がわかりにくくなりそうだからまぁいいかな、と。気が向いたらそのうちやってみるかも。

Node.jsはじめてみた

話題……というには今更だけどなんとなくNode.jsを始めてみた。
本当はSymfony2をモノにしようと勉強する予定だったんだけど、飲み会で「Node.jsやりたい!」って言ってる人がいて「ふーん」と思いつつもちょっと気になって手を出してみた。そしたらなんか面白くなってきてハマっちゃったかもw

Node.jsに抱いていたイメージ

自分がNode.jsに抱いていたイメージは「サーバサイドJavaScriptの一種」「ノンブロッキングI/Oとイベントループで大量のアクセスもさばけるらしい」とかそんな程度だった。最近だと「WebSocketのために使われる」みたいなイメージも。
でもまぁ、一部の用途ではいいソリューションになるんだろうなーと思いつつも、どこか「面白そうだったのでサーバサイドでJavaScript使えるようにしてみましたー」的な遊びっぽいイメージのほうが強かった。
けど、どうもそうじゃなかったらしい。

Node.jsとは何か

Node.jsを試してみるにあたって、とりあえず情報収集していると“node.jsとは何か”という自分の疑問にずばり答えてくれそうなエントリが見つかった。(4)まであるので自分みたいに「Node.jsって結局なんなの?」って思ってる人は是非とも読むべし。


簡単にまとめるとこういうことらしい。

  • C10k問題でよく比べられているアーキテクチャにスレッドモデルとイベントループモデルがある。*1
  • スレッドは数が多くなるとメモリ消費量が増える。
  • 対してイベントループは1プロセスのままなのでたいしてメモリ消費量は増えない。
  • だけどイベントループはどこかにブロックするやつがいると全体の処理が止まってしまって大変!
  • そして既存の言語にもイベントループの実装はあるけど、Non-Blocking I/Oを強制しているわけではないので止まってしまう不安がつきまとう。
  • 対してJavaScriptは元々がシングルスレッドでイベントループという仕組みを持っていた。
  • さらにWebやってる人ならだいたいJavaScriptは触ったことあるよね!→学習コストが低い。
  • さらにGoogle V8という高性能で組み込みやすいJavaScriptエンジンがある!

こうしてNode.jsは誕生したらしい。

とりあえず環境を作ってみる

前置きがすごーーーーーく長くなったけど対象のことを知るのは大事よってことで。むしろ、どういうものかわかったことで俄然興味が湧いてきた。


さてさて、自分はMacなのでhomebrewで簡単にインストールできるみたいなんだけど、どうやらnaveとかnvmっていう環境管理ツールを使うのがいいらしい。
RubyのRVMやPerlのPerlbrew、Pythonのvirtualenvみたいなやつで、Node.jsをバージョンごとにインストールして切り替えたりできるやつ。

nave

https://github.com/isaacs/nave

  • npmというNode.jsにおけるパッケージ管理システムの作者が作成しているので、なんとなく安心感がある。
  • nave useするときにシェルが再実行されるのでなんとなく気持ち悪い。環境変数とかぐちゃっとしそうだし。そのうち改善されるかな?
nvm

https://github.com/creationix/nvm

  • npmもインストールしてくれる。らしいけど、最近は最初からNode.jsについてる?
  • nvm useしてもPATHとかをexportし直すだけでシェルを多重起動したりしない。
  • zshといまいち相性が良くない。時々エラーが出たりする。が、概ね動く。

nvmのインストール

自分はnvmを入れてみたけど、たぶんどっちも大差ないと思う。
というわけでnvmのインストール。

git clone git://github.com/creationix/nvm.git ~/.nvm
source ~/.nvm/nvm.sh

んで、.bashrcとか.zshrcにもsource ~/.nvm/nvm.shを書いておく。
これで完了。
ちなみにnaveの場合はsourceで読み込む必要もなく、nave.shを落としてきてそれをコマンドとして使えばいいみたい。


使い方はこれ系のツールとだいたい同じで、サブコマンドのinstallとかuseとかを使えばよい。とりあえず実行するとヘルプが表示される。

Node.jsのインストール

さっそくnvmでNode.js本体をインストールしてみる。

nvm install v0.6.6

これだけ。で、使ってみる。

nvm use 0.6.6

これでv0.6.6が有効になった。

とりあえずHello, World!

Node.jsのトップにあるEXAMPLEを試してみよう。

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');

これをhello.jsとかに保存して

node hello.js

で実行。
ブラウザでhttp://127.0.0.1:1337/にアクセスすると「Hello World」が表示される。
シンプルなコードなのでだいたい上のコードがどういう内容なのか想像が付くはず。ちょっと肉付けしたら色々できそうでワクワクしてきたでしょ?

ライブラリとかフレームワークとか

Node.jsにはnpmという他の言語にもよくあるようなパッケージ管理システムがあって、これを使って色々なライブラリをインストールできる。
MySQLクライアントのnode-mysqlとか、WebアプリケーションフレームワークのExpressとか、テンプレートエンジンのejsとかとにかく色々ある。

npm install express

ってな感じで簡単にインストールできる。

コマンドラインツールとして

ここまで来るまで実はNode.jsってWebサーバなんだと思ってたんだけど、サーバたらしめてるのはどう見てもrequireしてるhttpってやつやnetのおかげらしくて、普通にJavaScriptを書けばサーバでもなんでもない普通の処理もできるってことに気づいた。
実際そういう使い方もあるみたいだし、標準でReadlineライブラリもあるし、npmにはoptimistとかjs-optsといったgetopt系のライブラリもあるみたい。
組み込みライブラリ、npm含めて結構色々揃ってるからそういう使い方もいいかなーとか思ったり。
っていうか本体にREPLついてるじゃん!

ドキュメント

とりあえずこの辺のドキュメントが参考になった。


特にハンズオン資料は一通り目を通すとNode.jsで何ができるのか、どうしたらいいのかがざっくりと理解できる。
で、APIマニュアルにざっと目を通してどんな機能があるのか把握しておけばよいかと。目次見るだけでも色々あってワクワクするね!

今後やりたいこと

  • Expressでとりあえず普通にWebアプリ作ってみる
  • WebSocketでなんかリアルタイムに動くやつとか!
  • コマンドラインツールとして使ってみる

*1:よく例に挙げられる代表はApacheとnginx

HTMLAnchorElement.hrefとElement.getAttribute("href")の違い

JavaScriptなんかでURIの示すリソースをどうこうするときに、どうしても絶対URIが欲しいことがあるんだけど、頑張って自分で組み立てなくても、相手がA要素なら意外と簡単に取れるみたい。

<a id="bar" href="../foo/bar.html">bar</a>

こんな感じのA要素があったとして、普通にHTMLAnchorElementオブジェクトのhrefプロパティを参照すると解決済みの絶対URIが入っているらしい。
ここでElement.getAttribute()を使うと現在設定されている値そのものが取れてしまう。

var link = document.getElementById('bar');

console.log(link.href);
// => http://example.com/path/to/foo/bar.html

console.log(link.getAttribute('href'));
// => ../foo/bar.html

仕様がいまいちわからない

ぐぐってみるとわりと常識らしいんだけど、どこまで信頼していいのか、ブラウザ互換性とかどうなのかがいまいちわからなかった。
DOM Level 2で規定されているという記述があったのでDOM Level 2 HTMLのHTMLAnchorElementのところを見てみると、

href of type DOMString
The absolute URI [IETF RFC 2396] of the linked resource. See the href attribute definition in HTML 4.01.

と書かれているので、この属性が絶対URIを扱うのは確かなようだ。


ただ、あまりにもそっけなく書いてあるので、相対URIを入れた場合はどうなるのか、自動的に絶対URIに変換してくれるのか、それとも設定する側が絶対URIを設定しなければいけないのか、とかいまいちよくわからない。
ちょっと試した感じだと相対URIを突っ込んでも読みだすときには絶対URIとして読み出せる模様。


「相対URIを絶対URIに変換するテクニック」のひとつとして、HTMLAnchorElementを生成してhrefプロパティから取り出すというのを時々見かけるので、きっと大概の環境で動くんだろう。うん、きっとそう。

Macにpythonbrew+virtualenvでPython環境を作ってみた

RubyPerlときたので残るPythonについてもpythonbrewとvirtualenvで環境を整えてみた。いい加減内容がテンプレ的で飽きてきたけどw
PythonSnow Leopardでは2.6.1なので2.7とか3.2が使いたいよねーってことで。
タイトルには「Macで〜」って入ってるけど、pythonbrew自体はUNIX系の環境で使えます。


pythonbrewっていうのは、複数のPythonバージョンを簡単にインストールしたり切り替えたりできるようにするツールで、RubyでいえばRVM、Perlでいえばperlbrewみたいなもん。*1
これを使えばOS標準の環境も汚さないし、2.6系、2.7系、3系とかプロジェクトで使用中のバージョンと最新版とか色々な複数の環境を簡単に共存させて使い分けることができる。ステキ!


pythonbrewを使うとこんな感じでサクサク環境を使い分けることができるようになる。

pythonbrew install 2.7.2  ←Python-2.7.2をインストール
pythonbrew install 3.2    ←Python-3.2をインストール

pythonbrew switch 2.7.2   ←Python-2.7.2に切り替え
pythonbrew switch 3.2     ←Python-3.2に切り替え


virtualenvっていうのは、Pythonの新しい独立した環境を構築して自由に切り替えて使えるようにするツール。
pythonbrewと何が違うのかというと、pythonbrewはPythonのインストールから管理してくれるのに対して、virtualenvは既存の実行環境を元にして新しい仮想環境を作ってくれる点が異なる。


virtualenvと、あとそれを便利にするvirtualenvwrapperっていうのを使うとこんな感じでサクサク環境を使い分けることができるようになる。

mkvirtualenv -p /path/to/python-2.6 foo       ←2.6をベースにfooという環境を作成
mkvirtualenv -p /path/to/python-2.6 foo2      ←2.6をベースにfoo2という環境を作成
mkvirtualenv -p /path/to/python-3.2 bar       ←3.2をベースにbarという環境を作成

workon foo     ←foo環境に切り替え
workon bar     ←bar環境に切り替え
deactivate     ←virtualenvの環境から抜けてOS標準に戻る


どっちかでいいんじゃないかって気もするけど、そう思うんならそれでいいんだと思う。
とりあえずpythonbrewで新しいインタプリタをインストールして、virtualenvで用途別にぽこぽこ環境を増やしていくというのが流行りらしい(?)のでそれに倣ってみる。

pythonbrewのインストール

pythonbrewのインストール方法は公式サイトに書いてあるコマンドを叩けば簡単に入る。


GitHub - utahta/pythonbrew: Python Environment manager

curl -kLO https://github.com/utahta/pythonbrew/raw/master/pythonbrew-install
chmod +x pythonbrew-install
./pythonbrew-install


流れとしてはこんな感じ。

  1. インストールスクリプトを落としてシェルで実行
  2. $HOME/.pythonbrew/etc/bashrcを.bash_profileとか.bashrcで読み込むようにする

perlbrewと同じだね。
これで$HOME/.pythonbrewにpythonbrewの環境ができあがる。

pythonbrewに関するコマンド

pythonbrewで入れることのできるバージョン一覧

pythonbrew list -k


pythonbrewのアップデート

pythonbrew update

これでpythonbrewが最新になる。

Pythonのインストール

Pythonのインストール

pythonbrew install 2.7.2

これでPython-2.7.2がインストールされる。


別名をつけてインストール

pythonbrew install --as=mypython 2.7.2

これでPython-2.7.2がmypythonという名前でインストールされる。


configureオプションを指定する

pythonbrew install --configure="CC=gcc_4.1" 2.7.2


アンインストール

pythonbrew uninstall 2.7.2

Pythonbrewを切り替える

入ってるPython一覧

pythonbrew list

これでインストールされているPythonの一覧が表示される。


Pythonを切り替える

pythonbrew switch 2.7.2

これで2.7.2を使うためのPATHとかその他の環境変数が切り替わったので、今すぐPython-2.7.2が使える状態になる。
RVMとは逆、perlbrewと同じで永続的に切り替わった状態になる。


現在のシェルだけ切り替える

pythonbrew use 2.7.2

切り替え状態はこのシェルだけ。


OS標準のPythonに戻す

pythonbrew off

これでperlbrewで入れたやつじゃない環境に戻る。

複数のPythonでまとめて実行

pythonbrewにはインストールしてあるPythonでまとめて実行する機能がある。
これを利用すると書いたプログラムが他のバージョンでもちゃんと動くか一発でテストできる。


まとめて実行

pythonbrew py hello.py

pythonbrewでインストールした全Pythonで実行される。


特定のバージョンで実行

pythonbrew py -p 2.6.6 -p 2.7.2 hello.py

2.6.6と2.7.2で実行される。


リンクを張る

pythonbrew symlink

こうするとpy2.6とかpy2.7.2みたいなリンクが.pythonbrew/binに出来るので手軽に実行出来るようになる。
ただしpythonbrew offするとリンクも消えてしまうみたい。


あと、実はpythonbrewはpybrewというコマンド名でも実行できる。

virtualenvとvirtualenvwrapper

続けてvirtualenvのインストール。
とりあえずどれでもいいのでvirtualenvを入れたい環境にswitchする。

pythonbrew switch 2.7.2


pipでvirtualenvとvirtualenvwrapperをインストール。
pythonbrewによってeasy_installとpipもインストールされている。

pip virtualenv virtualenvwrapper


.bashrcとかに環境変数VIRTUALENVWRAPPER_PYTHONを設定する。

VIRTUALENVWRAPPER_PYTHON=$HOME/.pythonbrew/pythons/Python-2.7.2/bin/python

pythonbrew symlinkでできたpy2.7.2とかを指定するのがいいっぽいんだけど、pythonbrew offすると消えちゃうので直に指定してみた。


.bashrcとかでvirtualenvwrapper.shを読み込む。

source $HOME/.pythonbrew/pythons/Python-2.7.2/bin/virtualenvwrapper.sh

これもpythonbrew symlink -d 2.7.2 virtualenvwrapper.shとかでできたのを指定するっぽいんだけど(ry

virtualenvで環境を操作する

まー、冒頭のサンプルの通り。
それ以外に一覧を表示するlsvirtualenvとか、環境を削除するrmvirtualenvとか色々ある。
詳しくは公式ドキュメントのコマンドリファレンスを参照。

*1:perlbrewにインスパイアされてできたらしい。

MacにperlbrewでPerl環境を作ってみた

実はperlbrewも入れてあったので、昨日に引き続きperlbrewを使ってPerl環境を整えてみた、を書いておく。
PerlSnow Leopardには最初から入ってるんだけど、5.10なので新しいの使いたいよねーってことで。
タイトルには「Macで〜」って入ってるけど、perlbrew自体はUNIX系の環境で使えます。


perlbrewっていうのは、複数のPerlバージョンを簡単にインストールしたり切り替えたりできるようにするツールで、RubyでいえばRVM、Pythonでいえばpythonbrewみたいなもん。
これを使えばOS標準の環境も汚さないし、5.10系、5.12系、5.14系とかプロジェクトで使用中のバージョンと最新版とか色々な複数の環境を簡単に共存させて使い分けることができる。ステキ!


perlbrewを使うとこんな感じでサクサク環境を使い分けることができるようになる。

perlbrew install perl-5.12.2  ←perl-5.12.2をインストール
perlbrew install perl-5.14.1  ←perl-5.14.1をインストール

perlbrew switch perl5.12.2    ←perl-5.12.2に切り替え
perlbrew switch perl5.14.1    ←perl-5.14.1に切り替え

perlbrewのインストール

perlbrewのインストール方法は公式サイトに書いてあるコマンドを叩けば簡単に入る。


http://www.perlbrew.pl/

curl -L http://xrl.us/perlbrewinstall | bash

流れとしてはこんな感じ。

  1. インストールスクリプトを落としてシェルで実行
  2. $HOME/perl5/perlbrew/etc/bashrcを.bash_profileとか.bashrcで読み込むようにする

RVMとかと同じだね。
これで$HOME/perl5/perlbrewにperlbrewの環境ができあがる。

perlbrewに関するコマンド

perlbrewで入れることのできるバージョン一覧

perlbrew availables


perlbrewのアップデート

perlbrew self-upgrade

これでperlbrewが最新になる。

Perlのインストール

Perlのインストール

perlbrew install perl-5.14.1

これでperl-5.14.1がインストールされる。


別名をつけてインストール

perlbrew install perl-5.14.1 as myperl

これでperl-5.14.1がmyperlという名前でインストールされる。
perlbrew aliasで入れたあとに別名をつけることもできる。


コンパイルオプションを指定する

perlbrew install perl-5.14.1 -D=useithreads

こんな感じで-D、-U、-Aで渡してあげる


アンインストール

perlbrew uninstall perl-5.14.1

Perlを切り替える

入ってるPerl一覧

perlbrew list

これでインストールされているperlの一覧が表示される。


Perlを切り替える

perlbrew switch perl-5.14.1

これで5.14.1を使うためのPATHとかその他の環境変数が切り替わったので、今すぐperl-5.14.1が使える状態になる。
RVMとは逆で永続的に切り替わった状態になる。


現在のシェルだけ切り替える

perlbrew use perl-5.14.1

切り替え状態はこのシェルだけ。


OS標準のPerlに戻す

perlbrew off

これでperlbrewで入れたやつじゃない環境に戻る。

複数のPerlでまとめて実行

perlbrewにはインストールしてあるPerlでまとめて実行する機能がある。
これを利用すると書いたプログラムが他のバージョンでもちゃんと動くか一発でテストできる。


まとめて実行

perlbrew exec perl hello.pl

perlbrewでインストールした全Perlで実行される。

cpanmも入れる

最近はperlbrewがcpanmも入れてくれるらしい。
これで入れるとperlbrewのコマンド類と同じところに入るので、Perlをインストールするたびに入れる必要が無くなって楽になるとか。

perlbrew install-cpanm


普通に各環境に入れる場合はperlbrew switchしてからこんな感じかな。

curl -L http://cpanmin.us | perl - --self-upgrade

cpanmとか

perlbrewあんま関係ないけど、ついでにやるだろうってことで。


cpanmのアップデート

cpanm --self-upgrade


App::cpanoutdatedを入れる

cpanm App::cpanoutdated


インストール済みモジュールの最新化

cpan-outdated | cpanm

MacにRVMでRuby環境を作ってみた

Snow LeopardにはRubyRailsも最初から入ってるんだけど、やっぱりRuby 1.9系が使いたいよねーということでRVMを入れてみた。
タイトルには「Macで〜」って入ってるけど、RVM自体はUNIX系の環境で使えます。


RVM(Ruby Version Manager)っていうのは、複数のRubyバージョン、Ruby処理系を簡単にインストールしたり切り替えたりできるようにするツールで、Perlでいえばperlbrew、Pythonでいえばpythonbrewみたいなもん。
これを使えばOS標準の環境も汚さないし、1.8系と1.9系とかプロジェクトで使用中のバージョンと最新版とかRails2とRails3とか、色々な複数の環境を簡単に共存させて使い分けることができる。ステキ!


RVMを使うとこんな感じでサクサク環境を使い分けることができるようになる。

rvm install 1.9.2        ←ruby-1.9.2をインストール
rvm install 1.8.7        ←ruby-1.8.7をインストール
rvm install jruby-1.6.2  ←JRuby-1.6.2をインストール

rvm use 1.8.7            ←ruby-1.8.7に切り替え
rvm use 1.9.2            ←ruby-1.9.2に切り替え

RVMのインストール

RVMのインストール方法はgemとかいくつかあるみたいなんだけど、とりあえず自分は公式サイトに載ってる方法で入れることにした。
ここに書いてもあれなので公式サイトを見てね。コマンドそのまま書いてあるからわかりやすいよ*1


https://rvm.beginrescueend.com/rvm/install/


流れとしてはこんな感じ。

  1. インストールスクリプトを落としてシェルで実行
  2. $HOME/.rvm/scripts/rvmを.bash_profileとか.bashrcで読み込むようにする

perlbrewとかと同じだね。
これで$HOME/.rvmにRVMの環境ができあがる。

RVMに関するコマンド

とりあえず基本的なところ。


このプラットフォーム特有の情報について

rvm notes


RVMのアップデート

rvm get [head | latest]
rvm reload


RVMで入れることのできる処理系一覧

rvm list known

ちなみにここでリストアップされるもの以外でもインストールはできるらしい。

Rubyのインストール…の前に

依存ライブラリのインストール

rvm package install readlineとか

Rubyで必要になる依存ライブラリもRVMの環境下に入れることができるらしい。OSに入れると競合したり上手くいかないことがあるので、閉じた環境に入れられるのはいい!
他にどんなライブラリが入れられるのかはhttp://beginrescueend.com/packages/を参照。


上記で入れたライブラリをリンクさせるためにはインストールコマンドに-Cとかでconfigureのオプションを指定しなければいけないんだけど、毎回やるのは面倒なので.rvm/config/dbのruby_configure_flagsに追加しておくと便利かも。

ruby_configure_flags=--enable-shared --disable-install-doc --with-readline-dir=/Users/pasela/.rvm/usr

こんな感じ。.rvmへのパスは適宜変えてね。

Rubyのインストール

Rubyのインストール

rvm install 1.9.2

これでruby-1.9.2がインストールされる。指定できるのはrvm list knownで出てきたやつ。JRubyならjruby-1.6.2とか。

configureオプションを指定する場合は-Cで指定する。複数指定する場合はカンマ区切りで並べるっぽい。

rvm install 1.9.2 -C "--enable-shared=true,--with-opt-dir=/usr/local"


アンインストール

rvm uninstall 1.9.2

これで1.9.2をアンインストールできる。uninstallの代わりにremoveを使うと入れるときに使ったソースなども消してくれる。

Rubyを切り替える

入ってるRuby一覧

rvm list

これでインストールされているRubyの一覧が表示される。


Rubyを切り替える

rvm use 1.9.2

これで1.9.2を使うためのPATHとかその他の環境変数が切り替わったので、今すぐruby-1.9.2が使える状態になる。


常時使用状態にする

rvm use 1.9.2 --default

切り替え状態はシェルを立ち上げなおしたりすると戻っちゃうんだけど、--defaultを指定するとずっと切り替えた状態にできる。


OS標準のRubyに戻す

rvm reset

これでRVMで入れたやつじゃない環境に戻る。

RubyGemsも切り替える

RVMではGemSetsという概念でもってRubyGemsも切り替えて使えるようになっている。
これを利用するとRails2とRails3を切り替えて使うとかできる。すごい。


まずはRubyGemsディレクトリの確認

rvm gemdir

今どこを向いているのかわかる。


GemSetsを作る

rvm gemset create foo

これでfooという名前のGemSetsができた。


GemSets一覧

rvm gemset list


GemSetsを切り替える

rvm gemset use foo

さっき作ったfooを使う。
切り替えるとrvm gemdirとか$GEM_PATH, $GEM_DIRとかが切り替わる。


Rubyを切り替えるときに@で一緒に指定することもできる。

rvm use 1.9.2@foo

複数のRubyでまとめて実行

RVMにはインストールしてあるRubyでまとめて実行する機能がある。
これを利用すると書いたプログラムが他のバージョンでもちゃんと動くか一発でテストできる。


まとめて実行

rvm ruby foo.rb


特定のバージョンを指定して実行

rvm ruby-head,ruby-1.8.7 foo.rb

rvmrc

.rvmrcファイルを利用するとRVMの設定を指定できたり、特定のディレクトリで自動的にバージョンを切り替えたりといったことができるらしい。

*1:といいつつ、自分は書かれているとおりにはやらなかった。