Quotes and circular references

J

JR

Hi. I came across an interesting situation today when quoting a
circular reference. For some reason, when I quoted the circular
reference $a, in the below script, and within the "h2" hash key for an
anonymous array, the output was different than when the circular
reference wasn't quoted (the output included HASH(0x1abf070) when the
circular reference was quoted, and the actual data when it wasn't).
I'm probably missing something very obvious here (it's the end of a
very long day). Does anyone know why this would be so?

Thanks much.

JR


------calling script-------
use lib 'OO_Practice';
use TRAVERSE_V2;
use Data::Dumper;
use strict;
use warnings;
use diagnostics;

## Circular reference
my $a = { name => 'joe', age => 31 };
$a->{circle_me_this} = $a;

my %hoa = (
h1 => [ "in_h1", [ "in_h1a" ], "out_h1" ],
h2 => [ "in_h2", [ "in_h2a" ], $a ],
h3 => [ "in_h3", [ "in_h3a" ], "out_h3" ],
);

my $sep = sub {print "-" x shift, "\n";};

print $a, "\n"; # prints HASH(0x1abf070)
print "$a\n"; # also prints HASH(0x1abf070) # quotes don't seem
# to matter here
$sep->(50);

my $object = TRAVERSE_V2->new(\\\\$a); # just data-good
&$sep(50);
print Dumper \\\\$a; # data and data structure-okay
&$sep(50);

$object = TRAVERSE_V2->new(\\\\%hoa); # prints: HASH(0x1abf070)
# $a is quoted; otherwise
# prints as expected

$sep->(50);
print Dumper \\\\%hoa; # prints: HASH(0x1abf070) when
# $a is quoted; otherwise
# prints as expected

------

------receiving class-------
use strict;
package TRAVERSE_V2;

sub new {
my (%r, $class);
my $self = shift;
my $class = ref($class) || $class;

while ($_ = shift(@_)) {
## beware circular references
## (handled by first condition of below clause)
$r{$_}>1 ? shift :
!ref($_) ? $r{$_}++ :
ref($_) eq 'REF' ? push @_, $$_ :
ref($_) eq 'HASH' ? push @_, %$_ :
ref($_) eq 'ARRAY' ? push @_, @$_ :
ref($_) eq 'SCALAR' ? push @_, $$_ :
ref($_) eq 'CODE' ? push @_, $_->() :
print "<<<Exception: $_>>>\n";
}

$self = [keys %r];
bless $self, $class; # create object
print "$_\n" for @$self; # print object
return $self; # return object
}

1;

----OUTPUT
HASH(0x1abf070)
HASH(0x1abf070)
--------------------------------------------------
joe
31
circle_me_this
name
age
--------------------------------------------------
$VAR1 = \\\\{
'circle_me_this' => ${${${${$VAR1}}}},
'age' => 31,
'name' => 'joe'
};
--------------------------------------------------
circle_me_this
out_h1
in_h1a
out_h3
h1
in_h2a
h2
name
h3
in_h3a
joe
in_h1
in_h2
in_h3
31
age
--------------------------------------------------
$VAR1 = \\\{
'h1' => [
'in_h1',
[
'in_h1a'
],
'out_h1'
],
'h2' => [
'in_h2',
[
'in_h2a'
],
{
'circle_me_this' =>
${${${$VAR1}}}->{'h2'}->[2],
'age' => 31,
'name' => 'joe'
}
],
'h3' => [
'in_h3',
[
'in_h3a'
],
'out_h3'
]
};
 
B

Bob Walton

JR said:
Hi. I came across an interesting situation today when quoting a
circular reference. For some reason, when I quoted the circular
reference $a, in the below script, and within the "h2" hash key for an
anonymous array, the output was different than when the circular
reference wasn't quoted (the output included HASH(0x1abf070) when the
circular reference was quoted, and the actual data when it wasn't).


Well, I'm having a bit of trouble understanding precisely what you mean
when you say "when the circular referenece was quoted". A string like
"HASH(0x1abf070)" is the sort of thing one gets when one stringifies an
unblessed hash reference. Placing a hash reference in a double-quoted
string will force a stringification. So it is not surprising that you
would get the stringification when quoting a hash reference. This has
nothing to do with circular references. If you are doing something akin to:

$z = "$hashref";

then $z will have something like the string HASH(0x...) as its value.


....

....
 
J

JR

Bob Walton said:
Well, I'm having a bit of trouble understanding precisely what you mean
when you say "when the circular referenece was quoted". A string like
"HASH(0x1abf070)" is the sort of thing one gets when one stringifies an
unblessed hash reference. Placing a hash reference in a double-quoted
string will force a stringification. So it is not surprising that you
would get the stringification when quoting a hash reference. This has
nothing to do with circular references. If you are doing something akin to:

$z = "$hashref";

then $z will have something like the string HASH(0x...) as its value.


...


...

Thanks much for your response.

[I suppose the it may not matter whether I'm dealing with a circular
reference or not-I just first noticed this situation when I was
dealing with them.]

I guess the reference context for stringification matters in this
case, because the quotes don't appear to matter when simply printing
out the circular reference, but they do when the circular reference is
contained inside in an anonymous array.

## Circular reference
my $a = { name => 'joe', age => 31 };
$a->{circle_me_this} = $a;

print "$a\n"; # prints HASH(0x1abf070)
print $a, "\n"; # print HASH(0x1abf070)

my %h = ( h1 => [ "in_h2", [ "in_h2a" ], $a ], );

print "$_\n" for %{$h{h1}[2]};

## Redefine %h (context of $a)
%h = ( h1 => [ "in_h2", [ "in_h2a" ], "$a" ], );

print "$_\n" for %{$h{h1}[2]};

#Can't use string ("HASH(0x1abf070)") as a
#HASH ref while "strict refs" in use at
#test_data_structure_traversal_v2.pl line 21.

I guess the moral of the story is simply not to force stringification
of unblessed references in any complex data structure, by
double-quoting the reference.
 
B

Brian Harnish

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, 09 Sep 2003 06:11:50 -0700, JR wrote:

[snip...]
[I suppose the it may not matter whether I'm dealing with a circular
reference or not-I just first noticed this situation when I was
dealing with them.]

[snip...]

I guess the moral of the story is simply not to force stringification
of unblessed references in any complex data structure, by
double-quoting the reference.

What you're seeing doesn't have to do with circular references. What you
are trying to do is use a string as a hash reference. If you get rid of
the bulk of your code, it's really trying to do this:

#!/usr/bin/perl -w
use strict;
my $a={this=>1,that=>2};
print $_ for %{$a};
print $_ for %{"$a"}; # <- Error here, can't use a string as a hashref!
__END__

After interopelation (sp?), it ceases being a reference to a hash, and is
now a string.

- Brian
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQE/Xf8siK/rA3tCpFYRAjGMAJ0YswFDiX60T5B5eHQcNZuEXXOV1wCcDz2j
QtdEwK3vxtgn31g5mN3oxXs=
=hHwg
-----END PGP SIGNATURE-----
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top