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.skype_attr_reader(*attr_sym)
attr_sym.each do |a|
module_eval %{def #{a.to_s}
# 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
Posted by evan on Tuesday, April 24, 2007
blog comments powered by Disqus
My name is Evan Light and, yes, I am a nerd. I'm also a professional software developer who, after spending one too many years contracting to the federal government, escaped into the far more enjoyable commercial world. Having spent several years using C and even more using Java (the latter very nearly caused me to give up programming entirely), I consider myself fortunate to have discovered Ruby and to use it as part of my daily work.