I notice after a Perl upgrade my hard working scripts started returning the
error "Too many arguments for undef operator".
My code includes lines such as:
undef ($var, @array, %hash, $var2);
The new documentation also tells me that I can now only undef one array /
scalar / hash at a time.
My 2 Questions are:
1) Is there another way I can undef multiple scalars / arrays / hashes at
once under the newer versions of Perl without having to add undef functins
for EVERY variable I want to undef?
2) Why was this tedious and annoying limit imposed on the newer versions of
Perl?
Thanks
aL
undef LIST never worked. See the perldelta manpage (for 5.6.1) :
Expressions such as:
print defined(&foo,&bar,&baz);
print uc("foo","bar","baz");
undef($foo,&bar);
used to be accidentally allowed in earlier versions, and produced
unpredictable behaviour.
--
Rafael Garcia-Suarez / http://rgarciasuarez.free.fr/
As luck would have it, I just figured it out myself two secs ago... :)
For other who were ignorant like me, just ditch the brackets, ie:
undef $var, @array, %hash, $var2;
Thanks again.
aL
"Rafael Garcia-Suarez" <rgarci...@free.fr> wrote in message
news:slrn9pbne0.r96...@rafael.kazibao.net...
> As luck would have it, I just figured it out myself two secs ago... :)
No, you haven't.
> For other who were ignorant like me, just ditch the brackets, ie:
> undef $var, @array, %hash, $var2;
Wont work. This will only undef $var and leave the other variables
untouched.
Tassilo
--
$a=[(74,116)];$b=[($a->[1]-1,$a->[1]++,0x20)];$c=[(97,110)];$d=[($c->
[1]+1,$b->[1],"her")];for(@{[$a,$b,$c,$d]}){for(@{$_}){$_=~/\d+/?print
(chr($_)):print;}}$c=sub{$l=shift;[(0x20+$l-1,0x50,0x65,0x73-0x01,108
),(0x20,0x68,0x61,)]};print(map{chr($_)}@{($c->(1))});$h={a=>33*3,b=>
10**2+7,c=>"1"."0"."1",d=>0162};@h=sort(keys(%$h));for(@h){print(chr(
ord(chr($h->{$_}))))};
So is there, or isn't there, a way to undef multiple variables at once?
aL
"Tassilo von Parseval" <Tassilo....@post.rwth-aachen.de> wrote in
message news:3B95E2B5...@post.rwth-aachen.de...
> Arrrghh!
>
> So is there, or isn't there, a way to undef multiple variables at once?
Don't know any such built-in function. You can do:
map { undef $_ } ($a, $b, @c);
Thanks for that.
"Tassilo von Parseval" <Tassilo....@post.rwth-aachen.de> wrote in
message news:3B95E505...@post.rwth-aachen.de...
The correct way to do this in later versions of Perl is to use lexical
variables in a code block.
#!/usr/bin/perl -w
use strict;
my $file_scope;
# do something with $file_scope
while ( <> ) {
my $block_scope;
# do something with $file_scope and/or $block_scope
}
# The variable $block_scope no longer exists
# do something with $file_scope
__END__
The variable $file_scope no longer exists
John
--
use Perl;
program
fulfillment
>> So is there, or isn't there, a way to undef multiple variables
>> at once?
> Don't know any such built-in function. You can do:
> map { undef $_ } ($a, $b, @c);
Some people don't like to use C<map> in a void context.
An alternative would be:
undef $_ for $a, $b, @c;
Damian
> My 2 Questions are:
> 1) Is there another way I can undef multiple scalars / arrays / hashes at
> once under the newer versions of Perl without having to add undef functins
> for EVERY variable I want to undef?
you could do:
($scalar, @array, %hash) = ();
hth, tina
--
http://www.tinita.de \ enter__| |__the___ _ _ ___
tina's moviedatabase \ / _` / _ \/ _ \ '_(_-< of
search & add comments \ \ _,_\ __/\ __/_| /__/ perception
Both solutions don't undef @c; they only undef @c elements.
OK, I've got a solution that works :
#!/usr/local/bin/perl -wl
$s = 1;
@a = qw/foo bar/;
%h = ( a => 1, b => 2 );
print defined $s ? 'def' : 'undef';
print defined @a ? 'def' : 'undef';
print defined %h ? 'def' : 'undef';
eval "undef $_" for qw/$s @a %h/;
print defined $s ? 'def' : 'undef';
print defined @a ? 'def' : 'undef';
print defined %h ? 'def' : 'undef';
--> output
def
def
def
undef
undef
undef
>> My 2 Questions are:
>> 1) Is there another way I can undef multiple scalars / arrays / hashes at
>> once under the newer versions of Perl without having to add undef functins
>> for EVERY variable I want to undef?
> you could do:
> ($scalar, @array, %hash) = ();
ok, looking at rafael's solution, i noticed that mine
doesn't really undef the @array and %hash, but normally
that shouldn't matter if you just want do delete all content.
regards,
> OK, I've got a solution that works :
> #!/usr/local/bin/perl -wl
> $s = 1;
> @a = qw/foo bar/;
> %h = ( a => 1, b => 2 );
> print defined $s ? 'def' : 'undef';
> print defined @a ? 'def' : 'undef';
> print defined %h ? 'def' : 'undef';
> eval "undef $_" for qw/$s @a %h/;
> print defined $s ? 'def' : 'undef';
> print defined @a ? 'def' : 'undef';
> print defined %h ? 'def' : 'undef';
hm, i just tried your version with strict and so i declared
all variables with my(). now i'm getting
defined(@array) is deprecated at -e line 6.
(Maybe you should just omit the defined()?)
defined(%hash) is deprecated at -e line 7.
(Maybe you should just omit the defined()?)
so i guess
($s,@a,%h)=();
should be ok.
There's no difference at the Perl level. Your solution has the advantage
over other solutions that $#a becomes -1.
And I had forgotten that the internal difference should now be
considered accidental and undocumented ;-(
what's wrong with
($a, $b, @c) = ();
--
H.Merijn Brand Amsterdam Perl Mongers (http://www.amsterdam.pm.org/)
using perl-5.6.1, 5.7.1 & 628 on HP-UX 10.20 & 11.00, AIX 4.2, AIX 4.3,
WinNT 4, Win2K pro & WinCE 2.11 often with Tk800.022 &/| DBD-Unify
ftp://ftp.funet.fi/pub/languages/perl/CPAN/authors/id/H/HM/HMBRAND/
> } > map { undef $_ } ($a, $b, @c);
> }
> } Some people don't like to use C<map> in a void context.
> } An alternative would be:
> }
> } undef $_ for $a, $b, @c;
>
> Both solutions don't undef @c; they only undef @c elements.
>
>
I don't see why they should not undef @c:
ethan@ethan:~$ perl
@a = wq(1 2 3);
undef @a;
if (! defined @a) { print 'not defined' }
^D
not definedethan@ethan:~$
So according to Perl, the array @a has been undefed.
As for the deprecation: this has been already mentioned.
But (! @a) is still true after undefing the array.
> Rafael Garcia-Suarez wrote:
> > Damian Conway wrote in comp.lang.perl.misc:
> >
> > } } undef $_ for $a, $b, @c;
>
> > Both solutions don't undef @c; they only undef @c elements.
>
>
> I don't see why they should not undef @c:
>
> ethan@ethan:~$ perl
> @a = wq(1 2 3);
> undef @a;
^^
> if (! defined @a) { print 'not defined' }
> ^D
> not definedethan@ethan:~$
now try the same thing with
undef $_ for @a;
and you'll see the difference. To go from @a to ($a, $b, @c) is left
as an exercise for the reader.
-mona
That doesn't work either:
my ($a, $b, @c) = (1..20);
map {undef $_} ($a, $b, @c);
print "\@c still has ", scalar(@c), " elements.\n";
aL, the most correct answer to your question may be that if you need
to 'undef' a lot of variables, you are probably doing something wrong.
Normally, the best way to build the program is to declare the
variables with 'my' in the scope in which they are used. For example,
instead of this:
while (something) {
undef $a; undef $b; undef @c;
# do something with $a, $b, @c...
}
You can use this:
while (something) {
my ($a, $b, @c);
# do something with $a, $b, @c...
}
The 'my' arranges that each time the loop executes, new, fresh
versions of $a, $b, and @c are used, and they are always automatically
'undef'.
Does that help?
--
@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print
> now try the same thing with
>
> undef $_ for @a;
>
> and you'll see the difference. To go from @a to ($a, $b, @c) is left
> as an exercise for the reader.
Ah, shit, indeed. ($a, $b, @c) of course becomes a flat list
($a, $c, $c[0], $c[1], ...)
I totally overlooked this.
>dam...@cs.monash.edu.au (Damian Conway) wrote in news:9n4q4a$e2a$1
>@towncrier.cc.monash.edu.au:
>> Tassilo von Parseval <Tassilo....@post.rwth-aachen.de> writes:
>>
>> >> So is there, or isn't there, a way to undef multiple variables
>> >> at once?
>>
>> > Don't know any such built-in function. You can do:
>>
>> > map { undef $_ } ($a, $b, @c);
>>
>> Some people don't like to use C<map> in a void context.
>> An alternative would be:
>>
>> undef $_ for $a, $b, @c;
>what's wrong with
> ($a, $b, @c) = ();
Nothing. It depends which effect you want.
All I was pointing out was that C<undef $_ for ...> is cleaner than
C<map { undef $_ } ...>
Damian
>> what's wrong with
>> ($a, $b, @c) = ();
DC> Nothing. It depends which effect you want.
DC> All I was pointing out was that C<undef $_ for ...> is cleaner than
DC> C<map { undef $_ } ...>
and i wish to point out that undef on aggregates is not what most people
want. it deletes the entire variable and means it needs more work to
reinstantiate it. assigning () to a hash or array is much cleaner and
easier to read.
i never like seeing undef used as a function with a variable as an
arg. i prefer using it bare and only for its value of undef.
and as someone else said, doing undef on a bunch of vars usually implies
a design flaw in the program. it is rare to need undef like that.
uri
--
Uri Guttman --------- u...@sysarch.com ---------- http://www.sysarch.com
SYStems ARCHitecture and Stem Development ------ http://www.stemsystems.com
Search or Offer Perl Jobs -------------------------- http://jobs.perl.org
Silly people.
!! An alternative would be:
!!
!! undef $_ for $a, $b, @c;
Yeah, except that doesn't undef @c - just its elements.
An alternative would be to start all the variables you want to undef
with a particular letter, say U. No other variables should start with U.
Also, the variables should be package variables.
Then you can undefine them using the little known function reset:
reset "U";
Abigail
--
#!/opt/perl/bin/perl -w
$\ = $"; $; = $$; END {$: and print $:} $SIG {TERM} = sub {$ := $_}; kill 15 =>
fork and ($; == getppid and exit or wait) foreach qw /Just another Perl Hacker/
That would require the variables to be package variables.
Anno
>> Then you can undefine them using the little known function reset:
>>
>> reset "U";
>
>That would require the variables to be package variables.
That's clearly stated in Abigail's post.
Cheers,
Bernard
--
perl -l54e's yyw q q tvmrx "h\ywx ersxliv zivp legoiv"qiy;y #a-zA-Z#d-gu-z#
chefghijklmnopqrstuvwxyzcJab-def-uPwxyzc;s j j s u u s t t s r r s
ppevalpereeteueje'
Uh, yes. Recently I listed three methods to make people overlook a
statement. I'll amend:
- Print it in all-caps
- Draw a box around it
- Put it in the first sentence
- Put it in the last sentence
:-)
Anno
>My code includes lines such as:
>undef ($var, @array, %hash, $var2);
>
>The new documentation also tells me that I can now only undef one array /
>scalar / hash at a time.
>
>My 2 Questions are:
>1) Is there another way I can undef multiple scalars / arrays / hashes at
>once under the newer versions of Perl without having to add undef functins
>for EVERY variable I want to undef?
>2) Why was this tedious and annoying limit imposed on the newer versions of
>Perl?
It's always been like that. Silly, counter-intuitive even, but true.
An alternative:
($var, @array, %hash, $var2) = ();
--
Bart.
> Yeah, except that doesn't undef @c - just its elements.
>
>
> An alternative would be to start all the variables you want to undef
> with a particular letter, say U. No other variables should start with U.
> Also, the variables should be package variables.
>
> Then you can undefine them using the little known function reset:
>
> reset "U";
Which is very errorprone if you (by accident) use a variable that also starts
with a 'U' but you don't want to reset.
A much cleaner way to do the same is to use a hash (%U) populated with the
variables you want to reset
@U{qw( a b c )} = ( 1, "x", [ 0, "12S" ] );
and later
%U = ();
<CODE>
my $Scalar="hello";
my @array=(1,2,3,4);
my %hash=('A' => 1, 'B' => 2);
sub my_undef {
while ($_=shift) {
undef ${$_},next if ref eq "SCALAR";
undef @{$_},next if ref eq "ARRAY";
undef %{$_},next if ref eq "HASH";
}
}
print "Scalar ".(defined $Scalar?"":"un")."defined\n";
print "Array ".(defined @array?"":"un")."defined\n";
print "Hash ".(defined %hash?"":"un")."defined\n";
my_undef(\$Scalar,\@array,\%hash);
print "Scalar ".(defined $Scalar?"":"un")."defined\n";
print "Array ".(defined @array?"":"un")."defined\n";
print "Hash ".(defined %hash?"":"un")."defined\n";
<END CODE>
/jN
> I've come up with a subroutine that works.
Admittedly a nice and pleasantly exotic solution. Yet, it wont always work:
$a = "hello";
$b = \$a;
$c = \$b;
print ref $c;
__END__
REF
So $c would not be undef()ed since it is neither a SCALAR-, an ARRAY-
nor a HASH-ref.
> sub my_undef {
> while ($_=shift) {
> undef ${$_},next if ref eq "SCALAR";
> undef @{$_},next if ref eq "ARRAY";
> undef %{$_},next if ref eq "HASH";
> }
> }
Tassilo
> print ref $c;
> REF
> So $c would not be undef()ed since it is neither a SCALAR-, an ARRAY-
> nor a HASH-ref.
not to talk about GLOB, CODE, LVALUE, ...
>> So $c would not be undef()ed since it is neither a SCALAR-, an ARRAY-
>> nor a HASH-ref.
> not to talk about GLOB, CODE, LVALUE, ...
okay, ignore CODE and LVALUE... it's just GLOB...
i'm typing quicker than thinking i guess... :-/
>>not to talk about GLOB, CODE, LVALUE, ...
>>
>
> okay, ignore CODE and LVALUE... it's just GLOB...
> i'm typing quicker than thinking i guess... :-/
No, CODE is in fact a valid ref-type so that's one more that should be
taken into account when rolling one's own undef() function.
>>>not to talk about GLOB, CODE, LVALUE, ...
>>>
>>
>> okay, ignore CODE and LVALUE... it's just GLOB...
>> i'm typing quicker than thinking i guess... :-/
> No, CODE is in fact a valid ref-type so that's one more that should be
> taken into account when rolling one's own undef() function.
yes it is, but a reference to CODE is still a REF, and with your
addition of REF it would work. if you always feed references to the
my_undef() it will only be HASH, SCALAR, ARRAY, REF and GLOB.
(not sure about LVALUE, though)
but anyway, as others pointed out,
i really think there's no need for undef(@array).
i don't see where it could be necessary to make a difference
between if (@a) and defined(@a). (it's deprecated anyway... =)
regards,
tina
> yes it is, but a reference to CODE is still a REF, and with your
> addition of REF it would work. if you always feed references to the
> my_undef() it will only be HASH, SCALAR, ARRAY, REF and GLOB.
> (not sure about LVALUE, though)
Ah, ok, you had been one step ahead of me.
But as for LVALUE: How can I create a ref to that? I don't think I have
ever seen it before.
: >>not to talk about GLOB, CODE, LVALUE, ...
: >>
: >
: > okay, ignore CODE and LVALUE... it's just GLOB...
: > i'm typing quicker than thinking i guess... :-/
: No, CODE is in fact a valid ref-type so that's one more that should be
: taken into account when rolling one's own undef() function.
I liked Rafael Garcia-Suarez's suggestion best.
Rafael Garcia-Suarez <rgarci...@free.fr> wrote:
> eval "undef $_" for qw/$s @a %h/;
You could put it in a function if you like
sub my_undef { eval "undef $_" foreach @_ }
but you have to remember to call it with qw or such like
my_undef(qw( $s @a %h )) ;
It's the 21st century. People like to live on the edge.
== A much cleaner way to do the same is to use a hash (%U) populated with the
== variables you want to reset
That's so seventies.
Abigail
--
my $qr = qr/^.+?(;).+?\1|;Just another Perl Hacker;|;.+$/;
$qr =~ s/$qr//g;
print $qr, "\n";
Not difficult :
perl -le '$x="a";print ref \substr($x,1);'
--
Twas brillig, and the Protocols
Did USER-SERVER in the wabe.
All mimsey was the FTP,
And the RJE outgrabe. -- RFC 0527
> Does that help?
Thank you to everyone who posted replies to this query. You'll all be glad
to know that the intense, high-level (at least for me) discussion of Perl's
intricacies that's been going on in response to my post has thoroughly
scared the bejesus out of me ... enough so, in fact, that I'm now been
motivated to take everybody's advice and rewrite my volumous code so that I
won't need undef in the first place. :)
Thanks again for all your help.
aL
You can put it in a sub, but you can't (usefully) put that sub in a
module. If you did, eval() would be compiled in the context of the
module and my_undef() could only undef lexicals in that scope.
Anno
Perhaps slightly more efficient:
sub my_undef { my $eval;
$eval .= "undef $_;" for @_;
eval $eval; die $@ if $@;
}
(Assuming taint checking is a non-issue since unmentioned)
--
Charles DeRykus