In article <KJJim.77878$>,
John W. Krahn <> wrote:
>Tim McDaniel wrote:
>> This is a function which trims leading and trailing whitespace from
>> a variable in-place, operating on $_ if there are no arguments
>> provided. (If the value is undef, it leaves it undef.) I feel a
>> bit unclean using "goto &sub" and hand-manipulation of @_.
>> Opinions? Better ways to do it?
>
>sub trim {
> if ( @_ ) {
> s/^\s+//, s/\s+$// for @_;
> }
> else {
> s/^\s+//, s/\s+$// for $_;
> }
> }
Oo-er. So I should depend on
The array @_ is a local array, but its elements are aliases for
the actual scalar parameters. In particular, if an element $_[0]
is updated, the corresponding argument is updated (or an error
occurs if it is not updatable).
instead of taking references explicitly or implicitly. Hrm. It's a
run-time error instead of compile-time, but it's much more elegant and
Perlish.
Two improvements occur to me.
> s/^\s+//, s/\s+$// for $_;
has the effect of creating a new $_ and aliasing $_ to, um, old $_,
which is not needed. It would be easier to just do
s/^\s+//, s/\s+$//;
> if ( @_ ) {
> s/^\s+//, s/\s+$// for @_;
> }
> else {
> s/^\s+//, s/\s+$// for $_;
> }
looks very symmetric and therefore elegant. But the individual
actions have to fit in a comma expression. Also, the set of
statements are repeated, so any change has to be done in two places --
in particular, one part of the spec is that undef should be silently
ignored, but the above code causes two "Use of uninitialized value $_
in substitution (s///)" warnings.
My first version defined a return value, but I don't really need it,
since the function changes variables. I prefer to always return an
explicit value, if nothing else to prevent accidental communication of
the function's last expression, causing the caller to accidentally
depend on the implementation.
I think I'll do something along these lines:
sub trim(@) {
foreach (@_ ? @_ : $_) {
if (defined $_) {
s/^\s+//;
s/\s+$//;
}
}
return undef;
}
or something equivalent. Maybe I will go for
defined($_) && (s/^\s+//, s/\s+$//) for @_ ? @_ : $_;
Many thanks for the insight.
--
Tim McDaniel,