On Tue, Apr 20, 2004 at 12:01:44AM +0900, ts wrote: > >>>>> "Z" == Zsban Ambrus <ambrus / math.bme.hu> writes: > > Z> def mypr; if block_given?; then proc do yield; end; else proc do puts > Z> "default"; end; end; end; p= mypr do puts "hi"; end; 5.times(&p); q= mypr; > Z> 5.times(&q); > > Well, try this > > def mypr; if block_given?; then proc do yield; end; else proc do > puts "default"; break; end; end; end; p= mypr do puts "hi"; break; end; > 5.times(&p); q= mypr; 5.times(&q); > > > This is not me which have tried to obfuscate the code :-))) ... > Guy Decoux 0. Sorry for the one-liner. 1. Only the first break causes a problem: def mypr; if block_given?; then proc do yield; end; else proc do puts "default"; end; end; end; p= mypr do puts "hi"; break; end; 5.times(&p); q= mypr; 5.times(&q); works as expected, that is, the "hi" block breaks out. 2. The problem with the first break is that it is not in the lexical scope of the times loop. This just shows that ruby has a nice lexical semantics for break, unlike perl in which the loop control statements act on the innermost dynamically enclosing block, and if it has a label, it will search for it in the dynamical scope. I consider this an advantage. Look. In a perl code like sub twice (&) { $_[0](); $_[0](); } # ... later ... BACK: print "before twice:\n"; twice { print "hello\n"; rand()<0.5 and goto BACK; }; Although you can jump to the label BACK, you must first make sure that the sub `twice' (which may be written by someone else) does not have a label called BACK. Although ruby does not have labeled loop control statements and gotos, it is still better if the loop control statements work in a lexical fashion (that is, they will jump only with respect to the visible loop that is near the jump-control statement in the code), especially because of the greater role of iterators (as compared to perl). This is of course only my opinion, you may still think that dynamic control sturctures are better. And btw, ruby has both: exceptions are dynamic, callcc and loop control are lexical in this sense. 3. This has nothing to do with making a proc from the yield-block. def mypr (&f); if block_given?; then f; else proc do puts "default"; end; end; end; p= mypr do puts "hi"; break; end; 5.times(&p); q= mypr; 5.times(&q); works the same and def mypr (&f); if block_given?; then f; else proc do puts "default"; break; end; end; end; p= mypr do puts "hi"; break; end; 5.times(&p); q= mypr; 5.times(&q); fails the same as above. ambrus