Prev: Split text into equal characters but keeping whole words
Next: watir 1.6.5, ruby 1.8.7 and character encoding problem
From: Regis d'Aubarede on 3 Jun 2010 09:28 Hello, So i try to define a methode by providing a bloc which can contain a yield. I got a error 'no block given (yield)' on yield execution Here is my test code : class B def p1 ; puts "p1"; end def p2 ; puts "p2 1" ; yield ; puts "p2 2" ; end def self.add_tag(name,&blk) puts "defined #{name}..." define_method(name) do instance_eval(&blk) end end def self.add_tag2(name,str_bloc) puts "defined2 #{name}..." module_eval %{ def #{name}() #{str_bloc} end } end end add_tag2 work well, but is not pretty : > B.add_tag2 "p4" "puts 'p4 '; p1 ; p2 { puts 'inp2' } ; yield" defined2 p4... => nil > b.p4 { puts 'in p4' } p4 p1 p2 1 inp2 p2 2 in p4 => nil add_tag give a Exception if bloc contain a yield: > B.add_tag("p5") { puts 'p5 '; yield } defined p5... => #<Proc:0x027edcd4@./essai.rb:6> > b.p5 { puts 'in p5' } p5 LocalJumpError: no block given from (irb):14 from ./essai.rb:7:in `instance_eval' from ./essai.rb:7:in `p5' from (irb):15 from :0 Is there a solution ? Thank you! Attachments: http://www.ruby-forum.com/attachment/4772/essai.rb -- Posted via http://www.ruby-forum.com/.
From: Robert Dober on 3 Jun 2010 11:04 On Thu, Jun 3, 2010 at 3:28 PM, Regis d'Aubarede <regis.aubarede(a)gmail.com> wrote: > Hello, > > So i try to define a methode by providing a bloc which can contain a > yield. This is known as the single biggest PITA of Ruby1.8, well by me. If you can, use Ruby1.9 and you can do such wonderful things as define_method :alpha do |beta, &gamma| . . gamma[...] .. end in 1.8. you have to do some nasty tricks with converting methods to blocks or use simply "eval" or "module_eval" with a string. HTH R.
From: Regis d'Aubarede on 3 Jun 2010 12:22 Robert Dober wrote: > in 1.8. you have to do some nasty tricks with converting methods to > blocks or use simply "eval" or "module_eval" with a string. > I try actualy with 1.9, but no solution by the way ... -- Posted via http://www.ruby-forum.com/.
From: Robert Dober on 3 Jun 2010 13:00 On Thu, Jun 3, 2010 at 6:22 PM, Regis d'Aubarede <regis.aubarede(a)gmail.com> wrote: > Robert Dober wrote: > >> in 1.8. you have to do some nasty tricks with converting methods to >> blocks or use simply "eval" or "module_eval" with a string. >> > > I try actualy with 1.9, but no solution by the way ... > -- ok my bad, you call yield in the "client" block, that cannot work, let us look at what yield really is def implicit yield # invoke the block provided by the client end def explicit &blk blk[] # or blk.call, here it is clearer end now on the client side implicit{ yield } # what shall be invoked here??? obviously explicit{ blk[] } cannot work as blk is the block you provide here, right. Does this make your problem clearer? HTH R. now if you call ex > Posted via http://www.ruby-forum.com/. > > -- The best way to predict the future is to invent it. -- Alan Kay
From: Regis d'Aubarede on 3 Jun 2010 14:28
Here a (partial) solution : class B def p1 ; puts "p1"; end def self.add_tag(name,&blk) define_method(name) do |*args,&blocs| instance_eval { blk.call(*args,&blocs) } end end end b=B.new b.instance_eval { B.add_tag("p5") { |*a,&bb| p1 ; bb.call(*a) ; p1 } } b.p5(1,2,3) {|*a| puts "in bloc p5 : #{a.inspect}" } > p1 > in bloc p5 : [1, 2, 3] > p1 'b.instance_eval' seem necessary for that p1() call in add_tag() bloc bind to 'b' instance Thank you , -- Posted via http://www.ruby-forum.com/. |