Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Accessing hash from within module

by Xiong (Hermit)
on Feb 12, 2012 at 07:18 UTC ( #953289=note: print w/ replies, xml ) Need Help??


in reply to Accessing hash from within module

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:
Fuji ### $f: bless( { ### apple => 'Fuji', ### oddball => 1 ### }, 'OO::Module' )
I'm not the guy you kill, I'm the guy you buy. —Michael Clayton


Comment on Re: Accessing hash from within module
Select or Download Code
Replies are listed 'Best First'.
Re^2: Accessing hash from within module
by BrowserUk (Pope) on Feb 12, 2012 at 09:10 UTC
    This is almost as evil as global variables; just a bit less so.

    The real trouble with this OO route -- besides that it derives no true benefit from the costs of the OO -- is the clumsy syntax.

    Somewhere in your OO-football wrapped global, there is an array that needs to be iterated and its contents accessed:

    my $o = OO::Module->new; for my $i ( 0 .. $o->yyy->highest_index ) { $o->yyy->set_element( $i, $o->yyy->get_element( $i ) + 1 ); }

    For contrast, compare with:

    our @yyy; *yyy = \@{ $main::lglobal{ yyy } }; ++$yyy[ $_ ] for 0 .. $#yyy

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice. -- The problem with OO; is not the OO, but ooholes that use it.

    The start of some sanity?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://953289]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (8)
As of 2015-07-31 04:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (274 votes), past polls