IronRuby と C#のバインディングを通じて、Azure上でホスティング出来ないか?を検討している。
その中でIronRuby の文字列と .NET(C#)の文字列の間にさらに気になった事が出てきたのでまとめておく
MutableStringと.NET String
先日 C#とIronRubyのかけ橋 MutableString なる物を書いた。 その記事を書きつつ、自分で失敗して半日悩んだので、その事例について書いておく
検証コード
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Run();
Console.ReadLine();
}
private static void Run()
{
var engine = IronRuby.Ruby.CreateEngine();
var src = @"
hash = Hash.new
hash['abc'] = 123
k1 = 'abc'
puts hash[k1] #=> 123
puts hash[k2] #=> nil
puts k1.class
puts k2.class
puts hash[k2.to_s] #=>123
puts k2.to_s.class
";
var source = engine.CreateScriptSourceFromString(src);
var scope = engine.CreateScope();
scope.SetVariable("k2", "abc");
source.Execute(scope);
}
}
}
上記のコードは、RubyのHashオブジェクト hash のキー"abc"と値 123 をマッピングする 物である。
その値を参照する為に hash['abc'] などとしてアクセスしている。
k1 = 'abc' puts hash[k1] #=> 123
このコードは動いて当然。 k1 は Ruby の String である。そのため、普通に動く。 (たぶん内部では MutableStringのはず)
問題は次のコード
var scope = engine.CreateScope();
scope.SetVariable("k2", "abc");
source.Execute(scope);
とした後の以下のコード。
puts hash[k2] #=> nil
このコードはnilが変える。
調べてみると
puts k1.class puts k2.class
k1のクラスは'String'であるが、k2は'System::String'である。
では、どのように.NETからMutableString を渡すか?というと1つの方法は 以下のようにする事である。
puts hash[k2.to_s] #=>123 puts k2.to_s.class
さいごに
IronRubyと.NETバインディングは比較的簡単であるが、上記のような点は 気にする必要がある。
ちなみに .inspect すると、"" か '' の違いとして表示されるので、 興味深い。
皆さん試してみてください。(試すのか?)


コメントする