Re: Safe list assignment

[email protected] ("Jenda Krynicky")
Newsgroups perl.beginners
Message-ID <[email protected]>
From: "Chas. Owens" <[email protected]>
> Not that I am aware of, but it is a breeze to build one:
> 
> #!/usrbin/perl
> 
> use strict;
> use warnings;
> 
> sub safe_assign {
> 	unless (@_) {
> 		my ($f, $l) = (caller)[1,2];
> 		die "bad number of arguments to safe_assign at $f line $l.\n";
> 	}
> 	my $targets = shift;
> 
> 	my $expected = @$targets;
> 	my $got      = @_;
> 	unless ($expected == $got) {
> 		my ($f, $l) = (caller(1))[1,2];
> 		die "bad number of arguments, exected $expected got $got at $f line $l.\n";
> 	}
> 
> 	for my $target (@$targets) {
> 		$target = shift;
> 	}
> 
> 	return @$targets;
> }
>
> sub test {
> 	safe_assign([my ($one, $two, $three)], @_);
> }
> ...

Except that it doesn't work. Try to print the variables within the 
test(). You'll find out they were never set. The catch is that only 
the @_ contains aliases to the parameters, not the anonymous array.

You'd have to use something as

  safe_assign([\(my ($one, $two, $three))], @_);

to get references to those variables and then change the loop in 
safe_assign() to

 	for my $target (@$targets) {
 		$$target = shift;
 	}

It's not very nice, is it?

It would be better to switch the way you pass the parameters:


  safe_assign( my ($one, $two, $three) => \@assigned_array);


#!/usr/bin/perl
use strict;
use warnings;
use Carp;

sub safe_assign {
    unless (@_) {
        croak "bad number of arguments";
    }
    my $values = pop(@_);

    my $expected = @_;
    my $got      = @$values;
    unless ($expected == $got) {
        croak "bad number of arguments, exected $expected got $got";
    }

    for (0..$#_) {
        $_[$_] = $values->[$_];
    }

    return @_;
}

sub test {
    safe_assign(my ($one, $two, $three) => [@_]);

    print "\$one=$one\n";
}

sub test2 {
    safe_assign();
}

for my $i (0 .. 4) {
    my @args = 1 .. $i;
    eval { test(@args) };
    if ($@) {
        print "args were: (@args)\nerror was: $@\n\n";
    } else {
        print "args were: (@args)\n\n";
    }
}
test2();
__END__


Jenda
===== [email protected] === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed 
to get drunk and croon as much as they like.
	-- Terry Pratchett in Sourcery
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.