Go to list of users who liked
Share on X(Twitter)
Share on Facebook
More than 5 years have passed since last update.
Emacsに mrubyを組み込んでみました. 以下のようなことができるようになります.
(let((mrb(mruby-init)))(mruby-evalmrb"def fizzbuzz(num) (1..num).map do |n| case when n % 15 == 0 then \"fizzbuzz\" when n % 5 == 0 then \"buzz\" when n % 3 == 0 then \"fizz\" else n end endendfizzbuzz(ARGV[0].to_i)"20))このS式の結果は以下のようになります.
[12"fizz"4"buzz""fizz"78"fizz""buzz"11"fizz"1314"fizzbuzz"1617"fizz"19"buzz"]Emacs Lispのオブジェクトに対して mrubyのメソッドを呼ぶこともできます(注: mrubyの Arrayの機能を使う場合はリストでなくベクタを使用する必要があります)
(let((mrb(mruby-init)))(mruby-sendmrb-10'abs));; => 10(let((mrb(mruby-init)))(mruby-sendmrb"hello WORLD"'swapcase));; => "HELLO world"(let((mrb(mruby-init)))(mruby-sendmrb[1[23][4[56]]]'flatten));; => [1 2 3 4 5 6]仕組み
Emacs 25で実装予定の Dynamic module機能を使って実現しています(なので実際のところ, 組み込んだというほどではないです). 要は dlopen的なもので, 共有ライブラリを実行時に読み込んでその機能を使うというものです. これにより Cライブラリの機能を再ビルドすることなく使えることになります. 高速化や機能の拡張が期待されます. 他のエディタの人からするとまだ実装していなかったのかというような機能かもしれないですが, それが Emacsでもついに使えるときが来たわけですね.
リポジトリ
セットアップ
Emacsの構築
現状 Dynamic module機能は emacs-25ブランチにしか実装されていないので, emacs-25ブランチのソースコードからビルドする必要があります.
% git clone git://git.savannah.gnu.org/emacs.git% cd emacs% git checkout -b emacs-25 origin/emacs-25% ./configure --with-modules --prefix=installed_path # --with-modulesが必須% make% make installmruby.elのインストール
現状規約も何もない感じですが, とりあえず Dynamic moduleのテストと同様にmodules/以下に置いておきます. 現状 Linux環境(Ubuntu 15.10 x86_64)でしかテストしていませんが, Dynamic module機能は Windowsでも MacOSXでも使えるように開発が行われています.
% cd modules% git clone https://github.com/syohex/emacs-mruby-test.git% makemruby.elのロード
makeしたディレクトリで下記のように起動してください(同ディレクトリに load-pathを通して,(require 'mruby)だけでもよいです). emacsは上記で構築した emacsを使ってください.
% emacs -Q -L . -l mruby.elAPI
実装は@mattn さんのgo-mrubyを参考にしました.
(mruby-init)
mrb_stateオブジェクトを作成. GCされるとき,mrb_close関数が呼ばれるので明示的に終了関数を呼ぶ必要がありません.
(mruby-eval mrb code &rest args)
第一引数はmruby-initの戻り値です. 第二引数が mrubyのコード, 第三引数以降はARGVに設定されます.
コード例
(let((mrb(mruby-init)))(mruby-evalmrb"ARGV.map{|x| x + 1}"123));; => [2 3 4](mruby-send mrb code method &rest args)
第一引数はmruby-initの戻り値です. 第二引数が mrubyのコード, 第三引数がメソッド名(シンボル), 第四引数以降はARGVに設定されます.
コード例
(let((mrb(mruby-init)))(mruby-sendmrb["vim""emacs""atom"]'join"+"));; => "vim+emacs+atom"おわりに
Emacs 25で導入予定の Dynamic module機能を使って mrubyを使えるようにしてみたことを示しました. 現状はお遊びというレベルですが, lambda式の扱いとか mruby側から Emacs側を操作する方法等について検討していきたいと思います. また mruby力が超絶に低いのでそこを鍛えて面白い発想ができるようにもなっていければと思います. アイデア, 問題点等ありましたら,github issuesかtwitterまでお知らせいただければと思います.
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme