IronRuby と C# バインディングの注意点2

| コメント(0) | トラックバック(0) このエントリーを含むはてなブックマーク

IronRuby と C#のバインディングを通じて、Azure上でホスティング出来ないか?を検討している。

その中でIronRuby と Hash構造について気になった事が出てきたのでまとめておく

.NET な環境で Hash構造

.NETな環境でも Ruby の Hashに近い構造があった。 「System.Collections.Generic.Dictionary ジェネリック クラス」である。

このクラスを元にIronRubyとの連携についてみてみる。

HttpRequestのHeaders プロパティ

何故、Dictionaryに興味が出たかというと、作業の関係上 HttpRequestのHeaders プロパティが出たからである。

結論から言うと、、HttpRequestのHeaders プロパティは System.Collections.Specialized.NameValueCollectionであり、Dictionaryではなかった。

このNameValueCollectionとIronRubyの事でハマったので記載する

検証コード

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Run2();
            Console.ReadLine();
        }

        private static void Run2()
        {
            var engine = IronRuby.Ruby.CreateEngine();

            var src = @"
puts '<<<c1>>>'
c1.each do |item|
  puts item.class
  puts item.inspect
end
puts '<<<c2>>>'
c2.each do |item|
  puts item.class
  puts item.inspect
end
";
            var source = engine.CreateScriptSourceFromString(src);
            var scope = engine.CreateScope();

            var c1 = new System.Collections.Specialized.NameValueCollection();
            c1.Add("abc", "123");
            c1.Add("def", "234");
            c1.Add("ghi", "456");

            var c2 = new System.Collections.Generic.Dictionary<string, string>();
            c2.Add("abc", "123");
            c2.Add("def", "234");
            c2.Add("ghi", "456");

            scope.SetVariable("c1", c1);
            scope.SetVariable("c2", c2);
            source.Execute(scope);

        }
    }
}
 
 

NameValueCollection

このオブジェクトは System::String をキーとし、値も System::String である。 これを IronRubyから利用する場合には

var c1 = new System.Collections.Specialized.NameValueCollection();
c1.Add("abc", "123");
c1.Add("def", "234");
c1.Add("ghi", "456");

scope.SetVariable("c1", c1);
 
 

とした後

c1.each do |item|
  puts item.class
  puts item.inspect
  ## use item
end
 
 

のようにした。

Ruby の Hash をご存知の方だと

hash.each do |key,val|
  ## use key and val
end
 
 

としたいかと思うが、実際には違った。 Rubyの等価コードだと以下のように 思えるかと思う。

hash.keys.each do |key|
  ## use key
end
 
 

Dictionary

このオブジェクトは System::String をキーとし、値も System::String である。 これを IronRubyから利用する場合には

var c2 = new System.Collections.Generic.Dictionary<string, string>();
c2.Add("abc", "123");
c2.Add("def", "234");
c2.Add("ghi", "456");

scope.SetVariable("c2", c2);
 
 

とした後

c2.each do |item|
  puts item.class
  puts item.inspect
end
 
 

のようにした。

この結果

System::Collections::Generic::KeyValuePair[System::String, System::String]
[abc, 123]
System::Collections::Generic::KeyValuePair[System::String, System::String]
[def, 234]
System::Collections::Generic::KeyValuePair[System::String, System::String]
[ghi, 456]
 
 

となり、Ruby の Hash のような感じがする。

これらの違い?

まだ詳しく調べていないが、「GetEnumerator メソッド」が影響していると 考えられる。

さいごに

当然のことながらRubyと.NET構造、よく似ているようで違う。 しかし ruby の each などが絶妙な形で融合している。 この点は興味深い。

皆さんもぜひ試していただけると(あまりいない)

トラックバック(0)

トラックバックURL: http://www.m-tea.info/mt-tb.cgi/59

コメントする

あわせて読みたいブログパーツ

このブログ記事について

このページは、k1ha410が2010年1月 4日 03:29に書いたブログ記事です。

ひとつ前のブログ記事は「IronRuby と C# バインディングの注意点1」です。

次のブログ記事は「Azureで独自のハンドラ ( IIS と IHttpHandler )」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。