develooper Front page | perl.perl5.porters | Postings from April 2010

Re: trim function example for perlfaq4.pod

Thread Previous | Thread Next
From:
Tom Christiansen
Date:
April 9, 2010 17:55
Subject:
Re: trim function example for perlfaq4.pod
Message ID:
5828.1270860903@chthon
> Here is a trim function that operates in-place in void context, in-line
> in scalar and array contexts, takes an alternate regular expression
> as an optional last argument, and works on C<$_> in the absence of
> other input:

No, don't make it an optional *last* argument; that's messy 
and hides what's really going on.  The pattern is the most
important, so it goes first.  Use the pattern as an optional
invocant, putting it right out in front where it belongs, 
just as split // has it in front for the same reason:

    printf "Trimmed %d strings\n", trim(@strings);

vs
    printf "Trimmed %d strings\n", trim { qr/\s/ } @strings;

There, isn't that much nicer?  

Working proof-of-concept follows, although the trivial exporting into 
the caller's package has been left as an exercise for the reader.

Feel free to make it do that inplace stuff in void context if you
want and have different returns otherwise--so long as you don't
think that makes it unduly complicated.

--tom

    use strict;
    use warnings;

    use Carp ();

    {
        my $rx_class = ref qr//;

        my $trim_fn  = sub {
            my $did = 0;
            my $ws  = q/[\h\v]/;

            if (ref($_[0])) {
                unless (ref($_[0]) eq $rx_class) {
                    Carp::confess("invoked on wrong object type, expected $rx_class");
                }
                $ws = shift;
            } 

            for (@_) {
                $did += 0 <   s/ \A $ws+    //x
                            + s/    $ws+ \Z //x;
            } 
            return $did;
        };

        no strict "refs";
        *trim = *{ $rx_class . "::trim" } = $trim_fn;
    } 

    my @old = ("   so whatever", "you say", "isn't working   \t\cK\t");
    my @new = @old;
    printf "Trimmed %d strings\n", trim(@new);
    for my $i ( 0 .. $#new ) {
        printf "[%d] <%s> => <%s>\n", $i, $old[$i], $new[$i];
    } 

    @new = @old;
    printf "Trimmed %d strings\n", trim { qr/\s/ } @new;
    for my $i ( 0 .. $#new ) {
        printf "[%d] <%s> => <%s>\n", $i, $old[$i], $new[$i];
    } 

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About