http://qs1969.pair.com?node_id=50593


in reply to How do you chomp your chomps?

chomp is based on chop and chop modifies in place so that it can return the character that was chopped, so it makes some sense to have chomp also modify in place since it just a "safer chop". chomp can also work on a list of items, in which case the return value is more than a Boolean.

Also, shortening a string in place is extremely efficient. To return a modified value would require allocating another buffer and copying nearly the entire string.

There are several operations that modify in place: s///, tr///, read(), sysread(), etc. For most of them, I've run into cases where I'd rather have them return the modified value so I do see your point. But the inconvenience is fairly minor -- we just get used to not having to up with even minor inconvenience because we are using Perl. (:

Also, if it only returned the modified value (and didn't also modify in place), then you'd constantly be writing $input_line= chomp($input_line) and requiring the repetition isn't good. If it modified in place and returned the modified value, then there'd be no good way to tell if a modification took place.

So it's a mixed bag. :-}

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re: How do you chomp your chomps?
by Anonymous Monk on Jan 09, 2001 at 04:11 UTC
    And, of course, one could always write their own little function such as:
    sub my_chomp { my $str = shift; chomp($str); return $str; }
    Though this doesn't handle arrays, it also doesn't modify the input string in place.
      Well, heck. If we're gonna go that route, may as well golfuscate it:
      sub my_chomp { substr shift, 0, (length) - 1 if $_[0] =~ /\n$/}; # :-)

      Cheers,
      Ovid

      Update: Can anyone tell that I am *seriously* bored at work?

      sub my_chomp { wantarray ? (map{ /\n$/ ? substr $_, 0, (length)-1 : $_ + } @_) : chomp(my $x = shift),$x };
      That ugly hack will work for both arrays and scalars (I think). I noticed that it appears to be returning an empty element at the end of the array, though. :(

      Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

        All fine and good while $/ is \n. Dunno about you :), but I've been known to change it now and then:

        sub my_chomp { substr shift, 0, ((length) = length($/)) if $_[0] =~ /$\$/};

        Untested, but I would like to point out that the regex is pretty.

        Why not go ahead and Make A Better Chomp(tm)? Here's my first stab at it; it basically follows the rules of:
        1. Currently just strips all trailing white space
        2. If passed a reference, operate on it directly (duh! But also works for passing arrays of references) and return a dud value
        3. Otherwise return the modified string(s) without touching the originals.
        4. Works on scalar, arrays and hashes (why not? :) It modifes the values, not the keys, though it would be no problem to add that, too)
        5. Recursive (didn't a just read something here about "real" uses of recursion?) so you can use wacky data structures.

        I didn't put a lot of brainpower into this; just wanted to share a thought of improvement. Enjoy!

        sub mchomp { my @a=@_; local $_; foreach (@a) { if (ref $_ eq 'SCALAR') { $$_=~s/\s+$//; } elsif (ref $_ eq 'ARRAY') { @$_=mchomp(@$_); } elsif (ref $_ eq 'HASH') { for my $k (keys %$_) { $_->{$k}=mchomp($_->{$k}); } } else { s/\s+$//; } } wantarray ? @a: $a[0]; }

        Examples

        ## returns the modified string print mchomp $string; ## modifies the variable directly mchomp \$string; print $string; ## returns an array of modified strings print join ",",mchomp @array; ## modifes the array inplace mchomp \@array; print join ",",@array; ## returns the modified hash %new=mchomp %hash;print values %new; ## modifes the hash inplace mchomp \%hash;print values %hash;