http://qs321.pair.com?node_id=11116966


in reply to Re: Converting Hashes to Objects
in thread Converting Hashes to Objects

my %vars  = %$rvars;

A note on this: When you do this, you're creating a (shallow) copy of the hash, and if $rvars happens to be a Util::H2O object, you'd lose its methods. If that's not what you want, you'll have to work with the hash reference directly. In newer versions of Perl (>=5.22), there is an experimental feature that allows aliasing:

use experimental 'refaliasing'; my $rvars = { foo=>"bar" }; \my %vars = $rvars; # alias print $vars{foo}, "\n"; # prints "bar" $vars{abc} = "xyz"; # modifies $hashref's contents

But since it's experimental, it's probably better to stick with $rvars->{foo} instead.

Q1) How is a "setter" to be implemented?

In the context of Util::H2O, getters/setters are created for every key that exists in the hash or is given as an "additional key" at the time of the h2o call. So for your $hash->x("z") to work, there'd need to be a key x in the hash or you need to specify it to the h2o function; you don't need to write your own sub x.

Q2) Do I still have to pass this around as clumsily as I am with these hash references now.

Q3) Is there now a better way to do this?

TIMTOWTDI, here's how I might have written it without the module:

use Path::Tiny; use Time::Piece; my $ref_var = { abs => path(__FILE__)->absolute, cwd => Path::Tiny->cwd, }; init_vars($ref_var); print $ref_var->{save_file}, "\n"; sub init_vars { my $rvars = shift; # ... $rvars->{save_file} = path( $rvars->{cwd}, "games", localtime->strftime("%d-%m-%Y-%H-%M-%S.txt") )->touchpath; # ... }

And with the module, one can write:

use Path::Tiny; use Time::Piece; use Util::H2O; my $ref_var = h2o { abs => path(__FILE__)->absolute, cwd => Path::Tiny->cwd, }, qw/ save_file ... /; init_vars($ref_var); print $ref_var->save_file, "\n"; sub init_vars { my $rvars = shift; # ... $rvars->save_file( path( $rvars->cwd, "games", localtime->strftime("%d-%m-%Y-%H-%M-%S.txt") )->touchpath ); # ... }