Loading Modules with "require"

G

Gunnar Hjalmarsson

I'm trying to figure out how Perl operates regarding the 'require'
function.

Say I have the following code in an included library because several
modules use the code:

$sel = $dbh->prepare("SELECT acronym, table_name, proper_name
FROM table_data WHERE acronym = '$x_table' AND email_ind = 'Y'");
$sel->execute() || die "Select of table $x_table failed: ",
$dbh->errstr, "\n";
($acronym,$table,$name) = $sel->fetchrow_array();
$sel->finish;

Notice that there are some variables there, '$x_table', etc. What I am
noticing is that Perl will load it once, and then reuse that exact
code.

So, the very first time Perl will fill in the variable values, and then
that code remains static. So, even if the variables change, they do
not change for the included code.
Is there a way around this?

Put the code in a subroutine and call that routine rather than requiring
the library repeatedly.
 
A

amerar

Hi All,

I'm trying to figure out how Perl operates regarding the 'require'
function.

Say I have the following code in an included library because several
modules use the code:

$sel = $dbh->prepare("SELECT acronym, table_name, proper_name
FROM table_data WHERE acronym = '$x_table' AND email_ind = 'Y'");
$sel->execute() || die "Select of table $x_table failed: ",
$dbh->errstr, "\n";
($acronym,$table,$name) = $sel->fetchrow_array();
$sel->finish;


Notice that there are some variables there, '$x_table', etc. What I am
noticing is that Perl will load it once, and then reuse that exact
code.

So, the very first time Perl will fill in the variable values, and then
that code remains static. So, even if the variables change, they do
not change for the included code.
Is there a way around this?

Arthur
 
P

Paul Lalli

I'm trying to figure out how Perl operates regarding the 'require'
function.

Say I have the following code in an included library because several
modules use the code:

$sel = $dbh->prepare("SELECT acronym, table_name, proper_name
FROM table_data WHERE acronym = '$x_table' AND email_ind = 'Y'");
$sel->execute() || die "Select of table $x_table failed: ",
$dbh->errstr, "\n";
($acronym,$table,$name) = $sel->fetchrow_array();
$sel->finish;


Notice that there are some variables there, '$x_table', etc. What I am
noticing is that Perl will load it once, and then reuse that exact
code.

So, the very first time Perl will fill in the variable values, and then
that code remains static. So, even if the variables change, they do
not change for the included code.
Is there a way around this?

The correct way of doing what I believe you are trying to do is to wrap
that code in a subroutine, and pass the relevant variables in to the
subroutine as parameters.

sub do_sql {
my ($x_table) = @_;
my ($acronym, $table, $name);
#... your code here
return ($acronym, $table, $name);
}

my ($acr, $tbl, $nme) = do_sql('SCUBA');


Hope this helps,
Paul Lalli
 
A

amerar

If I can ask a stupid question: If the module is loaded only once with
'require', then what good is it? If I have several procedures that use
the same code and I want to make an 'include', which may get used
several times in the same procedure, it seems that it serves no
purpose.

The idea is to have code that you can make generic and use in many
different scripts, load as many times as you need to, etc......
 
G

Gunnar Hjalmarsson

If I can ask a stupid question: If the module is loaded only once
with 'require', then what good is it? If I have several procedures
that use the same code and I want to make an 'include', which may get
used several times in the same procedure, it seems that it serves no
purpose.

If you put the code in a subroutine, it gets compiled when you "require"
(or "use") it, while it gets executed each time you call the subroutine.

See also Paul's example.
The idea is to have code that you can make generic and use in many
different scripts, load as many times as you need to, etc......

I did understand that.
 
A

amerar

What I am unclear about is this: Say I had the following declaration
in my script: $x = $y + 4;

Now, the first time that the coed was 'required' it would take the
value of $y and compute a value for $x. However, next time I
'require' that code in the same execution of the program, the values
would not change, even if $y had changed........
I need the values to be able to be modified......
 
G

Gunnar Hjalmarsson

What I am unclear about is this: Say I had the following declaration
in my script: $x = $y + 4;

Now, the first time that the coed was 'required' it would take the
value of $y and compute a value for $x. However, next time I
'require' that code in the same execution of the program, the values
would not change, even if $y had changed........

## Addlib.pm
package Addlib;
sub add {
my $arg = shift;
return $arg + 4;
}
1;

## test.pl
#!/usr/bin/perl
use strict;
use warnings;

require Addlib;
my ($x, $y);

# First calculation
$y = 5;
$x = Addlib::add($y);
print "\$x = $x\n"; # prints 9

# Second calculation
$y = 3;
$x = Addlib::add($y);
print "\$x = $x\n"; # prints 7

__END__

Please study

perldoc perlmod
perldoc perlsub
 
A

amerar

I sort of see who that works. Are you saying that to have the values
in an 'include' change when it is executed more than once, I need to
basically make that include a packaged subroutine? Passing to it any
values used within and receiving any values returned from?

But, here you are dealing with a single value. How would you code
thing that deals with arrays, and things like this:

$sel = $dbh->prepare("SELECT table_name, proper_name, acronym FROM
table_data $where");
$sel->execute() || die "Select of table names failed: ",
$dbh->errstr, "\n";
while (($table, $name, $acr) = $sel->fetchrow_array()) {
$tables{$table} = $name;
}
$sel->finish;

Thanks.
 
G

Gunnar Hjalmarsson

I sort of see who that works. Are you saying that to have the values
in an 'include' change when it is executed more than once, I need to
basically make that include a packaged subroutine? Passing to it any
values used within and receiving any values returned from?

Not saying you *need* to do it that way, but I think it's the best
approach. For instance, you *can* do it without a separate package:

## Addlib.pl
sub add {
my $arg = shift;
return $arg + 4;
}
1;

## test.pl
#!/usr/bin/perl
use strict;
use warnings;

require 'Addlib.pl';
my ($x, $y);

# First calculation
$y = 5;
$x = add($y);
print "\$x = $x\n"; # prints 9

# Second calculation
$y = 3;
$x = add($y);
print "\$x = $x\n"; # prints 7

__END__
But, here you are dealing with a single value. How would you code
thing that deals with arrays, and things like this:

$sel = $dbh->prepare("SELECT table_name, proper_name, acronym FROM
table_data $where");
$sel->execute() || die "Select of table names failed: ",
$dbh->errstr, "\n";
while (($table, $name, $acr) = $sel->fetchrow_array()) {
$tables{$table} = $name;
}
$sel->finish;

You can pass multiple arguments, which can be objects, and return
multiple values. Arrays are preferrably passed as array references.

Did you study "perldoc perlsub", btw?
 
J

Joe Smith

Hi All,

I'm trying to figure out how Perl operates regarding the 'require'
function.

Say I have the following code in an included library because several
modules use the code:

You're going about it all wrong.

Don't put code in a module; but function definitions in the module.
Then call the function with the appropriate arguments - do not
in-line the code over and over.

Put this in My_module.pm:

sub my_database_function_1 {
my $x_table = shift;
... bunch of statements that use $x_table go here
return;
}

Then in main.pl:
use My_module;
@data = my_database_function_1("table1");

And in foo.pl:
use My_module;
@results = my_datbase_function_1("foo");
 
J

Joe Smith

If I can ask a stupid question: If the module is loaded only once with
'require', then what good is it?

If the module only defines subroutines and declares constants, then
loading it only once is most appropriate.

If I have several procedures that use the same code

You should have several procedures that call the same user-defined
functions.
The idea is to have code that you can make generic and use in many
different scripts, load as many times as you need to, etc......

That's exactly what you get when you write user-defined functions
instead of just copy-and-paste in-line code.
-Joe
 
J

Joe Smith

I sort of see who that works. Are you saying that to have the values
in an 'include' change when it is executed more than once, I need to
basically make that include a packaged subroutine?

No. You do know how subroutines and functions work, don't you?

You define a function once, then invoke the function one or more
times. Each invocation can use a different set of arguments,
and the function can return zero, one or many values. (It can also
change global variables, but that's often not good programming practice.)
Passing to it any values used within and receiving any values returned from?

Exactly, if by 'it' you mean a user-defined function (and not the name
of a perl module).
But, here you are dealing with a single value. How would you code
thing that deals with arrays, and things like this:

Have you read the part in the Perl documentation where it talks
about @_ (the special array used for passing function arguments)?
Also look at the documentation for shift(), which acts differently
inside a function definition than outside.
-Joe
 
J

Juha Laiho

(e-mail address removed) said:
I sort of see who that works. Are you saying that to have the values
in an 'include' change when it is executed more than once, I need to
basically make that include a packaged subroutine?

If your code all is in a single file/package anyway, all you need is
a subroutine declared within that file. So, you don't even need the
use/require syntax. If you're setting up a multi-file program, then
it'd do good to play with some simple value-passing code first to
learn what happens (and contrast your findings with the relevant
documentation).

Somehow it looks here that the mere concept of a subroutine is foreign
to you, so start with that.
But, here you are dealing with a single value. How would you code
thing that deals with arrays, and things like this:

$sel = $dbh->prepare("SELECT table_name, proper_name, acronym FROM
table_data $where");
$sel->execute() || die "Select of table names failed: ",
$dbh->errstr, "\n";
while (($table, $name, $acr) = $sel->fetchrow_array()) {
$tables{$table} = $name;
}
$sel->finish;

Let's see; apparently that is dependent on the external variables
$dbh and $where, and the results should be inserted to a hash named
%tables . $sel, $table, $name and $acr are local to the routine.

sub get_name_and_acronym()
{
my ($dbh,$where,$tables_ref)=@_;
my ($sel,$table,$name,$acr);

$sel = $dbh->prepare( ... );
...
while ( ... ) {
$tables_ref->{$table} = $name;
}
$sel->finish();
}

.... and call from surrounding code with

get_name_and_acronym($dbh,$where,\%tables);

Things to note:
- the subroutine only accesses variables declared within the subroutine
(parameters are explicitly passed through the 'my (...) = @_;'
mechanism)
- variable names within the subroutine are independent of the variable
names outside the subroutine (so, within the subroutine you could
rename $dbh to $d, $where to $w, and so on, and it would still work
the same
- all variables declared with 'my' within the subroutine are local
to the subroutine, and will not be accessible anywhere outside the
subroutine (though, you may have other variables with the same names
outside the subroutine)
- the \-sign preceding the %tables when calling the subroutine;
this'll create a reference to the named data structure, instead of
passing the structure itself, and thus the called routine can access
(even to modify) the contents of the structure
- the arrow notation for accessing hash contents through a reference
(so "$tables_ref->{$table}" because $tables_ref is a reference to
a hash)
 

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

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top