Journal InTime


2010-08-24 (Tue)

_ [Ruby] RubyKaigi2010発表

RubyKaigi2010でBest Imitation of Your Classという発表をする予定だが、裏番組が強力で誰も来ないのではないかという不安があるので宣伝しておく(ここで宣伝して意味あるのか?)。

タイトルはもちろんBen Folds Fiveのファーストアルバムに収録されているBest Imitation of Myselfのパクリである。 Best Imitation of Myselfは、女の子の好みに合わせて見せかけの自分を演じるという女々しい*1曲である。 Best Imitation of Your Classというのは、あなたの望むような見せかけのクラスを提供してあげようという趣旨であるが、要はclassboxを実装してみましたという話。

あんまり書いちゃうとネタバレになっちゃうけど、以下のような話。

  • ついにclassboxを実装した。
  • 文法の変更はなし。
  • 影響はclassboxをimportした(一見)静的なスコープに限定される。

上記のために○○を実装したり、上記の応用で○○を実装したりしたので、それも紹介するつもり。

参加してくれる人は、できれば、T_ICLASSとかcrefとかiseq->klassとかについて予習しておいてください。

*1  「南部訛りをなくすために授業を受けるべきだと思うかい?」なんて歌詞が出てくるくらい。

本日のツッコミ(全6件) [ツッコミを入れる]

_ ささだ [1.9.3 で,iseq->klass とかは消したいなぁ,と思っています.]

_ shugo [たぶん、ささださんが期待する方向じゃないと思うんですが、iseq->klassは使わないようにしました]

_ さく [たぶんそうなんだろうなぁと思ったら、「授業」はやっぱり class なんですね。]

_ shugo [Do you think I should take a class?ですね。「レッスン」くらいの方がよかったかな。]

_ さく [もとが class だと分かると、ダブルミーニングっぽくて面白いなー、と思いました。 ]

_ shugo [なるほど、スライドに入れときます]


2010-03-16 (Tue)

_ [Ruby] メソッドのネスト

Rubyist Hotlinksを読んでて思いついたアイデアをメモ(るびま関係者のみなさん、おつかれさまでした)。

まつもと メソッドの中で def を定義した時に何が定義されるかって言う時に、もしそれがメソッドであるとすれば、どっかのオブジェクトに属してないとダメだよね。で、そのスコープにいる時だけ存在するメソッドって何なんだろうって。

[Rubyist Hotlinks 【第 23 回】 yhara さんより引用]

というまつもとさんの発言を読んで思いついたんだけど、これってselector namespaceが導入されたら、外側のメソッドのスコープだけで有効になる匿名のnamespaceを作って、そこに内側のメソッドを定義すればいいんじゃない?

問題は、selector namespaceをどうするかだけど。

あと、namespaceとそのメソッドが定義されるタイミングがいつか、という問題もあるな。 外側のメソッドが呼び出される度に…というのはちょっといやなので。


2010-02-13 (Sat)

_ [Python] MailmanにFML風のヘッダを追加する

まつもとさんの松江Ruby会議の講演に触発されて、ひさびさにRubyに関係ないコードをハックしてみた。

etchでFMLがなくなっているので、ruby-listなどをMailmanに移行しようと思っているのだが、Mailmanには一つ問題がある。 それは、Pythonで書かれていること…ではなくて、メールに追加されるヘッダフィールドがFMLと違うことだ。

Subjectについては、設定でFML風にできることが確認できたが、X-ML-NameとX-Mail-Countについてはどうやったら追加できるかわからなかった。 X-ML-Nameは「代りにList-Idを見てね」で許されるかもしれないが、X-Mail-Countは、なくなるとbladeなんかで困りそうである。 ruby-talkはSubjectに番号を入れてないので、Subjectから番号を取ることもできない。

そこで、コードを修正できるところがOSSのいいところである。

調べてみると、直接Mailman本体を修正しなくても、Handlersディレクトリ にスクリプトを置いて、設定ファイルを少し書き変えれば拡張できるようだ。

以下のようなファイル(FMLHeaders.py)をHandlersディレクトリに置いて

def process(mlist, msg, msgdata):
    msg['X-ML-Name'] = mlist.internal_name()
    msg['X-Mail-Count'] = "%d" % mlist.post_id

mm_cfg.pyに以下の一行を追加したら見事ヘッダフィールドが追加された。

GLOBAL_PIPELINE.insert(1, 'FMLHeaders')

PythonもMailmanもよくできてますね。


2010-01-20 (Wed)

_ [プログラミング] シェルスクリプトの引数を一部加工して他のコマンドに渡す

シェルスクリプトの引数を一部だけ加工して他のコマンドに渡すには、どうすればいいだろう。

たとえば、UTF-8でパターンを受け取り、EUCのファイルをgrepで検索し、結果をUTF-8で出力するようなシェルスクリプトeucgrepを作りたいとする。

bashだったら配列を使って以下のように書けるようだ。

#!/bin/bash

declare -a options

while expr "$1" : "^-" > /dev/null ; do
    options=("${options[@]}" "$1")
    shift
done 
pattern=`echo $1 | nkf -Wexm0`
shift
grep "${options[@]}" $pattern "$@" | nkf -Ewxm0

POSIXの範囲で同じことを実現できるだろうか。

_ [Ruby] Developers Summit 2010

今年は、「C++0x、Ruby、ECMAScript5 言語の国際標準化について」というパネルディスカッションに参加させていただくことになった。

技術的な話が中心になると思うので、興味がある方はどうぞ。

本日のツッコミ(全2件) [ツッコミを入れる]

_ knu [POSIXの範囲だと配列は一本しかないのできついですね。 語彙が"$@", set -- ..., shift [..]

_ shugo [なるほどー、evalですか。]


2009-12-24 (Thu)

_ [Emacs] Emacsユーザのためのadvice

Emacs Advent Calendar jp: 2009の参加記事。昨日はid:hayamizさん。 明日は他に参加する人がいなければid:authorNariさん。

最近はVimを使うことが多いけど、shiroさんのお話を聞いてやっぱりLispは強力だなあとか思ったりしたので参加してみた。 知ってる人も多いと思うけど、Emacs Lispのadviceという機能を簡単に紹介しよう。

adviceとは、簡単に言うとCLOSのmethod combinationみたいなものだ。あるいは、Railsのbefore/after/aroundフィルタみたいなものと言った方がいいだろうか。要は、既存の関数(正確にはマクロや特殊フォームを含む)の実行の前(before)あるいは後(after)、前後両方(around)で実行したいコードを定義する機能である。

たとえば、以下のコードはGNU Emacs拡張ガイド―Emacs Lispプログラミングに載っている例(だったと思う)で、switch-to-bufferで存在しないバッファ名を指定した時に、新しいバッファを作らないようにするためのものだ。

(defadvice switch-to-buffer (before existing-buffer activate compile)
  "When interactive, switch to existing buffers only,
   unless given a prefix argument."
  (interactive
   (list (read-buffer "Switch to buffer: "
                      (other-buffer)
                      (null current-prefix-arg)))))

簡単に説明すると、defadviceはadviceを定義するためのマクロ(マクロ万歳!)で、defunに似ているがちょっと違う。 switch-to-bufferの部分には拡張対象の関数名を指定し、beforeの部分にはbefore/after/aroundのいずれかを、existing-bufferの部分にはadviceの名前を指定する。activateとcompileはフラグで、それぞれadviceを活性化することと、コンパイルすることを指示している。 詳細はマニュアルなどを参照。

以下の例は、find-fileを拡張して、C-u C-x C-fのようにprefix引数付きで実行した時に明示的にcoding-systemを指定できるようにするもので、標準の機能が見つからなかったので自分で定義して愛用している。

(defadvice find-file (around coding-system activate compile)
  "When a prefix argument given, specify coding-system-for-read."
  (let ((coding-system-for-read
         (if current-prefix-arg
             (read-coding-system "coding system: ")
           coding-system-for-read)))
    ad-do-it))

aroundの場合は、元の関数(この場合はfind-file、正確には自分より内側で実行されるaround adviceも含む)の前後でadviceを実行するわけだが、上記のad-do-itの部分で元の関数が実行される。 この例だとad-do-itの後に何も処理していないのでbeforeでもいいと思われるかもしれないが、letでcoding-system-for-readを束縛する範囲にad-do-itを含めるためにaroundにする必要がある(Emacs Lispはdynamic scopingを採用しているので、letで束縛されたcoding-system-for-readの値は、ad-do-itで呼び出される元のfind-fileからも参照されることに注意)。

というわけで、今日はEmacs Lispのadviceを紹介した。 こういったadviceが色んな人の.emacsに散らかっている(そしてどれもちょっとずつ違う)のが、Emacsの楽しいところであり、やっかいなところでもある。 他人のマシンで作業する時のために、第2母エディタとしてviなども習得しておくことをお勧めする…というのが僕からのEmacsユーザのためのadviceである。