(\/)(\/) has asked for the wisdom of the Perl Monks concerning the following question:

I am new to module programming using Perl and am stuck.
I have this situation.

I have A.pm in dir /X
I have B.pm in dir /X/X
I have C.pm in dir /X/X

Now A.pm has a variable $i_am_the_problem that will be assigned a value by the script that uses these modules. At the same time function exported by B.pm and C.pm also need to access this value of $i_am _the_problem variable set.

How do I go about implementing this spec.??

Thanks,
Mystic Mayhem

Replies are listed 'Best First'.
RE: Module programming
by merlyn (Sage) on Oct 30, 2000 at 21:55 UTC
    You haven't said if you are the designer of these modules, or are just using these modules. If you're the designer, please redesign. Global variables are generally not a good idea, and you're starting to head down a treacherous area of heavy-duty coupling between these modules that will make life bad for you and your maintenance programmers.

    -- Randal L. Schwartz, Perl hacker

      I realise that global variables are not a very good idea. But can someone sugegst a better design ??

      In the example above, I need to pass my Proxy details to each module B.pm and C.pm so that they can fetch individual docs. from the Internet. Now there are three ways of doing it, as far as I can see.

      1. Pass the value individually to each module.
      2. Insert the proxy value into a config file that is opened by each module.
      3. Set the proxy value for A.pm and then use it for B.pm and C.pm

      Now I do not like (1) so much because I need to pass the same value again and again to each module.

      I do not like (2) so much because I want to keep the config as simple as possible - Nothing extra other than the config needed for basic PERL modules.

      Thus I came down to (3).

      Any other suggestions ??
        Can you give real names to A, B, and C? What roles are they playing? Can B and C be specializations (subclasses) of A? Can B and C ask A what the current proxy setting is? If you had three people named A, B, and C, what would their job titles be, what would each of them know, and what would they have to get from each other?

        A global variable is like person B riffling through the desk drawers belonging to person A just to get some info he knows. It's better to ask, not steal from behind. Because what happens if person A no longer puts it in the same drawer?

        -- Randal L. Schwartz, Perl hacker

Re: Module programming
by btrott (Parson) on Oct 30, 2000 at 21:58 UTC
    It sounds like you've got a rather convoluted setup; often when things seem difficult in Perl, it's a sign that you may need to rethink how you're structuring your code. In this case, your modules.

    However, you did ask, so--this seems to work. I've only done B.pm, not C.pm, because they should be quite similar if I understand what you're asking.

    Here's A.pm (your $i_am_the_problem is now called $problem):

    package A; use strict; use vars qw/@EXPORT @ISA $problem/; use Exporter; @ISA = qw/Exporter/; @EXPORT = qw/$problem/; 1;
    Here's B.pm:
    package B; use strict; use vars qw/@ISA @EXPORT/; use A; use Exporter; @ISA = qw/Exporter/; @EXPORT = qw/foo/; sub foo { print "problem is $problem\n" } 1;
    And here's a small script that sets $problem, then calls the exported function foo:
    use A; use B; $problem = "bar"; foo();
    That said, again: you really may want to rethink your code design.
Re: Module programming
by arturo (Vicar) on Oct 30, 2000 at 22:06 UTC

    You could, if you go with AgentM's suggestion (and you should listen to merlyn's advice), set up a method in A.pm that would look like so (assuming your object is a reference to an anonymous hash):

    sub the_problem { my $self = shift; $self->{_the_problem} = shift if (@_); # sets _the_problem to the +value we've been passed *if* we've been passed a value $self->{_the_problem}; # returns the current value of _the_problem }

    It's important to put this method in A.pm so B and C can inherit this method.

    In the script which uses the modules, you would then set this property by calling the method with arguments.

    use strict; use A::B::C; #use your modules. Pay attention to btrott's advice abov +e on Exporter etc. ... my $foo = new A::B::C; $foo->the_problem("argle bargle"); # $foo->{_the_problem} now eq 'argl +e bargle' print $foo->the_problem(); # prints "argle bargle"
    HTH

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Re: Module programming
by AgentM (Curate) on Oct 30, 2000 at 21:50 UTC
    if you're coming up against a wall here, you'll come across more. try reading through the object-oriented programming section of our famous amos Tutorials.
    AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.
Re: Module programming
by princepawn (Parson) on Oct 30, 2000 at 22:00 UTC
    Asumming the various directories are on your @INC variable (see use lib or perl -I in perlman:perlrun for more details).
    $A::i_am_prob=27; package B; # now in package B print $A::i_am_prob; # prints 27 package C; # now in package C print $A::i_am_prob; # prints 27
Re: Module programming
by (\/)(\/) (Novice) on Nov 02, 2000 at 15:41 UTC
    Thank you all. I have coded the Perl module. If anyone is interested, please visit Backend News Project

    (\/)(\/)