global variables in oop

E

edward.nigma

This appears to be an example shown on many diffrent articles for
creating global values available to all packages in a Perl script...
looks good except I have one alternation to it that I am not quite able
to figure out...

This assumes that your packages are being loaded from remote files with
the use command...

BEGIN CODE -->

script.pl:
----------------
use vars qw($q);
use CGI;
use lib qw(.);
use My::HTML qw($q); # My/HTML.pm is in the same dir as script.pl
use My::Doc qw($q); # Ditto
$q = new CGI;
My::HTML::printmyheader();
My/HTML.pm
----------------
package My::HTML;
use strict;
BEGIN {
use Exporter ();
@My::HTML::ISA = qw(Exporter);
@My::HTML::EXPORT = qw();
@My::HTML::EXPORT_OK = qw($q);
}
use vars qw($q);
use My::Doc qw($q);
sub printmyheader{
# Whatever you want to do with $q... e.g.
print $q->header();
My::Doc::printtitle('Guide');
}
1;
My/Doc.pm
----------------
package My::Doc;
use strict;
BEGIN {
use Exporter ();
@My::Doc::ISA = qw(Exporter);
@My::Doc::EXPORT = qw();
@My::Doc::EXPORT_OK = qw($q);
}
use vars qw($q);
sub printtitle{
my $title = shift || 'None';
print $q->h1($title);
}
1;

END CODE -->

What if your packages are being established within the same file? Such
as the following.

Now you do not have the opportunity to include this line, which I
belive is necessary for this to function properly.
use My::HTML qw($q); # My/HTML.pm is in the same dir as script.pl

BEGIN CODE -->

script.pl
-------
use strict;

$hello = 1;
TESTING->showtest; # output 1
TESTING2->showtest; # output 2
print $hello; # output 3

package TESTING;
use strict;

sub showtest {
print $hello;
}

package TESTING2;
use strict;

sub showtest {
$hello++;
print $hello;
$hello++;
}

END CODE -->

Thank you! This may be a pretty simple solution, but I am new to object
oriented perl.
 
A

A. Sinan Unur

(e-mail address removed) wrote in
This appears to be an example shown on many diffrent articles for
creating global values available to all packages in a Perl script...
looks good except I have one alternation to it that I am not quite
able to figure out...

This assumes that your packages are being loaded from remote files
with the use command...

The code just feels weird. That might be for two reasons. First, it is
entirely possible that I do not know enough Perl to understand a very
neat solution to a problem I cannot quite comprehend. Second, it might
be crap. I am actually interested in the opinion of others in this
newsgroup who know infinitely more than I do.
BEGIN CODE -->

What is the problem this code is attempting to solve?
script.pl:
----------------
use vars qw($q);
Why?

use CGI;

use CGI();
use lib qw(.);
use My::HTML qw($q); # My/HTML.pm is in the same dir as script.pl
use My::Doc qw($q); # Ditto

use My::HTML;
use My::Doc;
$q = new CGI;

my $cgi = CGI->new;
My::HTML::printmyheader();

my $out .= My::HTML::myheader($cgi);
My/HTML.pm
----------------
package My::HTML;
use strict; ....
sub printmyheader{
# Whatever you want to do with $q... e.g.
print $q->header();
My::Doc::printtitle('Guide');
}

sub myheader {
$_[0]->header . My::Doc::mytitle($_[0], 'Guide');
}
My/Doc.pm
----------------
package My::Doc;
use strict; ....
sub printtitle{
my $title = shift || 'None';
print $q->h1($title);
}

sub mytitle {
$_[0]->h1(+shift || 'None');
}

My suggestions are untested.

Now, I think CGI.pm implements the singleton pattern. So, why not make
My::HTML and My::Doc inherit from CGI.pm. Are you under the impression
that there will be many objects replicating all the query data?

I must admit, I am confused.
What if your packages are being established within the same file? Such
as the following.

What is your question? Are you asking how to have a variable which is
accessible to all the packages defined in the script?
BEGIN CODE -->

script.pl

Please show real code! Have you seen the posting guidelines for this
group?

D:\Home\asu1\UseNet\clpmisc> perl -c ooo.pl
Global symbol "$hello" requires explicit package name at ooo.pl line 3.
Global symbol "$hello" requires explicit package name at ooo.pl line 6.
BEGIN not safe after errors--compilation aborted at ooo.pl line 9.

#!/usr/bin/perl -w

use strict;

my $hello = 1;

PACKAGE1->showtest;
PACKAGE2->showtest;

print "$hello";

package PACKAGE1;
use strict;

sub showtest { print "$hello\n" }

package PACKAGE2;
use strict;

sub showtest { $hello++; print "$hello\n"; $hello++; }

__END__

D:\Home\asu1\UseNet\clpmisc> ooo
1
2
3

Why do you want to do this?

Having methods depend on the name of an external variable is not a good
idea.
Thank you! This may be a pretty simple solution, but I am new to
object oriented perl.

What book are you using?

Sinan
 
S

Sherm Pendley

John Bokma said:
why ( the () )

From "perldoc -f use":

If you do not want to call the package's "import" method (for
instance, to stop your namespace from being altered), explic-
itly supply the empty list:

use Module ();

sherm--
 
A

Anno Siegel

This appears to be an example shown on many diffrent articles for
creating global values available to all packages in a Perl script...
looks good except I have one alternation to it that I am not quite able
Alternation?

to figure out...

This assumes that your packages are being loaded from remote files with
the use command...

BEGIN CODE -->

[snip]

If I understand your question, you are asking what to do instead of
"use" if a module is defined in the same file that wants to use it.

There are several solutions to this. One receipt is this: Where the
"use" statement would go, put two BEGIN {} blocks. The first contains
the module definition proper, more or less as it would appear in an
external file. The second calls the modules ->import method with
the arguments you would have given to "use". Example:

#!/usr/bin/perl
use strict; $| = 1;

BEGIN {
package My::Module;
require Exporter;
our @ISA = qw( Exporter);
our @EXPORT_OK = qw( $q);

our $q = 123;
}

BEGIN {
My::Module->import( '$q');
}

print "$q\n";

Anno
 
J

John Bokma

Sherm Pendley said:
From "perldoc -f use":

If you do not want to call the package's "import" method (for
instance, to stop your namespace from being altered), explic-
itly supply the empty list:

use Module ();

Thanks, I had the feeling that it did that but wasn't aware that CGI
imports stuff by default though, I always thought one had to explicitly
state that stuff had to be imported (e.g. use CGI qw:)default);)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top