# SPUG: spug: What is the idiomatic way to extractfirst/lastitemafter split?

DeRykus, Charles E charles.e.derykus at boeing.com
Thu Jun 30 09:28:06 PDT 2005

```
On Wed, Jun 29, 2005 at 11:41:25AM -0700, DeRykus, Charles E wrote:
Rick: Rick Croote wrote:
Rick: DeRykus, Charles E wrote:

Charles:True and the same thing applies to J. Krahn's elegant solution.
Charles: Once
Charles:the output's drained, the rest of the list will be undefined.

Charles: (\$first,\$last) = (split ...)[0,-1];    # \$last undefined if list of 1

Rick: Not true, the slice "[0,-1]" does not "drain", but just reuses the
Rick: same element in the case of one element after the split. This then
Rick: creates the appropriate 2 elements to initialize \$first and \$last.
Rick: Of course, \$string must be initialized to something other than what
Rick: it would split on.
Rick:     my \$string = "one";
Rick:     my (\$first,\$last) = (split /\s+/, \$string)[0,-1];
Rick:     print "\$first\n";
Rick:     print "\$last\n";

Charles:  True, but that's very much semantic overkill in my opinion. I'd  have
Charles: to argue that the result is certainly the same as a "drain"  even ,if
Charles: technically, split is orchestrating the effect.

Yitzchak:Can you expand on that?  Using a list slice on [0,-1] is an idiom to get the first and last elements; Yitzchak: sometimes it looks like this:

Yitzchak:  my (\$min, \$max) = (sort { \$a <=> \$b } @values)[0, -1];

Yitzchak: While there is an argument for writing completely or almost completely idiom free perl,
Yitzchak: I don't see how using an idiom like this could be described as "semantic overkill".  A
Yitzchak: and split's role is just creating the list; I don't understand what you mean by orchestrating.

Ok,  I characterized this as a "drain" because, superficially at least, you're filling a
bigger bucket with a smaller one.  The split output consists of a single item but the
Action of the function split populates \$first with  that single item; and then backfills
\$last with  an undef. Here's what I assume Rick was referring to in claiming that no "drain"
occurred:

perdoc -f split:

When assigning to a list, if LIMIT is omitted, Perl supplies a LIMIT
one larger than the number of variables in the list, to avoid
unnecessary work.

perl -MO=Deparse -e '(\$first,\$last) = split(" ","foo");'
(\$first, \$last) = split(" ", 'foo', 3);

The split really generates only 1 element; behind the scenes, split orchestrates output
so \$first gets populated with that 1 element and then \$last gets backfilled with an 'undef'
because the original list is exhausted. Maybe that seat-of-the-pants explanation is flawed
somehow...

I assume Rick felt that because split generates values for both \$first and \$last this shouldn't
be thought of as a "drain". To me, it just seems natural to call it a "drain" because there's
really a 1 item output and that's trying to fill 2 slots.

--
Charles DeRykus
```