Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

using modules already 'used'

by cLive ;-) (Prior)
on May 09, 2002 at 12:08 UTC ( [id://165343]=perlquestion: print w/replies, xml ) Need Help??

cLive ;-) has asked for the wisdom of the Perl Monks concerning the following question:

Let's say I have module 'A.pm' that uses CGI.pm (for param() mainly).

And let's say I have module 'B.pm' that also uses CGI.pm for similar reasons.

When I run test script.cgi from shell that uses 'A.pm' and 'B.pm', I get the "Enter params" thingy twice.

I *think* that I'm getting asked every time a new CGI object is created.

So my question is, what's the best way to share a CGI object over several scripts and associated modules? ie, if:

my $q = new CGI;
is already defined in one module, to use that object rather than create a new one. Typeglobs? Exporter? It needs to be flexible, because not all modules are used by each script, but both modules use CGI::param(). Then I could use something like this:
$q = new CGI unless defined $q;
I guess what I'm asking is, "What's the best way to control the existance of one object over several namespaces?".

I'm probably not making much sense here (it's 5am and I need to sleep :), but if anyone does have a clue what I'm going on about, I'd appreciate some clarity on this.

thanks

cLive ;-)

--
seek(JOB,$$LA,0);

Replies are listed 'Best First'.
Re: using modules already 'used'
by ariels (Curate) on May 09, 2002 at 12:22 UTC

    What you want is what the heavy-OO people call a "singleton". You could write one yourself (WARNING! Untested code!):

    package CGI::Single; our @ISA; @ISA = ('CGI'); my $instance; sub instance { defined $instance or $instance = new CGI; $instance; } 1;
    Now, say "$q = CGI::Single->instance" instead of "$q = new CGI".

    Or, CPAN has Class::Singleton, which should let you just say (again, untested!), mixin-style,

    package CGI::Single; our @ISA; @ISA = qw(CGI Class::Singleton); 1;
    with the same use as before.

Re: using modules already 'used'
by tachyon (Chancellor) on May 09, 2002 at 12:37 UTC

    Here are a few pointers.

    • When you use or require a module it gets placed in %INC. If you use or require it elswhere then perl just ignores you as it is already loaded
    • With CGI.pm or CGI::Simple when you create a new CGI object all the data on STDIN is read in (this gets there when you POST) so you can ONLY read this data once as once the data is read in it's gone. Thus you MUST only create one object if you are using POST. With GET the data is stripped off $ENV('QUERY_STRING') so you could have more than one (accurate) object.
    • To pass information between modules you have objects, accessor methods and globals to play with

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: using modules already 'used'
by japhy (Canon) on May 09, 2002 at 13:26 UTC
    I cannot duplicate your problem:
    package X; use CGI; $q = CGI->new; package Y; use CGI; $r = CGI->new; print $X::q->param('a'), " = ", $r->param('a');
    friday:~ $ perl cgi (offline mode: enter name=value pairs on standard input) a=123 = 123 = 123

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      Funny, I can't find the scripts now where I was having this problem, but here's the rough issue:
      package X; use CGI; $q = CGI->new; $q->param('test','test value'); print "In Package X: ", $q->param('test'), "\n"; package Y; use CGI; $r = CGI->new; print "In Package Y: ", $r->param('test'), "\n";
      Wheras, I want $r to contain the correct value of test. Now do you see what I mean? So I just want one CGI object created over the several namespaces.

      cLive ;-)

      --
      seek(JOB,$$LA,0);

      I cannot duplicate your problem:

      Different problem. You are effectively using GET data. Try the same trick with POST and $r->param('a') wil be undef as you have stripped all the data off STDIN. See Re: using modules already 'used'

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: using modules already 'used'
by BUU (Prior) on May 09, 2002 at 12:28 UTC
    There are two options (aside from the one above) that i see off hand. First off, you could have a global cgi object, and have each module say somethine like if(ref $x ne CGI){%$x=new cgi;} Note that you must use this form, blah = new cgi unless.. doesnt work, it clobbers whatever was in the variable before.

    The second option is to make your modules all take a cgi object as a parameter, then you can just keep passing the same obj around.
Re: using modules already 'used'
by kappa (Chaplain) on May 09, 2002 at 13:01 UTC
    $q ||= new CGI;
    ...is also cool, but of course not strictly equal to your variant :)
Re: using modules already 'used'
by abell (Chaplain) on May 09, 2002 at 16:22 UTC

    I would create a module creating the cgi object and then <it>use</it> it in all modules requiring the cgi object. For instance something along the lines of:

    package CGI::Instance; use strict; use CGI; use Exporter (); use vars qw(@ISA @EXPORT $cgi); @ISA = qw(Exporter); @EXPORT = qw( $cgi ); $cgi = new CGI; 1;

    And then in A.pm and B.pm put a use CGI::Instance. This way, $cgi is only created once and is available both in A and in B.

    Best regards

    Antonio Bellezza

Re: using modules already 'used'
by shotgunefx (Parson) on May 09, 2002 at 18:23 UTC
    In this case, I would consider using the functional interface. The only difference is it uses $CGI::Q internally for it's object which means they should all share the same $CGI::Q

    -Lee

    "To be civilized is to deny one's nature."

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2024-04-24 22:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found