Hoopla!

now with extra whiz-bang!

Hoopla!

Proc To Send

March 31, 2008 · 3 comments

Ruby provides a handy shortcut for simple procs by letting you use a symbol:
[1, 2, 3].map {|number| number.odd? }
# => [true, false, true]
[1, 2, 3].map(&:odd?)
# => [true, false, true]

Despite a performance hit that occurs from converting the symbol to a proc it’s really useful and I use it in lots of production code when I only have to iterate through a loop a few times.

Today I was iterating through a few properties of an object and unconsciously used the inverse of the Symbol-to-Proc trick:

[ :name,
  :type,
  :amount_in_cents, 
  :created_at,
  lambda {|record| record.class.superclass }
].map {|attribute| @item.send(attribute) }

Rather than specifying a symbol to perform a proc operation I felt like specifying a proc itself and just passing that into send. Surely that would get executed, right? Err… no. I know passing an eval-able string (e.g. @item.send(‘class.superclass’) ) doesn’t work, so I figured I’d throw that lambda in there to calculate the name of @item’s superclass. No dice. But there’s a pretty simple workaround:


module ProcToSend
  def self.included(target)
    target.class_eval do
      def send_with_proc_to_symbol(*args)
        if args.first.is_a?(Proc)
          args.shift.call(self, *args)
        else
          send_without_proc_to_symbol *args
        end
      end
      alias_method_chain :send, :proc_to_symbol
    end
  end
end

Module.send :include, ProcToSend
Object.send :include, ProcToSend
Now this works:

Item.send Proc.new {|x| x.name }
# => 'Item'

But, like all hacks, I need to go refactor away the need for this.

Tags:··

3 responses so far ↓

  • 1 Ted // Mar 31, 2008 at 10:45 AM

    It took me about ten minutes and some doodling in irb to figure out WTF you are doing here, but I finally got it, and it’s pretty slick :-)

  • 2 Daniel Fischer // Apr 02, 2008 at 12:32 PM

    All I have to say is that you’re a badass.

    Except one more thing… you going to Railsconf this year? I’ll come say hi again.

  • 3 Jack Danger // Apr 02, 2008 at 01:54 PM

    @dfish: Yeah, I’ll be there. Though I’m thinking of selling my conference ticket and using it all for beer money at CabooseConf.

Leave a Comment