On Thu, Jul 18, 2002 at 12:39:06PM +0100, Mark Fowler wrote:
> Oh finally a note on some syntax that we can't support with splice and
> still do the right thing. In order for this to work correctly
> (auto-promotion of a scalar to a list)
>
> splice(10,0,ascalar)
>
> This can't work
>
> splice(10,0,ascalar,asecondscalar,athirdscalar)
>
> As we can't tell then if this
>
> splice(10,0,alistcontainingjustonescalar)
>
> means insert that scalar at the 11th place in the list, or insert a
> listref containing that scalar at the 11th place in the list.
I believe the solution I posted in my previous message is the best
general purpose solution to this (but of course I'm willing to hear
opinions to the contrary... :-)
If you pass multiple arguments as a replacement list then they're spliced
into the list:
splice(offset, length, foo, bar, baz)
If you pass one argument which is a *not* a reference to a list then
it gets splice in as above:
splice(offset, length, foo)
However, if that one item is a list, then the contents of the list
get spliced in.
items = [ foo, bar, baz ]
splice(offset, length, items)
Now this could be ambiguous, but I believe it's more convenient for
the general case. And it's easy to explicitly disambiguate certain
cases, e.g.
splice(offset, length, [ items ]) # splice ref to items list
I think it's much less likely (although not improbable) that you're
going to want to splice a single reference to a list into another
list. Much more common for you to want to add a bunch of items to
a list, or to add the contents of one list to another.
Larry, Huffman coding, etc. Make the people who want to do the slightly
more complex things have to write the slightly more complex code.
The alternatives are to treat a single item as a single item, be it
a list reference or otherwise, or to ensist that 'replace' is specified
as a reference to a list whose contents are spliced into the list.
Let's look at them. First, we expect splice() to take a list of items:
splice(offset, length, foo)
splice(offset, length, foo, bar)
Like this, it would be very hard, if not impossible to splice in the
contents of a list. If you knew how long it was you could do this:
splice(offset, length, items.0, items.2, etc...)
but otherwise, you would be stumped.
The other alternative is to force the 'replace' parameter to be a single
list. Then we can easily add the contents of a list:
splice(offset, length, items)
or to add multiple items:
splice(offset, length, [ foo, bar, baz ])
a single item can be add like so:
splice(offset, length, [ foo ])
or
splice(offset, length, foo.list)
What should our splice virtual method do if the replace argument isn't
a reference to a list? Well, the nice behaviour would be to promote it
to a single element list. Then it just works as expected when you do this:
splice(offset, length, foo)
And if we're allowing the user to add a single item this way, then it
makes sense to provide them with the convenience of adding multiple
items this way:
splice(offset, length, foo) # this works...
splice(offset, length, foo, bar) # ...so why shouldn't this?
So now we've come full circle, back to where we started. If they pass
a single item and it's a list then we take the contents. Otherwise,
we treat it as a list of items.
Good, bad or ugly? :-)
A