Pre-allocating an anonymous data type

J

J Krugman

I've run into a paragraph in an old clpm post that I don't understand:

You are allowed to dereference an undefined value as an lvalue
(to make an assignment, for example); Perl allocates memory for
its referent automatically. But what about using `undef' as an
rvalue? Dereferencing the undefined value as an rvalue just produces
another undefined value--unless you're running under the `use strict'
directive. In that case, it instead raises an exception!
[ so far so good ]
This is one
reason why you may sometimes want to pre-allocate an anonymous data
type by reference.

Huh? What does it mean to "pre-allocate an anonymous data type
*by reference*"? (Please, could someone give me an example?) And
why is the foregoing a reason one may want to do such pre-allocation?

TIA!

jill
 
U

Uri Guttman

JK> I've run into a paragraph in an old clpm post that I don't understand:

JK> You are allowed to dereference an undefined value as an lvalue
JK> (to make an assignment, for example); Perl allocates memory for
JK> its referent automatically. But what about using `undef' as an
JK> rvalue? Dereferencing the undefined value as an rvalue just produces
JK> another undefined value--unless you're running under the `use strict'
JK> directive. In that case, it instead raises an exception!

that is misleading. deref an undef rvalue and it will be stringified to
the null string and that will be used to lookup that var in the symtable
and it is likely to be not there so it gets back the undef value. that
is what is happening.

perl -MData::Dumper -e '$r = $$x; print Dumper \$r'
$VAR1 = \undef;
perl -MData::Dumper -e '$x = "z" ; $z = 3 ;$r = $$x; print Dumper \$r'
$VAR1 = \3;

so the value you get depends on what is in $x, not the fact that it is
undef.

JK> [ so far so good ]

well, not exactly. the poster was confused and not clear or correct at all.

JK> This is one reason why you may sometimes want to pre-allocate
JK> an anonymous data type by reference.

JK> Huh? What does it mean to "pre-allocate an anonymous data type
JK> *by reference*"? (Please, could someone give me an example?) And
JK> why is the foregoing a reason one may want to do such pre-allocation?

i agree, Huh?!? i have no clue about what that poster meant. now, if he
was talking about autovivification which is an lvalue thing, i would
understand this 'preallocation' stuff. and if you want to learn more
about that read this tutorial:

http://www.sysarch.com/perl/tutorials/autoviv.txt

uri
 
J

J Krugman

JK> I've run into a paragraph in an old clpm post that I don't understand:
JK> You are allowed to dereference an undefined value as an lvalue
JK> (to make an assignment, for example); Perl allocates memory for
JK> its referent automatically. But what about using `undef' as an
JK> rvalue? Dereferencing the undefined value as an rvalue just produces
JK> another undefined value--unless you're running under the `use strict'
JK> directive. In that case, it instead raises an exception!
that is misleading. deref an undef rvalue and it will be stringified to
the null string and that will be used to lookup that var in the symtable
and it is likely to be not there so it gets back the undef value. that
is what is happening.
perl -MData::Dumper -e '$r = $$x; print Dumper \$r'
$VAR1 = \undef;
perl -MData::Dumper -e '$x = "z" ; $z = 3 ;$r = $$x; print Dumper \$r'
$VAR1 = \3;
so the value you get depends on what is in $x, not the fact that it is
undef.

Uri, thanks for your reply, but I can't follow your last sentence
above. On the one hand it seems too obvious that the value of $x
would affect the result of '$r = $$x; print Dumper \$r'. On the
other hand, in your second code snippet, $x is *not* undef, so I
don't see how it applies to the discussion. What am I missing?

Jill
 
C

ctcgag

J Krugman said:
I've run into a paragraph in an old clpm post that I don't understand:

You are allowed to dereference an undefined value as an lvalue
(to make an assignment, for example); Perl allocates memory for
its referent automatically. But what about using `undef' as an
rvalue? Dereferencing the undefined value as an rvalue just produces
another undefined value--unless you're running under the `use strict'
directive. In that case, it instead raises an exception!
[ so far so good ]
This is one
reason why you may sometimes want to pre-allocate an anonymous data
type by reference.

Huh? What does it mean to "pre-allocate an anonymous data type
*by reference*"? (Please, could someone give me an example?)

Sure. assuming $x is originally undef, then

case 1:

@$x=(1,2); # uses autovivification

case 2:

$x=[]; #pre-allocates an anonymous data type by reference
@$x(1,2); # and thus does not use autovivification

And
why is the foregoing a reason one may want to do such pre-allocation?

I ran into something like this before when building a tree structure.
I've forgotten much of the details, and never figured out some
of the others, but the problem boiled to the fact that, depending
on prior traversal history, for a node with no left child sometimes
$node->{LEFT} was undefined, and sometimes $node->{LEFT} was a reference
to an empty hash. Hilarity ensued. I remember thinking that if rvalue
deref \ of undef would autovivify, or if lvalue deref of undef would error
out (under strict), I wouldn't have had nearly as much problem making it
work.

Xho
 
U

Uri Guttman

JK> Uri, thanks for your reply, but I can't follow your last sentence
JK> above. On the one hand it seems too obvious that the value of $x
JK> would affect the result of '$r = $$x; print Dumper \$r'. On the
JK> other hand, in your second code snippet, $x is *not* undef, so I
JK> don't see how it applies to the discussion. What am I missing?

the fact that $x is undef and $$x gets a value of undef is not related
to the undefness of $x. it is a simple symref deref of undef which gives
a null string which is looked up and no symbol is found and you get
undef. i might be partly off there since perlguts is insane. but my
point is that the value of $$x is undef is not because $x is undef, but
because what $x refers to is undef. i couldn't find an easy way to show
this and the code i posted showed some of it.

uri
 
B

Ben Morrow

Uri Guttman said:
the fact that $x is undef and $$x gets a value of undef is not related
to the undefness of $x. it is a simple symref deref of undef which gives
a null string which is looked up and no symbol is found and you get
undef. i might be partly off there since perlguts is insane.

'fraid so:

~% perl -le'print ${undef()}'

~% perl -le'${undef()} = 1'
Can't use an undefined value as a SCALAR reference at -e line 1.
~% perl -le'${""} = 1; print $$x'

~% perl -le'${""} = 1; $x=""; print $$x'
1

Perl seems to make a distinction between a deref of the empty string
and a deref of undef; the former is a perfectly straightforward
symbol, the latter is undef as an rvalue or throws an error as an
lvalue.

None of this nonsense works under strict 'refs', of course; so to a
large extent it's purely academic.
perlguts is insane.

Yup!

Ben
 
C

ctcgag

Uri Guttman said:
JK> I've run into a paragraph in an old clpm post that I don't
understand:

JK> You are allowed to dereference an undefined value as an lvalue
JK> (to make an assignment, for example); Perl allocates memory for
JK> its referent automatically. But what about using `undef' as an
JK> rvalue? Dereferencing the undefined value as an rvalue just
produces JK> another undefined value--unless you're running under
the `use strict' JK> directive. In that case, it instead raises an
exception!

that is misleading. deref an undef rvalue and it will be stringified to
the null string and that will be used to lookup that var in the symtable
and it is likely to be not there so it gets back the undef value. that
is what is happening.

perl -MData::Dumper -e '$r = $$x; print Dumper \$r'
$VAR1 = \undef;
perl -MData::Dumper -e '$x = "z" ; $z = 3 ;$r = $$x; print Dumper \$r'
$VAR1 = \3;

so the value you get depends on what is in $x, not the fact that it is
undef.

I don't think your examples are relevant to your claim.

perl -MData::Dumper -e '$x = undef ; ${""} = 3 ;$r = $$x; print Dumper \$r'
$VAR1 = \undef;

perl -MData::Dumper -e '$x = "" ; ${""} = 3 ;$r = $$x; print Dumper \$r'
$VAR1 = \3;


derefing undef as an rvalue is different from derefing the empty string
as an rvalue.



Xho
 
B

Brian McCauley

I ran into something like this before when building a tree structure.
I've forgotten much of the details, and never figured out some
of the others, but the problem boiled to the fact that, depending
on prior traversal history, for a node with no left child sometimes
$node->{LEFT} was undefined, and sometimes $node->{LEFT} was a reference
to an empty hash. Hilarity ensued. I remember thinking that if rvalue
deref \ of undef would autovivify, or if lvalue deref of undef would error
out (under strict), I wouldn't have had nearly as much problem making it
work.

You can get autovivification in an rvalue context by an extra deref-ref.

my $left = \%{$node->{LEFT}};

Of course some would argue it's neater as:

my $left = $node->{LEFT} ||= {};

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,145
Messages
2,570,824
Members
47,371
Latest member
Brkaa

Latest Threads

Top