Robert Klemme
10/11/2007 9:33:00 AM
2007/10/11, Eric Hodel <drbrain@segment7.net>:
> On Oct 11, 2007, at 24:12 , Anonymous wrote:
> > So I'm new to Ruby and I'm trying to use OptionParser to parse in some
> > command line arguments. I looked at some documentation on
> > OptionParser and there is something that's confusing me to no end.
> > In all the examples a block is being passed in to the constructor
> > of the OptionParser object. The constructor simply makes a yield
> > call, passing self as an argument.
> >
> > What is the point of this? Can we not convert
> >
> > opts = OptionParser.new() {|opts| body}
> >
> > To
> >
> > opts = OptionParser.new()
> > body
> >
> > ? This seems more natural to me. But the former seems like a common
> > Ruby idiom so I'm wondering what I am missing.
>
> It works both ways. Blocks are pretty, so people use them.
There are in fact important differences to both approaches. First,
OptionParser's #initialize is free to yield whatever it decides to the
block. So you are not guaranteed to receive the new OptionParser
instance. This is important to keep in mind because the
implementation might change at a later point so the lib could yield a
different instance which should, of course, support the documented
interface.
Second, with the block form OptionParser#initialize is able to detect
when the user initialization has finished and can do finalizing work.
It could, for example, invoke #freeze to make sure the configuration
is not changed any more. Or it can verify that client code properly
initialized it (avoiding duplicate or ambiguous option settings for
example).
An alternative that some may find nicer would implement OptionParser()
(a method) in Kernel and have that receive the block.
Kind regards
robert