Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Inheritance

by Anonymous Monk
on Jun 04, 2005 at 00:21 UTC ( [id://463431]=perlquestion: print w/replies, xml ) Need Help??

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

Hey Oh Wise ones, I am just getting into coding with inheritance for modules. I know when I want to export something from a module into another module I need to use
require exporter; export = qw (functions, $variables, @arrays);
To make sure whatever is in export can be seen by something else. But what Im not sure on, or how to tackle it is how to export things from my main script to its child modules for example
$dbh = $dbi->connect(...) $variable2= $something2->othermethod();
With explictly passing $dbh into othermethod() as
$variable2= $something2->othermethod($dbh,...);
How can I export a specific set of variables from the main script to everything that gets call from inside the main script Hope my description is understandable :-) Thanks! The Dumb one seeking wisdom

Replies are listed 'Best First'.
Re: Inheritance
by chromatic (Archbishop) on Jun 04, 2005 at 01:09 UTC

    I'm not sure exactly what you're looking for. "Inheritance" is a term specific to object oriented programming that describes one way to say "This thing acts like this other thing, perhaps with some small changes."

    Inheritance may be one way to solve what you're doing here, but I don't think it is.

    You have a couple of options for making one variable or object available across multiple modules:

    • Make it a global and always access it via a namespace, with something like $DB::Package::dbh. This has the drawback that you can't control who reads from or writes to it. That can be hard to debug.
    • Add it to the export list wherever you need it. This is still effectively a global variable, but it's a little less messy.
    • Store all of the database-related stuff in an object or package of its own and don't let it leak out anywhere else. This is a good practice anyway because it's easier to find what you need to change and because with good encapsulation it's more difficult to change things elsewhere accidentally.
    • Add an accessor to your database-related module from which to retrieve your database handle and only ever grab it via the accessor, perhaps my $dbh = DB::Package->fetch_dbh().

    There are other options, but they're mostly variants of these strategies. I do suggest modularizing your code by behavior and duty, though. It has many other benefits.

Re: Inheritance
by tilly (Archbishop) on Jun 04, 2005 at 01:37 UTC
    Whoa! Back up a minute!

    To export something from a module you need to use:

    use Exporter; # require works; @ISA = 'Exporter'; @EXPORT_OK = qw(functions $variables @arrays); # I put this after the above, some put this above and then use "our". use strict;
    and then your caller has to use Foo qw(functions $variables @arrays);

    What you wrote, by contrast, has several syntax errors, forgets that Perl is case-sensitive, and has some more subtle mistakes (eg the , inside of qw()). One of the more subtle mistakes is choosing to use @EXPORT instead of @EXPORT_OK, which works, but which will make debugging much harder. (Where did this come from?)

    As for the question that you're asking, the simple way to do it is to use fully qualified package names. Like this:

    # In the main script... use strict; use vars qw($foo); # ... time passes ... $foo = "whatever"; # In the module... print $main::foo;
    If you're tired of typing those variables time after time, you could always create a module whose job is to hold all of the variables that you want to share. Then you can just use that module from everywhere and the variables will be in your namespace.

    PS: Note that I've pushed you towards using strict.pm. There are good reasons for that...

      @EXPORT instead of @EXPORT_OK, which works, but which will make debugging much harder

      This is not related to debugging.

      The difference is that subs and vars included in @EXPORT will always be exported to the modules use'ing the module, while on the other hand, things included on @EXPORT_OK will only be exported when explicitely requested on the use statement.

      The problem with @EXPORT is namespace pollution that leads to name collisions when exported functions are added in new versions of some module.

        There is also a debugging problem. Two of them in fact.

        The first debugging problem is figuring out what happened after name collisions. (Creating bugs leads to debugging...) The second, and to me more important, one is the added trouble in finding the functions and variables that you see being called and accessed.

        The difference is that subs and vars included in @EXPORT will always be exported to the modules use'ing the module...

        Not to be overly retentive here, but that's not quite right. Or at least not sufficiently clear. In the empty list case -

        use Some::Module ();

        - no symbols are exported, even the ones in @EXPORT. In fact, @EXPORT are only imported in the default (unspecified) case. If you specify your imports explicitly, then you only get what you ask for.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://463431]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-03-29 10:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found