I have a class with several variables, one of which is a hash (_runs):
sub new
{
my ($class, $name) = @_;
my $self = {
_name => $name,
...
_runs => (),
_times => [],
...
};
bless ($self, $class);
return $self;
}
Now, all I'm trying to do is create an accessor/mutator, as well as another subroutine that pushes new data into the hash. But I'm having a hell of a time getting all the referencing/dereferencing/$self calls working together. I've about burned my eyes out with "Can't use string ("blah") as a HASH ref etc etc" errors.
For the accessor, what is 'best practice' for returning hashes? Which one of these options should I be using (if any)?:
return $self->{_runs};
return %{ $self->{_runs} };
return \$self->{_runs};
Further, when I'm using the hash within other subroutines in the class, what syntax do I use to copy it?
my @runs = $self->{_runs};
my @runs = %{ $self->{_runs} };
my @runs = $%{ $self->{_runs} };
my @runs = $$self->{_runs};
Same goes for iterating over the keys:
foreach my $dt (keys $self->{_runs})
foreach my $dt (keys %{ $self->{_runs} })
And how about actually adding the data?
$self->{_runs}{$dt} = $duration;
%{ $self->{_runs} }{$dt} = $duration;
$$self->{_runs}{$dt} = $duration;
You get the point. I've been reading articles about using classes, and articles about referencing and dereferencing, but I can't seem to get my brain to combine the knowledge and use both at the same time. I got my _times array working finally, but mimicking my array syntax over to hashes didn't work.
You are storing references to array or hashes in your object. To use them with standard functions you'll need to dereference them. For example:
@{ $self->{_array_ref_key} };
%{ $self->{_hash_ref_key} };
If you need pass parameters to standard function:
push( @{ $self->{_array_ref_key} }, $some_value );
for my $hash_key ( keys %{ $self->{_hash_ref_key} }) {
$self->{_hash_ref_key}{$hash_key}; ## you can access hash value by reference
}
Also $self->{_hash_ref_key}{$hash_key}
syntax is shortcut for $self->{_hash_ref_key}->{$hash_key}
(which can make for sense if you see it first time).
Also take a look at corresponding manual page.
Might as well take my comments and make a proper answer out of it. I'll illustrate exactly why your sample code failed.
use warnings;
my $self = {
_name => $name,
_runs => (),
_times => [],
};
bless ($self, $class);
use Data::Dump::Streamer; DumpLex $self;
__END__
Odd number of elements in anonymous hash at …
$self = bless( {
_name => undef,
_runs => '_times',
"ARRAY(0x88dcb8)" => undef,
}, '…' );
All the elements in the list form the key/value pairs for the hash whose reference is going to be bless
ed. ()
is an empty list, so what you're really expressing is the list '_name', $name, '_runs', '_times', []
. You can see that _times
moves up to become a value, and the reference []
is stringified as hash key. You get the warning because there's no value left for it; this will be automatically coerced to undef
. (Always always enable the warnings
pragma.)
Now for the guts part: hash values must be a scalar value. Arrays and hashes aren't; but references to them are. Thus:
my $self = {
_name => $name,
_runs => {},
_times => [],
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With