Reputation: 23
I try to build a tree on my own. I start with an anonymous hash and created the first knot ("there"). From there on I want to create a child knot, but what I attempted didn't work.
use Data::Dumper;
$tree = {};
$tree->{'these'} = {};
$tree = $tree->{'these'};
$tree->{'are'} = {};
print Dumper $tree;
$tree = $tree->{'these'};
doesn't move $tree
to the anonymous hash.
The output is
$VAR1 = {
'are' => {}
};
but I wanted it to be
$VAR1 = {
'these' => {
'are' => {}
}
};
Any idea is very appreciated.
Upvotes: 2
Views: 114
Reputation: 386361
Let's start with a look at the last two lines you wrote:
$tree->{'are'} = {};
print Dumper $tree;
After that, how can $tree
possibly be a reference to a hash that contains only the key these
as you say you want?
The problem is that you're trying to use $tree
for two different things:
Those two hashes/nodes aren't always the same, so we need two variables. In fact, I'll use three for completely clarity.
$tree
, a reference to the root node. $node
the node we are creating.$parent
the node into which we want to insert.We start by creating a root node and assign it to $tree
my $tree = {};
We don't want to lose track of the root node, so we'll never assign to $tree
again. We can assign to elements of the hash referenced by $tree
, though.
The next time we insert, we want to insert into the root node.
my $parent = $tree;
Now it's time to start adding new nodes.
my $node = {};
$parent->{these} = $node;
The next time we insert, we want to insert into the newly created node.
$parent = $parent->{these};
We insert again.
my $node = {};
$parent->{are} = $node;
And that's it! All together:
use strict; # ALWAYS use this.
use warnings; # ALWAYS use this.
use Data::Dumper qw( Dumper );
my $tree = {};
my $parent = $tree;
{
my $node = {};
$parent->{these} = $node;
$parent = $parent->{these};
}
{
my $node = {};
$parent->{are} = $node;
$parent = $parent->{are};
}
print(Dumper($tree));
If that's clear, we can simplify a bit.
use strict; # ALWAYS use this.
use warnings; # ALWAYS use this.
use Data::Dumper qw( Dumper );
my $tree = {};
my $parent = $tree;
$parent->{these} = {};
$parent = $parent->{these};
$parent->{are} = {};
$parent = $parent->{are};
print(Dumper($tree));
We can even take it a step further!
use strict; # ALWAYS use this.
use warnings; # ALWAYS use this.
use Data::Dumper qw( Dumper );
my $tree = {};
my $parent = $tree;
$parent = $parent->{these} = {}; # Assignments are performed right-to-left.
$parent = $parent->{are} = {};
print(Dumper($tree));
Upvotes: 2
Reputation: 222582
Consider:
use strict;
use warnings;
use Data::Dumper;
my $tree = {};
$tree->{these}->{are} = {};
print Dumper $tree;
Rationale: your original code keeps reassigning new values to $tree
, overwriting the previously assigned value:
$tree->{'these'} = {}; # original assignment
$tree = $tree->{'these'}; # new assignment: now $tree is an empty hash ref
$tree->{'are'} = {}; # new assignment: now $tree contains { are => {} }
Here is another way to express your intent using another variable:
use strict;
use warnings;
use Data::Dumper;
my $tree = {};
my $child_tree = {};
$child_tree->{are} = {};
$tree->{these} = $child_tree;
print Dumper $tree;
Unrelated side note: always use strict; use warnings;
!
Upvotes: 2