Re: Could someone please explain the magic in this code



On Feb 1, 2009, at 3:15 PM, John Small wrote:

I need to use erb templates so I went to look at the documentation. It
all seems straight forwards until I get to the example where a lot of
new coding concepts are pulled in and I'm left totally mystified about
what's going on.

The code, from the api documentation is
<pre>
require "erb"

# build data class
class Listings
PRODUCT = { :name => "Chicken Fried Steak",
:desc => "A well messages pattie, breaded and fried.",
:cost => 9.95 }

attr_reader :product, :price

def initialize( product = "", price = "" )
@product = product
@price = price
end

def build
b = binding
# create and run templates, filling member data variebles
ERB.new(<<-'END_PRODUCT'.gsub(/^\s+/, ""), 0, "",
"@product").result b
<%= PRODUCT[:name] %>
<%= PRODUCT[:desc] %>
END_PRODUCT
ERB.new(<<-'END_PRICE'.gsub(/^\s+/, ""), 0, "", "@price").result b
<%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %>
<%= PRODUCT[:desc] %>
END_PRICE
end
end

# setup template data
listings = Listings.new
listings.build

puts listings.product + "\n" + listings.price

</pre>
My questions are;-

(1) what does "<<-" do just before 'END_PRODUCT'

That's a "here document". <<-'END_PRODUCT' means to take the
following lines up until a line begins with END_PRODUCT as if they
were a string. The - let's END_PRODUCT be indented from the beginning
of the line. The single quotes say that no interpolation is to be
done on the string (that is, it should act like a string literal with
single quotes).


(2) how do the lines after .result b get substituted into END_PRODUCT

I hope (1) answers that ...


and why is there a gsub there.

The gsub is removing the leading whitespace /^\s+/ from each line.
This lets the here-document contents be intended to where code would
normally be.

My understanding of the order things are
happening is clearly deficient because the gsub to remove white space
will have no effect on 'END_PRODUCT' since there's no white space in
it.
So somehow 'END_PRODUCT' is getting replaced by the lines below, which
aren't in quotes, before the gsub happens. wtf is going on here?

Do you get it now?

The equivalent would look like:
ERB.new("<%= PRODUCT[:name] %>\n<%= PRODUCT[:desc] %>\n",
0, "", "@product").result b
If the here-document were not used.


(3) How does binding work? The documentation is pretty opaque. What is
it doing in this context and why is it required?

You want the PRODUCT, @product, and @price to be evaluated in the
context of the Listings object rather than the new ERB object just
created.



All explanations welcome
--
Posted via http://www.ruby-forum.com/.



I hope this helps.

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@xxxxxxxxxxxxxxxxxxxxxx



.



Relevant Pages

  • wayne, have a raw acceptance. You wont jump it
    ... There Shah will cure the string, and if Ramez ... price the sudden breeze. ...
    (sci.crypt)
  • Re: How do you price a unique bass?
    ... If you post a too-high price, the worst that happens is it ... UNIQUE HEADLESS CUSTOM 5 STRING BASS. ... QUALITIES OF BARTOLINI PICKUPS AND ACTIVE PREAMPS. ...
    (alt.guitar.bass)
  • Re: Providing default value with raw_input()?
    ... You can only get a prompt string printed to the screen with raw_input, ... Japanese stock sale switcheroo of price and number of shares that cost many megabucks). ... Current price of apple is $1.29 per pound ...
    (comp.lang.python)
  • Re: Update query on all records in a table automatically
    ... Dim SQL1 as string ... if you find yourself cycling through a top level table and running queries ... > to run a price matrix against the price fields in the ...
    (microsoft.public.access.queries)
  • Re: Killing dead spaces around pipe delimiter
    ... ' DBFILE ... while and eventually test it to convince myself that the 2nd gsub() ... blanks is because that first gsubwill return 1 even if there are no ... I imagine the implementation probably has 2 steps - 1) find a string in the ...
    (comp.lang.awk)