From: Gavin Kistner Date: 2005-08-19T23:33:53+09:00 Subject: Re: #puts inside ERB --Apple-Mail-3-125934299 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed On Aug 19, 2005, at 2:07 AM, Mark Hubbart wrote: > How about this? Still somewhat hacky, but maybe less breakable. It > should work unless you supply a binding in the Kernel module context; > the new #puts is defined in Object. Tricky! I moved the module into ERB::Writeable. Despite your super calls, I used Object.class_eval to dynamically override #puts, #print and #p at the start of ERB#result, and then undefs those methods at the end of #result. It's sure to be more of a performance hit (though I'll have to benchmark to see how much it affects things) but I wanted to really leave the house as clean when I left as when I entered. Oh, I also needed to add some .to_s calls inside Writeable's methods, to handle non-string arguments. In summary (for the google-able archives): using Mark's technique, I have made a patched version of ERB which causes calls to puts, print, and p inside an ERB to place their information into the ERB output string, instead of immediately sending the results to $stdout. (If you use this patch but need some debug information in your ERB template, you can still use $stdout.puts to hide output from the ERB string.) You can download the patched file from http://phrogz.net/RubyLibs/ erb_1.8.2_with_puts.rb.gz After ungzipping, the file should be renamed to 'erb.rb' and replace the file in (for a standard install): /usr/local/lib/ruby/1.8/erb.rb Finally, for the naysayers (and the archive), this functionality (using Ruby code inside an ERB template to inject strings into the ERB template in place without using <%=...%>) can be achieved without the above patch by using the "eoutvar" option for ERB. By default, this is a local variable named "_erbout", but you can name it whatever you wish by modifying the fourth parameter to ERB.new. For example: require 'erb' template1 = <<'ENDTEMPLATE' Hello <% 1.upto(9){ |i| _erbout << "\t#{i} x #{i} = #{i*i}" _erbout << "\n" unless i==9 } %> Goodbye ENDTEMPLATE ERB.new( template1 ).run template2 = <<'ENDTEMPLATE' Hello <% 1.upto(9){ |i| OUTPUT << "\t#{i} x #{i} = #{i*i}" OUTPUT << "\n" unless i==9 } %> Goodbye ENDTEMPLATE ERB.new( template2, nil, nil, 'OUTPUT' ).run Both of the above output: Hello 1 x 1 = 1 2 x 2 = 4 3 x 3 = 9 4 x 4 = 16 5 x 5 = 25 6 x 6 = 36 7 x 7 = 49 8 x 8 = 64 9 x 9 = 81 Goodbye --Apple-Mail-3-125934299--