Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

resize_array (PerlArray)

7 views
Skip to first unread message

Aldo Calpini

unread,
Aug 1, 2002, 11:28:12 AM8/1/02
to perl6-i...@perl.org

take this little assembler program:

new P1, .PerlArray
set P1, 100
bsr GETLEN

set I0, P1[0]
print "P1[0]="
print I0
print "\n"
bsr GETLEN

set I0, P1[10000]
print "P1[10000]="
print I0
print "\n"
bsr GETLEN
end

GETLEN:
set I0, P1
print "length="
print I0
print "\n"
ret

it prints:

length=100
P1[0]=0
length=100
P1[10000]=0
length=10001

fetching an element out of bound changes the
length of the array. but should this really happen?
why does perlarray.pmc act like this:

if (ix >= SELF->cache.int_val) {
resize_array(interpreter, SELF, ix+1);
}

instead of:

if (ix >= SELF->cache.int_val) {
value = pmc_new(INTERP, enum_class_PerlUndef);
return value->vtable->get_integer(INTERP, value);
}

are there any reason for this that I can't see or does it
just need a patch?

cheers,
Aldo

__END__
$_=q,just perl,,s, , another ,,s,$, hacker,,print;

Dan Sugalski

unread,
Aug 1, 2002, 3:42:19 PM8/1/02
to Aldo Calpini, perl6-i...@perl.org
At 5:28 PM +0200 8/1/02, Aldo Calpini wrote:
>fetching an element out of bound changes the
>length of the array. but should this really happen?
>why does perlarray.pmc act like this:

Because that's the way Perl's arrays work. Joys of autovivification.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Graham Barr

unread,
Aug 1, 2002, 4:04:35 PM8/1/02
to Dan Sugalski, Aldo Calpini, perl6-i...@perl.org
On Thu, Aug 01, 2002 at 03:42:19PM -0400, Dan Sugalski wrote:
> At 5:28 PM +0200 8/1/02, Aldo Calpini wrote:
> >fetching an element out of bound changes the
> >length of the array. but should this really happen?
> >why does perlarray.pmc act like this:
>
> Because that's the way Perl's arrays work. Joys of autovivification.

Only if the element fetched is being used in an lvalue context.

Just reading an array element will result in undef and no change to the array
internals

Graham.

Dan Sugalski

unread,
Aug 1, 2002, 4:11:44 PM8/1/02
to Graham Barr, Aldo Calpini, perl6-i...@perl.org

Good point. Read shouldn't extend, write should.

Aldo Calpini

unread,
Aug 2, 2002, 4:25:12 AM8/2/02
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski wrote:
> At 5:28 PM +0200 8/1/02, Aldo Calpini wrote:
>>fetching an element out of bound changes the
>>length of the array. but should this really happen?
>
> Because that's the way Perl's arrays work. Joys of
> autovivification.

I have to disagree. the corresponding Perl script
does not show this behaviour:

my @a = (undef) x 100;
print "length=", scalar(@a), "\n";
print "a[0]=", $a[0], "\n";
print "length=", scalar(@a), "\n";
print "a[10000]=", $a[10000], "\n";
print "length=", scalar(@a), "\n";

the output is:

length=100
a[0]=
length=100
a[10000]=
length=100

John Porter

unread,
Aug 2, 2002, 7:46:09 AM8/2/02
to perl6-i...@perl.org
Aldo Calpini wrote:
> I have to disagree. the corresponding Perl script
> does not show this behaviour:

It all depends. :-)


$\ = "\n";
$#a = 100;
print scalar(@a);
$x = $a[10000][0];
print scalar(@a);

101
10001


Perl has to autoviv if it has to drill down.

--
John Douglas Porter

Aldo Calpini

unread,
Aug 2, 2002, 8:55:12 AM8/2/02
to John Porter, perl6-i...@perl.org
John Porter wrote:
> It all depends. :-)
>
> [...]

>
> Perl has to autoviv if it has to drill down.

good point. but since we don't have multidimensional
array access right now (at least AFAIK), this seems
to be a non-issue. I don't know if p6 will autovivify
the way p5 does (and I hope not). IMHO, PerlArray.pmc
should behave the way I suggested: if the index is out
of bound, returns undef tout-court. I have the patch
under my toes ;-)

Leopold Toetsch

unread,
Aug 2, 2002, 9:11:41 AM8/2/02
to perl6-i...@perl.org
John Porter wrote:

> Aldo Calpini wrote:
>
>>I have to disagree. the corresponding Perl script
>>does not show this behaviour:
>>
>

> $\ = "\n";
> $#a = 100;
> print scalar(@a);
> $x = $a[10000][0];


This _writes_ to @a[10000] by generating the entry:

P0, 100
P1 = new .PerlArray
P1 = 0
P0[10000] = P1
I0 = P1[0]


> Perl has to autoviv if it has to drill down.


Not on reading.


I vote for the proposed patch.
leo

Haegl

unread,
Aug 2, 2002, 10:28:50 AM8/2/02
to perl6-i...@perl.org
On 2002/08/02 16:11:26 Nicholas Clark <ni...@ccl4.org> wrote:

>It does on reading. I forget the eloquent explanation about the how or
>why, but all references bar the leftmost are vivified. (Even inside
>defined). In effect, all bar the last reference are in lvalue context -
>only the rightmost is rvalue.

The explanation is the part that would have been the most interesting...
Everyone: Is this just some unwanted but unavoidable behaviour that
results from the lvalue/rvalue processing or is there a real reason
behind it? (I don't see one, that's why I ask :-)


Florian Haeglsperger

unread,
Aug 2, 2002, 10:37:01 AM8/2/02
to perl6-i...@perl.org
That "Haegl" was actually me, Florian Haeglsperger (actually Häglsperger, but I don't mind).
I accidently sent the mail using the wrong e-mail account. It is not my intention to hide
myself behind a stupid nickname like "rEaLkEwLgUy2o0o" or something like that ;-)


Nicholas Clark

unread,
Aug 2, 2002, 10:11:26 AM8/2/02
to Leopold Toetsch, perl6-i...@perl.org
On Fri, Aug 02, 2002 at 03:11:41PM +0200, Leopold Toetsch wrote:
> John Porter wrote:
>
> > Aldo Calpini wrote:
> >
> >>I have to disagree. the corresponding Perl script
> >>does not show this behaviour:
> >>
> >
> > $\ = "\n";
> > $#a = 100;
> > print scalar(@a);
> > $x = $a[10000][0];

> > Perl has to autoviv if it has to drill down.
>
>
> Not on reading.

It does on reading. I forget the eloquent explanation about the how or


why, but all references bar the leftmost are vivified. (Even inside
defined). In effect, all bar the last reference are in lvalue context -
only the rightmost is rvalue.

$ cat ~/test/drilldown.pl


$\ = "\n";
$#a = 100;
print scalar(@a);
$x = $a[10000][0];

print scalar(@a);
__END__
$ perl ~/test/drilldown.pl
101
10001

Nicholas Clark

Matt Fowles

unread,
Aug 2, 2002, 12:08:17 PM8/2/02
to perl6-i...@perl.org
All~

> >It does on reading. I forget the eloquent explanation about the how or
> >why, but all references bar the leftmost are vivified. (Even inside
> >defined). In effect, all bar the last reference are in lvalue context -
> >only the rightmost is rvalue.
>
> The explanation is the part that would have been the most interesting...
> Everyone: Is this just some unwanted but unavoidable behaviour that
> results from the lvalue/rvalue processing or is there a real reason
> behind it? (I don't see one, that's why I ask :-)

I am not entirely certain for Perl, but in C the [ ] operator dereferences a
pointer, and can be assigned to so the [ ] operator yields a possible
lvalue.
If the resultant value is then dereferneced with another [ ] operator you
have just used the first value in an lvalue context...

Thus each but the last [ ] force lvalue context, and the final one waits to
see its own context...

Matt

PS-Appologies to Haegl for accidentally replying to him alone at first....

Dan Sugalski

unread,
Aug 2, 2002, 4:02:58 PM8/2/02
to Haegl, perl6-i...@perl.org

It's an artifact of the implementation, and most people'd be just as
happy if it went away.

Benjamin Stuhl

unread,
Aug 4, 2002, 2:52:17 PM8/4/02
to Haegl, perl6-i...@perl.org

IIRC, it's basically because Perl5 doesn't have multidimensional keys,
so $a[0]{"foo"}[24] becomes (in pseudo-perl5-assembler, assume each
op pops its args and pushes its results)

push $a
array_fetch 0
hash_fetch "foo"
array_fetch 24

So, in order that it not segfault in the middle by trying to do a fetch out of
a NULL hash or array, the first to fetches are called in lvalue context (or
rather,
"this element must exist - create it if you have to" context). With
multidimensional
keys, Perl6 can avoid this trap, but we really still need an lvalue fetch -
one reason
being references. We need to support

$a = \@b[2];
$$a = 4;

which only does a fetch on @b[2], but @b[2] had better autovivify, or the
deref may
segfault.

-- BKS

0 new messages