From: Vincent Pit Date: Thu, 23 Dec 2010 13:56:37 +0000 (+0100) Subject: Document and test vivification of function arguments X-Git-Tag: rt62800~3 X-Git-Url: http://git.vpit.fr/?a=commitdiff_plain;h=6b897414257c5dc3056ed7b36b8e47b54dff5d41;p=perl%2Fmodules%2Fautovivification.git Document and test vivification of function arguments --- diff --git a/lib/autovivification.pm b/lib/autovivification.pm index bf8b735..4f4f98b 100644 --- a/lib/autovivification.pm +++ b/lib/autovivification.pm @@ -110,6 +110,8 @@ Turns off autovivification for lvalue dereferencing expressions, such as : $hashref->{$key} = $value for ($arrayref->[$idx]) { ... } for ($hashref->{$key}) { ... } + function($arrayref->[$idx]) + function($hashref->{$key}) An exception is thrown if vivification is needed to store the value, which means that effectively you can only assign to levels that are already defined In the example, this would require C<$arrayref> (resp. C<$hashref>) to already be an array (resp. hash) reference. diff --git a/t/20-hash.t b/t/20-hash.t index 6438056..70e0ab9 100644 --- a/t/20-hash.t +++ b/t/20-hash.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 9 * 3 * 290; +use Test::More tests => 9 * 3 * 302; use lib 't/lib'; use autovivification::TestCases; @@ -116,6 +116,20 @@ $x->{a} = 1 # 1 for $x->{b}; () # '', undef, { a => 1, b => undef } # +delete $x->{a} = 1 # 1 for $x->{a}; () # '', undef, { a => 1 } # +store $x->{a} = 1 # 1 for $x->{b}; () # '', undef, { a => 1, b => undef } # +store +$x # do_nothing($x->{a}); () # '', undef, { } +$x # do_nothing($x->{a}); () # '', undef, { } # +$x # do_nothing($x->{a}); () # '', undef, { } # +fetch +$x # do_nothing($x->{a}); () # '', undef, { } # +exists +$x # do_nothing($x->{a}); () # '', undef, { } # +delete +$x # do_nothing($x->{a}); () # qr/^Can't vivify reference/, undef, undef # +store + +$x # set_arg($x->{a}); () # '', undef, { a => 1 } +$x # set_arg($x->{a}); () # '', undef, { a => 1 } # +$x # set_arg($x->{a}); () # '', undef, { a => 1 } # +fetch +$x # set_arg($x->{a}); () # '', undef, { a => 1 } # +exists +$x # set_arg($x->{a}); () # '', undef, { a => 1 } # +delete +$x # set_arg($x->{a}); () # qr/^Can't vivify reference/, undef, undef # +store + --- dereferencing --- $x # no warnings 'uninitialized'; my @a = %$x; () # ($strict ? qr/^Can't use an undefined value as a HASH reference/ : ''), undef, undef diff --git a/t/30-array.t b/t/30-array.t index d8497f3..8163523 100644 --- a/t/30-array.t +++ b/t/30-array.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 9 * 3 * 290; +use Test::More tests => 9 * 3 * 302; use lib 't/lib'; use autovivification::TestCases; @@ -116,6 +116,20 @@ $x->[$N[0]] = 1 # 1 for $x->[$N[1]]; () # '', undef, [ 1, undef ] # +delete $x->[$N[0]] = 1 # 1 for $x->[$N[0]]; () # '', undef, [ 1 ] # +store $x->[$N[0]] = 1 # 1 for $x->[$N[1]]; () # '', undef, [ 1, undef ] # +store +$x # do_nothing($x->[$N[0]]); () # '', undef, [ ] +$x # do_nothing($x->[$N[0]]); () # '', undef, [ ] # +$x # do_nothing($x->[$N[0]]); () # '', undef, [ ] # +fetch +$x # do_nothing($x->[$N[0]]); () # '', undef, [ ] # +exists +$x # do_nothing($x->[$N[0]]); () # '', undef, [ ] # +delete +$x # do_nothing($x->[$N[0]]); () # qr/^Can't vivify reference/, undef, undef # +store + +$x # set_arg($x->[$N[0]]); () # '', undef, [ 1 ] +$x # set_arg($x->[$N[0]]); () # '', undef, [ 1 ] # +$x # set_arg($x->[$N[0]]); () # '', undef, [ 1 ] # +fetch +$x # set_arg($x->[$N[0]]); () # '', undef, [ 1 ] # +exists +$x # set_arg($x->[$N[0]]); () # '', undef, [ 1 ] # +delete +$x # set_arg($x->[$N[0]]); () # qr/^Can't vivify reference/, undef, undef # +store + --- dereferencing --- $x # no warnings 'uninitialized'; my @a = @$x; () # ($strict ? qr/^Can't use an undefined value as an ARRAY reference/ : ''), undef, undef diff --git a/t/31-array-fast.t b/t/31-array-fast.t index 6f62040..d36a1cf 100644 --- a/t/31-array-fast.t +++ b/t/31-array-fast.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 9 * 3 * 290; +use Test::More tests => 9 * 3 * 302; use lib 't/lib'; use autovivification::TestCases; @@ -116,6 +116,20 @@ $x->[0] = 1 # 1 for $x->[1]; () # '', undef, [ 1, undef ] # +delete $x->[0] = 1 # 1 for $x->[0]; () # '', undef, [ 1 ] # +store $x->[0] = 1 # 1 for $x->[1]; () # '', undef, [ 1, undef ] # +store +$x # do_nothing($x->[0]); () # '', undef, [ ] +$x # do_nothing($x->[0]); () # '', undef, [ ] # +$x # do_nothing($x->[0]); () # '', undef, [ ] # +fetch +$x # do_nothing($x->[0]); () # '', undef, [ ] # +exists +$x # do_nothing($x->[0]); () # '', undef, [ ] # +delete +$x # do_nothing($x->[0]); () # qr/^Can't vivify reference/, undef, undef # +store + +$x # set_arg($x->[0]); () # '', undef, [ 1 ] +$x # set_arg($x->[0]); () # '', undef, [ 1 ] # +$x # set_arg($x->[0]); () # '', undef, [ 1 ] # +fetch +$x # set_arg($x->[0]); () # '', undef, [ 1 ] # +exists +$x # set_arg($x->[0]); () # '', undef, [ 1 ] # +delete +$x # set_arg($x->[0]); () # qr/^Can't vivify reference/, undef, undef # +store + --- dereferencing --- $x # no warnings 'uninitialized'; my @a = @$x; () # ($strict ? qr/^Can't use an undefined value as an ARRAY reference/ : ''), undef, undef diff --git a/t/lib/autovivification/TestCases.pm b/t/lib/autovivification/TestCases.pm index 13feb5a..82b9b68 100644 --- a/t/lib/autovivification/TestCases.pm +++ b/t/lib/autovivification/TestCases.pm @@ -12,6 +12,10 @@ sub import { sub in_strict { (caller 0)[8] & (eval { strict::bits(@_) } || 0) }; +sub do_nothing { } + +sub set_arg { $_[0] = 1 } + sub generate { my ($var, $init, $code, $exp, $use, $opts, $global) = @_; my $decl = $global ? "our $var; local $var;" : "my $var;";