There are many workable approaches and you've already seen several; I'd like to offer another. I hesitate to call it a true object-oriented approach. What I'm doing here is suborning OO techniques to manage what I call a pseudo-global football. This is almost as evil as global variables; just a bit less so.
Code such as $f->{barky} is only marginally more complex than a lexical $barky (and it should be, at least a little, since the football goes all over the field). Besides new() and init() you can write additional methods that deal primarily with the football; with the extra payoff that the calling convention is quite clean. Otherwise, you can pass the football around to almost anything, almost anywhere:
do_stuff({ -more_important_stuff => $my_stuff, -football => $f, });
In the following demo, I've put the OO::Module class in the same file as the main script. Don't do that in real life; make a real module and put it in /lib. While you're at it, change identifiers to match your project's needs.
#!/usr/bin/perl # football.pl # = Copyright 2012 Xiong Changnian <xiong@cpan.org> = # = Free Software = Artistic License 2.0 = NO WARRANTY = use 5.014002; use strict; use warnings; use lib qw| lib |; use Devel::Comments '###', '####'; #~ use Devel::Comments '#####', ({ -file => 'debug.log' }); #--------------------------------------------------------------------- +-------# # Get a new football. my $f = OO::Module->new; # Call OO method on football. $f->_method({ fruit => 'apple', name => 'Fuji', }); # Access football, bypassing class package. if ( $f->{oddball} ) { say $f->{apple} }; # Dump entire football for debugging. ### $f #===================================================================== +=======# package OO::Module; use strict; use warnings; #--------------------------------------------------------------------- +-------# #=========# CLASS METHOD # # my $obj = $class->new(); # my $obj = $class->new({ -a => 'x' }); # # Purpose : Object constructor # Parms : $class : Any subclass of this class # anything else will be passed to init() # Returns : $self # Invokes : init() # # Good old-fashioned hashref-based object constructor. # sub new { my $class = shift; my $self = {}; # always hashref bless ($self => $class); $self->init(@_); # init remaining args return $self; }; ## new #=========# OBJECT METHOD # # $obj->init({ k => 'v', f => $b }); # # Purpose : Initialize hashref-based object. # Parms : $self # : $hashref : arbitrary key/value pairs # Returns : $self # Throws : dies if $hashref can't be dereferenced to a hash # See also : new() # sub init { my $self = shift; my $hashref = shift // {}; # Do any pre-initializing of defaults here... $self->{oddball} = 1; # Merge all values. Newer values always overwrite. %{$self} = ( %{$self}, %{$hashref} ); return $self; }; ## init #=========# OBJECT METHOD # # $obj->_method({ '-parm' => $value, }); # short # # Purpose : ____ # Parms : ____ # Reads : ____ # Returns : ____ # Invokes : ____ # Writes : ____ # Throws : ____ # See also : ____ # # ____ # sub _method { my $self = shift; my $argref = shift; # Access pseudo-global football. $self->{ $argref->{fruit} } = $argref->{name}; return $self; }; ## _method __END__
| Output: |
|
In reply to Re: Accessing hash from within module
by Xiong
in thread Accessing hash from within module
by hmonroe
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |