Great, thanks! I don't feel strongly about it so I'll just put in a little helper function to my .NET project to convert a Hash to a Dictionary<string, object>. The monkey-patching method might not work too well since there will be many functions that might use this pattern, and having to monkey-patch every single one of them might get annoying.
On Thu, Jun 23, 2011 at 2:45 PM, Jimmy Schementi <jscheme...@gmail.com> wrote: > On Jun 23, 2011, at 11:45 AM, Rob Britton wrote: > > I'm attempting to write a method in C# that is called by IronRuby to > speed up an existing script, and I call it like this: > > foo :limit => 5, :offset => 10 > > How would I go about accessing these objects from C#? I'm trying > something like this: > > void foo(Hash options){ > int limit = (int)options[new RubySymbol("limit")]; > ... > } > > However this doesn't work since RubySymbols constructor is private. > How would I go about getting the objects within the hash? > > > Rob, it's best to avoid depending on IronRuby built-in types in your .NET > API unless you absolutely need to, as well as always having your .NET API's > arguments be interface types, so both Ruby and .NET can call into them. If > you did this: > // C# > public class MyClass { > public void Foo(IDictionary args) {} > } > You can still call it from Ruby: > my_class.foo :limit => 5, :offset => 10 > As for indexing, you can copy the provided Hash into a Dictionary<string, > object> to provide string-based indexing: > void Foo(IDictionary args) { > var dict = new Dictionary<string, object>(); > foreach (DictionaryEntry a in args) dict[a.Key.ToString()] = > a.Value; > var limit = dict["limit"]; > var offset = dict["offset"]; > // do your stuff > } > > > Another option (which I like more) is to write a Ruby wrapper around it to > convert the keys to CLR strings: > require 'MyClass' # load above assembly > class MyClass # monkey-patch above .NET class > alias :orig_foo :foo > def foo(args) > orig_foo args.inject({}){|i,(j,k)| i[j.to_clr_string] = k; i } > end > end > Then you wouldn't have to do the conversion in C#: > void Foo(IDictionary dict) { > var limit = dict["limit"]; > var offset = dict["offset"]; > // do your stuff > } > I like the latter option best because you do what Ruby needs in Ruby; your > .NET code assumes it's getting a CLR string rather than forcing it to be. > However, it's not ideal as you have to copy the dictionary in both cases, > but for an argument hash it's very unlikely to become an issue. > You'll notice that if you a .NET method that accepts a string, you can pass > it a Ruby symbol; we do the conversion between Ruby symbols and .NET > strings. However, we don't do conversions between generic arguments, > especially with a Ruby Hash, were they keys could be different types. But we > could convert a Hash to a statically typed Dictionary if all they keys are > the same type; if you feel strongly about this please open a bug. > ~Jimmy > _______________________________________________ > Ironruby-core mailing list > Ironruby-core@rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core > > _______________________________________________ Ironruby-core mailing list Ironruby-core@rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core