Re: Safe list assignment
[email protected] ("Chas. Owens")
| Newsgroups | perl.beginners |
|---|---|
| Message-ID | <[email protected]> |
On Tue, May 27, 2008 at 6:00 AM, Ed Avis <[email protected]> wrote: > Perl's list assignment feature is very useful. > > sub returns_three_things { return (1, 2, 3) } > my ($x, $y, $z) = returns_three_things(); > > Often, though, you want to add some error checking. Particularly when providing > an interface that others can call. > > # Parameters: first name, last name, birthday. > sub print_person_details { > croak 'pass three arguments' if @_ != 3; > my ($first_name, $last_name, $birthday) = @_; > say "$first_name $last_name was born on $birthday"; > } > > The extra 'croak' test gives a more friendly error message than 'use of > uninitialized value in ...', which would require the user of the subroutine to > go digging in its code to find what he passed wrongly. > > Even in code that's not part of a public interface, you may want to check that > the list has the right size before you do the assignment, just to catch > programmer mistakes early rather than waiting for an uninitialized value warning > later on. > > But it's rather a pain to keep checking the list size each time. When you > 'unpack a tuple' in Python the size is checked and an exception is thrown if > it's too big or too small. Is there an equivalent in Perl? Something like > > safe_assign ($a, $b, $c) = @array; # will die if scalar(@array) != 3 snip 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)], @_); } sub test2 { safe_assign(); } for my $i (0 .. 4) { my @args = 1 .. $i; eval { test(@args) }; print "args were: (@args)\nerror was: $@\n" if $@; } test2(); } -- Chas. Owens wonkden.net The most important skill a programmer can have is the ability to read.