serotta1958 has asked for the wisdom of the Perl Monks concerning the following question:

I need to over ride a setting in a package or module (not sure what the difference is) and cant figure out how to do it. I think I am struggling with the object oriented syntax but not sure.

In the code below I want to override the server address to point to the test environment.
sub set_defaults { my $self = shift; $self->server('prod.website.net') unless $self->server; $self->port('443') unless $self->port; $self->path('/xml/v1/request.api') unless $self->path;

Replies are listed 'Best First'.
Re: Overrides in a Package
by jethro (Monsignor) on Aug 23, 2011 at 01:20 UTC

    You should have some object $x (you usually get one with an object oriented interface), and you would do: $x->server('local.website');

    A package is just a separate name space for variables and functions. A module is a package crafted so that it can be used as a reusalbe library

Re: Overrides in a Package
by norbert.csongradi (Beadle) on Aug 23, 2011 at 06:35 UTC

    This code should belong to a package/class (let's call it Request::Server for example).

    You can override server/port/etc. settings right after you've created your instance with:

    my $server = Request::Server->new; # code for set_defaults executed... # and you override the default before using your object $server->server('qa.website.net'); # and do the rest... $server->start; # just an example!

      Thank you!! The I show in my post above already exists in a package called Business::OnlinePayment. That package has the url destination hardcoded and I want to override that url. when I code "$self->server('qa.website.net'); I get the message Can't call method "server" on an undefined value at /usr/lib/cgi-bin/simplearb.pl line 160. I fixed this on my home computer by just going into the PM code and changing the url but I cant do that on my hosted environment.

        This is because in the environment where you are calling the server(), $self doesn't have the object in it. $self has the object in the Business::OnlinePayment class because it follows the Perl standard for a method:
        sub server { my $self = shift; ... }
        A Perl method call automatically adds the object that the method is being called on to the beginning of the parameter list. This allows the method to address things in the object (for instance, the server name).

        I suspect two things are happening in your code:

        1. You didn't use strict, or you just added a my $self; without knowing why you were doing it.
        2. You didn't instantiate a Business:OnlinePayment object, or if you did, you didn't call set_defaults with it, as opposed to on it (a regular subroutine call instead of a method call).
        Remember: you aren't in the Business::OnlinePayment namespace wen you create set_defaults (although you could be, see below), so you need to call it like this:
        my $payer = Business::OnlinePayment->new(); set_defaults($payer);
        Your code could add the set_defaults method to the class dynamically by defining it as
        sub Business::OnlinePayment::set_defaults { ... your code here ... }
        If you instantiate the Business::OnlinePayment class with this subroutine defined, then you'll be able to say
        my $payer = Business::OnlinePayment->new(); $payer->set_defaults();
        as defining the sub with a fully-qualified name automatically adds it to the namespace, and if it's in the namespace, Perl will treat it as if it were a method defined in the Business/OnlinePayment.pm file, no matter where it was actually defined. I would recommend you not do this unless you comment it extensively! The next person along will not be expecting this, and if you invoke $payer->set_defaults() he or she will expect to find that in Business/OnlinePayment.pm and will confused and irritated if it is not there but works.