Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

trim() magic

by japhy (Canon)
on Oct 14, 2000 at 03:32 UTC ( [id://36684]=CUFP: print w/replies, xml ) Need Help??

It's the typical trim(), with optional in-place behavior, and $_ argument defaulting.
sub trim { @_ = $_ if not @_ and defined wantarray; @_ = @_ if defined wantarray; for (@_ ? @_ : $_) { s/^\s+//, s/\s+$// } return wantarray ? @_ : $_[0] if defined wantarray; } trim; # trims $_ inplace $new = trim; # trims (and returns) a copy of $_ trim $str; # trims $str inplace $new = trim $str; # trims (and returns) a copy of $str trim @list; # trims @list inplace @new = trim @list; # trims (and returns) a copy of @list

Replies are listed 'Best First'.
Re: trim() magic
by Roy Johnson (Monsignor) on Jan 11, 2006 at 19:43 UTC
    What does the assignment @_ = @_ accomplish?

    Caution: Contents may have been coded under pressure.
      It breaks the aliasing nature of the elements in @_.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: trim() magic
by dragonchild (Archbishop) on Mar 30, 2005 at 14:21 UTC
    On the theory that storing the return from wantarray is always faster than computing it between 2 and 4 times, I was going to suggest the following:
    sub trim { if (defined my $w = wantarray) { @_ = ( @_ ? @_ : $_ ); for (@_) { s/^\s+//, s/\s+$// if $_ } return $w ? @_ : $_[0]; } else { for (@_ ? @_ : $_) { s/^\s+//, s/\s+$// if $_ } } }
    The if $_ is to protect against warnings for undefined values.

    Unfortunately, it turns out that I was wrong. Your version is usually faster than mine. The only place I'm faster is my $x = trim();. I'm not sure that case is worth making the code harder to read. (Though, if this were added to something like Scalar::Util, I would code it my way.)

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: trim() magic
by Aristotle (Chancellor) on Jan 13, 2006 at 03:48 UTC

    I tried to see if there were any knobs to twiddle on this one, using dragonchild’s benchmark cases.

    First thing I tried: using a recursive call to alias $_. This lets you get rid of the ternary in the for list.

    sub trim { return trim( $_ ) if not @_; @_ = @_ if defined wantarray; for ( @_ ) { s/^\s+//, s/\s+$// } return wantarray ? @_ : $_[ 0 ] if defined wantarray; }

    On my setup this is about 15% slower for the “inplace replacement of implicit $_” case, but ekes out a few percentage points on the other cases. But it let me proceed to switch from duplicate defined wantarray tests to a duplicate inner loop:

    sub trim2 { return trim2( $_ ) if not @_; return map { local $_ = $_; s/^\s+//, s/\s+$//; $_ } @_ if defined wantarray; for ( @_ ) { s/^\s+//, s/\s+$// } }

    This gets back most of the lost speed in the “inplace replacement of implicit $_” case, has roughly the same performance in other void contexts, but is also about 50% faster in many other cases, including the IMHO most important one – passing a scalar and assigning to one.

    Makeshifts last the longest.

      What I’d do differently now: at least this:

      sub trim2 { return trim2 $_ if not @_; return map { s/^\s+//; s/\s+$//; $_ } my @c = @_ if defined wantarray; for ( @_ ) { s/^\s+//, s/\s+$// } }

      And someone who can be bothered should benchmark the following variants:

      sub trim3a { return trim3a $_ if not @_; s/^\s+//, s/\s+$// for wantarray ? my @c = @_ : defined wantarray ? my $c = $_[-1] : @_; @c ? @c : $c ? $c : (); } sub trim3b { return trim3b $_ if not @_; my $w = wantarray; s/^\s+//, s/\s+$// for $w ? my @c = @_ : defined $w ? my $c = $_[-1] : @_; @c ? @c : $c ? $c : (); }

      Makeshifts last the longest.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://36684]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2024-03-28 07:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found