Brian's Waste of Time

Wed, 06 Apr 2005

Ruby Metaprogramming 201

If you find yourself doing a lot of eval(..) based metaprogramming, remember to include debug stuff!

begin
    eval("dsadh!!sadkhj how are you today?")
rescue Exception => e
    log.error "Metaprogramming error [#{e}]"
end

Which is nifty and all if the eval fails, but what happens on the way more subtle?

begin
  eval <<-EOM
    def foo
      robert is sick today
    end
  EOM
rescue Exception => e
  log.error "Metaprogramming error [#{e}]"
end

Where you don't get the syntax problem until you invoke foo. Solution!

eval <<-EOM
  def foo
    begin
      robert is sick today
    rescue Exception => e
      puts "Error while invoking foo defined from [insert stuff to help you debug]: \#{e}"
    end
  end
EOM 

You cannot catch syntax errors, but because so much of ruby uses ruby this isn't a big deal most of the time =) Note escaping the hash in \#{e} -- this is important because just #{e} would fail. Why is an exercise left to the reader ;-)

writebacks...

Jim Weirich

Another Approach
I have found the following to be useful when using eval. Runtime errors will be reported as usual with the file/line number pointing to the line of code in the eval string. begin eval <<-EOM, binding, __FILE__, __LINE__+1 def foo robert is(sick(today)) end EOM end foo

Jim Weirich


Ok, that code doesn't look so good in the comment. Try this link: http://rafb.net/paste/results/813q7t62.html I added the parens to avoid syntax warnings.

Brian


much appreciated!

gabriele renzi

def/begin/rescue/end/end ->def/rescue/end
notice that you don't need a begin-end encompassing a whole method body to have a rescue. In absence of a begin/end pair, the rescue (and ensure) assumes the whole method definition as it's block.

comment...

 
Name:
URL/Email: [http://... or mailto:you@wherever] (optional)
Title: (optional)
Spam Guard, translate l33t to English: (hint, it's an Australian animal, plural form)
Comments:
Save my Name and URL/Email for next time