AnyEventの良いところを3行で
教えて!と言われたのでそのとき答えた物をここにも記す。
- POE みたいにきもくない
- Danga::Socket とかだと自分で実装しないといけないread queueとかそういうのも面倒見てくれる便利モジュールがある>AnyEvent::Handle
- ドキュメントがアツイ
最後のは主に AnyEvent::Intro のことを言ってますが、これ一通り読めばとりあえず AnyEvent 使えるようになるっていうくらい完璧な内容となっています。
AnyEventとは何かからはじまり、非同期プログラミングの説明からAnyEventを使用したシンプルな例が続き、AnyEvent::Socket や AnyEvent::Handle を使用するのを順々に詳しく説明してくれています。 どうして AnyEvent::Handle みたいな物を使うといいのかというところまで書かれているので、非同期プログラミングやネットワークプログラミングにあまり詳しくない人でも読めるのではないでしょうか。
AnyEvent で $poe_kernel->alias_set 的なことをする方法
最近 AnyEvent にはまっています。おもしろい!
AnyEvent と同じ非同期プログラミングフレームワークであるところの POE では
$kernel->alias_set('hoge');
などとしておくと
$kernel->post( hoge => 'state' );
みたいな感じでどこからでもそのコンポーネントを呼び出すことができました。 しかし AnyEvent ではそう言った機能がないため以下のように Object::Container を使って解決することにしました。
呼び出される側:
use AnyEvent;
use Object::Container 'event';
my $cv = AnyEvent->condvar;
$cv->cb(sub {
my (@args) = $cv->recv;
# ここになんか処理
});
event->register( foo => sub { $cv } );
呼び出す側:
use AnyEvent;
use Object::Container 'event';
event('foo')->send(@args);
Condvarをグローバルなシングルトンコンテナに入れ、それを使って相互にやりとりをするという感じですね。
Object::Container は export する機能がなかったのですが、毎回 Object::Container->get(...) などとかくのがだるかったので import に引数渡すとその名前でコンテナを export する機能をつけました。(0.2以降)
同等のことはいろいろな方法があると思いますが、これが一応今の所の僕の解となってます。参考までに!
さっきのパッチ取り込んでもらった
なんと jesse のプロジェクトだったらしい。パッケージ名でなんか見たことあるなーって思ってたんだけど、気がつかなかったなぁ。世間せまい!
コミット権もらったのでこれからもなんかあったら貢献しよう。
k9mailを日本語環境でただしく使えるようにした
GDP1 で android のメールアプリが Connection error と言うエラーで新しいメールをまったく受信してくれない状態になってしまった。GDDフォンだとこの問題はいまのところ出たことはない。
昔、 brad のブログで k9mail というのを見たのを思い出したのでそれを入れてみたのだが、ヘッダーのエンコード処理がされておらず日本語の件名などをつかうと化け化けになってしまう。
機能的には k9mail のほうが優れていて、このエンコード問題さえ解決できれば使えそうだなーと思ったのでいっちょパッチを書いてみた。
diff --git a/src/com/android/email/mail/internet/MimeHeader.java b/src/com/android/email/mail/internet/MimeHeader.java
index 24aad4d..a117e08 100644
--- a/src/com/android/email/mail/internet/MimeHeader.java
+++ b/src/com/android/email/mail/internet/MimeHeader.java
@@ -11,6 +11,7 @@ import java.util.List;
import com.android.email.Email;
import com.android.email.Utility;
import com.android.email.mail.MessagingException;
+import org.apache.james.mime4j.codec.EncoderUtil;
public class MimeHeader {
/**
@@ -97,12 +98,35 @@ public class MimeHeader {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
for (Field field : mFields) {
if (!Utility.arrayContains(writeOmitFields, field.name)) {
- writer.write(field.name + ": " + field.value + "\r\n");
+ String v = field.value;
+
+ if (hasToBeEncoded(v)) {
+ v = EncoderUtil.encodeEncodedWord(
+ field.value,
+ EncoderUtil.Usage.WORD_ENTITY
+ );
+ }
+
+ writer.write(field.name + ": " + v + "\r\n");
}
}
writer.flush();
}
+ // encode non printable characters except LF/CR codes.
+ public boolean hasToBeEncoded(String text) {
+ for (int i = 0; i < text.length(); i++) {
+ char c = text.charAt(i);
+ if (c < 0x20 || 0x7e < c) { // non printable
+ if (c != 0x0a && c != 0x0d) { // non LF/CR
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
class Field {
String name;
github にもあげた。
この実装がただしいかどうかはわからないけど、これで一応ちゃんとエンコードされるようになる。
ところで、おもしろいのがこのパッチは com.android. なパッケージを編集してしまっていると言うこと。 なんと k9mail は com.android.* のパッケージも含んでいるのである。android のメール機能を持ってきて再利用している。 これはアプリごとにVMが別れてるandroidだからできることなのかなぁとか思ったりした。
エンコードされないとかどう見てもバグなので issue 登録しておいた。パッチは採用されないと思うけどw android のメールではこの問題はおこらないということは com.android.* なところはいじらなくても実現可能ということなので。
Text::MicroTemplate を拡張してみた
最近は Text::MicroTemplate (TMT) をよく利用するようになったのですが、使用するにつれ不満なところが出てきたのでそれを解決するために少し拡張してみました。
実際には拡張したのは Text::MicroTemplate ではなく、Text::MicroTemplate::File です。
http://github.com/typester/text-microtemplate-extended-perl/tree/master
現在二つの機能を追加してあるのでそれを以下にまとめておきます。
テンプレートの継承機能を追加
テンプレートを分割するような規模になってくると現状の TMT では
<?=r $self->render_file('header.mt') ?>
ここにコンテンツ
<?=r $self->render_file('footer.mt') ?>
などのように書くことになりますが、これは TT の wrapper 機能などに慣れていると少しめんどくさい。
追記: TMTでもwrapperはつかえるみたいです。> $mtf->wrapper_fileそこで、TMT でも wrapper 機能をつかえるように!! ・・・しようかと思ったのですがやめて、代わりに Django のテンプレートなどで採用されている継承という仕組みを実装してみました。
詳しい説明は Django のテンプレートのドキュメントがとても詳しいのでそちらを参照するといいと思います。
で、上記の Django ドキュメントにあるテンプレート継承の例をこの拡張版 TMT で書くとどうなるかというと、base.html (base.mt) が
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title><? block title => sub { ?>My amazing site<? } ?></title>
</head>
<body>
<div id="sidebar">
<? block sidebar => sub { ?>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
<? } ?>
</div>
<div id="content">
<? block content => sub {} ?>
</div>
</body>
</html>
child.html (child.mt) は:
? extends 'base'
<? block title => sub { ?>My amazing blog<? } ?>
? block content => sub {
? for my $entry (@$blog_entries) {
<
のようになります。
TT のような wrapper という方式と、このような継承という仕組みはどちらも一長一短ありますが、柔軟にテンプレートを定義できるのは継承の方かなぁと感じてます。
ちなみに Django テンプレートに実装されている block.super 相当の機能はまだ実装できていません。
テンプレートに名前付き引数を渡せる機能を追加
もう一つ、テンプレートに名前付きで値を渡せる機能も追加しました。オブジェクトを作成するときに
Text::MicroTemplate::Extended->new( include_path => ['.'], template_args => { foo => 'bar' } );
などのように template_args パラメータにハッシュリファレンスを渡しておくと、テンプレート中でこのハッシュのキーを
<?= $foo ?> # => bar
と参照することができるようになるという機能です。
SBankNotify for android
android アプリケーションの習作に、iPhone脱獄アプリSBankNotifyを android に移植してみました。
インストールするだけで自動的に機能が有効になります。必要がなくなったらアンインストールしてください。 機能の詳細などは上記の本家SBankNotifyのページを参照ください。
アプリは android マーケットにアップしてあるのでマーケットアプリで「SBankNotify」と検索するとこのアプリが見つかると思いますが、正直めんどくさいのでこのサイトのQRコードを「BarcodeScanner」で読み取ってマーケットのアプリページに飛ぶのが簡単です。
将来気が向いたら設定ダイアログも作ろうと思っています。通知のON/OFFとかその方法の選択とかですね。
というわけで僕的 Hello Android World! でしたが、目的が不明なものを作ってしまった。。。今度はもう少しまともなアプリに挑戦します。
ソースコードは github に置いています。
lighttpd だけで多言語サイトを作る方法
lighttpd 1.4.21 以上では $HTTP["language"] という新しい変数(?)が設定の中で使えるようになり、これを使用するとクライアントの Accept-Language に応じて lighttpd の設定を変えることが可能になります。
これを利用して多言語化しているサイトとしては opensource.kayac.com が有名です。
このサイトは以下のような設定で動作しております。
$HTTP["url"] !~ "^/(?:(?:css|js|img|images?|static|tmp)/|[^/]+\.[^/]+$)" {
$HTTP["url"] !~ "^/(en|ja)(?:$|/)" {
$HTTP["language"] =~ "(en|ja)" {
url.redirect = ( "^/(.*)" => "/%1/$1" )
}
$HTTP["language"] !~ "(en|ja)" {
url.redirect = ( "^/(.*)" => "/en/$1" )
}
}
}
ちょっとややこしいですが、
$HTTP["url"] !~ "^/(?:(?:css|js|img|images?|static|tmp)/|[^/]+\.[^/]+$)" {
で、cssやjsディレクトリ、もしくはルート直下のファイルへのアクセスはそのまま。
$HTTP["url"] !~ "^/(en|ja)(?:$|/)" {
で、すでに /ja/ や /en/ へのリクエストであればそのまま。
上記に該当しなかった場合、
$HTTP["language"] =~ "(en|ja)" {
url.redirect = ( "^/(.*)" => "/%1/$1" )
}
で、Accept-Context が en か ja の場合はそれに応じてリダイレクト先を振り分ける。それ以外の時(対応していない言語の場合)は
$HTTP["language"] !~ "(en|ja)" {
url.redirect = ( "^/(.*)" => "/en/$1" )
}
で、デフォルトの言語(ここではen)にリダイレクトする。
というような感じで動作しております。
このような使い方以外にもさまざまな使い方ができそうですね。覚えておくともしかしたら使えるかもしれません。
.ppkファイルとか渡されて困ったとき
PuTTY 独自の形式の .ppk ファイルで鍵ペアを渡されて困ったときのためにメモ。
PuTTY に付属している puttygen コマンドで普通の公開鍵・秘密鍵に分離できる。
Debian 系なら putty-tools パッケージをインストールするだけでいいらしい(未確認)
OSX だと ports 使うか自分でビルドする。
ぼくは自分でビルドした。
wget http://the.earth.li/~sgtatham/putty/latest/putty-0.60.tar.gz
tar zxvf putty-0.60.tar.gz
cd putty-0.60/macosx
make puttygen
で puttygen だけビルドできる。っていうか全体 make はぼくの環境では失敗した。まぁこれさえビルドできればOK。
秘密鍵を取り出す。
./puttygen unko.ppk -O private-openssh -o private_key
公開鍵
./puttygen unko.ppk -O public-openssh -o public_key
ひさびさ
やっと引っ越し先のネット環境が整ったのでまたここを更新できるようになった。
ネットがない間は自分のメモを Google Cache 経由で読むという謎の状況になっていた。つらい。
カヤックxクックパッド主催 技術者交流会で発表してきた
これ
オーディエンス的にperlの話よりいいと思ったので、もっと概念的な、もっといろいろオープンにしてこうぜ!っていう話をしました。
スライドはこちら
以下感想
ElectricCafe.js 村式 中川さん
js でポリゴン。写真を元にポリゴン化。すごい!
村式と言えば鎌倉小町通り沿いにオフィスを構えたご近所さん。こんなところにこんな変態がいたとは!!(褒め言葉)
また遊びに行かせてください!
イケメンCTOの画像検索、全然出ないし!!! だまされた!
誰かが質問してたけど、特徴点をjsだけで自動で出せたら面白いなー。
プログラミングの【さしすせそ】 kwappa.net 塩谷さん
- 料理
- つくる -> たべる -> おいしい!
- プログラミング
- つくる -> うごかす -> たのしい!
どっちも楽しい。幸せを作る作業 だといっていた。いい言葉ダナー;;
さて、どちらもやはり基礎が大事だよね!
- 料理
- さしすせそ
- プログラミング
- コンピューターサイエンス
というわけで、基礎を勉強するコミュニティをつくったらしい。おわり。えー!
詳細はこちら
Railsメールウェア Cookpad インターン中村さん
Cookpadに「つくれぽ」という機能がある。
レシピを公開してる人に対し、つくってみたよー、とかおいしかったよー、とかいうのを送れる機能らしい(たぶん)。ネーミングセンスいいなー。
で、それを携帯で送れたらいいよね!っていうことになり、インターンの中村さんががんばったよっというお話。
Javaの James を参考に Ruby で同じような物を実装したとのこと。すごいなー。
perl だと qpsmtpd とかみたいなイメージかな。個人的には最近は qpsmtpd で受信してジョブキューにつっこんであとはゆっくりそっちで処理。というパターンをよく使うな。
皮肉なことに James をホストしてる apache.org のメールサーバーは qpsmtpd だったりするのよねー。
というわけで歓談タイムにqpsmtpdをプッシュしまくっておいた。
あと作ったものを公開はしないんですか? と聞いたところ stable になったら公開したい! とのことなので期待。
カヤックxクックパッド イケメンCTO二人 + 技評 馮さんのトークセッション
クックパッド、何をするかを決めるときに何がベストかをすごい慎重に決める。何かをやるための時間を決めたらその 1/3 は計画に使う。
そして驚いたのは、その計画は全員が納得するまでやるといっていたところ。気持ち悪くなると言っていた。
そして計画で決めるのは仕様ではなく指標。ロジックとなる部分。
完璧なロジックには反対できない。
しかしそれでも会議の結論に対して全員が納得できるというのは相当なことだなーと思って、そのためにどういう手法をとっているのか質問した。
3つあるという答え
- 会議の前に共有された3つの前提条件がある
- この3つがそろったものしかやらない
- EOGS (Emotion Oriented Goal Setting)
- ユーザーの欲求をもとにしてゴールを設定するための指標シート
- ロジックツリー (マインドマップ)
- 前述の通り決めるのはロジック
質問したくせに、3つの前提条件の内容を失念してしまったのでググったところ、 ryo_katsuma さんのナイスな記事がひっかかった。
Ruby on Rails セミナーに参加してきました - blog.katsuma.tv
- Bestなことを見つけるまでのの3つの輪
- やりたい(情熱を持ってとりくめること)
- できる(世界で1番になれること)
- やるべきこと(儲かること)
ってことかな?
やっぱり会議前から前提条件をしっかりそろえて会議のコンテキストをそろえること、会議中も正しくゴールに近づけるようなシステムがある。
広げるだけ広げて、収束しない会議ってよくあると思うんだけど、そういう人たちは参考にするといいと思った。僕もここはもう少し掘り下げてみたい。
あと、イベント終了後にすこしお話しさせてもらったときに、「数値化して比較する」っていうことも最近はやってるとおっしゃっていた。どっちの方法が良いのか迷ったときに、効果や費用などすべてを数値化することで客観的に判断できる。なるほど。
まとめ
料理とプログラミングは似ている。
cookpad 面白い会社。