Create code dynamically with eval and here documents
Here documents, sometimes called "heredocs," can be a powerful way to spruce up a call to eval without declaring a method on a single line. Take, for instance, this code, which might reside in your Rails project's routes.rb file:
map.with_options(:controller => "items") do |obj|
obj.items("/items", :action => "list")
obj.item("/items/:id", :action => "show", :id => /\d+/)
end
map.with_options(:controller => "people") do |obj|
obj.people("/people", :action => "list")
obj.person("/people/:id", :action => "show", :id => /\d+/)
end
The above code uses the Object#with_options method, which makes it easy to extract out common parameters in method calls. Without the call to with_options, it would have been necessary to provide the ":controller => "items"" parameter in each of the route calls.
Anyway, back to the point. After creating the above code on one controller, you might want to do it for a second, and third, etc. That quickly becomes unmanageable. Enter eval and here documents:
named_routes = [:item, :person]
named_routes.each do |controller|
eval <<-STR
map.with_options(:controller => "") do |obj|
obj.("/", :action => "list")
obj.("//:id", :action => "show", :id => )
end
STR
end
The here document is specified by providing "<<-STR." You can name your heredoc whatever you'd like, as long as you close it using the same name. You can even nest heredocs, but we're not focused on that right now. Combining eval and here documents makes your code more reusable and more maintainable, not to mention easier to read.