Neat trick: delaying variable evaluation in Ruby meta-code

Working on rb-skypemac 0.2.0, I found myself in the position of either implementing 40 getter/setter pairs by hand or writing some meta code. I always prefer to write meta code. If you don’t, seek treatment — or else you will soon find yourself in treatment of the straight jacket variety.

Anyhow, as I’m writing this meta code, I realized that I needed to delay the evaluation of a variable inside a String, i.e., delaying the evaluation of #{stuff} within “This is a load of #{stuff}”. Why? Because I didn’t have the variable yet! The variable is an instance variable and my meta code generating method is at the class level. So I began to stress. And then I figured, what the hell; I’ll just escape the ‘#’ because that would just make sense.

You know what? It just worked.

Matz did one fine job designing several portions of this language!

Example below:

  class User
    def User.skypeattrreader(attrsym)
      attrsym.each do |a|
        moduleeval %{def #{a.tos}
          # The line below is the REALLY cool part
          r = Skype.send_ :command => “get user \#{@handle} #{a.to_s}”
          r.sub(/^.#{a.to_s.upcase} /, “”)
        end}
      end
    end

skype_attr_reader :fullname, :birthday, :sex, :language, :country, :province

1 comment so far ↓

#1 John Trupiano on 06.07.08 at 9:24 pm

Was looking for delayed eval — thanks! Worked like a charm.

Leave a Comment