« 2009年10月 | メイン | 2010年1月 »

2009年12月24日

ありえるえりあ勉強会@五反田~テスト編~のご案内
このエントリーをはてなブックマークに追加 このエントリーをlivedoorクリップに追加

こんにちは。中村です。

アリエル・ネットワークに友人がいるきっかけで、ありえるえりあ勉強会にウノウが参加することになりました。個人的にですが、アリエルさんといえばFirefoxの拡張を作成しているときにFirefox拡張機能(extension)の作り方という記事でとてもお世話になりました。

今回のテーマはテストということで、ウノウからはテスト番長山本がスピーカーとして参加します。

発表予定内容は次のようになっています(告知文より抜粋のため敬称略)。

  • 山本番長【絶版プレミア本に学ぶウェブアプリのテスト方法】
    • テストの書籍や資料を探すとウェブアプリを対象にしたものは少ないのが現状です。絶版のため高値になっている良書「インターネットアプリケーションのためのソフトウェアテスト」の内容を辿りながら、ウェブアプリのテスト法全般について日本の状況を交えながらお話したいと思います。
  • 佐藤【rhino on junit】
    • JavaによるJavaScript処理系であるMozilla Rhino上で、JUnitを用いてJavaScriptのユニットテストを行う手法や Javaのクラスを対象にしたテストケースをJavaScriptで記述する手法などを紹介します。

開催は来年になりますが、年始の忙しさから少し落ち着く時期ではないかと思いますので、ご興味のある方は下記ATNDから是非参加登録ください。

  • 日時: 2010年1月29日(金) 19:00~21:30
  • 定員: 30人
  • 会場: ウィン五反田ビル6F (株)ワークスソリューションズ (東京都品川区西五反田1-30-3)
  • 備考: 勉強会のあと、ピザパーティー(無料)があります。
  • 参加登録: ありえるえりあ勉強会@五反田~テスト編~ : ATND

2009年12月17日

Q4Mを触ってみる
このエントリーをはてなブックマークに追加 このエントリーをlivedoorクリップに追加

yukiです。そろそろクリスマスですね。みんな浮かれていればいいと思います!最近急に目が悪くなって、ツリーの赤色電球と居酒屋の赤提灯の色が判別出来なくなってきました。嘘です。

今回は、みんな大好きメッセージキュー、Q4Mを触ってみた感想を今更ながらレポートします。

ウノウでは特に最近、積極的にエンジニアを採用しています。
採用ページをご覧になり興味のある方、ぜひご応募ください!!
Find Job!でも募集開始してます!

Q4M

公式ページはこちらhttp://q4m.31tools.com/

Q4Mはサイボウズラボの奥 一穂氏が開発されており、MySQLの5.1以上でストレージエンジンとして利用できるメッセージキューで、MySQLプラグインとしてGPLライセンスで配布されております。

特長

MySQLのストレージエンジンとして利用できるので、テーブル作成時にストレージエンジンを指定するだけで利用できます。

CREATE TABLE hoge (
     ...
 ) ENGINE = QUEUE

キューの作成(enqueue)は通常のレコード操作と同様にINSERTで行い、キューの取り出し(dequeue)も同様にSELECTで行えるので、シンプルに扱う事が出来ます。

導入事例

公式ページには導入事例として以下の2つが載っています。

インストール

最新版は0.8.9となっています。こちらからバイナリ・ソース版と用意されているので、適切なものを選んでインストールします。

GCCのバージョンによってはコンパイルに失敗するエラーがありましたが、現バージョンでは解消されて手軽にインストールできるようになりました。

インストールが終わると、MySQLにプラグインとして認識されているのがわかります。

mysql> show plugins;
+------------+----------+----------------+--------------------+---------+
| Name       | Status   | Type           | Library            | License |
+------------+----------+----------------+--------------------+---------+
| binlog     | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| partition  | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| ARCHIVE    | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| BLACKHOLE  | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| CSV        | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| FEDERATED  | DISABLED | STORAGE ENGINE | NULL               | GPL     |
| MEMORY     | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| InnoDB     | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| MyISAM     | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| MRG_MYISAM | ACTIVE   | STORAGE ENGINE | NULL               | GPL     |
| QUEUE      | ACTIVE   | STORAGE ENGINE | libqueue_engine.so | GPL     |
+------------+----------+----------------+--------------------+---------+

実際に動かしてみる

まずはテーブルを作成します。

mysql> CREATE TABLE queue_table (
  message TEXT NOT NULL,
  priority TINYINT UNSIGNED NOT NULL DEFAULT 10
)
ENGINE = QUEUE

次に、実際に処理するキューを作るため、キューをINSERTします。

mysql> INSERT INTO queue_table (message) VALUES ('ms1'), ('ms2') ,('ms3');

dequeueしてみます。dequeueにはqueue_waitというfunctionを利用します。

mysql> SELECT queue_wait('queue_table');
+---------------------------+
| queue_wait('queue_table') |
+---------------------------+
|                         1 |
+---------------------------+
1 row in set (0.00 sec)

成功すると、結果として1が返って来ます。
キューを取り出しているこの状態をオーナーモードと呼び、この状態だと、該当のテーブルからは1レコードだけ引けるようになります。

mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms1     |       10 |
+---------+----------+
1 row in set (0.00 sec)

取り出して処理が完了した場合、queue_endを呼ぶと、取り出したキューが削除されます。同時にオーナーモードが解除され、非オーナーモードに戻ります。

mysql> SELECT queue_end();
+-------------+
| queue_end() |
+-------------+
|           1 |
+-------------+
1 row in set (0.00 sec)

非オーナーモードに戻ったので、通常のSELECTを行うと、残りの全キューを引くことができます。
ただし、別のコネクションでオーナーモードになっている場合、そのコネクションで得たキューは表示されません。(後述。)

mysql> SELECT * FROM queue_table;
 +---------+----------+
 | message | priority |
 +---------+----------+
 | ms2     |       10 |
 | ms3     |       10 |
 +---------+----------+
 2 rows in set (0.00 sec)

またこのとき、処理中に例外エラーなどでキューを戻したい場合は、queue_abort()を利用すると直前に取り出したキューを戻します。queue_wait()→queue_abort()した際の流れです。

mysql> SELECT queue_wait('queue_table');
+---------------------------+
| queue_wait('queue_table') |
+---------------------------+
|                         1 |
+---------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms2     |       10 |
+---------+----------+
1 row in set (0.00 sec)

mysql> SELECT queue_abort();
+---------------+
| queue_abort() |
+---------------+
|             1 |
+---------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms2     |       10 |
| ms3     |       10 |
+---------+----------+
2 rows in set (0.00 sec)

オーナーモードと非オーナーモード

queue_wait()を呼ぶとオーナーモードに入り、先述したように、そのコネクション内では1行のみ取得できるようになります。
また、別のコネクションでは、他コネクションでオーナーモードで取得した行以外を取得できるようになります。

コネクション1

% mysql -u test test
mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms2     |       10 |
| ms3     |       10 |
+---------+----------+
2 rows in set (0.01 sec)

コネクション2

% mysql -u test test
mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms2     |       10 |
| ms3     |       10 |
+---------+----------+
2 rows in set (0.01 sec)

コネクション1でオーナーモードに入る

mysql> SELECT queue_wait('queue_table');
+---------------------------+
| queue_wait('queue_table') |
+---------------------------+
|                         1 |
+---------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms2     |       10 |
+---------+----------+
1 row in set (0.00 sec)
コネクション2でキューを全件表示すると、コネクション1で引いたキューは表示されない。
mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms3     |       10 |
+---------+----------+
1 row in set (0.00 sec)

優先度別キュー取出

優先度低めのキューテーブルを作り、優先して取得したい順にqueue_waitの引数に加えます。

mysql> CREATE TABLE low_priority_queue (
   message TEXT NOT NULL,
   priority TINYINT UNSIGNED NOT NULL DEFAULT 10
 )
 ENGINE = QUEUE;

mysql> INSERT INTO low_priority_queue (message) VALUES ('lm1'), ('lm2'), ('lm3');

mysql> SELECT queue_wait('queue_table', 'low_priority_queue');
+-------------------------------------------------+
| queue_wait('queue_table', 'low_priority_queue') |
+-------------------------------------------------+
|                                               1 |
+-------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

成功すると、取得できるテーブルの順の番号が返って来ます。(上記は1なのでqueue_table、2であればlow_priority_queueになります)あとは通常通り取得します。

mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms2     |       10 |
+---------+----------+
1 row in set (0.00 sec)

ここの挙動がよくわかりにくく、どなたか分かる方がいたら教えて頂ければ大変嬉しいのですが、優先度が高いテーブル(queue_table)の中身が空の時、タイムアウトを指定しないでqueue_waitすると「ゼロ」(データ無し)と返って来ます。

2009/12/21追記: 複数指定する場合は、必ずタイムアウト引数を付けなくてはいけないので、この用法は間違いでした。お詫びいたします。

mysql> TRUNCATE queue_table;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT queue_wait('queue_table', 'low_priority_queue');
+-------------------------------------------------+
| queue_wait('queue_table', 'low_priority_queue') |
+-------------------------------------------------+
|                                               0 |
+-------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

タイムアウトを与えてやると、正しく取得できます。下記の場合はqueue_tableにレコードがないので、low_priority_queueから取得するため2番が返り、期待通りの動作となります。

mysql> SELECT queue_wait('queue_table', 'low_priority_queue', 10);
+-----------------------------------------------------+
| queue_wait('queue_table', 'low_priority_queue', 10) |
+-----------------------------------------------------+
|                                                   2 |
+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM low_priority_queue;
+---------+----------+
| message | priority |
+---------+----------+
| lm1     |       10 |
+---------+----------+
1 row in set (0.00 sec)

条件付き取り出し

簡易なWHERE句のようにして取得することが可能です。queue_waitのテーブルを指定する引数に、条件を付加して取得します。
下記の例は優先度2で新たなキューを発行し、優先度3以下で取得するようにしてみます。

mysql> INSERT INTO queue_table(message, priority) values ('blocker', 2);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| ms1     |       10 |
| ms2     |       10 |
| ms3     |       10 |
| blocker |        2 |
+---------+----------+
4 rows in set (0.00 sec)

mysql> SELECT queue_wait('queue_table:priority<3');

mysql> SELECT * FROM queue_table;
+---------+----------+
| message | priority |
+---------+----------+
| blocker |        2 |
+---------+----------+
1 row in set (0.00 sec)

リレー

別のサーバにキューをリレーする事が出来ます。同梱されているq4m-forwardというperlスクリプトを起動すると、無限ループでキューを待ち、別のサーバへ転送するような処理になっています。
同様の処理であれば、自作のスクリプトで同様の処理が可能です。
daemontoolsなどを使えば、割とお手軽に転送させることが出来るかと思います。

まとめ

いかがでしたでしょうか。メッセージキューイングというとActiveMQやTheSchwartzなど、いろいろなソリューションがあると思いますが、キューイング方法などかなり手軽に扱えるので、1度試してみてはいかがでしょうか。

試している最中、queue_wait()してオーナーモード中にtruncateしてしまい、drop databaseすら効かなくなってrm -r /var/lib/mysql/testしたりしましたが、ご愛敬ということで。

2009年12月 9日

PHPテンプレートエンジンTwigをいじってみました
このエントリーをはてなブックマークに追加 このエントリーをlivedoorクリップに追加

今年のX'masは一人で高いシャンパンを買って飲もうとおもってるKeitaです。

しばらく、情報収集をさぼっている間に、symfonyの開発元であるSensio Labsから、PHPのテンプレートエンジンTwigが出ていたので、1時間ほど試してみました。

つかってみたよーとか、ここきついとかありましたら、コメントなどで教えていただけるとうれしいです。

インストール

本家サイトのINSTALLATIONを参考に僕はtar.gzのファイルを手動どインストールして試してみました。

インストールはpearコマンドなどでもできるようです。

というか、www.twig-project.orgのフッタを見てみるとPEAR Serverも自作してること発見してびっくりました。

テンプレート側

テンプレート側のコードは下記のように記述します。

<html>
<title>title</title>
</html>
<body>
メリー {{ congratulation }}!!
メリー {{ congratulation|safe }}!!
</body>

実際のコード

テンプレートを呼び出す側のコードはTwig for Developersにあります。

これをほぼ丸写しして下記のようなコードを書いてみました。

<?php
require_once '/path/to/twig/lib/Twig/Autoloader.php';
Twig_Autoloader::register();

$loader = new Twig_Loader_Filesystem('/path/to/template/'); //(1)ファイルのほかに文字列直接とか配列を指定できる。
$twig = new Twig_Environment($loader,
array(
  'cache' => '/path/to/var/tmp/cache',
  'auto_reload' => true, //デフォルトがfalseなわきゃないと思うだけど
)
);
$escaper = new Twig_Extension_Escaper(true); //(2) デフォルトHTMLエスケープしてパラメータをつけるとエスケープしないようなコードがかける
$twig->addExtension($escaper);

$template = $twig->loadTemplate('nomal.html');
echo $template->render(array('congratulation' => 'X\'ss'));

実行してみると下記のようなHTMLが出力されます。

<html>
<title>title</title>
</html>
<body>
メリー X&#039;ss!!
メリー X'ss!!
</body>

(1) の部分でファイルからの読み込みが指定されてますが配列や文字列そのももの指定できるようような指定ができます。また、Loader自体の拡張も、たとえばMySQLやKVS的なものからデータを読み込むような指定もできます。

(2)の部分は、変数の出力時に何も指定しなければエスケープ処理を行うようにしてあります。 エスケープしない場合は{{hoge|safe}}のような記述します。 また上記設定しない場合は{{hoge|e}}とった感じの書き方でエスケープされます。

テンプレート継承

テンプレートを下記のように記述します。
base.html
<html>
<title>{% block title %}テスト{% endblock %}</title>
</html>
<body>
{% block body %}
本文だよ
{% endblock %}
</body>
title.html
{% extends "base.html" %}
{% block title%}継承テスト{% endblock %}

title.htmlを実行すると下記のような出力が行われます。

<html>
<title>継承テスト</title>
</html>
<body>

本文だよ

</body>

キャッシュされるテンプレート

どうやって継承とかしているのなーと思いキャッシュされたテンプレートを覗いてみました。

<?php

/* base.html */
class __TwigTemplate_0071f6af5144b1d5aaf62ae6db08f444 extends Twig_Template
{
  public function display(array $context)
  {
    // line 1
    echo "<html>
<title>";
    // line 2
    $this->block_title($context);
    echo "</title>
</html>
<body>
";
    // line 5
    $this->block_body($context);
    // line 7
    echo "
</body>
";
  }

  // line 2
  public function block_title($context)
  {
    echo "テスト";
  }

  // line 5
  public function block_body($context)
  {
    echo "
本文だよ
";
  }

}
title.html
<?php

$this->loadTemplate("base.html");

/* title.html */
class __TwigTemplate_f7f5efb7dcc094ca38d2c84bd671d4bc extends __TwigTemplate_0071f6af5144b1d5aaf62ae6db08f444
{
  public function display(array $context)
  {

    parent::display($context);
  }

  // line 2
  public function block_title($context)
  {
    echo "継承テスト";
  }

}
なるほど、クラスを生成して普通の継承を行っているんですね。 よく考えれば当たり前な気がしますが正直、Smartyなどのテンプレートエンジンは素のPHPっぽいテンプレートを返すのでクラスを吐き出すというのが自分的にはとても新鮮でした。

感想

触ってみた時間は短いですが、「あぁ考えられているな」と感じました。 そのほかにもSandboxやデバッグなどの機能があるみたいですが試せてはいません。 また、マルチバイトがかなり意識されていて、Filterのソースコードを見ると、mb_stringがあった場合には、それを使って処理するようになっています。海外のアプリケーションでmb_stringを使っているものを久しぶりに見ました。 PHPのテンプレートエンジンといえば、PHPそのものはもちろん、Smartyが有名ですが、これはこれで、メジャーバージョン3のベータ版が出ていたりしてそれはそれで興味深いですので正式版がでたら使ってみたいと思います。 何かのご参考になれば幸いです。

2009年12月 3日

2009年版Python開発環境を整えよう
このエントリーをはてなブックマークに追加 このエントリーをlivedoorクリップに追加

なでしこの作者じゃない方のsakatokuです。

以前書いた「Python開発環境を整えよう」という記事からだいぶ時間が経ってしまったので、内容を更新したいなぁと思っていたのですが、ようやくその機会が来ました。

virtualenvで開発環境をつくる

開発環境をつくるにあたって次のような問題が生じると思います。

  • root権限がないためにインストールしたいライブラリが使えない
  • 新しいライブラリをインストールしたり、既存のライブラリをアップグレードすることで、既に動いているアプリケーションを壊したくない
  • 複数のバージョンのPythonを使って開発、テストを行いたい
  • 自作したPythonパッケージのインストールのテストを行いたい

以前の記事ではvirtual-pythonという解決策を紹介しましたが、現在ではvirtualenvというツールが広く使われるようになってきています。

virtualenvをインストールするには、もしroot権限があるならば、CentOS/Fedoraの場合、

$ sudo yum install python-setuptools

でsetuptoolsというPythonパッケージ配布ライブラリを入れて、setuptoolsに含まれているeasy_installコマンドを使い、

$ sudo easy_install virtualenv
$ which virtualenv
/usr/bin/virtualenv

で入れるのが楽です。

一般ユーザの権限でvirtualenvを利用するには、適当なディレクトリに最新版のvirtualenv(1.4.3以降)の配布物をダウンロードし、その配布物に含まれるvirtualenv.pyを叩くのが簡単です。最新版の1.4.3以降を薦める理由はpipというツールが同梱されるようになったことにありますが、これに関しては後述します。

$ wget http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.4.3.tar.gz
$ tar xzf virtualenv-1.4.3.tar.gz
$ cd virtualenv
$ python virtualenv.py --python=/usr/bin/python2.4 ~/mypython

上の例では、最後の行で~/mypythonというディレクトリにPython2.4の仮想開発環境を作成しています。--pythonオプションで利用するPythonのバイナリを指定します。"~/mypython"は、virtualenvで作る仮想的なPython環境のパスですが、これは好みに合わせて何にしても構いません。

もし、/usr/local/bin/python2.5にPython2.5がインストールされている環境で、そのPython2.5を使った仮想環境を~/mypythonというパスに作りたいならば、以下のようにします。

$ python virtualenv.py --python=/usr/local/bin/python2.5 ~/mypython

実際にこれらの開発環境に切り替えるには、仮想環境ディレクトリにbin/activateというシェルスクリプトがあるのでそれを使います。

$ source ~/mypython/bin/activate
$ which python
~/mypython/bin/python
$ python
Python 2.5.4 (r254:67916, Nov 28 2009, 20:37:01)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

この環境をカスタマイズした場合には、仮想環境ディレクトリにlib/python2.4/site-packages/sitecustomize.pyというファイルを作り、そこで固有の設定を行います。よく行われるのは、デフォルトのエンコーディングの指定です。

cat << END > ~/mypython/lib/python2.5/site-packages/sitecustomize.py
heredoc> import sys
heredoc> sys.setdefaultencoding("utf-8")
heredoc> END

pipを使ってパッケージを管理する

仮想環境を作ると、仮想環境以下のbinディレクトリにpipというコマンドもインストールされます。

$ source ~/mypython/bin/activate
$ which pip
~/mypython/bin/pip

このpipは、Pythonで長らく主流となってきたsetuptools/easy_installに替わって最近使われるようになってきたパッケージ管理ツールで、PHPで言えばpear、Rubyで言えばgem、Perlで言えばcpanコマンドに相当します。

pipを使ってPythonパッケージをインストールするには、次のように"pip install <パッケージ名>"と入力します。インストールするパッケージが依存している別のパッケージがあれば、それもインストールしてくれます。

$ pip install Django

pipはデフォルトでは、Python Package Index(通称PyPI)に登録されているパッケージをインストールしますが、URLを指定して直接インストールすることもできます。次の例は、Pythonの標準的な画像処理ライブラリであるPILを、tar.gzからインストールする例です。

$ pip install http://effbot.org/downloads/Imaging-1.1.6.tar.gz

インストール済みのパッケージを確認するには、freezeコマンドが利用できます。

$ pip freeze
IPy==0.70
PIL==1.1.6
uamobile==0.2.8
virtualenv==1.4.3
wsgiref==0.1.2

最新版のpipではuninstallコマンドを使ってパッケージのアンインストールもできるようになりました。

$ pip uninstall IPy

pipのコマンドを確認するには、helpコマンドを使います。helpの後にコマンド名を続けると詳細な内容を確認できます。

$ pip help
$ pip help install

virtualenvwrapperを使って開発環境を切り替える

virtualenvとpipを使えば、プロジェクト毎に仮想環境を作っておけば、別のバージョンのライブラリを利用することができます。

# project1という環境を作る
$ python virtualenv.py --python=/usr/bin/python2.5 ~/project1
# 切り替え
$ source ~/project1/bin/activate
# 必要なライブラリをインストール
$ pip install "Django==1.0.4"
# project2という環境を作る
$ python virtualenv.py --python=/usr/bin/python2.5 ~/project2
# 切り替え
$ source ~/project2/bin/activate
# 別のバージョンのライブラリをインストール
$ pip install "Django==1.1.1"

相互の開発環境の切り替えはactivateを使うことになりますが、同時にたくさんの環境を使っていると、いちいち"source ~/project1/bin/activate"を打つのが面倒になってきます。

そんな状況で便利なのがvirtualenvwrapperです。

$ wget http://www.doughellmann.com/downloads/virtualenvwrapper-1.21.tar.gz
$ tar xzf virtualenvwrapper-1.21.tar.gz
$ cd virtualenvwrapper-1.21

virtualenvwrapperは普通のPythonパッケージのように配布されていますが、実態はvirtualenvwrapper_bashrcというシェルスクリプトです。このvirtualenvwrapper_bashrcを.bashrcや.zshrcで読み込むことにより、virtualenvを使った開発を便利にするいくつかのコマンドが使えるようになります。virtualenvwrapper_bashrcという名前になっていますが、zshでも使えます。僕の場合は、

$ cp virtualenvwrapper_bashrc ~/.virtualenvwrapperrc

のように、ドットつきでファイル名を改名してホームディレクトリ直下に置き、.zshrcで、

# Import virtualenvwrapper
if [ -f ~/.virtualenvwrapperrc ]; then
  source ~/.virtualenvwrapperrc
fi

のように読み込むようにしています。さらに、$HOME/.virtualenvsという仮想環境を置くディレクトリが必要なのであらかじめ作成しておきます。

$ mkdir ~/.virtualenvs

もしこのディレクトリを変更したい場合は、WORKON_HOMEという環境変数を定義することで変更できます。

virtualenvwarrperを読み込むと、ターミナル上で、

$ mkvirtualenv --python=/usr/bin/python2.5 temp

のようにして、仮想環境を作り

$ workon temp

のように"workon (仮想環境名)"と打つと、その開発環境に切り替えてくれるので便利です。その仮想環境を無効にするには、

$ deactivate

のようにdeactivateを使います。

もし、ある仮想環境が必要なくなったならば、deactivateを使って一度その環境を離れた上で、rmvirtualenvコマンドを使って削除することができます。

$ deactivate
$ rmvirtualenv temp

普段の開発では、

$ workon project1

のようにしてproject1の開発に切り替え、いつも通りコードを書いたり、テストを行って、もし別のproject2のタスクをする必要が出た場合には、

$ workon project2

のようにしてproject2の開発に切り替え...のようにして作業を進めています。

virtualenvwrapperは非常に便利なのですが、PATHが通った場所にvirtualenvがないとmkvirtuanenvコマンドはエラーになり実行できません。もし、いつもPATHが通っている場所にvirtualenvコマンドをインストールできるならば、その解決方法がいいような気がしますが、$WORKON_HOMEに手動で「仮想環境を作るための仮想環境」を作れば一応は解決できます。

$ mkdir ~/.virtualenvs
$ python virtualenv.py --python=/usr/bin/python2.4 ~/.virtualenvs/bootstrap
$ source ~/.virtualenvs/bootstrap/bin/activate
$ pip install virtualenv
$ mkvirtualenv mypython

書き残していること

以上駆け足で、Python開発環境を整えるための三種の神器、virtualenv、pip、virtualenvwrapperを紹介しましたが、ぱっと考え付くだけでも、まだ言及していないことがたくさんあります。

  • virtualenvの--no-site-packagesオプション
  • virtualenvの--relocatableオプション
  • virtualenvの--distributeオプション(Pythonの新しいパッケージ管理ライブラリDistributeについて)
  • virtualenvと同様によく使われるzc.buildoutについて
  • pipを使って複数のモジュールをまとめる(pip bundle)
  • pipを使ってSubversion/git/Mercurialレポジトリから直接モジュールをインストールする
  • virtualenvを使った実際のアプリケーションのデプロイ方法

こうした点についても、今後この場をかりて紹介していければと思っています。

ウノウでは特に最近、積極的にエンジニアを採用しています。
採用ページをご覧になり興味のある方、ぜひご応募ください!!
Find Job!でも募集開始してます!

About 2009年12月

2009年12月にブログ「ウノウラボ by Zynga Japan」に投稿されたすべてのエントリーです。過去のものから新しいものへ順番に並んでいます。

前のアーカイブは2009年10月です。

次のアーカイブは2010年1月です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Zynga Japan