Hatena::ブログ(Diary)

ess sup RSSフィード Twitter

2011年02月21日

Node.jsとnvmを初めてインストールするときのハマりポイントと対策

最近何かと話題の Node.js を使ってみることにした。 インストール自体は公式の Wiki を見ればそんなに難しくない。いつもの configure, make, make install するだけだ。

でも Node.js はまだまだ開発中のプロジェクトで、今でもがんがん更新されてる。すぐに新しいバージョンが出てくるんだけど、そのたびにソースからインストールし直すのもいやだし、ちょっと前のバージョンに戻したくなることもあるかもしれない。

そんなわけで、最近の Node.js は nvm というツールを使うのが流行みたいだ。こいつを使うと複数バージョンのインストール、切り替えが出来るようなって便利。

Mac でも Linux(Ubuntu) でも使えるんだけど、微妙にハマったとこがあったので手順を書いておく。

準備

まず始めに、必要なパッケージとかをあらかじめインストールしておく。

Ubuntu の場合

Node.js をビルドできるようにするために、以下をインストールする。

% sudo aptitude install build-essential
% sudo aptitude install libssl-dev

あと、nvm は wgetcurl の両方が必要になる(統一しろよ...)。Ubuntu はデフォルトで curl が入っていないのでインストールしておこう。

% sudo aptitude install curl
Mac の場合

Mac でも基本的に Ubuntu と同じ。まず XCode をインストールして Node.js 自体をビルドできるようにしよう。

Mac の場合、 curl は入ってるんだけど wget が入っていないのでインストールする。

# homebrew を使う場合
% brew install wget

# Mac ports を使う場合
% sudo port install wget

もちろんインストール済みならそのままで OK。この辺は各自の環境に合わせて適当に調整しよう。

nvm のインストール

nvm は Node Version Manager のことで、Node.js のインストール、バージョンごとの管理、シェルの環境設定をやってくれる。

nvm を使うには Githubリポジトリクローンする。

% git clone git://github.com/creationix/nvm.git ~/.nvm

あとは nvm 本体を source すれば OK。

% source ~/.nvm/nvm.sh

... のはずなんだけど zsh の場合はエラーが出てしまう。実は nvm.shbash が前提になっていて、${BASH_ARGV[0]} ってとこが zsh で解釈できないからだ。

この問題は本家の Issues にも挙がってるので、それを参考に bash でも zsh でも動くように直した。

diff --git a/nvm.sh b/nvm.sh
index 99eb87a..9e9951b 100644
--- a/nvm.sh
+++ b/nvm.sh
@@ -5,8 +5,7 @@
 # Implemented by Tim Caswell <tim@creationix.com>
 # with much bash help from Matthew Ranney

-# Auto detect the NVM_DIR using magic bash 3.x stuff
-export NVM_DIR=$(dirname ${BASH_ARGV[0]})
+export NVM_DIR=$(cd $(dirname ${BASH_SOURCE[0]:-$0}); pwd)

 nvm()
 {

これを適応して、改めて source してみよう。

% source ~/.nvm/nvm.sh

エラーが出なくなった。よしよし。

nvm を使用して Node.js をインストールする

いよいよ Node.js 本体をインストールする。nvm がちゃんと入っていればコマンド1つ打つだけでよくて簡単。

今回は 0.4.0 をインストールした。

% nvm install v0.4.0

インストールできたら use コマンドを使って環境を切り替える。

% nvm use v0.4.0
Now using node v0.4.0

ちゃんとインストールできてるか確認してみよう。

% node --version
v0.4.0

OKOK。パスも通ってる。

別のバージョンもインストールできる。試しに0.3系もインストールしてみた。

% nvm install v0.3.8

複数インストールした後は nvm ls コマンドでバージョン一覧が見れる。

% nvm ls
v0.3.8
v0.4.0 *

今有効になってるバージョンには * がつく。別のバージョンに切り替えたいときは use コマンドを使おう。

% nvm use v0.3.8
Now using node v0.3.8

% node --version
v0.3.8

これで複数のバージョンを切り替えできるようになったし、新しいバージョンが出ても簡単に更新できる。

インストールできるバージョン一覧は nvm コマンドでは見れないので、公式のダウンロードページで確認しよう。

シェルの設定を追加

nvm の設定はログアウトすると無くなってしまうので、シェルの初期化ファイルに書いておこう。

# ~/.zshenv, ~/.bash_profile などに以下を追加
source ~/.nvm/nvm.sh
nvm use "v0.4.0"

ただし、この書き方の場合 nvm とかがインストールされてない環境で余計なエラーが出てしまう。それではかっこわるいのでインストール済みかどうかチェックするようにした。

# nvm と指定されたバージョンの Node.js がインストール済みの場合だけ
# 設定を有効にする
if [[ -f ~/.nvm/nvm.sh ]]; then
  source ~/.nvm/nvm.sh

  if which nvm >/dev/null 2>&1 ;then
    _nodejs_use_version="v0.4.0"
    if nvm ls | grep -F -e "${_nodejs_use_version}" >/dev/null 2>&1 ;then
      nvm use "${_nodejs_use_version}" >/dev/null
    fi
    unset _nodejs_use_version
  fi
fi

インストール済みの場合だけ nvm use するようにした。.zshrc をいろんな環境で使い回してるときはこうした方がいいと思う。

これでインストールと環境設定は終わり。新しいバージョンが出てきても簡単に設定を変えれるようになったし、もう安心だ。

参考リンク

2011年02月07日

15分でわかる zsh

2011年01月29日(土) に大阪で Minami.rb 第4回勉強会 が開かれた(告知ページ)。Ruby on Rails(Ruby)メインの勉強会だ。

そこで15分枠の発表コーナーがあったので zsh の発表をしてきた。zsh って高機能なんだけど、実はシェルに詳しくない人でも便利に使える。なので、なんか興味あるけど難しそうって思ってる人は参考にして欲しい。

発表資料

発表資料はこんな感じ。これ自体はあんまり読まなくてもいいけど、一応貼り付けておく。

これに実際のコマンドライン操作を見せながら説明した。発表内容は以下。

補完

zsh はなんと言っても補完が便利。とにかくこれを ~/.zshrc に書いておこう。

autoload -Uz compinit
compinit

これでいろんなコマンドのオプション引数をかしこく補完できるようになる。

grep の補完の例

例えば grep の場合。オプションを指定するとき普通はこんな感じになると思う。

% grep -nH -r 'method1' src

でも -n とか -H とか覚えてられない。毎回 --help とか man とかで調べてる人もいるかもしれない。

1文字のオプションは分かりにくいってことで、長いオプションも用意されてる。

% grep --with-filename --line-number --recursive 'method1' src

これはこれでめんどくさい。--with-filename なんて打ってたら日が暮れる。

zsh の補完を使うとこれが全部解決できる。

% grep --wi[TAB]        # ここでタブを押す
% grep --with-filename  # オプション名が補完される
% grep --with-filename --line[TAB]     # 今度もタブを押す
                                       # 候補が出てくる
  --line-buffered        -- flush output on every line
  --line-number          -- prefix output with line numbers
  --line-regexp          -- force pattern to match only whole lines

% grep --with-filename --line-number   # 何回かタブを押して欲しいものを選ぶ

ポイントはオプション名が分からなくてもいいってとこ。何となく名前を入れて、後は補完して選べば OK。オプション名を覚えたり入力したり、そんなどうでもいいことにパワーを使う必要はない。

git の補完の例

みんな大好きな git も当然補完できる

% git a[TAB]     # git コマンドの補完
% git add -[TAB] # add のオプションの補完

% git add [TAB]  # add するファイル名の補完
                 # 編集済みのファイルしか出てこないので、
                 # add する必要のあるファイルだけが補完される

checkout の場合もいい感じに補完してくれる。

% git checkout [TAB] # ファイル名とブランチ名を補完

ブランチを行ったり来たりするときに便利。

その他補完が便利になるもの

その他、補完が便利になるものとしてこんなものがある。

  • man
  • cd
  • kill
  • apt-get

使い方も同じで、何か欲しくなったときにタブを押すだけ。それだけで man の場合はマニュアルページ名を補完してくれるし、 cd の場合はディレクトリ名だけが補完できる。

もちろんこれ以外でも、よく使うコマンドはたいてい対応している。

とにかくこの機能が便利。適当にタブを押すだけでいい感じのものが補完されるので、自分で考えて入力するってのが激減する。

ファイル名生成

補完以外にも、** で指定する再帰的なファイル名生成が便利。

% grep h1 **/*.html

これは grep h1 *.html */*.html */*/*.html ... という意味になるので、今のディレクトリ以下の html ファイル全部が grep 対象になる。

いろいろ使い道がある。

% rm -f **/*.bak  # .bak を削除する
% vim **/*.rb     # ruby ファイルを vim で開く

ファイルを探すのにも使える。

% ls **/MyClass.rb  # ファイル名を指定して探す
% ls **/*.png       # png ファイルを探す

「あのファイルどこいったのかなー」ってときに便利。find コマンドでも同じようなことが出来るんだけど、それよりも簡単に使えてうれしい。

まとめ

なんと言っても zsh は補完が便利。しかも使い方はタブを押すだけ。それだけで zsh がそのとき必要なものを出してくれる。

なので、コマンドラインの操作になれてない人でも便利に使える。というか、コマンドとかオプションとか全部覚えてたら補完する必要はないわけで、あんまりなれてない人にこそ使って欲しい。

zsh は高機能なので難しい設定とかしてる人もいるけど、初心者でも役に立つので自分の扱える範囲で活用して欲しい。

.zshrc の例

簡単な .zshrc の例は以下。とりあえず最初はこのあたりから始めてみよう。

# 強力な補完を有効にする
autoload -Uz compinit
compinit

# ヒストリの設定
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000

# emacs 風キーバインドにする
bindkey -e

# その他とりあえずいるもの
export LANG=ja_JP.UTF-8
setopt print_eight_bit   # 日本語ファイル名を表示可能にする
setopt no_flow_control   # フローコントロールを無効にする

参考資料

漢のzsh | マイコミジャーナル
マイコミジャーナルの連載記事。ちょっと古いけど今読んでも役に立つし、 zsh の一通りのことが解説してある。
連載:zshで究極のオペレーションを|gihyo.jp … 技術評論社
zsh の本の著者による連載記事。
zsh 記事一覧 - ess sup
僕のブログの zsh 記事一覧。
.zshrc - GitHub
僕の .zshrc ファイル。GitHub で公開してる。

2011年01月20日

Kanasan.JS JavaScript第5版読書会でベジエ曲線について発表した

2011年01月15日(土) に京都で Kanasan.JS JavaScript第5版読書会 #11 が開かれた(告知ページ)。みんなでサイ本を読む会だ。第1回からだいたい3年ぐらい続いてて、今回でいよいよ最終回となった。僕は途中半分の第6回くらいからの参加なんだけど、最後のまとめとして気合いを入れて参加した。

読んだところ

今回は P561 から P629(最後)まで。主にクライアントサイドのグラフィック制御のところを読んだ。

いろんなグラフィック関係のテクニックが書いてあったけど、本が出てから時間がたってることもあって今では使わないようなものもあった。その中で注目はやっぱり SVGcanvas 要素。サンプルコードが書いてあったのでみんなで読んだ。

SVG

SVG は XML で定義された画像フォーマットの一種。V は Vector の V で、その名の通りベクターグラフィックになってる。HTML の中に SVG を埋め込めて、さらにそいつを JavaScript から操作できる。

指定した経路に沿って線を書くこともできる。例えば扇形を書くときはこんな風に経路を指定する。

// この文字列に線の経路情報を保持する
var d = "M " + cx + "," + cy +    // 始点(円の中心)
        " L " + x1 + "," + y1 +   // 始点から (x1, y1)まで直線を引く
        " A " + r + "," + r +     // 円弧の半径
        " O " + big + " 1 " +     // 円弧の向き。
                                  // 終端まで弧を書く際に近いほう/遠いほうのどちらを通るかを指定する
        x2 + "," + y2 +           // 円弧の終端
        " Z";                     // 始点まで戻って終わり

超読みにくい。でもこんな指定を繰り返すと円グラフが描けたりする。

canvas 要素

canvas 要素は JavaScript で動的に画像を描くための要素。できあがりはビットマップ画像になる。lineTo, arc などの API を使ってチマチマ画像を描いていく。その後僕は発表したんだけど、そこでも canvas を使った。

ベジエ曲線について

今回はグラフィック関連の章ということで、僕はベジエ曲線について発表した。

ベジエ曲線って名前は聞いたことある、もしくは使ったことあるっていう人も多いんじゃないのかな。 Illustrator, Photoshop とかでも描けるし、canvas 要素の quadraticCurveTo(2次)、bezierCurveTo(3次)という API でも描ける。

でもアルゴリズムまでは知ってる人少ないと思う。僕は学校でそういうの勉強したので、いい機会だと思って発表した。

ベジエ曲線とは

ベジエ曲線とは、線分の内分点を取る操作を繰り返すことにより得られる曲線のこと。といってもよく意味が分からないかもしれない。jsdo.it でデモページを作ったので適当に遊んで欲しい。

f:id:mollifier:20110120020437p:image

入力となるいくつかの点があって、そこからアルゴリズムに基づいて曲線を描く。その「いくつかの点」というのを制御点という。Illustrator では「開始地点のアンカーポイント」とか呼ばれてるやつね。

数学的な理論の話は「ベジエ曲線とベジエ曲面」というページに書いてある。大学の講義用の資料でかなり本格的。その中で、曲線の定義、表現方法は「ベジエ曲線とベジエ曲面1」と「ベジエ曲線とベジエ曲面2」を読むと分かる(どっちも PDF ファイル)。

JavaScript での実装

僕のデモページで一番大事な関数は以下。ベジエ曲線上の1点を求めてる。

// bezierCurve.js 58行目

// 与えられた制御点に対して、 t を固定して得られる
// ベジエ曲線上の1つの点を取得する
// @points : 任意の数の制御点を格納した配列
bezierPointT : function(t, points) {
    if (points.length >= 2) {
        var dividedPoints = [];
        for (var i = 0; i < points.length - 1; i++) {
            dividedPoints.push(
                BezierCurve.dividePoint(t, points[i], points[i+1]));
        }
        return BezierCurve.bezierPointT(t, dividedPoints);
    } else {
        return points[0];
    }
}

この t を0から1まで動かせばなめらかな曲線になる。実際には連続的に無限の点を求めることはできないので、0から1までを適当に分割して折れ線で近似してる。

拡大/縮小、平行移動

ベジエ曲線の便利な性質として「アフィン写像に対して普遍」というのがある。なんかまた難しい用語が出てきたけど、かみ砕いて言うと以下の通り。

  • ベジエ曲線を描いてから曲線全体を平行移動させるのと、先に制御点を平行移動してからベジエ曲線を描くのとでできる結果は同じ
  • 回転、拡大、縮小、鏡写しについても同様
  • そういう変換の組み合わせでも同様

この性質については、さっきの講義ページでは「ベジエ曲線とベジエ曲面6」に解説がある(これも PDF)。

実際に曲線を変換する場合は後者の方法、先に制御点を変換する方が楽に実装できる。

さらに、拡大の場合なんかは曲線全体を拡大すると困ることがある。曲線とは言っても実際には折れ線で近似していることを思い出そう。小さいうちは折れ線には見えなくても、拡大すると角の部分も拡大されるのでカクカクに見えてしまう。

そんな場合でも、後者の方法の場合は拡大した分だけ分割数を増やせば角は見えなくなる。曲線のアルゴリズムだけ決まっていて実際の精度は描画する時に決めれるので、必要に応じて精度を上げるということができるのだ。これが「ベクター画像は拡大してもギザギザがでてこない」という理由になってる。ベジエ曲線便利。

実用上はこういう理論を知らなくても必要なところだけ利用すればいいんだけど、数学を使うと「その性質が必ず成り立つ。絶対に大丈夫」という保証ができる。数学って何してるのかいまいち分かりにくいところがあるけど、こんなところに役に立ってる例があった。

あと、最初に言ったように canvas にはベジエ曲線を描く API があるので、これに実用上の意味はない。アルゴリズムを理解するためのサンプル。

そんなこんなで読書会は無事最後まで終了した。

最後に

思い出してみると、僕が初めて参加した勉強会が Kanasan.JS だった。それから2年以上たって、僕のプログラミングのレベルも上がったし、いろいろ発表するようにもなった。この勉強会を通して学んだことは大きかった。

Kanasan.JS はいろんな勉強会の中でもトップクラスの技術レベルだと思う。それもみんなで本を読んだりして勉強した結果だ。メンバーが入れ替わりながら何年も継続できているのは、この勉強会を大切に感じている人がいるからこそだと思う。そして、そういう流れを作ってくれた初代代表の Kanasan にはとても感謝しています。

今回でサイ本読書会が終わったので、次回以降は jQuery コードリーディングと単発企画ものを行う。これからも継続して、関西を代表する勉強会になればいいと思う。