On 3/2/07, Gary Wright <gwtmp01 / mac.com> wrote:
>
> On Mar 1, 2007, at 9:49 PM, dblack / wobblini.net wrote:
> > I guess I tend to think in terms of error handling: that is, let
> > objects call [], but catch the ones that fail, or the ones that hand
> > back nonsense (in the context) values.
>
> Let me make the situation a little more concrete.
>
> I'd like to define a class that accepts the following syntax for
> construction:
>
>         A.new
>         A.new(1)
>         A.new(1,2)
>         A.new(3 => 4)
>         A.new(1, 3 => 4)
>         A.new(1, 2, 3 => 4)
>
> So the arguments to A.new are zero or more objects followed by an
> optional hash. I can certainly look for that trailing hash via
> (Hash === args.last) but what if I don't want to lock it down to
> a Hash?
>
>         tree = RBTree.new
>         A.new(1, 2, tree)
>
> I'd like that to work also and I'm sure there are other sorts of
> objects that would work just fine (i.e. respond to #fetch/#[], has_key?,
> and perhaps is Enumerable). If I use a class based test to discover
> if the last argument is an instance of Hash, I'm eliminating those
> other possibilities.  I also don't want to use args.last[key] and
> catch an exception because that is only useful *after* I've
> discovered if an optional final hash-like object has been passed.
>
> I could have different constructors:
>
>         A.new(1)
>         A.new_with_hash(1, 1=>2)
>
> but it really isn't as nice, IMHO.
>
> At first I thought I could use respond_to?(:[]) on the last argument,
> but as I said in the original post integers and strings will create

Is it *really* a problem that strings and integers produce values that
your method would make use of? Say someone wants to encode those input
parameters into a string - as long as [] works, they can. Why is this
a problem?