ページ

2009年12月25日

ありえるえりあ勉強会@五反田~テスト編~


ありえるえりあ勉強会@五反田 テスト編」をウノウさんと共催で来年1月29日に開催します。アリエルはあまり人付き合いがよい会社ではないので、どこか別のところと何かをやるというのは珍しいことです。

さて、アリエルと言う会社はプログラマの人が中心となって作った会社ではっきり言って、僕はテストについてよく分からないです。ロータスでもそこそこテストしていましたが、苦手です。 テストに関してドキュメントや本を読むようになったのは、ほんの数年前です。

それでも、社内の人は雑誌にテストに関する記事を書いたりしていますが、 僕は全く自信がありません。以前からウノウさんのブログ(テスト番長)を読んでいてい、直接お話すれば何か分かるかも?と思っていたのですが、直接知り合う機会がなかった(もし、どこかで名刺交換していたらごめんなさい)ので、ちょっと仲良くなるために勉強会をすることにしました。  

テストに関してどんなコミュニティがあるのかも分からないし、ブログとかで断片的な情報だったり、いきなり小難しいことから入っていって読む気が失せたり・・・。 それが今回の勉強会で改善されたらうれしいな、と言う期待があったりします。それから、テストに興味がなくても、IT業界に興味があるひとでもおもしろい内容になるかも。

今回は自分の苦手な分野の勉強会でどうなるか楽しみです。 でわでわ




2009年12月22日

ブレスの位置

さて、golangは(多分trunkだけだと思う)文のセパレータとして基本的に改行が使われるようになりました。;をセパレータに使ってもいいですが、僕はない方が好きです。Pythonの影響です。それと同時にブレスの位置も微妙に厳しくなりました。

func myfunc() {
....
}

はコンパイルできますが、
func myfunc()
{
...
}
はコンパイルエラーになります。基本的に僕は最初の方の書き方しかしないのでいいのですが、今まで書いたコードの中に一カ所だけ下の方のコードのような箇所があり、コンパイルエラーがでました。

そんなことはどうでもいいのですが、それを開発部長に話したら、「そんな書き方するんですか?」と。まあ、間違って改行がはいちゃっただけなのですが。で、下の方の書き方は、C世代のおじさんたち書き方と言う結論になりました。今時のJava世代の若者は上の方の書き方をするのです。「僕はCでも上のような書き方をしてたよ」と言うと、「おおたにさんのAirOneのコードは全部下のかきかたですよ。」と開発部長。なかなかあなどれません。でも、AirOneのC/C++のあとにJavaになって、上の方になれてくると下の書き方は少し、違和感がありますが、開発部長はおじさんなので、「Cは下の方の書き方じゃないと違和感がある」と。おじさんは新しいものになじめません。(うーん、かなり事実をねじ曲げているような・・・)

まあ、言語ごとにコーディングスタイルが統一されていればそれでいいのです。

ブログを書くのは難しい

僕はブログを、多分、2000年頃(2000年はまだブログという言葉はなかったかもしれない)から書いています。最初はtDiaryの本当に日記のようなもの(と言うか日記)でした。そこそこの時間書いているので、特に抵抗もありません。

 アリエルでも、開発者用のブログがあります。僕はそこには書いていませんが、アリエルは割と緩い会社で、どこに書いてもいいというルールになっています。ある程度は業務の一部になっています。

でも、中々社員の人は書いてくれません。よく聞く理由は「時間がない」というものです。僕は大体、一個の記事あたり10分とか15分ぐらいで書いています。個人差があるので一概には言えませんが30分あれば十分でしょう。これぐらいの時間であれば作り出せるはずです。

次によく聞く理由は「忘れていた」です。多分、一週間に一個だから忘れるのです。習慣化するまで、毎日書けばいいだけです。 とか言うものの、業務の一部なので、書かないと給料が上がらない(上がり方が緩い)だけです。

でも、もっとよく聞く理由は、「ネタがない」というものです。なにやら、この手法を使えばネタはどんどん出てきそうな気がしますが、どうなんでしょう?僕は昔よりは書く頻度は減っていますが、全体を平均すると二日に一個は書くようにしています。ネタは、なくなります。一月ぐらいであればストックでなんとか書けますが、それ以上はなくなります。なので、技術的なこととか、アンテナを張ったり調べたりしています。あまりやり過ぎる(強迫観念がある)と本末転倒ですが、常に興味を持って調べるのは技術者には必要なことです。また、それを自分なりにまとめる作業も重要です。それが、他人の役に立てばいいですが、技術的なお話は完全に自分のメモなのです。と理由をつけても、結局自分が好きだからやっているだけです。

でも、ググって最初のページに表示されるのものが自分のページだったりするとがっかりするのはなぜなんでしょう? 

 



2009年12月17日

4階まであがれる体力

アドレナリンジャンキーを読んでいます

基本的には読み終わってからしか書かないのですが、たまには今読んでいるものについても少し書きます。アリエルでは、なぜかアドレナリンジャンキーが今はやっています。アリエルには読み終わった本は会社に捨てるという文化があるので、たまに同じ本が複数あったりします。そして、会社に捨てられたかわいそうなアドレナリンジャンキーの本が数冊あります。

読んでいるとかなりおもしろいです。自分に当てはまったり、納得できたり、ちょっと違うんじゃないかとおもうところもあります。でも、困ったことに読んでもよく分からないことがあります。過去にその状況に直面したことがないからかもしれないし、もっと別の原因かもしれません。

僕は80%の力で走り続けるチームを作りたいと思っていましたが、間違っていなかったかもしれません。開発部長は100%の力で走ろうとしているように見えます。 

 




2009年12月16日

Google Readerの「送信先」

僕はGoogle Readerをかなり前から使っています。Googleに思い入れがあるとかじゃなくって、単にユーザIDとパスワードの管理コストを減らしたいだけです。大昔はクライアントソフトを使っていましたが、iPhoneでも見たいと思うようになってからGoogle Readerだけを使うようになりました。

さて、そんなGoogle Readerですが、かなり前から英語版はSendToとかでInstapaperにエントリを保存できていました。でも日本語版はありませんでした。英語でも日本語でもどっちでもいいのですが、なぜか日本語で使っていました。で、今日、送信先という項目が追加されていることに気づきました。うーん、遅い?

で、送信先でInstapaperを使えるようにしましたが、新しいウィンドウがでて、保存ボタンを押さないと保存してくれません。僕はそんな確認をしてもらわなくても結構です。なので、カスタムリンクで登録します。ブックマークレットの内容をみて、リンク先はこんな感じ。
http://www.instapaper.com/b?v=4&k=よくわからないブックマークレットのキー&u=${url}&t=${title} - ${source}&s=
「よく分からないキー」は、ブックマークレットをみて、&k=の後に続いている文字列で、その次の&までです。。ついでに、アイコンは http://www.instapaper.com/favicon.png としてInstapaperのものを使います。これで、送信先を選択するとウィンドウが立ち上がってInstaperに勝手に保存してからウィンドウが勝手に閉じます。これならそれほどストレスになりません。

めでたしめでたし。

2009年12月15日

言っても伝わらないものは伝わらない

先週、会長が「プロジェクトのもっとうまく運営するためにモチベーションをコントロールしろ」とある人に言っていました。まあ、僕が普段言っていることで、何も目新しいことはありません。(会長に対してひどい物言いですね)

横で聞きながら、多分、相手には伝わっていないなー、と思っていました。僕が10年前に同じことを言われたら、言っていることが分からなかったと思います。まあ、当時分からなかったことが今分かったり、今でもまだ分からないこともあります。

伝わらないのは仕方ないことだと思っています。ただ、それは伝えようとしないこととは別です。伝えようとした上でそれでも伝わらないことがあります。ちゃんと説明すれば伝わるというのは幻想です。特にモチベーションのコントロールとか訳わかんないものはなおさらです。さらにすべてを工数で管理しようとする人にとっては、なおさら意味不明のことです。で、ちょっと前までは、伝えた上で自分で体験すれば、それが分かると期待していました。でも、最近は、同じことを体験しても、それが分かる人と分からない人がいます。体験した上で、やっぱりそれが分からないのは、なぜだか分かりません。それにどうすればそれが分かるようになるか、分かりません。

あと10年すればわかるようになるかもしれません。もっと時間がかかるかもしれません。 



2009年12月14日

websocketsの覚え書き

HTML 5 Web Sockets vs. Comet and Ajax
なかなかおもしろいような、当たり前のような・・・。AJAXは定期的にポーリングするので負荷が高くなりますね。Cometのロングポーリングは、コネクションの管理が大変な上に、HTTPヘッダーのオーバーヘッドの方が大きいよね。だからWebSocketsだよね。と言うお話。

W3Cの仕様。なんだか、HTTPを拡張した方がよくね?
HTTPのGETを使ってネゴシエーションした後に、コネクションをオープンにしたままデータの送受信を行う。wsと言うプロトコルが新たに定義されていて、ポート番号は81。ReverseHTTPとか言うのがあるらしいけど、WebSockets使った方がよくね?

これを使えば、IEなどHTML 5を使っていなくてもWebSocketsでハッピーになれるらしい。Cometみたいな感じでエミュレートするっぽい。サーバサイドでもGateway的に動作できるらしい。

どうでもいいけど、XMPP使ってサーバ同士がもっとおしゃべりしあうのもいいかも、と少し思った。今の会社の製品はデータベースかmemcacheを使っておしゃべりしている。


2009年12月12日

ThunderBird3


Thunderbird3が今週やっとリリースされました。一ヶ月か二ヶ月前までThunderbird2を使っていましたが、あまりの遅さに耐えられず、Thunderbird3のベータ版を使っていました。やっと正式版がでたので、アップグレードして、引け目を感じなくなりました。

Thunderbird3はそれでいいのですが、スケジュールもOutlookのようにメーラの中に表示したいので、Lightningを使っています。でも、この人はまだ、Thunderbird3に対応していないので、Lightingはnightlyビルドを使っています。仕事で使っているのに、冒険のしすぎのような気もします。でも、IMAPでデータはすべてサーバにおいてあるので、いざとなればクライアントを変えるだけです。 

さて、テーマを変えたいのですが、 僕のThunderbirdではメールの詳細画面を開くとアイコンが悲しいことになってしまいます。表示がおかしいです。しかたないので、味気ないデフォルトのテーマのままです。テーマがわるいのか、僕だけの問題なのか分かりませんが・・・。

メールの中で「添付」と入力すると、下の方に添付ファイルを追加を促すようになっています。これはそこそこ便利なんですが、添付ファイルをつけなくてもそのまま送信できてしまいます。添付ファイルをつけないまま送信しようとすると警告ダイアログとかを出してくれるともっとうれしいのだけどな・・・。 

それ以外は、そこそこ快適です。でも、メーラにそれほど機能を求めないので、 スピードさえ速ければ何でもいいです。




2009年12月11日

ChromeとWebSocket

WebSocketの仕組みはまだ、ちゃんと調べていませんが、昨日の続き。Chromeを立ち上げてreloadすると、netstatで見たコネクションの数が一個だったのが二個に増えます。一つのブラウザで三個以上になることはありませんが、気持ち悪いです。

window.onunload = function() {ws.close();};などして、明示的に接続を切ってあげると、コネクションは二個に増殖することはありません。closeを呼んであげないと、サーバの方で接続がまだ維持されているかのように振る舞い続けます。つまり、readは待ち続けるし、writeに至ってはちゃんと書き込めたかのようにみえます。

で、機能のサンプルは書き込み、読み込みそれぞれ、goroutineが作られるので、うれしくありません。クライアントがcloseをコールするとちゃんと、読み込み・書き込みでエラーというかEOFとかでてくれます。

やっぱり、オブジェクトのメモリが破棄されるときはcloseして欲しいですが、メモリが破棄されていないのかもしれません。

まあ、接続は明示的に閉じろと言うことで。

2009年12月10日

WebSocketでChatを作ってみた

MacにChromeを入れたことだし、HTML5のWebSocketでChatを作ってみました。サーバがgolangで作っています。クライアント側のコードは、こんな感じです。
<html>
<head><title>Web Socket Chat</title></head>
<body>
<script>
var ws = new WebSocket("ws://127.0.0.1:1972/chat");
ws.onopen = function() {
};

ws.onmessage = function(message) {
var txtNode = document.createTextNode(message.data);
var brNode = document.createElement('br');
var cnode = document.getElementById("content");
cnode.appendChild(txtNode);
cnode.appendChild(brNode);
};
</script>
<h1>Web Socket Chat</h1>
<div id="content">
</div>
<input id="message" type="text" onChange="javascript:ws.send(this.value);this.value='';"/>
</body>
</html>



ポイントは赤い文字の部分で、簡単にWebSocketのオブジェクトを制御できます。
サーバサイドはgolangでこんな感じ。まあ、いつぞやのチャットサーバを書き換えたものです。


package main

import (
"http";
"log";
"bytes";
"fmt";
"os";
"websocket";
)

const MAXREQSIZE = 0x10000;

func startServer() {
// initialize
queue := make(chan string);
listen_chan := make(map [*websocket.Conn] chan string);

go func() {
for {
mesg := <- queue;
for _, c := range listen_chan {
c <- mesg;
}
}
}();

read := func(ws *websocket.Conn, errChan chan os.Error) {
buf := make([]byte, MAXREQSIZE);
for {
fmt.Print("Reading...\n");
l, err := ws.Read(buf);
if err != nil {
fmt.Print(err);
errChan <- err;
return;
}
fmt.Printf("received: %s¥n", buf[0:l]);
queue <- string(buf[0:l]);
}
};

write := func(ws *websocket.Conn, mesgChan chan string, errChan chan os.Error) {
for {
mesg := <- mesgChan;
_, err := ws.Write(bytes.NewBufferString(mesg).Bytes());
if err != nil {
errChan <- err;
return;
}
}
};

OnConnected := func(ws *websocket.Conn) {
fmt.Printf("Connection Opend\n");
mesgChan := make(chan string);
listen_chan[ws] = mesgChan;
errChan := make(chan os.Error);

go read(ws, errChan);
go write(ws, mesgChan, errChan);
err := <-errChan;
fmt.Printf("Done%d\n", err);
listen_chan[ws] = nil, false;
};

// http handlers
http.Handle("/", http.HandlerFunc(func(c *http.Conn, req *http.Request) {
path := req.URL.Path;
log.Stdout("Request URL: " + path);
http.ServeFile(c, req, "." + path);
}));

http.Handle("/chat", websocket.Handler(OnConnected));

err := http.ListenAndServe(":1972", nil);
if err != nil {
log.Stderr(err.String());
return;
}
}

func main() {
log.Stdout("starting server...");
startServer()
}





これを実行して、Chromeを複数動かして、どれかで何かを打ち込むと、他のブラウザに打ち込んだものが出現します

2009年12月9日

Mac版Chromeを入れてみる


Mac版のChromeベータ版がでたのでインストールしてみました。起動がとても速いです。Safariよりも速いです。レンダリングスピードとか、JavaScriptの実行速度は体感的にはSafariと変わらないですが、タブを開く速さはSafariより快適です。Flashもみれるし、ちゃんと動いています。

全体的な見た目は悪くないけど、ウィンドウのバーの一部にタブが浸食していて、バーをつまんでウィンドウを移動するのがやりにくいです。 5pxぐらいの差なんですけどね。

ベータ版と言うことですが、まだ、実装されていない機能があります。フォントが変えられないとかぐらいは気にならないのですが、「タスクマネージャ」が使えないのが悲しいです。まあ、開発者しかうれしくない機能かもしれませんが・・・。それ以外にもアプリケーションとしてショートカットを作れないとか、寂しいこともありますが、正式版がでればSafariからのりかえてもいいかなー、と感じます。たぶん、Mobile Meとブックマークの同期ができれば、乗り換えるかも。でも、ブックマークに何かを登録したのは、遙か昔のこと。 




iPod TouchにWired Frameをいれた

家には使わなくなったガジェットが転がっています。GoogleがくれたAndroidは子供のおもちゃです。SIMカードがささっていないiPhone 3Gは、音がでるし、カメラはついているので、これも子供のおもちゃです。ゲーム機と化しています。それ以外にもiPod Touchがいます。これはDockみたいなのにつながっていて、時々嫁が音楽を聴いています。でも、あまりつかわれいません。Touchの画面が悲しいです。

なので、もったいないのでデジタルフォトフレームにしようと思って、Wired Frameをインストールしました。デジタルフォトフレームを数千円か数万円をだして買う価値は感じませんが、既存のものをフォトフレームにするのはありです。

Wired FrameはFlickrの画像を表示してくれます。とりあえず、Flickrに登録しようとすると、そのIDは使っているからだめよ、と怒られます。すでに僕はIDを持っていたようです。だからそれを使います。

FlickrにはiPhotoから簡単に写真をアップロードできます。最初はiPhoneで完結しているものを考えていましたが、こっちのほうが管理が楽そうです。

それ以外にも、天気とか、時間とか、RSSとかでて、うれしいです。スケジュールの内容も出たりするともっとうれしいかも。

いろいろ、情報が出ているので、ちらっと見る気になります。iPod Touchはうっちゃおうと思っていたのですが、やっぱり使い続けることにしました。  



2009年12月8日

遅延証明書

電車が遅れたので、遅延証明書をもらいました。まあ、出す必要性はないのですが、今の会社の管理の仕方が?なので、出します。駅でもらった遅延証明書を出すと遅れた時間が書いていません。自分で本当に遅れた時間を書いて出そうとすると、それではだめです。と言われます。ホームページで何分遅れたかのっているのでそれを出してよこせと言います。自己申告だと嘘を書いているかもしれないと言うのです。うーん、駅の人に聞いたら、自分で書いていいって言われたんだけど(これ本当)。
めんどくさくなったのでそのまま出さないでおこうかと思ったんですが、JRのページで調べてみると一時間以上おくれたことになっています。それをそのまま出したら、その通り処理してくれました。うーん、僕は嘘はついていないし、言われた通りにしただけなのに、20分の遅延が1時間以上の遅延に変わっています。インターネットはすごいです。管理の人って馬鹿なの?
数百人規模の会社であればいろな人が混じりますが、顔と名前が一致する規模の会社で「嘘」を申告するかもしれないって言われると、どうなのかなー、と思います。そうやって、みんなきっちり給料分というか、時間分しか働かなくなります。
まあ、開発の人は管理されるのが嫌いなので、宿命かもしれません。

golang楽しんだけど・・・

Googleが先月公開したGoという言語で遊んでいます。最近は積極的に新しい言語を試してみようという気になれなかった(年のせい?)のですが、ちょうど年末なので(理由になっていないけど)ちょっと遊んでいます。言語自体はちょっと気持ち悪いところもありますが、嫌いじゃないです。もしくは、慣れれば平気です。 Goの技術的な話は個人のblogに書いていますが、ここではちょっと別のお話です。

金曜に昔アリエルでバイトしていた人がやってきて、「Goで何か製品を作らないのですか?」と聞いてきました。Goに限らず、言語については意外とアリエルは保守的です。僕が保守的なだけかもしれません。新しい言語を使わない理由は、いろいろあります。

1. 誰かとっても詳しい人はいるか?

会社としてやっていくには、ちょっと勉強しただけの知識ではどうにもならないことがあります。誰も詳しい人がいなければ、採用しません。でも、僕がとっても好きな言語であれば、その詳しい人に自分がなればOKです。

2. 後方互換性があるか?

新しい言語だと、後方互換性があるかどうかすら分からないので、即却下です。これは言語に限らず、ライブラリでも同じ基準で採用を決めています。バージョンアップしてコードを書き換えないといけないと、とてもやっていけません。なので、Pythonでもこの辺はちょっと厳しい。Rubyはもってのほか(誤解していたらごめんなさい)です。Javaぐらい進化が 遅いといいのですが、それだとおもしろくありません。

3. プログラマを集められるか?

一昔前はC/C++プログラマは沢山いました。今はJavaプログラマが腐るほどいるので、Javaプログラマを集めるのは簡単かもしれません。アリエルの場合は、Javaプログラマを募集していますが、ぼくは純粋培養のJavaプログラマはそれほど、重要視していません。僕の知る限り、PythonやRubyをやっている人は、それしかできないということはないはずです。 つまり、その言語でプログラミングができるようになれる人を集められるかどうかです。僕の小さな社会の偏見では、純粋培養のJavaプログラマは他の言語を積極的に覚えようとしません。

それ以外にもいくつか基準はありますが、それはまた、今度。うーん、結論はJava最強?えっ、何それ? 



2009年12月4日

ロータスOB会

昨日はロータスのOB会でした。知らない人もいるかもしれないので、一応言っておくと、ロータスは車の会社ではありません。今はIBMに完全に統合されてしまった会社です。かつて1-2-3やNotesで一世を風靡して、その後かなしーことになった会社です。僕は完全に統合される前にやめちゃったので、ロータスがIBMに統合されてどうだったのかは知りません。

ロータスOBは400人ぐらいいて、200人ぐらいがIBMにまだいると言っていました。全部合計しても数百人ぐらいの会社だったのか・・・。 知らんかった。

さて、同期の人たちはあまり来ていなくて残念でした。ある人は、大企業の人とベンチャーで今もばりばりやっている人の文化の摩擦を嘆いていましたが、まあ、僕は、体調がいまいちよくなくって、よくわかりません。それはいいのですが、名前が思い出せなくて困りました。それから、IBMと言えば、アリエルとはコンペもする競合他社さんです。

僕がロータスをやめてから10年弱だと思いますが、みんな年取ったな。それから、ロータスとは全く違う文化の会社にいつづける気持ちはよく分かりません。でも、ロータスに入ってよかったと思うことは、同期がいることだと思います。それ以外は、うーん、



マズイ

2009年12月3日

マズイ

マンゴーあまり好きじゃないが

OAuth社内勉強会

アリエルでは主に2種類、正確には3種類の勉強会があります。一つが、9月のEmacs勉強会のような社外に対する勉強会です。来年の一月にまあ、勉強会を開きます。Emacsに限らず、今後は定期的に勉強会をする予定です。のこりの二つは社内勉強会です。社内勉強会はなぜか、2種類あります。一つが、「自称20代の人たちの勉強会」です。若者と自認している人たちが名目上は自発的に行っています。これは割と定期的に行われています。それと、不定期に勉強会があります。

社内勉強会はテーマは様々です。今回の不定期な勉強会のテーマはOAuthで開発部長が講師でした。 ちなみに内容は仕事とは全く関係がありません。さて、僕はOAuthとOpenIDの区別があまりついていません。基本的には同じような仕組みで、できることもほぼ同じだと認識しています。ちょっと乱暴ですね。で、OAuthがGoolgeさんでOpenIDがGoogleさんも含めていろんなところで使われているものと思っています。OpenIDでもできることが同じなので、僕はOAuthは過去の技術だと勝手に認定していました。でも、開発部長はそんな風に断定はしていません。

で、GoogleはAuthSubと言う認証の仕組みも持っています。こっちは、OpenIDとか、OAuthと違って簡単です。開発部長はAuthSubをCで実装してマルチスケジューラに組み込んでいます。すがPこと、菅原さんはこっそりEmacs Lipsで実装しています。僕もひっそりとPythonで実装したものをもっています。社内を見渡しただけでも3つも実装がありました。変な会社です。



2009年12月2日

@itのGolangの記事の誤解

第1回 Google Go登場の背景
現状のGoでは関数内に複数のreturnを書くことができない
って、それはすごーい誤解。と言うか、これぐらいはもう少し勉強してから書いて欲しい。if xxx { return x;} else {return y;}のように書けないと言うだけで、if xxx { return x;} return y;のようには書けるし。と言うか、複数のreturn書けないってありえないでしょう。

「クラスの継承」とオブジェクト指向が同一視されているところはなんとなーくJava脳になっているような気がする。で、書き方は変かもしれないけど継承も一応できるし。interfaceがduck typingなところが好き嫌いとか、今までと違うところのような気がする。genericはあまり興味がないけど、例外が欲しいというのは納得できるんだけど、僕はそれは単にjumpしたいから。

文法は、Pascalっぽくって、僕は好きじゃない。なれれば気にならないけど。

2009年11月27日

Blacows

バージョン管理いろいろ

ソフトウェアの開発にバージョン管理はなくてはならないツールです。たとえ一人だけで開発しているとしても、バージョン管理システムを使わずに開発している人たちがいるとは信じられません。

バージョン管理システムはほんの10年ぐらい前まではCVSがデファクトでした。これさえ覚えておけば、大体何とかなりました。その後、アリエルでも使っているSubversionがはやり出しました。CVSはいろいろ不満点があったので、(新しいものに適応できない)開発部長の反対を押し切ってSubversionを使い始めました。

さらに、時代は流れて、今はMercurialだ、gitだ、といろいろあります。会社の中はSubversionでとりあえず問題(branchの開発にはちょっと・・・)ないので、多分、そのままです。自分の個人のコードはMercurialで管理しています。

でも、いろんな他の人が作ったライブラリとかは、Mercurialだったり、gitだったりで 、いろいろあります。他の人を見ていると、いろんなツールを使いこなしているみたいです。少なくとも僕にはそう見えます。すごいです。置いてきぼりにならないようにしないといけません。でも、見栄をはって、分かっているような顔をしています。

ついでに、やっぱり分散リポジトリは会社とかそういう組織では管理できる気がしません。 



2009年11月26日

ザクザクザク2

ザクザクザク

ラブモードジンジャー

golangからPythonの関数を呼び出してみる

前回の続きです。golangのコードからPythonの関数を呼び出してみました。とりあえず、Pythonのドキュメントのここに書いてあることができるようになりました。とりあえず、動くことを目標にしているので、わざとはっしょってたりしています。golangは簡単にCのコードを呼び出せるのはいいのですが、ほとんど考えることがないので、ラッパーを自動生成できないのかな?

ついでに、macroはいやーん、だと思っていましたが、
package "py"

/*
#import "myheader.h"

void wrapper_func(int v) { SOME_MACRO(v); }
*/
import "C"
みたいな感じにしておけば、使えるのか・・・。

で、今のコードはgithubにいます。こんな感じになります。




func setArgs(pArgs *py.Object, index int, value int) bool {
pValue := py.Int_FromLong(value);
if pValue == nil {
fmt.Printf("Value : %d\n", value);
py.Err_Print();
return false;
}
pArgs.Tuple_SetItem(index, pValue);
return true;
}

func runFunc(pythonfile string, funcname string, arg []int) {
fmt.Printf("--- runFunc ------------------------------\n");
pName := py.String_FromString(pythonfile);
pModule := py.Import_Import(pName);
fmt.Printf("import done \n");
pName.DecRef();
if pModule != nil {
fmt.Printf("pModule %t\n", pModule);
pFunc := pModule.GetAttrString(funcname);
if pFunc != nil && pFunc.Callable_Check() != 0 {
pArgs := py.Tuple_New(2);
if setArgs(pArgs, 0, arg[0]) == false {
pArgs.DecRef();
pModule.DecRef();
fmt.Printf("Cannot Convert Argument\n");
return;
}
if setArgs(pArgs, 1, arg[1]) == false {
pArgs.DecRef();
pModule.DecRef();
fmt.Printf("Cannot Convert Argument\n");
return;
}
pValue := pFunc.CallObject(pArgs);
pArgs.DecRef();
if pValue != nil {
fmt.Printf("Result of call: %d\n", pValue.Int_AsLong());
pValue.DecRef();
} else {
pFunc.DecRef();
pModule.DecRef();
py.Err_Print();
fmt.Printf("Call Failed\n");
}
} else {
if py.Err_Occurred() != nil {
py.Err_Print();
}
fmt.Printf("Cannot find function %s\n", funcname);
}
py.XDecRef(pFunc);
pModule.DecRef();
} else {
py.Err_Print();
fmt.Print("error\n\n");
}
fmt.Printf("--- runFunc done ---\n\n");
}


でも、こっちをみたほうがわかりやすい。

でわでわ

2009年11月25日

インフルエンザがやってきた

3連休はインフルエンザで始まりました。僕がかかったわけではなく、次男がインフルエンザになりました。彼は生まれて初めてのインフルエンザでしかも新型です。正確には金曜の朝、熱が38度弱ありましたが、ぴんぴんして元気です。普段が37度ぐらいなので、ちょっと高いぐらいです。食欲旺盛で、いつもと全く変わりません。夜寝ているときに熱がどんどんあがりますが、すやすや寝ています。朝起きると38度弱にもどっています。まだまだ元気です。

とりあえず、もう一度お医者さんに行くとインフルエンザでした。タミフルをもらって夕方には、37度ぐらいに戻っています。元気です。でも、他の人にうつすといけないので、家の中に閉じ込めないといけません。一週間閉じ込めないといけません。大変です。困りました。

家の中には2才のちびがいます。どうせインフルエンザになるなら、一緒にかかればもう一度休まなくてもいいので、うつらないかなー、 と思っていましたが、全然平気です。僕はマスクが嫌いなので、マスクとかしないのですが、やっぱりまだ、うつりません。

おとなりさんの子供もインフルエンザになったらしいですが、他の人には移らなかったようです。新型に限らず、インフルエンザはこわい病気なので注意したほうがいいのかもしれませんが・・・。 



2009年11月24日

golangからPythonをちょっとだけ使ってみる

やっぱりヘビが好きなので、golangでも使いたいなー、と言うことでPythonを呼び出せるようにちょっとだけしてみました。goでインタープリタを実装する時間もスキルも、モチベーションもないので、CPYthonを呼び出すだけです。半分cgoのお勉強です。

まず、Pythonのコードを呼び出すようなテストコードgopy.goを書きます。pyで始まるようなところが、Pythonのラッパーです。Macでしか動かないMakefileです。


package main

import (
"py";
"fmt";
)

func main() {
fmt.Print("init\n");
py.Initialize();
fmt.Print("init done\n");
result := py.Run_SimpleString("print 'hello'");
fmt.Printf("script done %d\n", result);
py.Finalize();
fmt.Print("finalize done\n");
}


次にPythonのラッパー。とりあえず、テスト用なのでPy_Initialize, Py_Finalyze, PyRun_SimpleStringをラップします。次のコードgopywrapper.goがそれ。この人からCのコードとgoのコードが作られます。最初の方のコメントの部分がCと仲良くするための魔法です。

package py
/*
#include
*/
import (
"C";
)

func Initialize() {
C.Py_Initialize();
}

func Run_SimpleString(script string) int {
return int(C.PyRun_SimpleStringFlags(C.CString(script), nil));
}

func Run_Simple

func Finalize() {
C.Py_Finalize();
}



あとは、Makefileを書くだけです。実はこの人を作るのが一番時間がかかったかも。なぜかは、うーん、typo。でMakefile。


include $(GOROOT)/src/Make.$(GOARCH)

TARG=py
CGOFILES=\
gopywrapper.go

CGO_LDFLAGS+=-lpython -u _PyMac_Error /Library/Frameworks/Python.framework/Versions/2.6/Python
CGO_CFLAGS=-I/usr/include/python2.6/ $(CGO_FLAGS)
CFLAGS=-I/usr/include/python2.6/

LDFLAGS=-u _PyMac_Error /Library/Frameworks/Python.framework/Versions/2.6/Python

include $(GOROOT)/src/Make.pkg

%: gopywrapper.o install %.go
$(GC) $*.go
$(LD) -o $@ $*.$O

gopywrapper.o: gopywrapper.c
gcc -fPIC -O2 -o gopywrapper.o -c gopywrapper.c

gopy: install gopy.go
$(GC) gopy.go
$(LD) -o $@ gopy.$O



これで、make gopyとやれば、gopyという実行ファイルができます。./gopyを実行すると、


init
init done
hello
script done 0
finalize done


めでたしめでたし。次はこのへんをできるように・・・。

2009年11月20日

golangのevalをちょっとだけ見てみた

先日、evalがあると驚いていたので、golangのevalをちょっとだけ見てみましたが、よく分かりません。基本的には、eval_test.goをみて書いてみました。
テストケースとかstmt_test.goを見ると関数とかも値として返してくれるのかなー、と期待しましたが、違うようです。よく分かりません。動作としてはコンパイルして、スレッドの中で実行しているような気配を漂わせていますが、めんどーになってちゃんとは追ってません。実行時にバイナリを書き換えるとかいうソフトを昔聞いたような気がしますが、実行ファイルが自分でコンパイルして何かを実行するってやっぱりおもしろい。
でも、evalで何ができるかは、よく分からないんです。



package main

import (
"exp/eval";
"log";
)

func main() {
srcs := []string{
"1",
"type hoge struct {s string};",
"a:=1;",
"a",
"func f1() {}",
"1,2",
};

for _, src := range srcs {
world := eval.NewWorld();
log.Stdout("[Code] " + src + "\n");
code, err := world.Compile(src);
if err != nil {
log.Stderr("[Err] " + err.String());
} else {
value, err := code.Run();
if err != nil {
log.Stderr("[Err] " + err.String());
} else if value != nil {
log.Stdout("[Out] " + value.String() + "\n");
} else {
log.Stdout("[Out] (value == nil)\n");
}
}
}
}


実行結果

2009/11/20 17:42:25 [Code] 1
2009/11/20 17:42:25 [Out] 1
2009/11/20 17:42:25 [Code] type hoge struct {s string};
2009/11/20 17:42:25 [Out] (value == nil)
2009/11/20 17:42:25 [Code] a:=1;
2009/11/20 17:42:25 [Out] (value == nil)
2009/11/20 17:42:25 [Code] a
2009/11/20 17:42:25 [Err] input:1:1: a: undefined
2009/11/20 17:42:25 [Code] func f1() {}
2009/11/20 17:42:25 [Out] (value == nil)
2009/11/20 17:42:25 [Code] 1,2
2009/11/20 17:42:25 [Err] input:1:1: only one expression allowed


それから、"[...]int{1,2}"とかを実行すると、[Err] input:1:1: *ast.CompositeLit expression node not implementedとなる。

アリエルは新入社員をとってもいいと言う噂

アリエルでバイトしている女子大生は、もう、就職活動しています。僕は夏頃就職活動(と言うほどのこともしていないけど)したような記憶があるので、今時の人たちは早いです。何かが間違っていると思わなくもないです。

さて、アリエルは正規のルート(どこかの就職用のサイトとか)を通しては 新入社員を募集していないです。多分、開発に関しては僕が反対するので当分はやらないでしょう。でも、アリエルのサイト上にある採用用のメールアドレスに直接履歴書を送れば、大丈夫です。正確に言えば、履歴書じゃなくって、自分が書いているブログのURLと名前と連絡先だけでいいです。自分をアピールするためのものも、必要ないです。ブログを読んで、その人は技術が好きか、プログラミングが好きかを見ます。それだけです。

強いて言えば、Javaしかやっていない人はポイントが低いです。Javaは悪くないのですが、母数が多すぎてフィルタしにくいからです。それから、Javaはスキルをはかるのには向いていない言語ということもあります。

メインとなる言語(これは、Javaでもいい)と、もう一つ、別の言語(文化が違えばもっといい)ができればなおいいです。

今だと、「Go勉強しています」でもいいし、「これからはErlangでしょ」でもいいし、「ScalaはJavaの上で動きますが、いいですよ」でもいいし。

結局、新入社員だろうと、中途だろうとちゃんとしたプログラマしかとならいです。で、twitterで僕をフォローしている人のブログを読んだりすると、すごい人が一杯いるなー、と感じます。 



2009年11月19日

今更ながらGoのinterfaceとかstructとか・・・

Emacsのバッファにinterfaceとかstructとかをいろいろ試した時のコードがありました。ついでなので、載せておきます。

まずは、interface。interfaceって何かというとPython3のabcみたいなものです。えっ、わかんない?C++の純粋仮想クラスみたいなものです。えっ、だめ?Javaのinterfaceみたいなものです。
こんな感じで書きます
type MyInterface interface {
    Say() string;
}
Javaと同じで、interfaceに直接実装することができません。メソッドを定義できるかです。では、Javaのclass相当のことをするには、structを使います。基本的には、javaのfield値を指定します。
type MyStructBase struct {
    mesg string;
}
structに対してメソッドはfunc (self *MyStructBase) Say() string { return self.mesg; }のように書けば、このSayはMyStructBaseのメソッドになります。じゃあ、interfaceはどこよ?と言うことで、次のような関数を定義します。
func SaySomething(obj MyInterface) {
    mesg = obj.Say();
    fmt.Print(mesg + "¥n");
}
これは、引数にMyInerfaceという型のinterfaceを受け取ります。これを利用する側は、
obj := new(MyStructBase);
obj.mesg = "my struct base";
SaySomething(obj);
という感じです。SaySomethingの引数のMyInterface型のobjは、単にそのinterfaceが定義している関数をobjが持っているかどうかだけをチェックしています。だからduck typingなんですね。と言うか、いい加減なんですね。ちなみに、実行結果は"my struct base"と出力されるはずです。

次にMyStructBaseを継承したようなMyStructExtendを作ってみましょう。
type MyStructExtend struct {
    MyStructBase;
}
structのメンバーを書くところに直接基底クラスみたいなものを書きます。使うときは
obj := new(MyStructExtend);
obj.mesg = "my struct base";
SaySomething(obj);
です。実行結果も"my struct base"となります。MyStructBaseの実装がそのまま使えました
では、MyStructExtendに同じメソッドを追加します。func (self *MyStructExtend) Say() string { return self.mesg + "from MyStructExtend"; }
これを実行すると、"my struct base from MyStructExtend" となります。Javaのsuperみたいなことをするには、
func (self *MyStructExtend) Say() string {
    return self.MyStructBase.Say();
}
とします。これで、継承元のSay関数が呼び出されます。言語オタクはいろいろ言うかもしれませんが、僕は嫌いじゃないです。PythonなどのLLも外界との境界線上にはtype check(もしくは型宣言)があった方がいいと思っているので、このぐらいのいい加減さがいいです。

もっと、テスト用のコードを書いたんだけど、めんどいので、このぐらいで。

2009年11月18日

GoでHTTPサーバ その3 Cometもどき

GoでHTTPサーバの続きです。とって言っても、チャットサーバをHTTPっぽくしただけです。URLで/listenにアクセスすると、ずっと待ち続けます。URLが/say?message=なんかのメッセージにアクセスすると、「なんかのメッセージ」がlistenで待っているクライアントに配信されるだけです。


package main

import (
"http";
"log";
"io";
)

func startServer() {
// initialize
queue := make(chan string);
listen_chan := make(map [*http.Conn] chan string);

go func() {
for {
mesg := <- queue;
for _, c := range listen_chan {
c <- mesg;
}
}
}();

// http handlers
http.Handle("/", http.HandlerFunc(func(c *http.Conn, req *http.Request) {
path := req.URL.Path;
log.Stdout("Request URL: " + path);
http.ServeFile(c, req, "." + path);
}));
http.Handle("/listen", http.HandlerFunc(func(c *http.Conn, req *http.Request) {
reciever := make(chan string);
listen_chan[c] = reciever;
mesg := <- reciever;
io.WriteString(c, mesg);
listen_chan[c] = nil, false;
}));
http.Handle("/say", http.HandlerFunc(func(c *http.Conn, req *http.Request) {
mesg := req.FormValue("message");
queue <- mesg;
body := "Message \"" + mesg + "\" was sent";
io.WriteString(c, body);
}));

err := http.ListenAndServe(":1972", nil);
if err != nil {
log.Stderr(err.String());
return;
}
}

func main() {
log.Stdout("starting server...");
startServer()
}

やってはいけないこともやってしまう

スタートアップがやってはいけないこと10+1がなかなかおもしろいです。

アリエルができた時を振り返りながら見てみると、


1.  街のいい場所に立派なオフィスを借りてしまう

他人の金を自分の金のように使うな

アリエルができた当時はオフィスがなかったし、どちらかと言えば、このままオフィスなくてもいいじゃね?と思っていました。でも、なぜかオフィスができてしまいました。いい場所かどうかはわかりません。当時は割と安い方でした。ちなみに、一番最初の渋谷のオフィス(どこかの会社のを曲がり)はなぜか無料でした。 


2. 1回のツイートで何をしているか説明できない 

なぜあなたのプロダクトが優れているのか、短時間で説明できるようになれ 

  これは、そうだったかもしれません。


3. ざっと見回してもプログラマーがいない 

よい企業は彼らであふれている

残念ながらプログラマばかりでした。それはそれでどうかな?と思います。


4. PR会社と契約する(あるいはブログもツイッターも使ってない) 

素晴らしい企業は顧客がその企業のことをすすんで語るものだ

 途中から何かをやろうとしていたかもしれませんが、よく分かりません。


5. 間違ったことにお金を使っている 

コーヒーマシンではなく、プログラマによいイスとモニタと速いマシンを買ってやれ

 たぶん、日本の他の会社よりはいいですが、僕は全員に個室が欲しいです。


6. 解雇を躊躇する 

社内で方向性が異なるスタッフがいたら素早く対応すべきだ

 これって、アメリカと違って日本じゃ難しいんじゃないかな。変にやると訴訟になるし。ただ、アリエルができた時はみんな若かったので、その環境に慣れなくていなくなる人はいたけど。


7. インフラの選択を誤る 

私(スコーブル氏)はRackspaceの社員でありバイアスがかかっていると思うので、この件については誰かよいスタートアップに聞いてみるのがよい。

  ・・・


8. 早すぎる時期からベンチャーキャピタルにマネジメントと戦略をコントロールされてしまう
うーん、どうなんでしょう?ベンチャーキャピタルにもよるんじゃないかな?もしくは人によるのかもしれません。ただ、エンジニアはおとなしいので、対等に渡りあえるスーツが必要かもしれません。


9. クールすぎる社名やロゴ
 なんか、最初はすごい適当だったような・・・。


10. Yesといいすぎる。とりわけ技術的な決断に対して
うーん、これはどうとらえていいか分かりません。とりあえず、技術的な決断は結構やりとりがあったような気がします。


11. 詳しいからと古い技術を選んでしまう

これも微妙です。エンジニアは新しいから、おもしろそうだからと言う理由で技術を選んでしまうこともあります。やろうとしていることに対して、何が適切かじゃないかな?

まあ、最初はいろいろありましたが、なんでもいいから続けることが大事かもしれません。 



2009年11月17日

今日のgolang

Goの中からCのライブラリが呼べるのか・・・。でも、C++はどうなんだろう?

Stackless Pythonもすごそう。tokuhiromさんによると最近の「async/concurrencyブームにのっかって息をふきかえしてる」らしい。Twistedあやうし。っていうか、パフォーマンスはともかく、TwistedのDeferredGeneratorもおもしろいんだけどな。

それから、Goのevalは何者?ざっとコードを眺めると、evalの値をコンパイルしてネイティブコードにして実行しているみたいなんだけど・・・。これ使えば、LLのevalみたいな感じで使えるの?すげー。

GoでHTTPサーバ その2

rpcのパッケージもあるし、httpdのパッケージがあっても不思議ではなかった。もとは、これ。次はchannelまわりか。

package main

import (
"http";
"log";
)

func startServer() {
http.Handle("/", http.HandlerFunc(func(c *http.Conn, req *http.Request) {
path := req.URL.Path;
log.Stdout("Request URL: " + path);
http.ServeFile(c, req, "." + path);
}));
err := http.ListenAndServe(":1972", nil);
if err != nil {
log.Stderr(err.String());
return;
}
}

func main() {
log.Stdout("starting server...");
startServer()
}


GoのConcurrency

Goが広まるかどうかはよくわかりません。Chromeと融合するというお話もあるので、少なくともGoogleは使いそうです。スレッドをばんばん作るようなサーバを作るための言語かな?と思っていましたが、Chromeに絡めてくるとはちょっと意外でした。そんなGoですが、トップページにConcurrencyが特徴の一つとしてあげられています。Language Design FAQを読むとすごいです。
multiplex independently executing functions—coroutines, really—onto a set of threads
とあって、複数のスレッドでコルーチンが動いているような感じです。
When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked.
とあり、スレッド(コルーチン)内で何かがブロッキングIOをコールすると、ランタイムが勝手にそれを見つけてきてくれて、他のスレッドに切り替えてくれます。
他にも、コルーチンなので、計量スレッドになるとか書かれていますが、そのへんは大しておもしろくもありません。

さて、で、上のような仕組みって、結局Pythonとかでもできなくはないし、ありきたりと言えばありきたりです。でも、これがネイティブコードになると、どうやっているのか不思議です。Goのコードを書いていると、なんとなくスクリプトっぽさを感じます。duck typingのあたりやシンタックスもそうなんですが、コンパイルして実行するのが一瞬で、適当なシェルスクリプトなり、make && ./myappみたいに書いておけば、一瞬でコンパイル、実行できます。その辺もネイティブにコンパイルして実行していると言うことを忘れさせます。

で、goroutineがどんなネイティブコードをはくかはアリエルの井上さんがレポートしてくれるでしょう。

UNIXは体にいい

Goが公開され、オーサーの名前にKen ThompsonのようにUNIXの伝説の人が登場しています。基本的な設計だけをしたのかと思っていましたが、GoのコミットログをみるとKen Thompsonの名前で沢山のコミットがあります。中には「spell it with an "e"」のようなコミットログまであります。UNIXの年齢はちゃんとは覚えていませんが、UNIXが40年ぐらいだとすると、Ken Thompsonは60を超えているおじいちゃんのはずです。それでも現役で作業できるって素敵です。日本ではプログラマ35(40?)才定年説みたいなものがあったりしますが、多分、好奇心を持って楽しめれば何歳まででも現役のプログラマでいられるような気がします。そして、そうありたいです。

それから、先月号ぐらいのSoftware Designにカーニハン先生がのっていました。伝説の人たちは意外に長生きです。教育の方にシフトしたみたいですが、それでも現役で働いています。

UNIXは健康にいいのかもしれません。 



2009年11月14日

Goで超いい加減HTTPサーバを書いてみた感想

Goが公開されて、おもしろそうらしいので、GoでかなりはしょったHTTPサーバを書いてみました。その感想です。

まず、Goは名前がよくないです。ここでは、Goと言う言語がすでにあるから名前を変えてくれと言われているらしいですが 、変えて欲しいです。Issue9とか言う候補もあるらしいですが、まあ、僕はerlangのようにgolangでいいような気もします。ドメイン名もちょうどいいし。で、僕が名前を変えて欲しい理由は、グーグルさんで検索してもろくな検索結果が帰ってこないからです。これは悲しすぎます。

それでは、コードを書いた感想です。関数を実行して値を複数返せるのはすばらしいです。Pythonでコードを書くと当たり前のことが、CとかJavaとかだとできなくてフラストレーションの元でした。

それから、関数を抜けるときに実行する処理を書けるのもいいです。Javaだとtry〜finallyでやっていたことが気軽にできます。それから、returnするときに、そこに書かなくても途中で代入した結果を返してくれる機能とかもいいです。このあたりは小さなフラストレーションの固まりを解決してくれるのでいいところです。

でも、全体的にGoのシンタックスは好きではありません。99%ぐらいが慣れの問題だとおもいますが・・・。なんとなく、なじめません。

それから、goroutineはいいです。簡単に並列実行できます。本質的に難しいところは難しいのかもしれませんが、とってもいいところです。

インターフェースは、賛否両論あるところでしょうが、僕は好きです。実装が継承できないのは、うーんな気もしますが。それから例外がないのもちょっとなー。Javaのように例外でやり過ぎるのもどうかとは思いますが、例外のようなjumpが欲しいです。

ライブラリは、それほど使い込んでいないのでよく分かりません。まあ、最低限のことはできるぐらいはそろっています。最低限をどう定義するかは人によってまちまちでしょう。

ドキュメントがいまいち。まあ、僕はドキュメントはどうでもいいので、サンプルコードがかいてあればいいと思っているのですが、もうちょっと両方とも何とかならないかなー。

それから、まだ、チュートリアルちゃんと読んでません。長いです。英語です。会社のうさみみが、メーリスをつくったり、翻訳すると息巻いたりしています。翻訳してくれればちゃんと読むかもしれません。

 と言うことで、嫌いじゃないですが好きにもなれそうにありません。Pythonのようにインターラクティブモードがあれば好きになれるかもしれませんが。 



2009年11月13日

Goで超いい加減HTTPサーバ

超いい加減HTTPサーバを今はやりのGoで書いてみました。とってもいい加減です。カレントディレクトリのファイルをフィードしてくれます。ヘッダーのパースは、最低限のことしかしていません。レスポンスヘッダーもHTTP/1.0 200 OKしかかえしません。エラーがでたら無条件でブチッとコネクションを切ります。
goroutine楽です。connを閉じる場所が美しくないので、変えたい。


感想はこっち

package main

import (
"os";
"net";
"syscall";
"strings";
"fmt";
)

func Err(format string, v ...) {
fmt.Fprintf(os.Stderr, format + "\n", v)
}

func Msg(format string, v ...) {
fmt.Fprintf(os.Stdout, format + "\n", v)
}

func main() {
runServer()
}

func runServer() {
l, err := net.Listen("tcp", "127.0.0.1:1972");
if err != nil {
Err("Failed to Listen to 1972");
}
for {
conn, err := l.Accept();
if err != nil {
Err("Accept %s", err);
break
}
Msg("Request came");
go processRequest(conn);
}
}

func processRequest(conn net.Conn) {
defer conn.Close();

buffer := make([]byte, 1024);
headers := "";
for {
l, err := conn.Read(buffer);
if err == nil {
b := buffer[0:l];
headers += string(b);
count := len(headers);
if headers[count-4:count] == "\r\n\r\n" {
break;
}
} else if err == os.EOF {
Msg("EOF");
return;
} else {
Err("Err%s", err);
return;
}
}
url := strings.Split(headers, " ", 3)[1];
url = url[1:len(url)];
if len(url) == 0 || url[len(url)-1] == '/' {
url += "index.html";
}
fd, err1 := syscall.Open(url, syscall.O_RDONLY, 0);
if err1 == 0 {
conn.Write(strings.Bytes("HTTP/1.0 200 OK\r\n\r\n"));
fb := make([]byte, 1024);
for {
l, e := syscall.Read(fd, fb);
if e == 0 {
conn.Write(fb[0:l]);
}
if l == 0 {
break;
}
}
syscall.Close(fd);
}
Msg("done");
}

2009年11月12日

最近の気になる5つのこと

1. 野党のような与党と、与党の余韻に浸る野党がおもしろいなー。それから、「政治家としての責任」って、自分が言ったことを忘れること。
2. 池田先生と勝間氏との戦いが楽しかった。やっぱり戦いを野次馬としてみるのは楽しい。池田先生と勝間氏でトークライブやって欲しい。切込隊長さんが生暖かい司会をしてくれて、池尾先生が傍聴していて、ホリエモンが「そんなのどうでもいいから、起業しろ」みたいな感じで割って入って、金融日記を書いている人がそれらをなぜかまとめてくれる、と言うのを期待。
3. ちょっと前にクロージャ(Googleさんじゃないほう)が盛り上がっていたけど、Python始めた人にみんな言い過ぎ。で、Javaしか知らない人にクロージャを説明しようとして例がめちゃくちゃ悪かっただけのような気がする。大体、ファイルから読み出すのに"config.yaml"とかファイル名を直接指定なんてほとんど実際のコードではないでしょ。
4. Goとかクロージャ(Googleさんのほう)とか。まあ、クロージャの方はそれなりなんですが、Goはよく分からないです。まあ、ケン・トンプソンなのでいいものに違いない。

とりあえず、MacでGoを動かす

エンジニアならMacにXCodeやmercurialなどの開発環境が入っているのは当たり前だよね。ということで、
export GOROOT=~/myproj/gosrc
hg clone -r release https://go.googlecode.com/hg/ $GOROOT

でソースをとってきます。そして、環境変数をセットしてからビルドします。GOARCHの説明を読むと、intelのプロセッサしかだめなのかもしれません。Core2じゃないMacのひとは、そういう人はx86だけど買い換え時かもしれません。
export GOOS=darwin
export GOARCH=amd64
cd $GOROOT/src
./all.bash

でビルドします。プロキシの配下にいると、HTTP関係のテストで失敗してインストールできません。悲しいです。http_proxyなどの環境変数をセットすれば大丈夫なのかもしれませんが、run.bashのmake testをコメントアウトしてインストールします。~/binの下にインストールされます。僕は~/binにPATHが通っているのでその後は何もしなくても大丈夫。

で、インストールの説明ページにあるサンプルを動かします。6gとか6lとかうーむ。6gがコンパイラで6lがリンカーなのですね。うまくいけば6.outができていてちゃんと動きます。

Pascalのような、Pythonのような変な気分です。会社のうさみみがメーリスを始めたので、興味ある人はどうぞ。ちなみに、プロジェクトページのドキュメントは全部訳すと息巻いているようです。

2009年11月11日

jQuery派とクロージャ派

クロージャは、最近一部で盛り上がっている言語のお話じゃなくって、Googleが先日公開したクロージャライブラリの方です。

社内ではjQuery派とクロージャ派、およびどちらの勢力にも属さない3つの勢力に分かれています。どちらにも属さない日和見主義な人たちは無視しましょう。クロージャ派の言い分は、jQueryのコアライブラリは独特すぎてついていけないというものです。foreachとかの使い方をみても、独特です。さらに、uiライブラリが貧弱というものです。現在提供されているものは両手で数えられるぐらいしかないので、他のライブラリを見れば見劣りします。

jQuery派は、まあ、いろいろ考えてはいるようですが、純粋に技術的なことに関して言えば、GoogleのUIはシンプルすぎるとか、たくさん機能があるけど、今すぐ必要なものがないだとか、あげくに、IEじゃ動かないでしょ!とかいいだします。大体が言いがかりです。そして、技術的な議論をしたいのに「だって、Google嫌いだもん。結局Microsoftみたいなもんでしょ」と。

今会社で一番必要としていたのはUIライブラリなので、どうがんばってみたところでjQueryは不利です。 でも、jQuery派の人はクロージャに宗旨替えをしようとしていたのですが、話の成り行きからそれができなくなって頑なになっています。さて、どうなるでしょう?



2009年11月10日

アリエルにはボーナスがないという噂

来月はボーナス月です。アリエルには伝統的にボーナスがないです。業績分はともかく、基本的にボーナスって言うのは年俸を18でわって3を掛けたものを6月と12月にまとめて払う仕組みです。3じゃなくって、もう少し少なかったり多かったりする会社もありますが、そこは誤差です。会社がよほど業績が悪くない限り、ボーナスはもらえるはずです。

アリエルができた時から給料は年俸制でした。 年俸を12でわったものを毎月もらうか、18で割ってボーナス月に多くもらうか、自分で決めろと言われました。これは、人によって選択できるようにしようと、当時の社長は考えていたらしいですが、すぐにめんどくさくなって12で割ったものになりました。計算がしやすいように年俸も12できれいに割り切れる値になっていました。

さてさて、僕は選択を迫られた一人ですが、ひょっとしたら僕しか選択を迫られなかったかもしれません。結局、僕のせいで12でわるというのが残ったのかもしれません。で、12でわった方がいいというのは、できて間もない会社だったので、いつつぶれるかわかりません。ボーナスは前払いではなく、後払いです。先延ばしにして、もらえるはずの時に資金がショートしてもらえないと悲しいです。もらえるときにもらっておくのが吉です。という打算的な理由がありました。

なので、同じ年俸でもボーナスがある会社よりも一月の給料は多いです。

で、ボーナスがないと書きましたが、業績がよければ期末にボーナス(と言うかよく分かりませんが・・・)があります。これは業績と評価によって決まりますが、このおかげで、実際の年収は多分、他の会社よりは高いかもしれません。 業績分を社員に還元しているいい会社なのですが、他の人がボーナス月で浮かれているときには何もないので、寂しいと言えば寂しいのかもしれません。僕はなれてしまっているのであまり感じませんが、先日社員の人にちらっと言われました。でも、この仕組みをちゃんと理解していなかったようですが・・・。

さて、今は当時と違って会社がなくなるかもしれないという危機感は必要なくなりましたが、 会社ができた時はそんな感じだったというお話でした。



2009年11月9日

VirtualBoxにUbuntu 9.10を入れてMacっぽくした結果



Macっぽくした時の証拠画像。左上のGNOMEのアイコンはUbuntu Tweakだと変えられるみたいなことが書いてあるけど、変えられないです。オリジナルの画像をりんごに差し替えればいけますが、そこまでは僕はしません。

globalmenuは最新版じゃないとEclipseとかFirefoxが起動時に落っこちちゃうことがあるので注意が必要です。

それから、Ubuntu 9.04だと起動の画面やログイン画面などもMacっぽくなっていましたが、9.10だとそうなってくれません。滅多にログインするものでもないので、頑張りません。

2009年11月6日

VirtualBoxにUbuntu 9.10を入れてMacっぽくする

会社ではQuad CoreのマシンでVirtualBoxが動いています。そこにUbuntu 9.10をインストールしました。インストール直後にログインすると3Dのエフェクトが少しだけかかっています。ただ、エフェクトがかかるととても遅くなるので、3Dエフェクトは諦めます。VM上のことだから仕方ないのかもしれません。

さて、会社ではDual Monitorで使っていて、片方の画面はVirtualBoxをフルスクリーンで使っています。フルスクリーンだとVMで動いている感じがしなくていいです。さらにUbuntuの見た目をMacっぽくすると、一部の人は騙されおもしろいです。なので、カルマなコアラの9.10をMacっぽくします。昔と違って、かなり手順が簡略化されています。
まず、Mac4Linのサイトから最新版のMac4Linをダウンロードします。現在は、Mac4Lin_v1.0.tar.gzです。ついでにpdfがあって、そこにちゃんとした英語のドキュメントがあります。

ダウンロード後、解凍して
cd Mac4Lin_Install_v1.0/
./Mac4Lin_Install_v1.0.sh
と実行します。何か聞いてきたら「y」を入力して、パスワードを聞かれたらパスワードを入力します。次に、awn関係のパッケージをインストールします。とりあえず、こんな感じ
sudo apt-get install awn-applets-c-core awn-applets-c-extras awn-applets-python-core awn-applets-python-extras awn-manager
これで、下のパネル入らなくなったので、思いきって削除します。そして、アプリケーションのアクセサリのAvant Window Navigatorを機動します。下の方にドックが出現するので、右クリックして設定を開きます。ログイン時にAwnを自動起動するにチェックを入れて、あとは、お好きなように。
次に、壁紙をMacっぽいものに変えます。ホームディレクトリにMac4Lin_v1.0と言うフォルダがあるので、その中のWallpapersの中にわりとそれっぽい壁紙があります。また、別のところから落としてくるのもありかな。

Macと言えば、メニューはウィンドウの中ではなく、上のパネルの中です。これをやらないと意味がないです。まずは、ここにあるように最新版のglobalmenuをインストールします。Synapticマネージャを開いて設定のリポジトリを選択します。他のソフトウェアのタブに移動して追加で次の行を追加します。
deb http://ppa.launchpad.net/towolf/ppa/ubuntu karmic main
再読み込みしてからgnome-globalmenuをインストールします。まずは、上のパネルの左の方にあるメニューとかFirefoxのアイコンとかをことごとく消しちゃいます。そして、メイン・メニューのアイコンを追加。それから、Global Menu Panel Appletを追加します。それからPreferenceからGeneral Settingのタブにあるチェックをすべてつけて閉じます。Gnomeのアプリケーションのメニューはパネルの中に表示されます。これで、人を騙せます。

それからGnomeのアイコンは変えられるはずなんですが、変わってくれません。それはまた。

2009年10月31日

プロセス改善と感情のコントロール その2

アリエルの開発はとてもモチベーションが高い集団です。僕が普通の会社と考えているようなところでは、仕事でしかコードを書かず、仕事に関係なくコードを書く人はごくわずかです。アリエルとか、それ以外の変な会社は、仕事に関係なくコードを書く変態ばかりが集まっています。たまに普通の人も混じっていますが・・・。普通の会社と変態集団では、そのマネージメントって全く違います。と言っても、普通の会社の実態は知らないのですが。変態集団は何も言わなくても勝手にやるので、向かう方向を指し示すことと、歩みが遅い人の背中を押してあげるだけでいいです。それ以外のことは大体分かっているので、変に押しつけても効果がないです。また、変態達は個性が強いので、個別対応が必要です。人によって背中の押し方を変えないといけません。この辺が難しいところかもしれません。簡単に言えば、プロ意識とか、競争意識とかをくすぐるとか、絶対的な高みを見せつけるとか。プロ意識とか競争意識をくすぐるのは僕のやり方で、まあ、他にもいろいろやったりします。絶対的な高みを見せつけるのは開発部長のやり方でした。僕はそこまですごくはないので、くすぐったりするやり方しかできません。

やり方自体はいろいろあるのですが、多分、それは教えない方がいいと信じています。僕は基本的にモチベーションをコントロールしようとしていますが、目的なくまねるだけまねても多分うまくいかないかな。と言うのを最近見ました。本人はまねているつもりはなかったかもしれませんが。 

まあ、このエントリは特定の一人に対して書いていますが、直接言うのが恥ずかしいので、ブログに書いています。 



2009年10月30日

ubuntu 9.10をインストール

ubuntu 9.10がリリースされて他ので、さっそくMacのParallelsにインストールします。で、いきなり、ダウンロードしたisoイメージで起動できません。ここらへんの情報によると、ubuntuの画面がでたら、F6を押してacpi=offを選択してから起動すればよいらしい。それで、大丈夫でした。

なんとなーくParallelsよりVirtaulBoxの方がLinuxには優しい気がする。

プロセス改善と感情のコントロール その1

先日ミーティングがありました。ミーティングって、昔は嫌いでした。今でも嫌いですが、昔ほどではありません。楽しいミーティングは技術的な話とかだったんですが、最近はもうちょっと別の楽しみ方もしています。

先日のミーティングがおもしろかったのは、片方があるプロジェクトのプロセス改善の話をしていて、もう一方がそのプロジェクトに関わる人たちの期待値とかモチベーションのコントロールをしようとしていて、その進め方が全くかみ合っていなかったからです。まあ、目的地は同じなんですが・・・。

プロセス改善の話は、どちらかと言えば理路整然としていてとても正しそうに見えます。多分、本当に正しいのでしょう。一方のモチベーションのコントロールとかは、あまりにも人間的で泥臭いです。話は分かるけど・・・。

僕はプロセスがどんなに改善されても、モチベーションがうまくコントロールされなければ、結局はプロジェクトは失敗すると思っています。つまり、モチベーションをうまくコントロールした上でのプロセス改善でなければ意味がないです。ただ、プロセス改善の場合、具体的なアクションが見えやすいせいで、本当に改善されていっている錯覚を持ちやすいです。まあ、上の人に報告するときも、「これこれをやります」 と、「モチベーションをコントロールして、やる気をだしてもらいます」じゃ、前者の方がちゃんとしているように見えますね。



2009年10月27日

楽しく仕事をする

最初に入った会社はいい意味でも、悪い意味でも影響力が大きいです。僕は新入社員としてロータスに入りましたが、そのときよく言われていたのが「楽しく仕事をする」と言うことでした。「3つのXXX」とか言われていた何かがあったような気もしますが、これしか覚えていないです。僕はこの考え方が好きで、今でもことあるごとに思い出します。仕事をしていると、「それは無理でしょう?」とか、「おかしいでしょう?」見たいこともありますが、玉砕することもありますが大体笑いながら何とかしています。何で大変そうになると分かっているのに楽しそうか聞かれることがありますが、それはMだからです。楽しそうにしていないとやってられないというのもありますが。

さて、僕の知り合いの知り合い(遠いなー)がとある会社に入ることになって、その会社のカリスマ社長(新入社員には人気があるらしい)に「忙しいけど、その分成長できる」と言っていたらしいです。他の職種は知りませんが、開発者にとっては忙しさと成長は全くの別物です。アリエルの開発部長は、ロータスにいるときはとても暇そうにしていました。むしろ、本当の基礎力がないまま、忙しさのために目の前の仕事だけに忙殺されて泥のように働けば、数年で衰退してしまいます。

成長できるかどうかって、最初は本人次第だと思っていました。でも、今振り返ってみると環境の方が大きいかもしれません。ライバルと思える人がいたり、勉強会みたいなのが自生していたり、追いつけないと思える先輩がいたり(この辺は想像)、 自分の知らないことや知らない世界を知っている人がいたり、そうした環境が人を成長させるんじゃないかと。そうしたところであれば、楽しく仕事ができます。

あまり環境のよくないところでも、何人かはすごい人はいます。でも、全体としては普通になってしまっています。最近は勉強会などもたくさんあるので、そうしたところからの横のつながりで個人の環境を変えることもできます。そう考えるとやっぱり本人次第なのかもしれません。



2009年10月22日

Vaio Xを見てiMacが欲しくなる

会社帰りにVaio Xをみました。軽い‼でも、店頭には SSD128Gのモデルはありません。キーピッチももう少し広いほうが好みです。かなりそそられますが、気持ち 良くキーが打てないものはそのうち使わなくなるので、買うのを思いとどまりました。

ついでに、Appleの変なマウスをさわりに行きました。 予想に反してなかなかいいかも。でっかいiMacをお持ち帰りしたくなります。13kgぐらいなので子供より軽 いです。子供を抱っこできるので、iMacはモバイルマシンです。

でも、東海道線は混んでいるのでがまんしました。



世界は誘惑が一杯で危険です。

見えるものにだまされちゃいけない

下の動画は会社の製品の一部です。音もなくって、何をしているかも分かりませんが、そこは重要じゃなくって動きだけ見てください。マウスで箱を動かすと、ぐりぐり動きます。別の箱の上とか下でマウスを放すと、そこに置かれます。まあ、最近のWebのシステムではこの程度の動きはよくありますが、そこそこ、JavaScriptでコードを書かないといけないと信じていました。でも、それは嘘でした。ぐりぐり動くのは数十行のコードだけでした。線が曲がっていますが、それはあまり大事な機能ではないのですが、そこの計算が20行ぐらいです。無意味な機能の方が、がんばっています。

動きを最初に見たときはすごいと思いました。コードを見たときはだまされたと思いました。楽しい会社です。 

 




2009年10月21日

LL温泉の申し込みが始まっていた


毎年恒例(今年が2年目だけど)のLL温泉の申し込みが油断をしていたら始まっていました。由布院とちょっと遠かったり、金曜から日曜なので平日に少し入り込んでいたりしますが、いろんな人が集まるのでとてもいい刺激になります。とりあえず、こんな感じ。

■■■■■■ LL温泉 2009 大分(湯布院) 開催のお知らせ  ■■■■■■

2009年12月4日(金)から6日(日)、大分県由布市の日本文理 大学湯布院研修所にて「LL温泉 2009」を開催します。初冬の湯布院でおいし いものを食べ,飲み,温泉にもつかりながらLL漬けの3日間を楽しみましょう:-)。
合宿中は,言語のチュートリアルをはじめとした多数 のセッション,ライトニングトークなどを実施する予定です。プログラムの詳細 は,Webサイトに随時アップデートしてゆきます。
参加希望者は以下のフォームに必要事項をご記入の上,お申し込み下さい。

http://ll-onsen.jp/registration

名 称:LL温泉 2009 大分(湯布院)
    http://ll-onsen.jp/
日 時:2009年12月4日(金)~6日(日)
場 所:日本文理大学湯布院研修所(大分県由布市)
参加費:宿泊費,食費,渡航費を含む実費
    宿泊費:一泊3食7,500円(温泉付),渡航費35,000円 
(羽田よりの概算)
主 催:LL温泉 2009 大分(湯布院) 実行委員会

 




Google Friend Connect

一時期ニュースにもなっていたし、atsさんとこについていたので、blogのサイドバーにGoogle Friend Connectを表示するようにしました。でも、これって何なのか、何がうれしいのかよくわかんないんです。さらに、突然やってきた人ならともかく、RSSを登録していれば、記事が全文フィードされるので、ますます、気づきません。

これって、何がうれしいのでしょう?本当にわかんないんです。

今メインで使っているファイルの共有サービス

普通の人は大体PCを複数台持っていて、複数のPCでデータをどう共有するかは、悩みの種です。以前は、自分でサーバーを持っていたので、そこでSubversionのサーバーを動かして、ファイル共有兼バージョン管理していました。しかし、悲しいことに次々とサーバーが壊れていって使えなくなってしまいました。

バージョン管理は今はMercurialを使っています。この人を使って、がんばって共有すれば、サーバいらずで何とかできるかもしれませんが、やっぱり、ネットワークというか、インターネット越しでデータのやりとりをしたいです。しかも、自分一人で他人になるべく見られないように・・・。

で、自宅も持ち運び用にもMacを使っていて、WindowsとかLinuxはバーチャルマシンの中にいるので、基本的にMacでなんとかなればいいです。Mobile Meのサービスは買っているので、Mobile Meのファイル共有を使っていました。でも、この人、お馬鹿さんです。時々、というか、わりとしょっちゅう同期してくれないことがあります。さらに、遅いです。でも、容量は20Gぐらいあるので、最終的なバックアップ先になっています。

で、通常使っているサービスがDropboxです。 使い始めてかなりたちますが、とても満足いくものです。ただ、数Gしか使えないので、気をつけないとすぐに一杯になります。まあ、僕はソースコードとかプレゼンの資料とかをずっと保存しておいて(mercurialのpush先なんだけど)、あとは、一時的に写真とかを受け渡しするだけなので、工夫すれば大丈夫なんですが。お金をだせば、容量が増えますが、そこまでしなくてもいいなあー。まあ、数Gが無料で使えるって、すてきな世の中になりました。

Mobile Meはパスワードとかも同期してくれるので、こっちも捨てがたい・・・。 



2009年10月15日

Lucene2.9

そういえば先月末、Lucene 2.9がリリースされていました。会社の製品でLuceneを使っているのですが、ハイライト関係で2.9が使いたかったのですが、製品のリリースタイミングとうまく合わず、残念でした。9月上旬の予定だったので、ちょっと遅れたのですね。残念です。

まあ、HyperEstraierに最近ちょっと嫌気がさしているせいかもしれません。でも、僕のMacでPyLuceneがうまくビルドできないのが痛い・・・

WebアプリケーションのiPhone対応

リリース前の製品の機能をあんまり外に言ってはいけないことになっているので、あくまで、社内の研究成果と言うことで。

夏が始まる頃、とあるマネージャから自称21才のハッカー君に指令がありました。「夏が終わるまでに、このWebアプリケーションをiPhoneでかっこよく見えるようにしておいて。これは研究目的なので、営業などの開発以外の人には絶対に見せちゃだめよ」と。でも、開発している姿を後ろから見られたり、とあるマネージャがうれしそうに他の人に見せていたので、公然の秘密でした。

さて、実質2ヶ月か3ヶ月しかありません。PC用の画面がすでに大量にあります。スクラッチから書いても、今のものを対応させてもいいという指令です。最終成果はとあるマネージャが満足することという、なんだかよく分からない強権を発動しています。その成果を技術的にまとめたのがこれです。実際に作業した結果のドキュメントなので、読む価値はありますが、長いです。成果物もとあるマネージャは満足しているので、おおむね成功です。まあ、この成果を踏まえて製品としての扱いをどうするかはこれからです。

 今回はiPhoneでどうなるかということを検証しました。でも、ガジェット大好きなとあるマネージャは、まだ野望を抱いているようです。次は会社でブラックベリーとAndroidを買って対応させようと画策しています。それから、Windows Mobileの端末も必要だと息巻いています。でも、困ったことは、開発してくれる人がいないのです。ハッカー君は、学校に戻ってしまいました。ガジェット好きにはおもしろいかもしれないですね。 



2009年10月14日

サイクロンの掃除機買った

先週末は、掃除をしようとすると掃除機が動きません。電源をいれても反応がないのでたたくと一瞬だけ「ぶー」と最後の断末魔を発した後に沈黙しました。もともと、東京に引っ越してきた時に8000円ぐらいで買ったもので、もう、十数年使っているので寿命でしょう。

壊れたものはしかたないので、近所の電気屋さんに掃除機を買いに行きました。dysonの掃除機を見ましたが、8万円ぐらいしてあえなく断念しました。dysonはサイクロンとか言うかっこよさそうな仕組みで紙パックがいりません。子供が見ている仮面ライダーでも、サイクロンとかよく聞くので、きっとサイクロンはすごいに違いない、ということで、dysonじゃないサイクロンを選びます。といっても、どれも同じに見えるので安そうなやつ(シャープのやつ)を店員に勧められるまま買いました。

とりあえず、前の掃除機よりゴミが一杯たまっていいです。子供がゴミをためようと掃除機をかけてくれます。 






2009年10月6日

LL温泉は今年もあります

もうすぐ冬です。冬と言えば温泉です。そして、LLという名目の元、今年も温泉にまった〜りすべく、LL温泉が湯布院であります。今年は12月4日〜6日と、師走で何かと忙しい時期ですが、温泉にはちょうどいい季節です。宿泊先には露天風呂もあり、紅葉(湯布院の紅葉の季節知らない。去年はいい感じだったと思う)していればすてきな景色です。由布院駅の前には馬車もいるし。

 東京から隔離された地にLLの名の下にこいー(笑)面々が集まるだけでも刺激的だと思います。こいー面々は、一緒の場所に押し込んだだけで濃いーことを話したり、したりします。

また、自分の好きな言語以外の人がいると、違った文化に触れられて、それもおもしろさの一つです。去年はRubyの人はうるさく騒いでいました。Pythonの人たちは、蛇のようにひっそりとしていました。PHPの人たちは、もくもくと勉強していました。Perlの人たちは、好き勝手なことをやっていました。Emacsの人たちは・・・。思い出せない。 

ちょっと遠いですが、ゆふいんの森に乗りたいとか、ホーバー(つい先日つぶれた)とかに乗りたいと、よこしまなことを考えなければ、去年は5万円かかりませんでした(全部こみで4〜5万円ぐらいだと思う)。5万円を高いとみるか、妥当な値段と見るかは、人それぞれだと思いますが、僕は十分その価値があると思います。



2009年10月2日

マルチスケジューラとプロジェクトAを統合 - AirOneプロジェクトAの全機能を無料で提供 -

「ありえるえりあ」でも書いていますが、「マルチスケジューラとプロジェクトAを統合 - AirOneプロジェクトAの全機能を無料で提供 - 」ということになりました。まあ、販売終了とうことですね。ただ、販売しないと言うだけで、今後も普通に使えるし、バージョンアップもします。多分、売り物としてはなかなか入れられなかった機能とか、実験的な機能もどんどん入っておもしろくなるはず。まあ、かなり前から研究目的という位置づけだったので、無料になったこと以外大きな方針の転換もないんですが。

それから、このニュース、見つけるのがめちゃくちゃ大変。アリエルのホームページのトップにもないし・・・。アリエルはマーケティングできる人がいないなー、と思う今日この頃。

ソースを公開しないのか?って時々質問されますが、今のところ考えていません。ソースを公開するのはかなりめんどい、大変な作業なので・・・。

基盤的な部分は、技術的にはとってもおもしろい製品です。でわでわ



2009年10月1日

Tornadoのデータベース周りのブロックについて

まじめなお話じゃないです。イベントドリブンでシングルスレッドで処理すると、Webアプリだとデータベースの入出力あたりでブロックします。データベースのアプリケーションサーバ間は大体がネットワークでつながっていて、TCP/IPでお話ししています。で、Twistedにしろ、Tornadoにしろ、ネットワークでやるんだったらノンブロッキングでできそうですが、そうなっていません。また、データベース周りで遅くなることが結構あるので、このあたりがノンブロッキングになっているとよさそうに見えます。
さて、Twistedはシングルスレッドでノンブロッキングで動いているように見せかけておきながら、裏ではこっそりスレッドで動いています。まあ、PythonのデータベースのAPIにあわせる(ドライバーをそのままつけるようにする)とそうなっちゃうのはしかたないのですが、データベースのAPIを使わずにノンブロッキングでごりごり、専用のドライバーを書いちゃう猛者がいるとおもしろいなー。どこかで聞いたような気もするけど、とりあえず、TornadoかTwsitedで・・・。ちなみに、Twistedでデータベースの非同期を触ったら、とーってもめんどくさー、だった。完全に非同期でやる人って、あたまおかしいか、天才だ。

それから、Twsitedは完全にすべて非同期でやろうとしているんじゃなくって(しているところもあるけど)、インターフェースを統一して、すべてを同じように扱えるようにしているところがすごいんだな。まあ、やり過ぎのところもありそうだけど・・・

2009年9月30日

ホーバーがなくなる!?

大分ホーバーが会社清算へ 負債5億、不況で利用者減」。去年乗っといてよかった!でも、ドリフトしたり、海の上に出たりした最初の5分ぐらいしかうれしくはなかったけど・・・。

第一回五反田でEmacsをネタにピザを食べる会終わった

今日はアリエル主催の第一回五反田でEmacsをネタにピザを食べる会、略して(もしくは通称)五反田Emacs勉強会でした。アリエルができて8年か9年たちましたが、このような形で勉強会を開いたのは初めてなのです。ハートビートさんの会社のように、ある程度、勉強会を定期的にやっていきたいと思っています。一応、次回もEmacsで勉強会を11月ぐらいにやるつもりです。

それから、多分、今後も勉強会のあとはピザを振る舞えるはずです。社長に適当に意義や趣旨を吹き込んだら、そのぐらいは会社で出せることになっています。でも、会場がアリエルの社内じゃないので、お酒が出せません。

で、勉強会は多分、数え間違えていなければ26人ぐらいきていました。他の勉強会に比べて平均年齢が少し高めです。Emacsなのでしかたないのかもしれません。

最初はアリエルの井上さんのお話でした。まあ、挨拶みたいなもの?で、うーん、笑いをとろうとしている気持ちは伝わってくるのですが、何というか・・・。まあ、それも個性です。

そのあと、菅原さんのanythingについての説明でした。Software Designの連載でanythingを取り上げていたのですが、それをあまり前提にしすぎなかった方がよかったかもしれません。その辺は失敗なんですが、それでもなぜかそこそこ盛り上がった、もしくは楽しんでもらえたので、結果はよかったでしょう。それに雑誌の内容を補完したいということもあったので、目的の設定をもう少し変えた方がいいのかも。ちなみに、記事の延長線上というのは僕の思惑です。

それから、すがわらさんが謙遜していますが、彼はnavi2ch(昔ぼくも使っていた)の作者です。今はプロジェクトに関わっていないようですが・・・。なので、とってもすごい人なのです。ちなみに彼が今日、会社に来たのは17:00ぐらいです。

僕にとっては初めてのEmacsの勉強会なので、どんな人たちがあつまるのかどきどきでした。

さて、次回はまたEmacsなんですが、その次に変な言語特集、もしくはできたてほやほやの言語特集みたいなのもやってみたいなー。 



2009年9月28日

Tornadoってシングルスレッドのままなのかな?

前回は、パフォーマンスにちょっと疑問があるって書きました。で、その解決として、Tornadoのプロセスをたくさん立ち上げるのかなー、と夢想しました。でも、プロセスをたくさん立ち上げると、管理が大変です。でも、その辺は自動化すれば何とかなるかもしれません。で、プロセスやスレッドのスイッチングコストは無視するとして、プロセスでやる場合、メモリの使用量はどうなるんでしょう?まあ、数十のプロセスなら問題ないし、現状のアプリも数十個か数百個のスレッドでしかほとんど動いていないので、プロセスモデルで数十か数百のプロセスを作っても、問題なのかもしれません。まあ、プロセスはスレッドを作るよりさらにメモリを食うのですが、そこそこのサーバを使えば心配いらないのかも。

で、結局、Tornadoってロングポーリングに特化したWebアプリケーションサーバにしかならないんじゃないの?というのが今のところの僕の印象。結局、WSGIのアプリケーションを動かすにはC10K問題を解決していないんじゃないかなー。で、ほとんどのアプリがその恩恵にあやかれないので、現状はapache + mod_wsgi(現在のインフラを変える必要はないと言うこと)とかで十分かと。

2009年9月26日

キャッシュカードのICが壊れた


連休に突入するとキャッシュカードのICが壊れていることが判明しました。ATMにカードを入れてお金をおろそうとすると、「ICが壊れている」と怒られて引き出せません。連休中は他の家族は実家に帰省していて僕一人の独身生活です。で、そのとき財布の中には1000円しかありません。とりあえず、銀行に電話すると、「ICが壊れているか銀行の窓口で確認してください」と。 それから、「他のATMの機械でやれば?」とも。機械は2,3台試したし、ATMが壊れていると言っているんだから壊れているのです。確認するまでもないです。でも、どうしてもお金がおろしたいのでどうすればいいか聞くと、「IC非対応のATMでおろしてください」と。けれども、近くの銀行には非対応のATMは一台もいません。どこにそんなATMがあるか聞いてみると、「探してください。銀行に行けばあるところもあります」。僕の近所の銀行にはそんなところはないし、藤沢に昔あった気もするが、昔の話です。結局、連休中は見つかりませんでした。

連休が終わって銀行に行って再発行の手続きをしました。そのとき、「再発行するまでキャッシュカードは使いますか?」と。いや、使えないからここにいるんですけど・・・。で、「使いたくても使えない」と訴えると、「それではキャッシュカードを回収させていただきます」 。えっ?このカードってクレジットカードも一緒になっているので、回収されると困るんです。すると、「しばらくお待ちください」と言って奥の方でなにやら話し込んでいます。数分後、戻ってくると、「それでは手続きは終わりました。3週間ぐらいで届きます」。うーん、不便だ。




2009年9月25日

インフルエンザと運動会

僕の直接知っている人はまだだれも感染していないので実感がないのですが、インフルエンザは結構はやっているみたいです。アリエルの社長の子供の小学校では一部、学級閉鎖しているらしいです。それでも、ちょっと遠くの世界だと思っていましたが、自分の子供の通っている小学校でも学級閉鎖があるらしいです。連休は運動会があるはずでしたが、学級閉鎖しているクラスがあったので、一週間運動会が延期されました。一週間でなんとかなるかは微妙のような気もします。僕は運動会が嫌い(つまらない)なので、どうせなら中止すればとも思ってしまいます。ちなみに、去年は途中で雨が降ってきて、午前中で終わりました。

 保育園では、玄関のところでアルコール消毒(これはインフルエンザがはやり始めるといつもやっている)できるようになっていますが、さらに子供がいる部屋に大人がはいれません。入り口のところで、荷物を保育士さんにあずけます。最初は面倒になるし、そこまでする必要性を感じませんでしたが、実は面倒になるのは保育士さんだけで親は準備しなくていいので楽です。まあ、保育園で感染するとその親たちはみんな仕事にいけなくなるので、保育園も大変です。 

さて、インフルエンザは遠い世界だと思っていましたが、思ったより近くにもいたようです。子供が3人いるので、早く予防接種を受けさせたいですが、いつになるんでしょう? 



2009年9月24日

Tornadoの最初の印象

今噂のTornadoを少し触ってみました。と言っても、ホームページのHello, worldのサンプルを動かすぐらいですが・・・。

で、Hello, worldを見て、「雰囲気がTwistedに似ている」というのが最初の印象です。まあ、Tornadoを作った人たちは最初はTwistedを使おうとしていたらしいので、似ていて当然かもしれません。URLのディスパッチはRoutっぽいです。うーん、Railsっぽいです。TwistedやZopeみたいにURL Traversalするとコストがかかるので、賢明な選択かもしれません。

パフォーマンスがいいと言う評判だったので、自分で計測したかったのですが、めんどくさくなたので、やめました。mopemopeさんのお仕事(多分これ)です。生のデータしかのっていないので、よく分かりません。
パフォーマンスに関するTornadoのドキュメントを見るとすごそうです。でも、これって、Hello, worldでベンチマークしたものです。あまりにも処理が少なすぎます。実質HTTPのハンドリングする時間だけです。Hello, Worldのハンドラーが処理する時間ってほとんどありません。そうなってくると、他のフレームワークが培ってきたものはかえってあだになります。新しいものはそれだけコード量が少ないし・・・。それから、Tornadoはepollを使おうが、なんでもいいですが、シングルスレッドで動いています。で、handlerが少し重い処理をしたら、全体がとまります。他のフレームワークがスレッドなりで効率化しようとしていますが、Tornadoは(少なくとも現状は)無理です。まあ、ロングポーリングするようなところには向いているので、適用分野がちがうのかもしれません。でも、そうなら、ページに載っているベンチマークってあんまり意味がないような・・・。
で、多分、そんな風に思った理由がwsgiのコンテナとして機能するからかもしれません。wsgiのコンテナとして使うのなら、非同期IOのメリットが受けられれないTornadoは不利というか、向いていません。wsgiアプリがmultiprocessingとか、スレッドとかで動いていると思ったら、ここもすべてシングルスレッドで動いていました。まあ、そのうち、プロセスなりスレッドなりで動作するのかもしれません。それとも、プロセスをもっと立ち上げろと言うこと?まあ、少なくとも、ベンチマークの結果は気にしちゃいけない、もしくは自分のアプリで計測しろ、ということでしょう。

Python界ではWebアプリケーションと言えばWSGIばかりです。Twistedのにおいは感じますが、それでも別の仕組みのフレームワークが出てきたことはやっぱり楽しいです。でも、それを使うかどうかはちょっと微妙。多分、しばらくはウォッチすると思いますが・・・。それから、みんな騒ぎすぎ。というか、ほめすぎ。もしくは僕が否定的すぎ。でも、好きな子ほどいじめるので仕方ないです。

IEなんていなくなればいい

IEは困ったちゃんで、いつもいろいろ手を焼きます。パフォーマンスが問題になるときは、別のブラウザにすれば一桁パフォーマンスが上がるのに・・・、と思うこともあります。なので、会社でGeckoをIEのActiveXプラグインで使えないかなー、とまじめに計画を立てようとしたこともあります。

GoogleがWebの問題児Internet Explorer対策を発表: IEをChromeにしてしまう」。これ、いいですね。エンジンが違いますが、同じことを考えている人がいるみたいです。

2009年9月19日

InfoTalkでお話ししました

昨日、一時間ばかしInfoTalkでPythonのTwisted Frameworkで非同期プログラミンという内容でお話をしてきました。申し込みが開催の一週間前からで、人が集まるのかどきどきしていましたが、たくさん人がいました。

僕の話はプログラミングの話題で、しかも小難しいことが多いので、ほとんどの人が興味がないじゃ ないかと思っていました。寝ちゃっている人もいましたが、思った以上にちゃんと聞こうとしている人が多くてびっくりです。まあ、そのあとの懇親会でわかんなかったという人も結構いました。負け惜しみじゃなくって、思惑通りです。

日本人は奥ゆかしいので、多分、本人の前では悪いことは 言わないと思いますが、自分のしゃべっていることを冷静にみると、論理展開が矛盾してたり、はしょりすぎだろう?というところがたくさんありました。やっぱり、準備不足です。それでも楽しんでもらえる人には楽しんでもらえたのでよかったかな。それと、笑いをとるところはとれたので、そこは成功です。 

それから、大勢の前でしゃべるのって、かなり久しぶりのような気がします。まあ、緊張するとかっていうのはそれほどないのですが、時間配分がいまいちだったかもしれません。 

 次回はロボットのお話とC++のお話です。ロボットはガンダム世代にとってはとても興味があります。実際に手に触れるもの、っていうのはやっぱりおもしろいです。それから、C++。自分ではもう、よほどのことがない限りC++のコードは書かないと思いますが、C++のお話を聞くのは楽しいです。C++知らない人でも、プログラマーなら自分が知らない世界があって、わかんなくてもいいから、それを知ることができるって、とっても重要だと思うんです。なので、おもしろそう。



そういえばInfoTalkでおしゃべりします

書くのをすっかり忘れていましたが、今日の7時から、InfoTalkでTwistedについてお話しします。アナウンスが遅い?ごめんなさいごめんなさい。

どこかで僕がTwistedについて話しているのを聞いたことがある人であれば、それの焼き直しなので、安心?してください。 

 でわでわ 



2009年9月14日

PythonのWebサーバのベンチマーク

基本的にPythonベースのフレームワークとJavaのScalaで作ったもののベンチマークみたいです。これはTwistedは遅いとみるべきなのか、汎用化されたものは専用のものより遅いとみるべきなのか、fapws3は速いとみるべきなのか、PythonじゃJava(+Scala)に対抗できないとみるべきなのか・・・?

実際に自分でベンチマークしたことがないですが、感覚的なものとあっているので、納得できたりする。

2009年9月10日

第一回五反田Emacs勉強会 定員増やしました

第一回五反田Emacs勉強会ですが、会場を200mか300mずらして確保できたので、定員を増やしました。まだ、空きがあるので、興味のある人はどうぞ。

2009年9月9日

SIMBLがSnow Leopardに対応しつつある件

Snow LeopardになってSafariのプラグインたちが軒並み使えなくなって、理由がSIMBLが対応していなかったからです。SIMBLのサイトをみると、まだベータ版ですが、そこそこ動いているみたいです。やっぱりプラグイン自体はコンパイルし直さないといけないみたいですが、コンパイルし直せばだいたい動くらしいです。

でも、SafariStandは対応してくれるんでしょうか?ちょっと不便な生活です。 



社内勉強会の光景 その1

アリエルでは社内勉強会が定期的にあります。今後は勉強会の内容も「ありえるえりあ」で公開していきますが、その勉強会は自称20代の人たちが自発的に始めたもの(少なくとも表向きは)です。いろいろ試行錯誤していい感じになってきたので、それを社外にもアウトプットしようということになったようです。やっている内容は、Scalaとか、テスト手法とか、ツールの紹介とか、いろいろあります。以前はAndroidのお話とかが公開されたりしました。

アウトプットするのは、単に社内でためておくだけじゃもったいないし、あまり文書を書いたりしないのでその練習にもちょうどいいからです。それから、アリエルの開発の人は、単に仕事をしていればいいというわけじゃなくって、社外への情報発信というオブジェクションもあって、それは評価対象になります。でも、いきなりそんなこと言われても中々できません。特に、最近は人も増えてきて、アリエルができた時の文化とは少し違ってきています。それを取り戻すためにもちょうどいいです。

とかいいつつ、勉強会は一週間か二週間に一度あるので、お楽しみに。多分、一番楽しみにしているのは僕なのかもしれません。がんばって続けてほしいです。 



2009年9月7日

第一回五反田Emacs勉強会

第一回五反田Emacs勉強会が9/29にあります。Emacsを愛している人、Emacsを愛したい人、Emacsを愛していた人、Emacsと物別れをしてしまった人たちへの勉強会です。

とりあえず、第二回までは計画しています。二回目は来月か11月ぐらいで、もうちょっと大きな場所を借りる予定です。

それから、誤解がないように言っておくとアリエルの開発者すべての人がEmacsを使っている訳ではないです。僕のおとなりさんはvi使いです。僕の前の人はかたくなにEclipseを使い続けています。



Yahoo!JapanとGyaoが仲良くなると・・・

Yahoo!JapanとGyaoが仲良くなるとMacでも動画が見れるようになるのか!Silverlightは偉い。

2009年9月3日

Snow Leopardは本当に速くなったのか?(体感的に)

Snow LeopardはWeb上のレビューを読んでいると速くなったとよく書いています。特にMac Book Airを使っている人たちが感じているのかもしれません。僕はというと・・・。アルミになったMacBookで2.4GのC2Dで4Gのメモリですが、あんまりスピードが速くなったとは感じません。言われてみると速くなった気がしてきますが・・・。ただ、遅くはなっていないようです。

さて、ソフトウェアを会社で作っていますが、会社のソフトのパフォーマンスを計測すると、バージョンを上げれば以前に比べて30%速くなったり、50%速くなったりしています。地道に改善されています。ある程度までは一気に速くできますが、そこから先は小手先ではどうにもならなかったりします。そのなかで、30%速くなるだけでもすごいんですが、その程度のスピードアップだと体感的には変わらなかったり、言われてみると速くなっているかも、という違いしかありません。もっと悲しいことは、IE6で使っているのをやめて、Chromeなり、FireFoxなり、Safariにすれば劇的に速くなることです。せめてIE8とか・・・。それを知っていると、IE6のサポートは打ち切りたいです。なんだか、むなしい。

で、Snow Leopardも速くなったかもしれないけど、そんなに体感できるほどじゃないなー、という印象です。 



2009年9月1日

ParallelsでUbuntu9.04が動いたじょー

Parallelsがいつのまにか更新されていたので、アップデートしました。理由は、Snow Leopardにしたら遅くて使い物にならなくて、アップデートのチェックをしただけです。それで、更新するとParallelsの中のWindowsがまあ、遅すぎることはない程度に動くようになりました(微妙な言い回し)。

アップデートをしたので、今までParallels ToolsがインストールできなかったUbuntu 9.04にもう一度試してみました。今回はちゃんとイントールが終了して、画面のリサイズとかマウスの操作とか、まあ、まともっぽくなりました。めでたしめでたし。これで、あまり使わなくなっていたUbuntuも使えそうです。ただ、まともっぽくなっただけで、Ubuntuを全画面表示にしたときとか、なんだか動作が怪しいときがあります。1280x800にならずにそのふた周り小さいサイズを引き延ばしたような感じ。何回か画面サイズを変更するとちゃんとなったりするので、使えなくはないんですが、微妙です。

とりあえず、Ubuntuがうごいちゃったので、Virtual Boxに移行しようかと思っていたのはとりあえず見送ることにしました。まあ、Windwosのイメージを変換するのが面倒なだけなんですが・・・。多分、Virtual BoxにParallelsのイメージをインポートする機能があれば、Virtual Boxに移行していると思います。

2009年8月29日

Snow Leopardとイーモバイル(D31HW)

Snow Leopardにしてから、ふと、イーモバイルのD31HWをさしてネットに繋ごうとすると、あれ?動きません。D31HWは今は、イーモバイル付属のソフトではネットにつながらないので、ダイヤルアップで使っています。こっちの方がデバイスの認識が速かったりするので、USBデバイスをさしても付属のソフトが勝手に立ち上がらないようにするにはどうすればいいのでしょう?

さて、イーモバイルがちゃんと動作しないので、困ったなー、と思ってモデムの設定をみると、Leopardのときとどこか設定が変わっちゃっています。 製造元がHなんとかだったような気がするのですが、いません。とりあえず、製造元を「一般」、機種を「Dialup Device」、ダイアルを「トーン」にするとちゃんとつながりました。

なんだか、ドライバがいなくなっちゃったのか?まあ、動くからいいです。 



2009年8月27日

今作っているもの




今作っているも。こんな感じ。うーん、まだ、単なるGoogle Readerのクライアントで、画像は適当にダウンロードしてきたもの。基本的な機能ができたので、次に自分が欲しい機能を作って行くのかな。多分、Macでしか動かない・・・。

自分の欲しい機能
  • いらない広告は消す
  • 本文全体をとってきてほしい
  • 未読が沢山ありすぎると、似たエントリをまとめて一つにしちゃいたい。
  • Goolge Readerの英語版にあるSend Toとかが欲しい。と言うかGoogle Readerでできることは大体できるようにしたいけど、欲しい機能はStarだけかも。
  • 検索機能を忘れているよ。
  • オフラインでも、なんとかしたいなー。
それから、アプリケーションにアイコンをつけるのはどうやればいいのだろう?

Komodo Editのプラグインが消えた

Komodo Editを閉じて立ち上げなすと自分でインストールしたプラグインたちがどこかに言ってしまわれました。そしてかえってきませんでした。設定もなくなっていました。仕方ないので、プラグインをインストールし直しました。でも、Komodoのプラグインはもともと数が多くないし、どうしても必要なのって二つぐらいしかないので、まあ、あまりいたくありません。設定もそれほど変更していないし・・・

でも、悲しいです。

2009年8月20日

PyHyperEstraier 0.10.10

送られてきたパッチをあてて行って、いつの間にか、PyHyperEstraier0.10.10になりました。0.10.9はどこにもアナウンスしていなかったかもしれません。

0.10.10で、文字列をdecodeするときに'replace'のフラグを追加したのですが、なぜ、これが必要かは僕はよくわかりません。アナウンスを忘れたかもしれない0.10.9ではスニペットに空行があるとパーサがエラーを起こすのを直しています。

でわでわ。

今日のおやつ

2009年8月18日

wxのTreeCtrlのSetImageListとAssignImageList

wxでTreeCtrlの各アイテムに画像をセットするにはSetItemImageを使います。SetItemImageを使うときにはあらかじめTreeCtrlにイメージのリストを登録しておいて、そのリストのインデックスで指定します。イメージのリストはwx.ImageListを使います。この人のAddでビットマップのオブジェクトを指定すれば、よい訳です。

ImageListはTreeCtrlにSetImageListでセットすると信じ込んでいました。でも、これだとSetItemImageをしたりするとBus Errorが発生して動きません。なので、SetImageListじゃなくって、AssignImageListを使わないといけません。紛らわしい。SetImageListの意味がよくわかりません。SetImageListを使う場合、

tree = TreeCtrl(...)
tree.SetImageList(imageList)
tree.imageList = imageList

とかすれば動きます。ますます、SetImageListの意味が分かりません。
動きそうなサンプルは自分で書くのは面倒なので、これ。あれ?ドメイン名にjavaとかって入っているぞ!

2009年8月14日

2009年8月10日

wxのsplitter

wxのSplitterWindowでwx.3Dでボーダーを設定しています。なんだか、Macだと見た目がかっこわるいです。もう少しかっこ良くならないのかな?っていうか、Styleに何をしていしても同じように見えます。悲しいです。ボーダーが太すぎるのです。イモトの眉毛かもしれません。

夏休み中

でも、雨だ・・・。子供が飛び跳ねている。

2009年8月9日

wx.HtmlWindow使えない・・・

お盆休みなので、子供をじじばばに預けて遊んでいます。さて、wxWidgetsでHTMLをレンダリングするのにwx.HtmlWindowがいます。このひとを使おうと思ったのですが、簡単なHTMLなら大丈夫だと信じていたのですが、いまいち。レンダリングは(とっても)変です。それは我慢します。でも、とっても遅いです。さらに困ったことは、ページ遷移せいても、前のページやそのページが持っている画像がロードされるまで次のページをロードしようとしてくれないことです。そして、Macのマウスカーソルがクルクル状態(なんて言うのか知りません)になります。悲しいです。

で、wx.WebKitという人もいます。ヘルプには「wx.webkit.WebKitCtrl for Mac OSX」とか書かれていてMacでしか使えないようです。本当か?で、この人を使うと快適です。さすがWebKitと言いたいところですが、やっぱりwx.HtmlWindowがダメすぎです。

そんなこんなで、WebKitを使うことに・・・。でも、今作っているのはNetBookで使いたかったんだけどな。まあ、いいや。Geckoも使えたような気がするので、そっちを探そう。

2009年8月6日

アプリケーションが終わらない・・・

TwsitedとwxPythonの組み合わせですが、メニューから終了するときにreactor.stop()してもと待てくれないことがあります。wxreactorはスレッドを自前で作っていたような気がするので、どっちかのスレッドがちゃんと終わらないようです。常にじゃないんですが・・・。Macだからかもしれません。仕方ないので、sys.exit()。凶悪だ・・・!

2009年8月2日

iDiskは遅いけど、とっても遅い訳ではなかった

iDiskが遅いと文句をたれていましたが、それはプロキシ越しにアクセスしていたからっぽい。直接コネクションをはれるところだと、遅いことは遅いけど、めちゃくちゃ遅い訳ではなかった。なので、同期をとるときはプロキシを経由しなければそれほど、ストレスを感じなくてすみそうです。

でも、やっぱりデータの同期はUSBメモリ経由でいいかな?と思う今日この頃。

2009年7月17日

今日のランチ

ロッテリアの絶妙ハンバーガー

iDiskは遅かった

Mercurialのレポジトリをバックアップ目的でMobileMeのiDiskにおきました。僕のリポジトリは全体で22Mありますが、hg cloneに一時間ぐらいかかりました。思っていたより遅いです。

まあ、たまに気が向いたときにpushするだけなので、pushを開始したら寝ればいいだけです。ふっふっふ。

2009年7月15日

iDiskはマウントされていたのか・・・

以前はSubversionを使って個人のデータをバージョン管理していました。複数のPCがあったので、サーバで一元管理していました。これはこれで便利なんだったんですが、悲しいことにサーバは次々と壊れ、ついにはいなくなってしまいました。とりあえず、ローカルでバージョン管理していたのですが、その場合

  1. 複数のPCで共有できない
  2. バックアップがない
と、悲しいです。なんとかできないかなー、と思って調べると、この記事によると、MobileMeのiDiskはマウントされていて、Mercurialで普通にpushとかpullできるらしいです。つまりは、

hg clone myrepos /Volume/MobileMeのID/myrepos
これで、かなりの不満が解消できます。クライアントがMacじゃない場合は、どこかのMacのリポジトリと同期をとればいいし、大丈夫そうです。ただ、iDiskがめちゃくちゃ遅いけど、それは我慢。

ついでに、Mercurialのインストールは

$ sudo easy_install mercurial

で、コンソールで使えますが、MacMercurialでグラフィカルな画面で使ってみます。うーん、やっぱ、コマンドでいいかも。


2009年7月14日

IE7の機能、すごい。

IE7のリリースノートによると、

Internet Explorer 7 と OWA (Outlook Web Access) -- ユーザーが Outlook Web Access サーバーからログアウトすると、同じ Internet Explorer ウィンドウ内の他のタブで開いている、Cookie を使用してログオン セッションを確立する他のサイトからログアウトする場合があります。

すげー。何やっているんだ?

2009年7月2日

2009年6月23日

MSのすてきなセキュリティ向上手法

MSのIE8ですが、httpsのサイトの中にiframeとかでhttpのサイトが表示すると、セキュリティの警告がでます。警告が出ること自体はIE6や7など昔からある機能です。でも、IE8の警告は以前のものとはちょっと違います。

セキュリティで保護されたWebページコンテンツのみを表示しますか?
と聞かれて「はい」「いいえ」の選択肢があります。IE6や7は似たようなメッセージがでて「はい」を押すと表示されました。無意識にIE8でも「はい」を押しても何も表示されません。以前はセキュリティで保護されていないページも表示するか聞いてきていて、IE8からはセキュリティで保護されたページだけを表示するか聞いてきて、微妙に変わっています。

あまり、「いいえ」をおすことはないので、セキュリティの向上させるためにいい手かも知れません。でも、ほとんどの人がこんな微妙な表現の違いは認識できないような・・・。僕は一時間ぐらいかかりました。

2009年6月17日

結局、Emacsを隠れて使っている・・・

Emacsの悪口を言い回っていて、自分は使っていないふりをしています。でも、こっそり使ってしまいます。Javaのコードを書くときはEclipse以外ありえないのですが、Pythonのコードを書くときはKomodo Editを使います。この人はなかなか気に入っています。でも、この人、プロジェクト内のファイルならアクセスしやすいのですが、参照するというか、フレームワークのコードを読むというときにはちょっと不便です。テキストエディタとしてCotEditorをつかっていますが、これは日本語の書き物をしたり、ちょっと読むときに使うだけです。沢山のファイルを一気に開いて読むというのには使いにくいです。

そして、沢山のファイルを開いてコードを読んだりするのが、結局昔使っていたEmacsになっちゃったりします。使うときは見つからないようにしていますが。Emacsって、すくなくともファイルを開くのが他のエディタより簡単で、しかもキーボードから手を離さなくてもいいのがいいです。ただ、昔と違ってEmacsでコードを書いたり、デバッグしたりということはほとんどなくなりました。

2009年6月11日

iPhone OS 3.0のGM

数ヶ月前に会社の同僚をそそのかして、iPhone OS 3.0のβ版を入れさせていました。β版じゃなくってGM(Gold Master)版がでたので、早速入れてもらいました。GMだと、まだ、テザリングが使えているらしいです。僕は臆病者なので、普通に手に入るまでまちますが、テザリングは本当は使えるんでしょうか?使えるんだったら新しいiPhoneにしてもいいかな。

wxWidgetsでTwisted

Twistedという非同期IOフレームワークは恐ろしいことにselect/pollだけじゃなくって、Window sのイベントループで処理したり、それ以外のGUIのフレームワークのイベントモデルを使ったりできます。簡単に言うとGUIとの親和性が高いフレームワークです。でも、実際にWindowsのイベントルールを使ったことはありましたが、wxWidgetsを初めて使いました。どきどき。

コード自体は単純で、

from wx import wx
from twisted.internet import wxreactor
wxreactor.install()
from twisted.internet import reactor

class MyApp(wx.App):
いろいろ

app = MyApp(0)
reactor.registerWxApp(app)
reactor.run()

見たいで動きます。wx.MainLoop()は使わないんですね。さて、これで、メニューの終了とかでアプリケーションを終了させるためにFrame.Close()を呼んでもreactor.stop()を呼んでも終わってくれません。遠い彼方の記憶によると、wxのreactorはこっそり別のスレッドで動いているとかだったような気もしたので、reactor.callLater(0, reactor.stop)として、コールバックを登録してそのコールバックの中でreactorを止めるようにしたらちゃんと動き増した。なるほどです。

2009年6月5日

wxGladeは・・・

wxGladeを使ってみました。GUIで、配置・設定できるウィジェットの数が少ないです。まあ、必要最小限のものはそろっていますが。GUIでぺたぺた貼付けて、ぽちぽち設定をして、とりあえず、Pythonのコードを生成しました。動かない・・・。なんだか、途中で間違って設定したものの状態を覚えているようです。なおりません。しかたないので、生成した方のコードを直せば動きます。あたりまえか。それ以外にもwxGlade落ちるし・・。

wxFormBuilderというのがいて、この人もwxGladeみたいなことができます。こっちの方がUIはすっきりしていて好きです。また、サポートしているウィジェットの数も多いです。でも、こっちはPythonのコードは生成できません。C++だけです。

wxWidgetsでXMLの情報からGUIを構築できたような気がしたので、調べてみるとXRCというのがそのフォーマットらしいです。wxPythonからも使えます。PythonのコードをwxGladeで生成しても、結構見にくいし、GUIを変更したらソースコードも上書きされちゃたりするし、メンテナンス性がわるいです。なので、ここはXRCでいきます。ふふん。そうすれば、ソースコードはロジックに専念できるし、グラフィカルなものはXMLに追いやって、メンテナンスはGUIでごにょごにょできます。便利そうです。
なので、それでいきます。ちなみに、XRCはwxGladeもwxFormBuilderでも生成できます。

2009年6月4日

2009年6月3日

pyOpenSSLをMacに入れた

うしみつどきにいじっていたらpyOenSSLがMacにインストールされていないことが発覚しました。自分でビルドするのがめんどうなお年頃なので、Googleさまにお伺いをたてて(pyOpenSSL + Mac)みると、ここにお告げがありました。

なので、sudo python setup.py installでインストールして使ってみようとすると/usr/local/ssh/libにlibcryptoとlibsslがないとお怒りになります。この人たちはsite-packageのOpenSSLの下にいます。配置場所を間違っている・・・。しかたないので、自分でビルドした方がいいのかなー、と思いつつ、シンボリックリンクをはって動きました。うー。

ひとりごと

twistedベースのAPIのラッパーでけた。APIでの結果が今は文字列のままなので、それをパースして、オブジェクトにしてあげるのをやる。APIのラッパーよりそっちの方が大変そう。もしくは、feedparserに食わせちゃうか。あと、XMLパーサにくわせるか。

それが終わったら、データベースに保存してあげる。SQLAlchemy使えばとりあえずはいいか?SQLObjectでもいいけど。

それが終わればwxだ。wxGladeつかえば、簡単にUIつくれるんだったかな?


2009年6月1日

wxWidgetsをダウンロードした

久しぶりにwxWidgetsをダウンロードししました。正確にはwxPythonです。もう少し正確にはMac版です。さらに正確には、unicode版です。wxQTを使おうかと思ったのですが、新しいものを覚えるより過去の知識(まあ忘れてしまいましたが)がいかせた方がいいかも、とか、思ったりする訳です。まさに、おじさん化です。だめですね。

さて、インストールをして準備ができたので、とあるものを作ります。全く意味不明です。
でわでわ。

2009年5月29日

ログを監視してメールを送る

とある事情により、ログファイルを監視して指定した条件にマッチするとメールを送る簡単なスクリプトを書いてみました。スクリプトはここ
$ python tomarun.py ログファイルへのパス 正規表現 SMTPサーバ
送り先メールアドレス メールのタイトル

とこんな感じ。タイトルとかが日本語だと見事に化けますぜ、だんな。こんなツール、世の中にたくさんあって、意味ないですぜ。とか。すごーく汎用的に作りたいとか、プラグインでうんちゃらかんちゃらとかの誘惑に負けず・・・。

Vistaでpy2exeで作ったexeが・・・

僕のVistaにはPython2.6が入っています。この環境でpy2exeで作った実行ファイルを、別のWindows XPにもっていって実行すると、「実行できませんでした」と怒られます。でも、僕の手元にあるXPで実行してもちゃんと動きます。
僕のXPに入っているPython2.5でpy2exeで作った実行ファイルを、動かなかったXPに持っていくと動きました。わけわからん。

一度wineを使ったときにVistaのmsvcrt.dllとかだとちゃんと動かなかったりしました。そんなこととかと関係あるんでしょうか?

2009年5月26日

Eucalyptusのセットアップ

Ubuntuの9.04の主要機能の一つにEucalyptus(おれおれAmazon EC2作成ツール)があるので、インストールしました。でも、会社のサーバにインストールしたのですが、eucalyptus-cloudが起動できません。何かがブロックしていて先へ進みません。手元にCentOS 5.3があったので、そこへインストールしたときのメモ。

まず、前提条件としてCentOS5.3がインストールされていること。ここでは最小構成でインストールしています。

1. JDKのインストール
eucalyptusにはjava6が必要なので、インストールします。jdkが必要だと思っていましたがjreでいいようです。http://java.sun.com/ からjreのrpm.binをダウンロードして「sh jre-6u13-linux-i586-rpm.bin」でインストールします。

2. antのインストール
eucalyptusはantを使って起動するというすごいことをしているので、インストールします。「yum install ant-nodeps」でインストールできます。

3. その他一杯インストール
それ以外のものを一杯インストールします。「yum install perl apr apr-devel apr-util rsync bridge-utils dhcp」とします。dhcpやbridge-utilsはeucalyptus-ncにしか必要ないはずなのですが、要求されちゃうので入れておきます。それからXen関係のパッケージも必要になる(これも必要な理由がわからない)ので、次のようにインストールします。「yum groupinstall Virtualization」。余計なものが大量にインストールされましたが、気にしないでおきましょう。

4. eucalyptusのインストール
eucalyptusをインストールします。http://open.eucalyptus.com/downloads から32bit(64bit環境なら64bitのほう)のbinaryでCentOS 5.3のリンクをクリックすると必要なrpmがまとまったアーカイブがダウンロードできます。下のほうは個別にファイルをダウンロードできるようになっていますが、普通は使わないでしょう。ダウンロードが終われば、tgzのファイルを展開して、rpm -Uvhでeucalyptus-nc-1.5.1.i586.rpm以外をインストールします。これで、すべてをコントロールするツールがインストールできます。

5. 起動
/etc/init.dにeucalyptus-cloundとeucalyptus-ccがいるので、この二人を起動してあげます。自動起動できるようにchkconfigで設定しておいてください。

それぞれのデーモンの役割などは、次回。

今日のランチ2

混ぜた後

今日のランチ

陳家私菜の頂天麻婆豆腐

2009年5月21日

Python3に対応させたときのメモ その2

Python3に対応させたときのメモ」の続きです。主にモジュール。

今までは僕は、import hogeのように書いてform hoge import fugaのように書くことはほとんどありませんでした。でも、from hoge import fugaだと、モジュール名が変わってもクラス名や関数名が同じであればコードをそれほど変更せずに対応できるので、便利。

StringIOがモジュールだったのがioモジュールのStringIOになりました。unicodeの文字列を渡すとデフォルトではutf-8でエンコードしてバッファに書き込んでくれます。Python3で、Unicodeと8bit文字列がバイト列として分かれたと宣伝していますが、僕はunicodeとstrの暗黙の変換をutf-8でやってくれればそれでいいと思っていたので、そんなにうれしくはありません。多分、僕がCのプログラマだったからでしょう。

それから、urllibが・・・。urllibとurllib2の二つがあるのは困ったものでした。でも一つになるものめんどいですが、urllibのなかでさらにモジュールに分かれています。例外関係(と言ってもHTTPErrorぐらいですが)はurllib.errorにありました。あとはRequestクラスとurlopen、quoteがurllib.requestに移動されていますが、importさえできればあとはコードの変更なしで動くので、移動先を調べるのが一番大変かな?

それから、base64のencodestringで入力はunicodeになってしまった文字列で返値がバイト列です。バイト列はb'hoge'.decode()のようにdecodeメソッド文字列になってくれます。この辺は、Python2のころとあまり変わりません。

きっとその3に続くはず。

今日のランチ

2009年5月19日

Python 3に対応させたときのメモ

とあるライブラリをPython 3でも動くようにしたときのメモです。

まず、Python 3.xとそれ以前のPythonかの分岐

import sys

def is_python3():
version = sys.version_info[0]
if version < 2:
return false
else:
return true
辞書のキーの一覧をソートする。ちなみに、Python2ではmydict.keys()はlistを返しますが、Python3はdict_keysというクラスのオブジェクトです。このクラスにはsortメソッドがないので、listにします。

l = list(mydict.keys()).sort()
そういえばunicodeでu"hogehoge"と書けないので、uを消して回ります。

例外が・・・

Python3だと、

try:
# some code...
except SomeException as e:
# some code...


のように、asがいる。これ、知らなかったんだけど、 この記述でPython2.6だと動いた。これって、いつからあるんでしょう?手元のCentOSのPython2.4だとなかった。

Python2と3両方で動くコードはやっぱりムリポ。正確には、Python2.5以前とPython3で動くコードかな。。

2009年5月12日

Parallels Updateでも、Ubuntu9.04のサポートは・・・

Parallelsがアップデートされたらしいので、わくわくしながらアップデートしました。
Parallels 4.0だとUbuntu 9.04でXが動かなかったのですが、今回のバージョンではとりあえず動きます。でも、Parallels Toolsのインストール途中(X関連)でエラーで止まっちゃうのは同じです。悲しいです。とりあえず、つけますがいろいろ不便です。

2009年5月8日

[翻訳]Hadoopで動くPythonのMapReduceプログラムを書く

面白かったので、「Writing An Hadoop MapReduce Program In Python」の訳です(久しぶりです)。

HadoopMapReduceプログラムをPythonで書く



このチュートリアルでは、Hadoopの簡単なMapRecudeプログラムをPythonを使って書く方法を説明します。

動機


HadoopフレームワークはJavaで書かれていますが、Hadoop上で動くプログラムはJavaで記述する必要はありません。PythonやC++(バージョン0.14.1以降)のような他の言語で開発することができます。しかし、Hadoopのホームページのドキュメントや最も重要なPythonのサンプルコードを読むと、PythonコードをJythonを使ってJavaのjarファイルに変換しないといけないように考えてしまいます。明らかに、この方法はきわめて不便で、もし、Jythonが提供していないPythonの機能を使っている場合はともて問題です。Jythonのアプローチのもう一つの問題は、Hadoopと連携させてPythonプログラムを書くオーバーヘットです。<HADOOP_INSTALL>/src/examples/python/WordCount.pyを見れば、言っていることがわかると思います。Jythonのアプローチと、Pipeと呼んでいる新しいC++のMapReduce APIのアプローチを少なくとももう一度見てください。その違いはとても興味深いです。

このチュートリアルの目的は、HadoopMapReduceプログラムをもっとPython的なやり方、つまり、おなじみの方法で書くことです。

やりたいこと


これから、Jythonを使ってJavaのjarファイルに変換せずにHadoopで動くPythonの簡単なMapReduceプログラムを書きます。
プログラムはWordCountのサンプルコードをまねて作ります。つまり、テキストファイルを読み込んで、単語の出現頻度を数えます。入力はテキストファイルで出力もテキストファイルです。出力するテキストファイルの各行は、単語と出現回数をタブ文字で区切って記述します。

注釈: このチュートリアルに書かれているテクニックを使えば、PerlやRubyなどのPython以外のプログラミング言語を使うこともできます。 「舞台裏でおこっていること」も書いているので、間違いがあれば教えてください。


準備


Hadoopのクラスタをセットアップして起動しておいてください。この文書ではHadoopのセットアップと起動方法は説明しません。Hadoopクラスタがない場合は、次のチュートリアルが構築するための手助けになるでしょう。チュートリアルはUbuntu向けに書かれていますが、他のLinux/Unix環境でも使えるでしょう。


PythonのMapReduceコード


次のPythonコードのトリックは、HadoopStreaming(wikiのエントリを見てください)を使ってMapとReduceのプログラム間PでSTDIN(標準入力)とSTDOUT(標準出力)を介してデータを受け渡しています。単純にPythonのsys.stdinから入力データを読み込んで、sys.stdoutに出力データを書き込んでいます。
他のことはHadoopStreamingが面倒を見てくれるので、やるべきことは以上です。不思議ですか?まあ、少なくとも、私もびっくりでした。

Map: mapper.py


次のコードを/home/hadoop/mapper.pyに保存してください。このプログラムはSTDIN(ヒョジュン入力)からデータを著見込んで、単語に分割します。そして、STDOUT(標準出力)に単語の出現回数(中間データ)を記述した行(複数行)を出力します。Mapスクリプトは単語の出現頻度の合計(中間データ)は計算しません。かわりに、入力途中に「<word>」が複数回出現しても「<word> 1」とすぐに出力します。そして、次に続くReduceが最終的な合計を計算します。もちろん、すきなようにプログラムの振る舞いを変えることができますが、説明するためにこのチュートリアルではそのままにしています。


#!/usr/bin/env python
 
import sys
 
# input comes from STDIN (standard input)
for line in sys.stdin:
    # 行頭と行末の空白を取り除く
    line = line.strip()
    # 行を単語に分割する
    words = line.split()
    # カウンターを上げる
    for word in words:
        # STDOUT (標準出力)に結果を書き込む;
        # ここで出力したものはReduce(つまりrecuder.py)での
        # 入力になる
        #
        # タブ文字での分割; 単語の出現回数は 1
        print '%s\t%s' % (word, 1)


Reduce: reducer.py


次のコードを/home/hadoop/reducer.pyに保存してください。このコードはmapper.pyの結果をSTDIN(標準入力)から読み込んで、書く単語の出現回数を合計して結果をSTDOUT(標準出力)に出力します。
ファイルは実行権限があることを確認してください(chmod +x /home/hadoop/reducer.pyを実行すれば実行権限をつけられます)。実行権限がないと、問題が発生します。


#!/usr/bin/env python
 
from operator import itemgetter
import sys
 
# 単語の出現回数のマップ
word2count = {}
 
# 入力はSTDIN
for line in sys.stdin:
    # 行頭と行末の空白文字を除去
    line = line.strip()
 
    # mapper.pyの出力をパースする
    word, count = line.split('\t', 1)
    # 回数を文字列から数字に変換
    try:
        count = int(count)
        word2count[word] = word2count.get(word, 0) + count
    except ValueError:
        # 回数が数字でなければ
        # こっそり、この行はなかったことにして捨て去る
        pass
 
# 単語をアスキーソートする
#
# この処理は必要ないが、オフィシャルHadoopの単語の
# カウントサンプルコードの最終出力に似せるために行う。
sorted_word2count = sorted(word2count.items(), key=itemgetter(0))
 
# STDOUT (標準出力)に結果を書き込む
for word, count in sorted_word2count:
    print '%s\t%s'% (word, count)
    

コードをテストする (cat data | map | sort | reduce)


MapRecudeジョブでテストする前に手動てmapper.pyとreducer.pyをテストすることをお進めします。そうでなければ、問題なく終了するかもしれませんが、ジョブの結果のデータが全く出力されなかったり、期待した結果が得られないかもしれません。もし、失敗したらあなたか私が何か間違ったせいでしょう。
ここではMapとReduceスクリプトの機能テスト法のいくつかのアイデアがあります。

 # きわめて基本的なテスト
 hadoop@ubuntu:~$ echo "foo foo quux labs foo bar quux" | /home/hadoop/mapper.py
 foo     1
 foo     1
 quux    1
 labs    1
 foo     1
 bar     1
 quux    1  

 hadoop@ubuntu:~$ echo "foo foo quux labs foo bar quux" | /home/hadoop/mapper.py | sort | /home/hadoop/reducer.py
 bar     1
 foo     3
 labs    1
 quux    2
 # ebookの一つをテスト入力にする
 # (ebooksの入手方法は下記参照)
 hadoop@ubuntu:~$ cat /tmp/gutenberg/20417-8.txt | /home/hadoop/mapper.py
 The     1
 Project 1
 Gutenberg       1
 EBook   1
 of      1
 [...] 
 (わかった?)


HadoopでPythonコードを実行する


サンプルの入力データのダウンロード


サンプルとしてプロジェクトグッテンバーグの3つのebookを使います。


3つのebookをus-asciiエンコードでテキストファイルとしてダウンロードして、/tmp/gutenbergディレクトリなどの一時ディレクトリに解凍して保存してください。

 hadoop@ubuntu:~$ ls -l /tmp/gutenberg/
 total 3592
 -rw-r--r-- 1 hadoop hadoop  674425 2007-01-22 12:56 20417-8.txt
 -rw-r--r-- 1 hadoop hadoop 1423808 2006-08-03 16:36 7ldvc10.txt
 -rw-r--r-- 1 hadoop hadoop 1561677 2004-11-26 09:48 ulyss12.txt
 hadoop@ubuntu:~$

HDFSにローカルのサンプルデータをコピー


実際のMapReduceジョブを実行する前に、ローカルのファイルシステムからHadoopHDFSにファイルをコピーします。

 hadoop@ubuntu:/usr/local/hadoop$ bin/hadoop dfs -copyFromLocal /tmp/gutenberg gutenberg
 hadoop@ubuntu:/usr/local/hadoop$ bin/hadoop dfs -ls
 Found 1 items
 /user/hadoop/gutenberg  <dir>
 hadoop@ubuntu:/usr/local/hadoop$ bin/hadoop dfs -ls gutenberg
 Found 3 items
 /user/hadoop/gutenberg/20417-8.txt      <r 1>   674425
 /user/hadoop/gutenberg/7ldvc10.txt      <r 1>   1423808
 /user/hadoop/gutenberg/ulyss12.txt      <r 1>   1561677

MapReduceジョブの実行


準備ができたので、PythonのMapReduceジョブをHadoopクラスタ上で実行できるようになりました。既に述べたように、HadoopStreamingを使ってMapとReduceコード間をSTDIN(標準入力)とSTDOUT(標準出力)を介してデータを受け渡します。

 hadoop@ubuntu:/usr/local/hadoop$ bin/hadoop jar contrib/streaming/hadoop-0.19.1-streaming.jar -mapper /home/hadoop/mapper.py -reducer /home/hadoop/reducer.py -input gutenberg/* -output gutenberg-output


もし、Reduceタスクの数を増やすなどHadoopの設定を変更したい場合は、-jobconfオプションを使えます。

 hadoop@ubuntu:/usr/local/hadoop$ bin/hadoop jar contrib/streaming/hadoop-0.19.1-streaming.jar -jobconf mapred.reduce.tasks=16 -mapper ...


mapred.map.tasksの重要事項: Hadoopはmapred.map.tasksでヒントを検討しないようになっています。ユーザが指定したmapred.reduce.tasksを使用しますが、それらを変更することはしません。mapred.map.tasksを指定できませんが、mapred.reduce.taskは指定できます。


ジョブはHDFSgutenbergディレクトリからすべてのファイルを読み込んで処理し

上記のコマンドのコンソールでの出力例:

 hadoop@ubuntu:/usr/local/hadoop$ bin/hadoop jar contrib/streaming/hadoop-0.19.1-streaming.jar -mapper /home/hadoop/mapper.py -reducer /home/hadoop/reducer.py -input gutenberg/* -output gutenberg-output
 additionalConfSpec_:null
 null=@@@userJobConfProps_.get(stream.shipped.hadoopstreaming
 packageJobJar: [/usr/local/hadoop-datastore/hadoop-hadoop/hadoop-unjar54543/]
 [] /tmp/streamjob54544.jar tmpDir=null
 [...] INFO mapred.FileInputFormat: Total input paths to process : 7
 [...] INFO streaming.StreamJob: getLocalDirs(): [/usr/local/hadoop-datastore/hadoop-hadoop/mapred/local]
 [...] INFO streaming.StreamJob: Running job: job_200803031615_0021
 [...]
 [...] INFO streaming.StreamJob:  map 0%  reduce 0%
 [...] INFO streaming.StreamJob:  map 43%  reduce 0%
 [...] INFO streaming.StreamJob:  map 86%  reduce 0%
 [...] INFO streaming.StreamJob:  map 100%  reduce 0%
 [...] INFO streaming.StreamJob:  map 100%  reduce 33%
 [...] INFO streaming.StreamJob:  map 100%  reduce 70%
 [...] INFO streaming.StreamJob:  map 100%  reduce 77%
 [...] INFO streaming.StreamJob:  map 100%  reduce 100%
 [...] INFO streaming.StreamJob: Job complete: job_200803031615_0021
 [...] INFO streaming.StreamJob: Output: gutenberg-output  hadoop@ubuntu:/usr/local/hadoop$ 


上の出力からわかるように、Hadoopは統計と情報表示用に基本的なWebインターフェースを提供しています。Hadoopクラスタを実行時にhttp://localhost:50050/にブラウザでアクセスしてください。次の画像は、ジョブを実行後のHadoopのWebインターフェースのスクリーンショットです。

 

HDFSgutenberg-outputディレクトリに結果が正しく保存されているか確認してください:

 hadoop@ubuntu:/usr/local/hadoop$ bin/hadoop dfs -ls gutenberg-output
 Found 1 items
 /user/hadoop/gutenberg-output/part-00000     <r 1>   903193  2007-09-21 13:00
 hadoop@ubuntu:/usr/local/hadoop$ 
You can then inspect the contents of the file with the dfs -cat command:
 hadoop@ubuntu:/usr/local/hadoop$ bin/hadoop dfs -cat gutenberg-output/part-00000
 "(Lo)cra"       1
 "1490   1
 "1498," 1
 "35"    1
 "40,"   1
 "A      2
 "AS-IS".        2
 "A_     1
 "Absoluti       1
 [...]
 hadoop@ubuntu:/usr/local/hadoop$

この出力では、単語がクウォート(")で囲まれています。これは、Hadoopが挿入したものではありません。これらの単語は、Pythonコードが単語に分割した結果で、この場合は、ebookテキストの引用の開始部分です。自分でpart-00000ファイルを調べてみてください。


Pythonのイテレータとジェネレータを使ったMapperとReducerのコードの改善


上のMapperとReducerのサンプルコードは、初めてのMapReduceアプリケーションの書き方を説明しました。この記事の目的は、コードを簡潔に、Pythonの初心者でもわかりやすくすることです。しかし、実世界のアプリケーションではPythonのイテレータとジェネレータ(PDFでのもっとよい紹介記事)を使ってコードを最適化したいです。
一般的に、イテレータとジェネレータ(例えばPythonのyield文を使って、イテレータを作成するための機能)は、実際に必要になるまで配列の要素を作成しない利点があります。これは、タスクによっては計算時間の短縮やメモり効率改善につながります。

注意: 次のMapとReduceスクリプトはHadoop上で(MapReduceジョブのMappterとReducerとして)動作させたときだけ、正しく動作します。つまり、いくつかの機能はHadoopの機能に依存しているため、もう、「cat DATA | ./mapper.py | sort | ./reducer.py」を実行してテストできないことになります。

正確には、同じ単語が("foo"など)が連続して複数回現れたときだけ、("foo", 4)のように単語の出現回数の合計を計算します。大抵の場合、Hadoopが単純なPythonスクリプトより効率的にできるように、HadoopにMapとReduce間で(キー, バリュー)のペアにグルーピングさせます。

mapper.py


#!/usr/bin/env python
"""Pythonのイテレータとジェネレータを使った、より進んだMapper。"""
 
import sys
 
def read_input(file):
    for line in file:
        # 行を単語に分割
        yield line.split()
 
def main(separator='\t'):
    # 入力はSTDIN(標準入力)
    data = read_input(sys.stdin)
    for words in data:
        # 結果をSTDOUT(標準出力)に書き込む;
        # ここでの出力はReduceでの入力になる(reducer.pyの入力)
        #
        # タブ文字での分割; 単語の出現回数は 1
        for word in words:
            print '%s%s%d' % (word, separator, 1)
 
if __name__ == "__main__":
    main()
    
    

reducer.py


#!/usr/bin/env python
"""Pythonのイテレータとジェネレータを使った、より進んだReducer。"""
 
from itertools import groupby
from operator import itemgetter
import sys
 
def read_mapper_output(file, separator='\t'):
    for line in file:
        yield line.rstrip().split(separator, 1)
 
def main(separator='\t'):
    # 入力はSTDIN(標準入力)
    data = read_mapper_output(sys.stdin, separator=separator)
    # 単語ごとに出現回数がグルーピングされ
    # 連続したキーとグループを返すイテレータを作成する:
    #   current_word - 単語を含む文字列 (キー)
    #   group - すべての["<current_word>", "<count>"]アイテムをyieldするイテレータ
    for current_word, group in groupby(data, itemgetter(0)):
        try:
            total_count = sum(int(count) for current_word, count in group)
            print "%s%s%d" % (current_word, separator, total_count)
        except ValueError:
            # count was not a number, so silently discard this item
            pass
 
if __name__ == "__main__":
    main()