[Ironruby-core] Creating RubySymbols in C#

Rob Britton rob.s.brit at gmail.com
Mon Jun 27 09:40:30 EDT 2011

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

On Thu, Jun 23, 2011 at 2:45 PM, Jimmy Schementi <jschementi at 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 at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core

More information about the Ironruby-core mailing list