Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: Accessing hash from within module

by Xiong (Hermit)
on Feb 12, 2012 at 07:18 UTC ( [id://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

Replies are listed 'Best First'.
Re^2: Accessing hash from within module
by BrowserUk (Patriarch) 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
Domain Nodelet?
Node Status?
node history
Node Type: note [id://953289]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2024-04-19 21:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found