Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

trim() magic

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

Description: 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
Comment on trim() magic
Download Code
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 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 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.

Back to Snippets Section

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2014-12-27 07:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (176 votes), past polls