Austin Ziegler
1/29/2005 11:06:00 PM
On Sun, 30 Jan 2005 07:34:10 +0900, Jeff Davis <jdavis-list@empires.org> wrote:
> I know I can define a method like:
> def foo(&p)
> p.call
> end
> def foo
> yield
> end
> First, what's the difference between those two? I can pass a block to
> either.
In the former case, the block is silently converted to a Proc object
(there is a difference -- I'm not sure what -- between a Proc object
created with #proc or #lambda and a Proc object created with
Proc.new). In the latter case, it's not actually turned into an
object. It is easier to pass a Proc object downstream than a block,
unless the natural inclination in all cases is to yield. That is:
def foo
self.each { yield } # yields to the provided block, from within
# the block for #each.
end
> Also, how do I make the block optional? I would like to make a
> method that performs it's task as usual, but you could also pass
> it a block that it can use.
Two ways, depending on what you do:
def foo(&p)
p.call if p
end
def foo
yield if block_given? # a method of Kernel
end
> And also, can you pass more than one block to the same method? Is
> it only the last argument?
You can, but they must be regular parameters, and they must
explicitly be Proc objects:
def foo(cb1 = nil, cb2 = nil)
cb1.call if cb1
cb2.call if cb2
end
> And what's the difference between:
> proc { puts 'foo'}
> and:
> { puts 'foo' }
> ?
Thee former creates a Proc object. The latter is just a block and is
valid only after a method call.
-austin
--
Austin Ziegler * halostatue@gmail.com
* Alternate: austin@halostatue.ca