Second Drop of RubyCLR

It’s alive and it’s real:

This second release of my RubyCLR bridge contains a non-trivial Windows Forms 2.0 application written entirely in Ruby. If you don’t want to download the entire drop, you can click here to look at the source.

If you thought you’ve seen this application before, you’re right – it’s a partial port of Joe Stegman’s RSS Reader application that was designed to show off some of the more interesting features of Windows Forms 2.0.

I’m pretty sure I could have finished porting the rest of the app, but I think I ported enough of it to demonstrate that you can actually use this drop to build a real app.

There are now 106 tests and 165 assertions in the unit test suite. They all pass.

This build now contains release builds of RbDynamicMethod.dll and RubyClrTests.dll, so it should run on any computer that has Ruby 1.8.2 and .NET Frameworks 2.0 RTM installed.

Get the bits here.

Enjoy.

Twitter Digg Delicious Stumbleupon Technorati Facebook Email

18 Responses to “Second Drop of RubyCLR”

  1. Michael Trier 20. Feb, 2006 at 9:02 pm

    Wow! Impressive John, very impressive. I look forward to playing with all the bits.

  2. Hi!
    This all looks very, very promising!
    I’d love to be able to write an application UI in .Net (comfortable use of the designer in VS.Net), while writing the core application in Ruby (so terse, so nice to write, so easy to create DSLs!).
    Do you think this will be doable ?

  3. Yes – that’s absolutely a goal for this project. A secondary goal for myself (or hopefully someone I can recruit to this project) is to implement the CodeDOM support required to serialize designer output to Ruby. This would let folks use the VS 2005 designers to generate all of the ‘goo’ that I had to write by hand in that sample.

  4. Wow, really, really impressive. I hope to be able to play with this over the next couple of weeks. Thanks for all your hard work – this is great stuff!

  5. Got a chance to play with this. Fantastic. I’ll post my program in the Google News Group. A little feedback here tho:
    1) Would be nice if it was a little more forgiving on casing. I know Ruby isn’t, either, but it would be cool if form.Controls.add worked (instead of Add)
    2) Delegates seem flakey but I don’t have a better error report. Just seemed like sometimes my button wouldn’t respond to clicks. Is there a delay in hoooking those up somewhere or is it all single-threaded?
    3) Automatic determinination of enumeration being used. E.g.:
    textBox.AnchorStyles = Left | Right | Top
    instead of
    textBox.AnchorStyle = AnchorStyles::Left | AnchorStyles::Right | AnchorStyles::Top
    Again, really fantastic stuff!

  6. Thanks for the feedback, Justin!
    I’m planning on providing a switch somewhere where I would automatically map ruby-casing to CamelCasing. So:
    form.back_color would map to form.BackColor
    This is more in line with how some of the Rails ActiveRecord stuff works. I have to think more about that though …
    The delegate problem you’re having is a bit disconcerting though. If you could come up with a repro, that would rock. I recently added some code to deal with holding references onto Ruby blocks to prevent them from being GC’d – this might be causing your problem, though I’m not sure.
    The enumeration suggestion sounds cool, but I’m not sure how to implement it. It might be possible by fiddling with scope resolution but I’d have to check with folks who know a lot more about Ruby than I do :)
    Keep the comments coming!

  7. Great stuff! Question…when I click “Go”:
    C:\hold>ruby rssreader.rb
    ./ruby_dynamic_method.rb:138:in `method_missing’: undefined local variable or me
    thod `grid’ for # (NameError)
    from rssreader.rb:406:in `initialize’
    from rssreader.rb:404:in `call’
    from ./rubyclr.rb:275:in `Run’
    from ./rubyclr.rb:275:in `send’
    from ./rubyclr.rb:275:in `method_missing’
    from ./winforms.rb:23:in `Run’
    from rssreader.rb:434

  8. Oh yeah, I forgot to disable that. You’ll see from looking at the source that the event handler binds to a non-existant grid object (it was there earlier, but I forget to delete the code from that event handler).

  9. John,
    OK, I played around this some more and I have some deeper questions. How do I override the initialize method for all controls? I’d like to do something like this:
    Control.class_eval do
    def initialize
    super
    MessageBox.Show(“Overriding initialize”)
    end
    end
    and have that MessageBox show up each time I create a control:
    Button.new
    TextBox.new
    However, it doesn’t work that way. If I override each control class individually , it does.
    Any suggestions?

  10. John,
    I also found some crashing bugs. Here are the unit tests. Note that when these run they crash the interpreter.
    require ‘test/unit’
    require ‘rubyclr’
    RubyClr::reference ‘System’
    RubyClr::reference ‘System.Windows.Forms’
    include System::Windows::Forms
    # If any of these tests are run, the ruby interpreter crashes!
    class CrashyTests < Test::Unit::TestCase
    def test_form_meta_send
    form = Form.new
    class << form
    def init
    self.send(:Text=, “test_form_meta_send”)
    end
    end
    form.init
    assert(form.Text == “test_form_meta_send”)
    end
    def test_form_meta_init
    form = Form.new
    class << form
    def init
    self.Text = “test_form_meta_min”
    end
    end
    form.init
    assert(form.Text == “”)
    end
    def test_form_meta_min
    form = Form.new
    class << form
    end
    form.Text = “test_form_meta_min”
    assert(form.Text == “test_form_meta_min”)
    end
    def test_form_per_class
    form = Form.new
    def form.init
    self.Text = “test_form_per_class”
    end
    form.init
    assert(form.Text == “test_form_per_class”)
    end
    end

  11. Ouch, RedCloths bizarre formatting strikes again. I’ll just email you ;)

  12. Awesome! Not only the beautiful GUI, it also means I can optimize hungry-for-speed part of my ruby code into various .Net languages (such as Boo). Great work! Thanks.

  13. This f’n rocks.

  14. Great stuff! I’ve been waiting for Ruby on the CLR – but now that I have seen this I realize this is what I really wanted ;) .
    Are you going to set up a project on rubyforge?

  15. That’s awesome John!
    Ruby CLR is looking really sweet!
    Do you have any examples of using the bridge the other way in .NET to access Ruby? I’m thinking about implementing the bridge in my project.
    Thanks. :)

  16. I don’t have any explicit scenarios where I “hoist” the Ruby runtime into an existing .NET app. All of my supported scenarios involve delay-loading the CLR into an existing Ruby Win32 process.
    This will be something to look at down the road, however, since embedding Ruby as a scripting language for an existing .NET application is another scenario that I’d like to address.

  17. Very cool. :)
    One other thing, and this may be in a blog post you wrote or in the sample code (haven’t had a chance to look at it thorougly enough yet):
    How do you handle interfaces, since Ruby doesn’t support them?
    We’re creating an extensibility (add-in) architecture, and it would be really killer to write add-ins for our application in Ruby using Ruby CLR, but my only concern is the add-in will need to implement the specific memembers of a .NET interface.