in reply to Error using Data::Alias (how to allocate array w/o filling it in?) and help avoiding 'constant' len?

The above is more a question of 'why'

$a, $b and $c are being aliased to The undef (PL_sv_undef) rather than an undef (a scalar that happens to be undefined).

$ perl -MDevel::Peek -e'Dump(undef); Dump(my $x);' SV = NULL(0x0) at 0x8168784 REFCNT = 2147483616 FLAGS = (READONLY) SV = NULL(0x0) at 0x817bc18 REFCNT = 1 FLAGS = (PADMY)

It uses less memory to initially map elements to an existing scalar than to create a bunch of undefined scalars.

The solution is to reverse the mapping.

alias my @array = my ($x, $y, $z);

If that syntax doesn't work ( Tested: It does work ), you can achieve the intended as follows:

sub map_scalars_onto_array(\@@) { my $array = shift; alias $array->[$_] = $_[0] for 0..$#_; } map_scalars_onto_array my @local_array, my ($x, $y, $z);

By the way, you can force the vivification of an array element by taking a reference to it.

$ perl -E'$#a=5; for (1..2) { say exists($a[3])?1:0; \$a[3]; }' 0 1
  • Comment on Re: Error using Data::Alias (how to allocate array w/o filling it in?) and help avoiding 'constant' len?
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Error using Data::Alias (how to allocate array w/o filling it in?) and help avoiding 'constant' len?
by perl-diddler (Chaplain) on Sep 23, 2010 at 16:47 UTC
    Doing the reverse mapping seems like the best...I like it. Quirky, but I like it, and it makes sense too, since the values on the right are enumerated -- forcing them into 'undef'ed existence,

    I was trying to avoid anything that looped over the array elements, since that felt like wasted work in this case. I'll have to see if that solves my other issue, which was determining the length of my local variable list, putting their names into a list, and using that name-list in multiple places. I meant to put that in as a separate question, but got side tracked...but now will first see if any of the information you present here will solve issues I had in that problem.

    Thanks! It's excellent to have another set of eyes look over something like this when a simple solution can be staring one in the face!...

      I was trying to avoid anything that looped over the array elements

      Impossible. You want to do N aliases, so something will have to loop over the N variables/elements.

Re^2: Error using Data::Alias (how to allocate array w/o filling it in?) and help avoiding 'constant' len?
by perl-diddler (Chaplain) on Sep 23, 2010 at 17:47 UTC
    Actually turning it around helped me avoid the alias altogether -- save the vars on the 'stack', and not have to worry about early exists while having the saved values still being updated on the stack... Got rid of 'local_vars' array entirely, and now I just push them all on at creation time onto the stack:
    push @{this-{local_vars}], [my ($open_tag, $tag_print, $cur_class, $cur_id, $defines_class, $defines_id, $tag_output )];
    Came close to forgetting the square brackets until I was about to explain what I did here! Then I saw,, oops, I'm pushing 7 successive values onto @local_vars, instead of pushing 1 array containing them! Doh! But try to explain what I did, and caught that right off!

    Good illustration of why sometimes I snag some non-CS literate friend into helping look for some programing problem while I explain it to them in a way they can understand it -- meaning I really have to be very explicit as to what is going on -- maybe even with diagrams. Embarrassingly amazing how many times I catch my own bugs that way.

    I try to explain to them, that they really are performing a valuable function -- even if they don't understand everything, because when you explain your code so a non-CS person can understand it, you have to explain every assumption, and the effect of every operator...

      huh?

      push @{$this->{local_vars}}, [my ($open_tag, $tag_print, $cur_class, $cur_id, $defines_class, $defines_id, $tag_output )]; $open_tag = 123; use Data::Dumper; print(Dumper($this));
      $VAR1 = { 'local_vars' => [ [ undef, undef, undef, undef, undef, undef, undef ] ] };

      Mind you, putting the assignment to local_vars at the bottom will avoid aliases. That's the solution I suggested in your earlier thread.

      my ($open_tag, $tag_print, $cur_class, $cur_id, $defines_class, $defines_id, $tag_output ); $open_tag = 123; push @{$this->{local_vars}}, [$open_tag, $tag_print, $cur_class, $cur_id, $defines_class, $defines_id, $tag_output];
      $VAR1 = { 'local_vars' => [ [ 123, undef, undef, undef, undef, undef, undef ] ] };