mruby advent calendar 2013 ネタです。
コードは github においてあります。
はじめまして、mruby にコミットしてたり(最近はできてない)、
mruby gem を作っていたりする kaishuu0123 です。
なにげに Advent calendar 初参加。ヽ|・ω・|ゞ
はて、advent calendar ネタですが、
Advent calendar は クリスマスまでカウントダウンするカレンダー(だったっけ?)ということで、
mruby 使ってる人たちに何かプレゼントできないかなー、と考えて、
mruby の gem を作って、皆様に使ってもらいたいなー、と思ってます。ヽ( ・∀・)ノ
何か使ってもらえるものないかなーと考えたところ、
mruby でミニマムなシェルが作れるといいなー、と思いました。
今の実装でも、while ループと IO の組み合わせとかで作れますが、
やはり、シェルはオートコンプリートができてなんぼ(`ω´*) というわけで、
libreadline をラッピングした gem を作ってみました。
Mac 上で作っています。Linux でも多分動きますが、BSD は(ry
- readline() 関数で行指向の入力
- 文字列のオートコンプリーション
- エラー処理は無し。とりあえず正常系が動くまで。
- append_character の設定はまだ未サポート(そのうちやるよ!)
あとは自分で書け!
build_config.rb に以下の行を追加すれば、使えます
conf.gem :github => 'kaishuu0123/mruby-readline', :branch => 'master'
こんな感じのスクリプトが動いて、LIST 配列の中にあるワードを tab キーで補完してくれます。
LIST = [
'search', 'download', 'open',
'help', 'history', 'quit',
'url', 'next', 'clear',
'prev', 'past'
].sort
comp = proc { |s| LIST.grep( /^#{s}/ ) }
Readline.completion_append_character = " "
Readline.completion_proc = comp
while line = Readline.readline('> ', true)
p line
end
これだけで終わったら少し寂しいので、実装までの簡単な流れと、困ったところをば。
実装するにあたって、何を調べて、何を考えて作ったのか、 というところをメモしておきます。
- libreadline について調べる
- auto completion をする小さなサンプルを C言語で書いてみる
- mruby の gem を作るためのテンプレートをつくる
- 後は小さいC言語のサンプルを見つつ、gem の作り込みをする
コールバック関数を登録するような API の切り方をしているライブラリだと、mrb_state の引き継ぎ方が悩ましい件
- 基本的に mruby の拡張では、実行がイベントドリブンというより は、きちんと逐次処理だったりするので、 mrb_state という mruby の状態を持つ変数は、 全ての関数上で辿ることができます。ですが、コールバック関数形式だと、 ライブラリ側から呼び出しされたときに、 どの mrb_state を見ればいいのか、という話があります。 なので、readline の場合には、グローバルに mrb_state 変数を持って、 初期化時に渡された mrb のポインタを持ちます。
mrb_state *readline_mrb_state; /* XXX: global variable */
(...)
void
mrb_mruby_readline_gem_init(mrb_state* mrb) { <- 初期化関数
(...)
readline_mrb_state = mrb;
(...)
}
そして、コールバック関数内で再度取得するという
ごまかし ワークアラウンドをしました。~(´ー`~)
/* completion をするためのコールバック関数の中 */
static char
**readline_attempted_completion_function(const char *text, int start, int end) {
mrb_state *mrb = readline_mrb_state;
mrb_value *self = mrb->c->stack;
(...)
}
かなりインスタントではありますが、これで一応動作するため、これでお茶を濁しています。|´ー`)
- mruby advent calendar という記事に参加させてもらえて嬉しいで>す。カレンダーを見ると、mruby という
めちゃくちゃニッチ & マニアック珍しい実装にこれだけの人が集まっているということは、私個人として、正直びっくりしました。 - やっぱり、mruby を拡張したり、言語を安定させたり、ということは凄く楽しいことだと思います。
- あとは、とにかく Lua 並(くらい?)に使えるようになっているか、続けて使ってみていくことが大切だと思います。
Happy mruby gem life! ヽ(*´∀`*)ノ.+゚