Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Subroutine library calls in Perl

Posted on 2003-11-20
7
Medium Priority
?
775 Views
Last Modified: 2013-12-25
In Perl, I have created a file containing several shared subroutines ("subrout.lib") and then including the command "require 'subrout.lib';" in each script that references one or more of the subroutines.  That works well except when a script calls itself (for instance, to replot the screen with the data sorted differently).  It clearly accesses the subroutines the first time, but does not access them in subsequent calls.

When I include the shared subroutines in each script, everything works fine.  That obviously increases the size of my scripts and is no fun to maintain.  Before I proceed, I thought I would ask what is the best way to (a) set up a library of subroutines and (b) call a subroutine from that library.
0
Comment
Question by:ryuuseki
7 Comments
 
LVL 5

Assisted Solution

by:djplaistow
djplaistow earned 100 total points
ID: 9791156
For a package named DBUtilities, which by convention would be stored in a file named DBUtilities.pm, the begining would look like:

    package DBUtilities;

    require Exporter;
    @ISA = qw(Exporter);
    @EXPORT = (SqlFunction AnotherFunc); # List all subroutines and variables that will be automatically
                                                                   # exported to all scripts that use the module
    @EXPORT_OK = qw(Func1 $globalDsn  @tables); # List all subroutines and variables that will be exported
                                                                                  # to all scripts that explicitly name them

Then a script that wants to use subroutines and/or variables that are within DBUtilities would add a line like:

    use DBUtilities qw(SqlFunction @tables);

Thus, the script will have acces to the subroutines SqlFunction (which it did not have to explicitly request),  and AnotherFunc, and the variable @tables. However, it will not have access to the subroutine Func1 or the variable $globalDsn as it would have had to explicitly request them.
0
 
LVL 5

Assisted Solution

by:djplaistow
djplaistow earned 100 total points
ID: 9791186
I forgot to spell out the answer to "(b) call a subroutine from that library." Once you have included the line like:

    use DBUtilities qw(SqlFunction @tables);

You treat it as if the code for the function is within the script itself; it is analogous to the C++ using namespace construct.
0
 
LVL 85

Assisted Solution

by:ozo
ozo earned 50 total points
ID: 9791726
How does it fail when a script calls itself?
Could you give an example of code that does not work the way you think it should?
0
Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

 
LVL 51

Assisted Solution

by:ahoffmann
ahoffmann earned 50 total points
ID: 9800243
before converting to packages, could you please post the require and the exec (itself) part of your script
0
 

Author Comment

by:ryuuseki
ID: 9819929
I appreciate the comments.  Honestly, I was hoping there would be a simpler answer than working with packages.

In theory, should the calls using require work?  Is there any inherent problem with this method?  The scripts are on our internal server, and too large to post in this forum.  I can try to write a smaller script that replicates the failure, but I'd rather put my efforts toward proper technique if this method is not recommended.
0
 

Author Comment

by:ryuuseki
ID: 9820690
*sigh*  Just when I think I understood something, I realize I really didn't.

The failure appears to be related to the scoping of "my" variables.  I have always used strict scoping with "my" variables.  What I didn't quite understand was the concept of packaged scoping of the "my" vars.

Simply put, in the following example, $v2 is visible to the subroutine "test":

(main.pl)
use strict;
my($v1) = "VAR 1";
my($v2) = "VAR 2";
print "$v1\n";
print "$v2\n";
&test();

sub test {
  print "$v2\n"; }

If I change it to the following, $v2 is not visible to "test":

(main.pl)
use strict;
require "subrout.lib";
my($v1) = "VAR 1";
my($v2) = "VAR 2";
print "$v1\n";
print "$v2\n";
&test();

(subrout.lib)
sub test {
  print "$v2\n"; }

1;

By changing "my($v2)" to "our($v2)" it becomes visible outside of the "main" package.

I'm still not sure why the complicated script works the first time through but not on subsequent calls.  I'll have to dig deeper to figure that out.


In the meantime, I'd still appreciate comment regarding my previous comment re: the propriety of using require.
0
 
LVL 3

Accepted Solution

by:
rkosai earned 50 total points
ID: 9827046
To allieviate problems such as these, as well as making code easier to read (and following "better" coding practices), it is usually recommended to make each of your subroutines isolated from each other.  This avoids many problems, including ones like this.

So, alternatively, you'd write code like this.

use strict;
require "subrout.lib";
my $v1 = "VAR 1";
my $v2 = "VAR 2";
print "$v1\n";
print "$v2\n";
test($v2); #prints $v2

# -- (subrout.lib) --
sub test {
  shift; #captures the arguments to the subroutine, and stores them in $_
  print "$_\n"; }

1;
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It is becoming increasingly popular to have a front-page slider on a web site. Nearly every TV website,  magazine or online news has one on their site, and even some e-commerce sites have one. Today you can use sliders with Joomla, WordPress or …
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
Suggested Courses

926 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question