Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

When writing OO classes, try to stay away from initialising globals in the outer class definition. Doing that requires (as you have seen) funky work arounds, BEGIN blocks and the like. Its better to encapsulate your packages more clearly, such as the following:

use strict; use warnings; my $foobar_o = Foo::Bar->new( name => "object o" ); printf "%s\n", $foobar_o->text(1); # -- # Package # -- package Foo::Bar; # Package namespace 'our' globals (which must be forward-declared.) our $data; # Fairly minimal constructor, passed an optional "name" argument: sub new { my $class = shift; $class = ref($class) || $class; # subclass boilerplate. my %params = @_; initialise(); my $self = bless {}, $class; foreach my $key (keys %params) { my $func = lc $key; next unless $self->can("$func"); $self->$func($params{$key}); } return $self; } sub initialise { return if defined $data; $data = { 1 => "one", 2 => "two", 100 => "one hundred", }; } sub name { my $self = shift; my $value = shift; $self->{name} = $value if defined $value; return $self->{name} // "<unnamed object>"; } # Silly example method that returns the "text" keyed by %$data. sub text { my $self = shift; my $query = shift or return ''; # Sanity check, making sure the package namespace $data exists: die "Uh-oh, data is not defined!" unless defined $data; my $s = sprintf( "%s: %s is %s", $self->name(), $query, $data->{$query} // "<query value not defined>" ); return $s; } # Explicit RC to support require() and use(). # This is only useful when the package is a real module file. 1;
Notice how the inclusion of an initialise() function gets rid of the BEGIN block, useful in avoiding paying the piper if you don't actually create any objects of this class for whatever reason. Also notice that the use of an accessor shifts all of the code for that accessor to one clearly defined location, so if you decide to change anything about that piece of data it won't affect anything else (this becomes a lot more important when you start having very complex objects with complex rules defining how items are updated and default values).

I also like using named parameters for the constructor, even when only passing one or two parameters. It makes inheritance and future expansion of the class a lot simpler. Combining that with using accessors to get and set values makes the constructor incredibly simple.

In reply to Re: Behavior of 'our' variables in the package-namespace by SimonPratt
in thread Behavior of 'our' variables in the package-namespace by Apero

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (1)
As of 2022-05-19 03:23 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (71 votes). Check out past polls.