<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>The Dev Blog: Lost In Binding - Adventures In Ruby Metaprogramming</title>
    <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Putting Family Management on Rails!</description>
    <item>
      <title>Lost In Binding - Adventures In Ruby Metaprogramming</title>
      <description>&lt;p&gt;I've been using the &lt;a href="http://agilewebdevelopment.com/plugins/security_extensions"&gt;security_extensions&lt;/a&gt; plugin to secure forms in &lt;a href="http://www.famundo.com"&gt;Famundo&lt;/a&gt; and some other projects. It's a very simple plugin that adds protection against &lt;a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery"&gt;CSRF&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;When upgrading one of my projects to Rails 1.2, I got a deprecation warnings from Rails, as this plugin requires start_form_tag and end_form to work. Thinking it was all easy to change, I replaced all calls to the new form_tag ... do format. This change resulted in lots of errors, all complains from erb on missing the _erbout variable.&lt;/p&gt;

&lt;p&gt;After a lot of digging, I realized this error is caused by the way variables bindings work in Ruby, and the fact that erb uses it to pass along the output string it creates. &lt;/p&gt;

&lt;p&gt;What are bindings? Bindings are (put very simply) the context for the variables in an execution block. It's what's used in Ruby to bind a variable to a block and have the block access it even after the variable went out of scope in the original code block, or the variable is re-defined in a new block. Here is some code to make it clear:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# Define the a var&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
&lt;span class="comment"&gt;# Create a proc that prints a&lt;/span&gt;
&lt;span class="ident"&gt;level_a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;level_a&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; 5&lt;/span&gt;

&lt;span class="comment"&gt;# Create a method that accepts a proc, redefines a and calls the proc&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;level_b&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;blk&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
  &lt;span class="ident"&gt;blk&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;level_b&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;level_a&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; 5  &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The best place I found to learn about bindings is &lt;a href="http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc"&gt;this page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;How is this affecting the security_extensions plugin? The plugin needs to wrap the block given to the form, and inject into it the hidden field used to validate the form when it's posted back. When using the non-block accepting start_form_tag, it just appends a new field at the end:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;secure_form_tag&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;start_form_tag&lt;/span&gt;&lt;span class="punct"&gt;(*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="escape"&gt;\n&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt;
    &lt;span class="ident"&gt;hidden_field_tag&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;session_id_validation&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;security_token&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The simple solution I thought will work, is very simple:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;secure_form_tag&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_for_options&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{},&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{},&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;parameters_for_url&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;block_given?&lt;/span&gt;
    &lt;span class="ident"&gt;form_tag&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_for_options&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;parameters_for_url&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="keyword"&gt;yield&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;hidden_field_tag&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;session_id_validation&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;security_token&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{form_tag(*args)}&lt;/span&gt; &lt;span class="escape"&gt;\n&lt;/span&gt; &lt;span class="expr"&gt;#{hidden_field_tag('session_id_validation', security_token)}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It failed. I decided to try and call the external block directly: &lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;secure_form_tag&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_for_options&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{},&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{},&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;parameters_for_url&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;block_given?&lt;/span&gt;
    &lt;span class="ident"&gt;form_tag&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_for_options&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;parameters_for_url&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;call&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;hidden_field_tag&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;session_id_validation&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;security_token&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{form_tag(*args)}&lt;/span&gt; &lt;span class="escape"&gt;\n&lt;/span&gt; &lt;span class="expr"&gt;#{hidden_field_tag('session_id_validation', security_token)}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Failed again! The problem is that the context of the internal block is completely different from the context of the block passed to the function, and so the _erbout variable isn't bound to the internal block, only to the external one.&lt;/p&gt;

&lt;p&gt;The solution I used was to copy the binding from the passed block into the internal block, call the passed block, and then copy it back from the internal block to the passed block. Here is the code to do it:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;secure_form_tag&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_for_options&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{},&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{},&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;parameters_for_url&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;block_given?&lt;/span&gt;
    &lt;span class="ident"&gt;_erbout&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;eval&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;_erbout&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;form_tag&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;url_for_options&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;parameters_for_url&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="ident"&gt;concat&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;hidden_field_tag&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;session_id_validation&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;security_token&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;binding&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="ident"&gt;eval&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;_erbout = %q[&lt;span class="expr"&gt;#{_erbout}&lt;/span&gt;]&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="keyword"&gt;yield&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;eval&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;_erbout = %q[&lt;span class="expr"&gt;#{_erbout}&lt;/span&gt;]&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;block&lt;/span&gt;
  &lt;span class="keyword"&gt;else&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{form_tag(*args)}&lt;/span&gt; &lt;span class="escape"&gt;\n&lt;/span&gt; &lt;span class="expr"&gt;#{hidden_field_tag('session_id_validation', security_token)}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code does a lot of copying of strings, but as it's in very specific places that aren't performance sensitive, I rather get the nice way to use secured forms, and incur the performance penalty in this case. &lt;/p&gt;

&lt;p&gt;The same trick can be use to extended other erb related methods that use blocks and need the _erbout bindings.&lt;/p&gt;

&lt;p&gt;If there are better solutions, let me know. I'd love a simpler solution for this.&lt;/p&gt;</description>
      <pubDate>Wed, 28 Mar 2007 03:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:eb6423d0-6849-4be5-a220-3851a4bfad2e</guid>
      <author>guy.naor@famundo.com (Guy Naor)</author>
      <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming</link>
      <category>Ruby</category>
      <category>Programming</category>
    </item>
    <item>
      <title>"Lost In Binding - Adventures In Ruby Metaprogramming" by Guy Naor</title>
      <description>&lt;p&gt;Piers, unfortunately the code you posted still doesn't work. The reason it doesn't is that we still have an internal block in the call to form_tag that goes into the concatenator.&lt;/p&gt;

&lt;p&gt;But I did find a way of using capture which simplifies the code (though still makes it look a bit hackish...):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def secure_form_tag(*form_tag_params, &amp;amp;block)
  if block_given?
    @res = &amp;lt;&amp;lt;-EOF
      #{form_tag(*form_tag_params)}
      #{capture(&amp;amp;block)}
      #{hidden_field_tag('session_id_validation', security_token)}
      &amp;lt;/form&amp;gt;
    EOF
    eval '_erbout.concat @res', block
  else
    &amp;quot;#{form_tag(*form_tag_params)} #{hidden_field_tag('session_id_validation', security_token)}&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;BTW, notice the need to use @res to make it work, or the var is hidden from the block bindings.&lt;/p&gt;

&lt;p&gt;Thanks again for the capture trick, didn't see it before :-)&lt;/p&gt;</description>
      <pubDate>Sun, 01 Apr 2007 14:32:20 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:5949764b-3bb1-4d38-87cd-c6c9fb043250</guid>
      <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming#comment-112</link>
    </item>
    <item>
      <title>"Lost In Binding - Adventures In Ruby Metaprogramming" by Guy Naor</title>
      <description>&lt;p&gt;Piers,&lt;/p&gt;

&lt;p&gt;This is nice, though like you said, not much different with regard to all the copying of the strings, which I suspect can't be prevented.&lt;/p&gt;

&lt;p&gt;Thanks for the idea!&lt;/p&gt;</description>
      <pubDate>Sun, 01 Apr 2007 10:19:13 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:9ab8eb9d-6f07-4e03-80e8-06ecc0fabba5</guid>
      <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming#comment-111</link>
    </item>
    <item>
      <title>"Lost In Binding - Adventures In Ruby Metaprogramming" by Piers Cawley</title>
      <description>&lt;p&gt;Dang, forgot to replace both calls to &lt;code&gt;hidden_field_tag&lt;/code&gt; in that rewritten &lt;code&gt;secure_form_tag&lt;/code&gt;. &lt;em&gt;L'esprit d'escalier&lt;/em&gt; strikes again.&lt;/p&gt;</description>
      <pubDate>Sat, 31 Mar 2007 16:41:09 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:3a278c55-305f-48d9-9597-1e0ba165fd25</guid>
      <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming#comment-110</link>
    </item>
    <item>
      <title>"Lost In Binding - Adventures In Ruby Metaprogramming" by Piers Cawley</title>
      <description>&lt;p&gt;Ah yes, of course.&lt;/p&gt;

&lt;p&gt;Further inspection of the docs suggests that:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def security_token_field
  hidden_field_tag &amp;quot;session_id_validation&amp;quot;), security_token
end

def concatenator(binding)
  lambda {|str| concat(str, binding)}
end

def secure_form_tag(*form_tag_params, &amp;amp;block)
  if block_given?
    form_body = capture &amp;amp;block;
    concatenator(block).call \
      form_tag(*form_tag_params) { security_token_field + form_body }
  else
    &amp;quot;#{form_tag(*form_tag_params)}
#{hidden_field_tag('session_id_validation', security_token)}&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Should do the trick. All that ugliness with &lt;code&gt;string_eval&lt;/code&gt; still happens, but it's hidden behind the abstraction wall.&lt;/p&gt;

&lt;p&gt;I may have got a little bit Higher Order Function happy on &lt;code&gt;concatenate&lt;/code&gt;'s ass.&lt;/p&gt;</description>
      <pubDate>Sat, 31 Mar 2007 16:39:05 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:77c6ae85-ee76-4c8e-b08c-a363b9c61263</guid>
      <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming#comment-109</link>
    </item>
    <item>
      <title>"Lost In Binding - Adventures In Ruby Metaprogramming" by Guy Naor</title>
      <description>&lt;p&gt;Piers,&lt;/p&gt;

&lt;p&gt;Unfortunately this can't work. I wish it was that simple :-).&lt;/p&gt;

&lt;p&gt;The reason it doesn't, is that when using &lt;pre&gt;form_tag(...) do end&lt;/pre&gt; the form and /form tags wrap the form elements around the block. And so our added hidden field will be outside the form. We need a way to inject the hidden field into the block.&lt;/p&gt;</description>
      <pubDate>Fri, 30 Mar 2007 09:02:42 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:8db3d321-c9f9-45c9-ab6f-9a8d51ef38b2</guid>
      <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming#comment-108</link>
    </item>
    <item>
      <title>"Lost In Binding - Adventures In Ruby Metaprogramming" by Piers Cawley</title>
      <description>&lt;p&gt;I've not tried it, but what's wrong with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;form_tag(url_for_options, *parameters_for_url, &amp;amp;block)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you don't create a new block, you don't have to create a new binding.&lt;/p&gt;</description>
      <pubDate>Fri, 30 Mar 2007 03:15:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:94e78043-76b7-45c3-9bf4-cbf5ec6a6003</guid>
      <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming#comment-107</link>
    </item>
    <item>
      <title>"Lost In Binding - Adventures In Ruby Metaprogramming" by K. Adam Christensen</title>
      <description>&lt;p&gt;What if you just did a concat on the hidden tag and the block's binding and then pass that block into the form_for method.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://pastie.caboo.se/50396" rel="nofollow"&gt;http://pastie.caboo.se/50396&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not tested, but an idea.&lt;/p&gt;</description>
      <pubDate>Thu, 29 Mar 2007 16:58:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:8db4acd5-96ae-4d85-816f-9957dbfffec3</guid>
      <link>http://devblog.famundo.com/articles/2007/03/28/lost-in-binding-adventures-in-ruby-metaprogramming#comment-106</link>
    </item>
  </channel>
</rss>
