Mod Perl Icon Mod Perl Icon Perl Reference


[ Prev | Main Page | Next ]

Table of Contents:


The Writing Apache Modules with Perl and C book can be purchased online from O'Reilly and Amazon.com.
Your corrections of either technical or grammatical errors are very welcome. You are encouraged to help me to improve this guide. If you have something to contribute please send it directly to me.

[TOC]


Coverage

This new document was born because some users reluctant to learn perl prior to jumping into a mod_perl. I will try to cover some of the most frequent pure perl questions being asked at the list.

[TOC]


perldoc's little known but very useful options

To find what functions perl has, you would execute:

  perldoc perlfunc

To learn the syntax and to find an example of specific known function, you would execute (e.g. for open()):

  perldoc -f open

There is a bug in this option, for it wouldn't call pod2man and display the section in POD. But it's still readable and very useful.

To search the Perl FAQ (perlfaq) sections you would do (e.g for an open keyword):

  perldoc -q open

will return you all the matching Q&A sections, still in POD.

[TOC]


Using global variables and sharing them between modules/packages

[TOC]


Making the variables global

When you first wrote $x in your code you created a global variable. It is visible everywhere in the file you have use it. or if defined it inside a package - it is visible inside this package. But it will work only if you do not use strict pragma and you HAVE to use this pragma if you want to run your scripts under mod_perl. Read Strict pragma to find out why.

[TOC]


Making the variables global with strict pragma On

First you use :

  use strict;

Then you use:

 use vars qw($scalar %hash @array);

Starting from this moment the variables are global in the package you defined them, if you want to share global variables between packages, here what you can do.

[TOC]


Using Exporter.pm to share global variables

Assume that you want to share the CGI.pm's object (I will use $q) between your modules. For example you create it in the script.pl, but want it to be visible in My::HTML. First - you make $q global.

  script.pl:
  ----------------
  use vars qw($q);
  use CGI;
  use lib qw(.); 
  use My::HTML qw($q); # My/HTML.pm in the same dir as script.pl
  $q = new CGI;
  
  My::HTML::printmyheader();
  ----------------

Note that we have imported $q from My::HTML. And the My::HTML which does the export of $q:

  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);
  
  sub printmyheader{
    # Whatever you want to do with $q... e.g.
    print $q->header();
  }
  1;
  -------------------

So the $q is being shared between the My::HTML package and the script.pl. It will work vice versa as well, if you create the object in the My::HTML but use it in the script.pl. You have a true sharing, since if you change $q in script.pl, it will be changed in My::HTML as well.

What if you need to share $q between more than 2 packages? For example you want My::Doc to share $q as well.

You leave the My::HTML untouched, modify the script.pl to include:

 use My::Doc qw($q);

And write the My::Doc exactly like My::HTML - of course that the content is different :).

One possible pitfall is when you want to use the My::Doc in both My::HTML and script.pl. Only if you add:

  use My::Doc qw($q);

Into a My::HTML, the $q will be shared. Otherwise My::Doc will not share the $q anymore. To make things clear here is the code:

  script.pl:
  ----------------
  use vars qw($q);
  use CGI;
  use lib qw(.); 
  use My::HTML qw($q); # My/HTML.pm 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;
  -------------------

[TOC]


Using aliasing perl feature to share global variables

As the title says you can import a variable into a script/module without using an Exporter.pm. I have found it useful to keep all the configuration variables in one module My::Config. But then I have to export all the variables in order to use them in other modules, which is bad for two reasons: polluting other packages' name spaces with extra tags which rise up the memory requirements, adding an overhead of keeping track of what variables should be exported from the configuration module and what imported for some particular package. I solve this problem by keeping all the variables in one hash %c and exporting only it. Here is an example of My::Config:

  package My::Config;
  use strict;
  use vars qw(%c);
  %c = (
    # All the configs go here
    scalar_var => 5,
  
    array_var  => [
                   foo,
                   bar,
                  ],
  
    hash_var   => {
                   foo => 'Foo',
                   bar => 'BARRR',
                  },
  );
  1;

Now in packages that want to use the configuration variables I have either to use the fully qualified names like $My::Config::test, which I dislike or import them as described in the previous section. But hey, since we have only one variable to handle, we can make things even simpler and save the loading of the Exporter.pm package. We will use aliasing perl feature for exporting and saving the keystrokes:

  package My::HTML;
  use strict;
  use lib qw(.);
    # Global Configuration now aliased to global %c
  use My::Config (); # My/Config.pm in the same dir as script.pl
  use vars qw(%c);
  *c = \%My::Config::c;
  
    # Now you can access the variables from the My::Config
  print $c{scalar_val};
  print $c{array_val}[0];
  print $c{hash_val}{foo};

Of course $c is global everywhere you use it as described above, and if you change it somewhere it will affect any other packages you have aliased $My::Config::c to.

Note that aliases work either with global or local() vars - you cannot write:

  my *c = \%My::Config::c;

Which is an error. But you can:

  local *c = \%My::Config::c;

[TOC]


The Writing Apache Modules with Perl and C book can be purchased online from O'Reilly and Amazon.com.
Your corrections of either technical or grammatical errors are very welcome. You are encouraged to help me to improve this guide. If you have something to contribute please send it directly to me.
[ Prev | Main Page | Next ]

Written by Stas Bekman.
Last Modified at 08/16/1999
Mod Perl Icon Use of the Camel for Perl is
a trademark of O'Reilly & Associates,
and is used by permission.