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


More information about the spug-list mailing list