Evil Fun With IronRuby
June 17th, 2008
I was playing with IronRuby a bit last night while driving back from Columbus Ruby Brigade with Ken Adair. It started with wondering if it’s possible to .each on a .NET ArrayList (System.Collections.ArrayList) and iterate via a closure ala Ruby arrays. Here’s the result of my testing (testing/output via IR.cmd – IronRuby’s IRB – comments added later):
# Create a Ruby variable a and set it to a new instance of a .NET ArrayList
>>> $a = System::Collections::ArrayList.new
=> []
# Add the string "j" to the list
>>> $a << "j"
=> ["j"]
# Add the number 1 to the list
>>> $a << 1
=> ["j", 1]
# Add the string "joe" to the list using ArrayList.
>>> $a.Add("joe")
=> 2
# Call each and print out each element using a closure
>>> $a.each { |i| puts i }
j
1
joe
=> ["j", 1, "joe"]
So to answer the question, yes, it does iterate via a closure just like in Ruby! As an added bonus, we also found out that the add operator (<<) works with ArrayList too! Very cool. The question is, how does this work? Is there a layer that adds these methods to ArrayList or is ArrayList simply mapped to a Ruby array under the covers?
So we decided to take this experiment one step further: one of the awesome features of Ruby is open classes. So, what happens when I try to open a .NET type?
>>> class System::String
... def say_hello
... "Hello " + self
... end
... end
In the above snippet we opened up System.String and defined a say_hello method. So what happens when we try to call it:
>>> "joe".say_hello
:0:in `Initialize': undefined local variable or method `say_hello' for joe:String (NoMethodError)
At first glance you might think that it didn’t work. However, this is actually expected because “joe” is an instance of a Ruby String not a .NET string. Now if we do this:
>>> "joe".ToString.say_hello
=> "Hello joe"
Much better! So, somehow I can open System.String and add methods to it. Seems kind of evil to me. I wonder what the guidance will be around opening up .NET classes. Especially when you can’t even inherit from some of them in C#!
- Posted 2 months ago
- comments[1]
- Permalink
- Digg This!
July 3rd, 2008 at 02:50 AM
I guess if you’re gonna be using sealed classes from CLR, they ought to be “frozen” in Ruby sense. And that’ll get around being evil.