On Thu, Jun 19, 2003 at 04:59:32PM +0900, Markus Jais wrote:
> >class Array
> >
> >    def each_if(b)             # no &
> >        each do |e|
> >            if b.call(e)
> >                print "e: ", e, "\n"
> >                yield e
> >            end
> >        end
> >    end
> >
> >end
> 
> thanks. that works fine. the print was just for debugging. I will use this 
> for something else than the array class but the example was easier.
> 
> just for my understanding:
> what is the difference between using "proc" as in your example and using "&" 
> in the method definition like "def each_if(&b)

& reifies the "implicit block", that is, the one passed as in 
   somemethod { |x| foo(x) }

In your method, you needed 2 blocks:
 * the condition
 * the code the be executed in case the condition is true

In your first code, IIRC something like 
    def each_if(&b)    
        each do |e|
            if b.call(e)
                print "e: ", e, "\n"
                yield e
            end
        end
    end
both b.call and yield would execute the "implicit" block (code on
match), not the condition. That's why, as you need 2 different blocks,
one of them has to be passed explicitly as a Proc.

> one thing I found is that the "&b" solution does not work because of syntax 
> reasons.
> 
> ../bl.rb:20: syntax error
> a.each_if { |x| x > 4 } { |e| puts e }

I guess you were trying to do
def each_if(&condition, &block)
 each {|e| block[e] if condition[e]}
end

but this won't work because you can only pass one block to the function,
if you need more they have to be converted by hand to Proc with
Kernel.proc and then passed as normal parameters.
 
> are there any other differences ??
> according to the documentation both create a Proc object.

If no block is passed to
  def foo(&block)
  end

block.call(bla) will fail w/ NameError (undefined method `call' for nil)
whereas yield will raise a LocalJumpError (no block given).

-- 
 _           _                             
| |__   __ _| |_ ___ _ __ ___   __ _ _ __  
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
	Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Turn right here. No! NO! The OTHER right!