Prev: gem rake error
Next: pretty inspecting objects?
From: Andy Bogdanov on 28 Jun 2010 08:52 Hello I was trying to make an iterator that goes through a simple tree structure something like that: class Node ... def each_child(&block) @children.each { |child| yield(child) { child.each_child(&block) } } end ... end so i could generate a simple html menu: puts "<ul>" root_node.each_child { |node| puts "<li><a href=\"#{child.link}\">#{child.title}</a></li>" unless node.children.empty? puts "<ul>" yield puts "</ul>" end } puts "</ul>" But it turns out that Ruby syntax prohibits passing blocks to yield. A simple workaround is to use block.call instead of yield everywhere. Is there any good reason for that limitation? -- Posted via http://www.ruby-forum.com/.
From: Robert Klemme on 28 Jun 2010 13:32 On 28.06.2010 14:52, Andy Bogdanov wrote: > I was trying to make an iterator that goes through a simple tree > structure something like that: > > class Node > .. > def each_child(&block) > @children.each { |child| yield(child) { child.each_child(&block) } } > end > .. > end > > so i could generate a simple html menu: > > puts "<ul>" > root_node.each_child { |node| > puts "<li><a href=\"#{child.link}\">#{child.title}</a></li>" > unless node.children.empty? > puts "<ul>" > yield > puts "</ul>" > end > } > puts "</ul>" > > But it turns out that Ruby syntax prohibits passing blocks to yield. A > simple workaround is to use block.call instead of yield everywhere. > > Is there any good reason for that limitation? There is no point in passing a block to yield because yield implicitly calls the block passed to the current method. I think what you really want is this: def each_child(&b) b[self] # or b.call(self) or simply yield self @children.each {|ch| ch.each_child(&b)} self end Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Andy Bogdanov on 28 Jun 2010 17:32 > There is no point in passing a block to yield Maybe there always is a way to avoid using procs and lambdas, but i don't see other easy way in my case (see below). Proc#call accepts blocks, why does yield not? It's almost the same thing. > yield implicitly calls the block > passed to the current method. Thanks for the tip. Forgot that yield belongs to method context only. > def each_child(&b) > b[self] # or b.call(self) or simply yield self > @children.each {|ch| ch.each_child(&b)} > self > end This code will just pass all the elements to a block, there's no way to wrap lower levels into <ul> tag. I need to control what happens before and after each_child so i have use a number of procs as arguments or do this trick with a block. -- Posted via http://www.ruby-forum.com/.
From: Josh Cheek on 28 Jun 2010 18:28 [Note: parts of this message were removed to make it a legal post.] On Mon, Jun 28, 2010 at 7:52 AM, Andy Bogdanov <andy.bogdanov(a)gmail.com>wrote: > Hello > > I was trying to make an iterator that goes through a simple tree > structure something like that: > > class Node > ... > def each_child(&block) > @children.each { |child| yield(child) { child.each_child(&block) } } > end > ... > end > > so i could generate a simple html menu: > > puts "<ul>" > root_node.each_child { |node| > puts "<li><a href=\"#{child.link}\">#{child.title}</a></li>" > unless node.children.empty? > puts "<ul>" > yield > puts "</ul>" > end > } > puts "</ul>" > > But it turns out that Ruby syntax prohibits passing blocks to yield. A > simple workaround is to use block.call instead of yield everywhere. > > Is there any good reason for that limitation? > -- > Posted via http://www.ruby-forum.com/. > > Looks like you can get it to work by explicitly taking the block, rather than trying to yield. def foo(&block) block.call 1 do 2 end end foo do |param,&block| puts "The param is #{param}" puts "The block is #{block.call}" end I checked it on 1.8.7 - 1.9.2, it does not work on 1.8.6, though.
|
Pages: 1 Prev: gem rake error Next: pretty inspecting objects? |