Hi there, I''m learning basics with Agile Web Development with Rails, and encountered this piece of code : module StoreHelper def hidden_div_if(condition, attributes = {}, &block) if condition attributes["style" ] = "display: none" end content_tag("div" , attributes, &block) end end which is used like that : <% hidden_div_if(@cart.items.empty?, :id => "cart" ) do %> <%= render(:partial => "cart" , :object => @cart) %> <% end %> After reading some posts about blocks performance issues, I tried to change the code for that : module StoreHelper def hidden_div_if(condition, attributes = {}) if condition attributes["style" ] = "display: none" end content_tag("div" , attributes) {yield} end end But the result is an error (undefined local variable or method `_erbout''). I thought this issue had been fixed (http://dev.rubyonrails.org/ticket/7857), but maybe I''m missing the point. Is my code wrong, is my rails version out-of-date, or what ? Thanks -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Arnaud J. wrote:> def hidden_div_if(condition, attributes = {}, &block) > if condition > attributes["style" ] = "display: none" > end > content_tag("div" , attributes, &block)Look inside the content_tag source. Is it using capture? That takes a &block, and it must treat the block specially to bind to its eRB context.> <% hidden_div_if(@cart.items.empty?, :id => "cart" ) do %> > <%= render(:partial => "cart" , :object => @cart) %> > <% end %>eRB starts by converting <%%> marks into a mishmash of strings and eRB method calls. A simple do-end block would evaluate in the wrong context, so capture() provides the correct context. And you can''t just yield into it.> http://dev.rubyonrails.org/ticket/7857Someone may correct me, but that appears to apply to your first example, not your second. You yielded without a capture, so you yielded in the wrong context. -- Phlip http://www.oreilly.com/catalog/9780596510657/ "Test Driven Ajax (on Rails)" assert_xpath, assert_javascript, & assert_ajax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Jul 20, 2007, at 7:57 , Arnaud J. wrote:> I''m learning basics with Agile Web Development with Rails, and > encountered this piece of code :> After reading some posts about blocks performance issues, I tried to > change the code for that :As you''re just starting out with Rails, I wouldn''t worry about performance issues. Get the basics down and then benchmark your app. If it''s not performing adequately for your specifications, find the bottlenecks of your system, make changes, and benchmark again. Premature optimization at the best of times is a bad idea. As you''re just starting out, it''s likely going to cause you much more grief than any gains you might find. Michael Glaesemann grzm seespotcode net --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Michael Glaesemann wrote:> As you''re just starting out with Rails, I wouldn''t worry about > performance issues.I don''t worry about performance issues. While trying to understand blocks & yield, I found a post about performance issues (this one : http://www.ruby-forum.com/topic/71221#new), and since yield and blocks look like ruby basics, I tried to understand a little more about the difference between using a yield and a .call. In the example given in the topic mentionned above it seems like you can swap between one and another without too much changes. So, I tried to do the same with the method I was playing with, to test my comprehension. I wasn''t looking for the best solution, but for a didactic solution. And I still don''t understand well why my litte {yield} trick doesn''t work. I will try to reformulate. What is the difference between those to methods : def method_ampersand(&b) some_method(&b) end def method_yield some_method {yield} end With some_method defined like that def some_method(&block) #code end and the two methods called like that method_ampersand() { #code to be captured } method_yield() { #code to be captured } It might be a question of context, but I''m still a little bit confused about that. Note that some_method would be like our content_tag of my first post. Thank you for your time -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Arnaud take a look at the Rails source for content_tag: http://pastie.caboo.se/80983 def content_tag(name, content_or_options_with_block = nil, options = nil, &block) if block_given? options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) content = capture(&block) concat(content_tag_string(name, content, options), block.binding) else content = content_or_options_with_block content_tag_string(name, content, options) end end If you give it a block, it calls concat(content_tag_string(name, content, options), block.binding).> module StoreHelper > > def hidden_div_if(condition, attributes = {}) > if condition > attributes["style" ] = "display: none" > end > content_tag("div" , attributes) {yield} > end... If you use content_tag("div" , attributes) {yield} inside your hidden_div_if(), when concat inside content_tag() will be called w/ the binding of you block: {yield}, which has the StoreHelper''s context as to your View''s context: (the original block passed in hidden_div_if). As a result, when concat() gets called inside content_tag, it doesn''t have the right binding and hence missing: "_erbout." I hope this helps. :) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
David Dai wrote:> Arnaud take a look at the Rails source for content_tag: > http://pastie.caboo.se/80983 > > def content_tag(name, content_or_options_with_block = nil, > options = nil, &block) > if block_given? > options = content_or_options_with_block if > content_or_options_with_block.is_a?(Hash) > content = capture(&block) > concat(content_tag_string(name, content, options), > block.binding) > else > content = content_or_options_with_block > content_tag_string(name, content, options) > end > end > > If you give it a block, it calls concat(content_tag_string(name, > content, options), block.binding). > >> module StoreHelper >> >> def hidden_div_if(condition, attributes = {}) >> if condition >> attributes["style" ] = "display: none" >> end >> content_tag("div" , attributes) {yield} >> end > ... > > If you use content_tag("div" , attributes) {yield} inside your > hidden_div_if(), when concat inside content_tag() will be called w/ > the binding of you block: {yield}, which has the StoreHelper''s context > as to your View''s context: (the original block passed in > hidden_div_if). As a result, when concat() gets called inside > content_tag, it doesn''t have the right binding and hence missing: > "_erbout." I hope this helps. :)Thanks - that confirms what I implied, when I was too lazy to look up the actual method! The best way to use capture{} is don''t, guys! (-; -- Phlip http://www.oreilly.com/catalog/9780596510657/ "Test Driven Ajax (on Rails)" assert_xpath, assert_javascript, & assert_ajax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---