[#49148] Ruby 1.9で、バイト長の部分文字列を作りたくて悩んでます — Daisuke Yokotsuka <yokots_d@...3-net.ne.jp>

はじめまして。横塚と申します。

16 messages 2013/01/29

[ruby-list:49124] RE: [ruby-list:49120] Re: [ruby-list:49118] IronRubyとC#の連携

From: Shozo Arai <shozoa@...>
Date: 2013-01-08 08:39:34 UTC
List: ruby-list #49124
反応が遅くなりました、荒井です。

>エラーについてはエラー内容を貼ったりしないと
私も同意です。

>https://gist.github.com/4474447
整理していただいて、有難うございます。

本件ですが、忘れていたことを思い出すよう努力していました。
結果ですが、以下のようにすると動作します。

ScriptEngine engine = Ruby.CreateEngine();
ScriptScope scope = engine.ExecuteFile("test.rb");
scope.SetVariable("x", "IronRuby 1.1.3");
var result = (string) engine.Operations.InvokeMember
             (scope, "test", ".NET");
Console.WriteLine(result);

実は、test.rbが今回のような利用方法でハマる箇所になります。
def test (message)
   "Hello #{message} !!! and #{self.x}"
end

メソッド名とパラメータの間に空白を入れるのがポイントです。
空白をいれないで「test(message)」と定義すると、InvokeMemberで
messageが定義されていないというエラーが出力されます。
多分、スクリプトファイルのエンコードなどが、関係しているような
気がします。
#私の所では、動くようになってからはどちらでも問題なく動作します。
#これ以上は、原因追及をしていません。

それから、今回のようなパターンであれば以下のように記述して
呼び出すこともできます。
Func<string, string> rubyMethod;
var x = scope.TryGetVariable("test", out rubyMethod);
var y = rubyMethod("ABC");

最後にIronRubyを使う上で気になった点を以下に記載します。
1.ir.exeの利用(irb相当)
 このパターンであれば、ほぼ素直に利用することができます。
スクリプトから.NET Frameworkのライブラリや自分で作成した
ライブラリなども簡単に利用することができます。

2.C#/VBからの利用(組み込みパターン)
 今回のようにir.exeで利用するのとは、異なる箇所が存在します。
詳しい使い方を把握するには、DLRというライブラリの構造を把握
する必要があります。DLRとは、IronPythonの開発から作成された
.NET用の動的言語用の共通ライブラリです。DLRのヘルパーとして
ScriptEngine、ScriptScopeなどを始めとしてホスティング用の
クラスが提供されています。
ScriptScopeは、変数などを管理するスコープの概念に近いものですが、
利用方法の実態となると実装言語に依存します(特にIronRubyは、実装
過程でIronPythonとは異なる利用方法になっています)。こうなって
いますので、詳細を把握するには、実装言語のソースを読むなりしないと
理解することも難しいです。
従って、組み込み利用はir.exeを使う場合よりも格段に難しいと
言えます。このような事を理解できれば、「「test(message)」と定義した
パターンでは、testメソッド呼び出すスクリプトを
engine.CreateScriptSourceFromStringメソッドで作成してから、
Executeメソッドで実行すればInvokeMemberでのエラーを回避することが
できます。

使い方によって、ご注意ください。

以上。

In This Thread