Ruby muckin

February 12th, 2008

So I was writing a Rakefile and found myself doing stuff like this:

  cmd = "svn co #{src} #{dest}"
  puts cmd
  system cmd

Everytime I wrote lines like this, a little corner of my heart died.

I dreamt of something like this:

  "svn co #{src} #{dest}".to :puts, :system

But it's hard to do this properly, because you need to get hold of the receiver (in the above case main, or some Rake task) or binding, so that the methods can be sent where they ought. With crippled Kernel#caller, the the demise of Binding.of_caller (Ruby-debug solved the problem but there's significant overhead) it was looking like I should just wait for the next ruby release.

But I frowned like Hiro and came up with this:

  pass("svn co #{src} #{dest}").to :puts, :system

Briefly, Object gets #pass which creates a PassProxy (basic object). It keeps hold of the receiver, but acts like the object (in this case the string). When you send #to(:method) to this PassProxy, it calls the original receiver with the object.

This is just sugar, but its nice sugar in some cases. Compare:

   # plain ruby
   msg = "oooh!"
   MyObj.foo msg
   MyObj.far msg
   MyObj.faz msg
   msg
   # => 'oooh!'
   

   # returning (ActiveSupport)
   returning "oooh!" do |s|
     MyObj.foo s
     MyObj.far s
     MyObj.faz s
   end
   # => 'oooh!'

   # (pass) (this code)
   MyObj.pass("oooh!").to :foo, :far, :faz
   # => 'oooh!'

But eat too much sugar and your teeth will fall out: I realised that this probably has limited usefulness (how often do you need to send the same object to a bunch of different methods?). But at least I learned some things in that last couple of hours of coding.

Go get the code from pastie if you're interested.

Thanks for reading

1 Response to “Ruby muckin”

  1. Kwak McGuiness Says:
    Hey dude, Not bad Ruby - my head hurts trying to get around it and all. Kwak

Leave a Reply