I have a set of data that I would like to process.
In order to simplify my code, It would be nice to access to some subsets of my data through array of references that point to the original data.
Better than an explanation, I wrote down this example (which is not working yet). At the end, I would like to update the original data without having to also update all the subsets.
Is it possible to do something like this with Perl ?
#!/usr/bin/env perl
use strict;
use warnings;
# A set of data
my $design = {
box => {
ne => {data => 'north-east'},
nw => {data => 'north-west'},
n => {data => 'north'},
s => {data => 'south'},
e => {data => 'east'},
w => {data => 'west'},
se => {data => 'south-east'},
sw => {data => 'south-west'}
}
};
# Select a design
my $selected = 'box';
# Build some arrays
my $d = $design->{$selected};
my @eastside = (\$d->{e}, \$d->{ne}, \$d->{se});
my @westside = (\$d->{w}, \$d->{nw}, \$d->{sw});
my @northside = (\$d->{n}, \$d->{ne}, \$d->{nw});
# Update one data
$d->{ne}->{data} .= " updated!";
# Display
print join '', "Composed of:\n", map("\t".$_->{data}."\n", @eastside);
The script should output:
Composed of:
east
north-east updated!
south-east
All that is wrong is that you are taking a reference of values that are already hash references in the lines like
You should simple omit the backslashes and everything will work.
(By the way, you may want to know that the reference
\
operator is distributive, so you can write the same thing withbut it's no more correct that way!)
Some other points
You should make use of hash slices in situations like this where you need to extract a list of hash elements using multiple keys. In this case
@eastside
is just@{$d}{qw/ ne e se /}
Perl allows the indirection operator
->
between pairs of closing and opening braces and brackets to be omitted, so$d->{ne}->{data}
can be written$d->{ne}{data}
You are printing the result of a
join
with a null between the elements. You'll get the same result by just listing the items to be printed. You can also interpolate hash elements into a double-quoted string, so"\t".$_->{data}."\n"
is the same as"\t$_->{data}\n"
Making those changes results in this working program
output
You can check the data structure with Data::Dumper module.
Also check the next two
@east2
and@east3
examples, especially how is built the@east3
.prints:
You have scalar references in
@eastside
array, so in order to dereference scalar put extra$
in front of$_->{data}
, or use${$_}->{data}
.output