「ウェブの歴史は人類の歴史の繰り返し」という観点から色々勉強しています。2016の23日目の記事です。22日は、ore_publicさんのruby製のコマンドラインツールをmrubyに置き換えるでした。mrubyインタプリタ、mrubyの実装的にはmrb_state構造体なのですが、一つのプロセスの中で複数mrb_stateを作らざるを得ない場合に、複数のmrb_state間でデータを共有して使いたい場合がありませんか?ふむふむなるほど、やはり皆さん共有したいようですね。APIを拡張するmrbgemのmruby-pointerを作りました。github.com今回はその使い方を説明します。とあるmrb_state上で実行したメソッドの中で作られたポインタを、別のmrb_stateのメソッドの中で使いたい場合に、mruby-pointerを使えば以下のように簡単に実現できます。pter')メソッドを実行し、引数の文字列データを保存するmrb_srcインタプリタからmrb_dstインタプリタにその保存したデータのポインタをコピーするmrb_dstインタプリタからそのデータを使ってメソッドを定義し実行するになります。APIである、mrb_udptr_init、mrb_udptr_copy、mrb_udptr_set、mrb_udptr_get、mrb_udptr_freeを提供しています。詳しくはmruby-pointerのinclude/以下のヘッダを見ると良いでしょう。ふむふむ、簡単ですね。pterredisのコネクションデータをインタプリタ間でコピーするより実用的には、ミドルウェアにmrubyを組み込んでいる状況で、ミドルウェア起動時とミドルウェアに対するリクエスト処理のフックで、どうしてもmrb_stateを分離しないといけない場合があります。いった場合でも、ミドルウェア起動時に特定のmrb_state内でredisにコネクションを貼り、そのコネクションデータをリクエスト処理時の別のmrb_stateで使いまわすことができるようになります。以下にサンプルコードを示します。0;このように、mrb_srcで貼ったredisのコネクションデータのポインタをmrb_dstで使いまわせるように、mruby-redisのメソッドをmruby-pointerを使って実装しておくと、簡単にmrb_state間でデータを共有することできます。実際にmruby-pointerを使ってmruby-redisに上記のようなメソッドを実装したPRは以下になります。github.comふむふむなるほど、Redis.connect_set_rawによってredisにコネクション貼っておいて、そのポインタをコピー可能な領域に保存しておき、引数無しでRedis.newメソッドを実行した時は、そのデータ領域からコネクションデータを使って、redisオブジェクトを作るようになっていますね。ふむふむ、やはり簡単ですね。APIのヘッダファイルをアプリのビルド側から見えるようにする必要があります。そのためには、mruby-pointer/include以下に有効にしたいヘッダファイルをおいた上で、mrbgem.rakeの中に以下のように記述しましょう。"#{spec.dir}/include"endspec.mruby.cc.include_pathsを使うことで、例えば今回のmrb_pointer.hのincludeファイル場所がlibmruby.flags.makに反映されるため、アプリ組み込み時には以下のようなMakefileを書く事で動的にヘッダファイルの居場所を取得できるようになります。APIのテストにはbintest機能を使うmrubyのテストは基本的にRuby側でテストを行うので、mruby本体の機能としてCのテスト機能はもっていません。mruby本体の機能を使ってテストする場合はbintest機能を使うと良いでしょう。mruby-pointerの場合は、ステート間でデータをコピーするようなCのコードを書いた上で、それをbintestディレクトリの中にMakefileと共に配置して、build_config.rbでbintestをenabledにした上で、以下のような簡単なテストコードを書いています。Cのコードは上記で紹介した2つのコードを使っています。`../bintest/shared_redis_ctx`endこれが、mrubyのtest時に自動で解釈され、テストされます。まとめということで、これまでmrb_state間でデータを共有する際に、できるにはできたんですが、そのやり方があまりドキュメントになかったり、定番の方法があまり定まっていなかったということで、それを解決するためにmruby-pointerを作って、使い方を本エントリで示しました。皆さんも、どうしてもmrb_stateをわけないと行けない状況でも、mruby-pointerを使ってデータをうまく共有するようなメソッドを書いておけば、色々便利になると思われますので是非ご活用下さい。はてなブログPro研究者と技術者をやっています。詳しくはリンクの「研究・開発業績ページ」を御覧ください。さくらインターネットに入社して1年が経ちました非厳密計算で確率的に解釈するコンピューティングへの流れラストオーサーとしての国際会議投稿やジャーナル執筆のサポートについてviを:wqや:q!、あるいはZZで終了するのとではどちらが効率的か自分の研究開発に自信を持つためには月別アーカイブリンク研究・開発業績ページ旧ブログ検索はてなブログをはじめよう!matsumoto_rさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。