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:
umper;
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'
]
};
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:
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'
]
};