Can not add a scalar variable of path into @INC?

M

Michael Yang

I need to add the my lib path into @INC:
When I give the absolute path to the @INC, it works fine:
use lib "/home/michael/mylib";
But it doesn't work when I passed mylib as a scalar variable:
my $libpath = "/home/michael/mylib";
use lib $libpath;

In this way, the script can't locate the package in "mylib" path.
I need to use this scalar variable instead of hard-coded absolute
path.
Is there any ways to do this?
Thanks!
 
M

Michael Yang

I need to add the my lib path into @INC:
When I give the absolute path to the @INC, it works fine:
use lib "/home/michael/mylib";
But it doesn't work when I passed mylib as a scalar variable:
my $libpath = "/home/michael/mylib";
use lib $libpath;

In this way, the script can't locate the package in "mylib" path.
I need to use this scalar variable instead of hard-coded absolute
path.
Is there any ways to do this?
Thanks!

Seems that it doesn't work either using absolute path name.
During execution, it can not locate the *.pm file under "mylib" path.
But it works after I set the environment variable of "PERL5LIB" in the
command line.
This is not what I really need.
I want to add the lib path during the script run time.
 
T

Tad McClellan

Michael Yang said:
But it doesn't work when I passed mylib as a scalar variable:
my $libpath = "/home/michael/mylib";


That statement happens at run time.

use lib $libpath;


That statement happens at compile time.

compile time comes before run time, so the "use" is evaluated
before the variable has been given a value.

Didn't you get an error message like:

Empty compile time value given to use lib at ... ?

I need to use this scalar variable instead of hard-coded absolute
path.


Why do you need to use this scalar variable instead of hard-coded
absolute path?

Is there any ways to do this?


There is a way to force statements to be evaluated at compile time,
read up on the BEGIN block in perlmod.pod.
 
M

Michael Yang

Thanks so much, Tad!
Here is another problem after trying the BEGIN block statement:
my $mylib = undef;
BEGIN
{
$mylib = "/home/michael/mylib";
unshift @INC, $mylib;
}

print "\$mylib is $mylib.\n" ###########the value of $mylib is
empty.

The statement inside BEGIN is evaluated during compile time, seems not
in run time.
The $mylib value is set to undef outside the block.
How could make the codes inside BEGIN be evaluated both during compile
time and run time?
It's really appreciated of your answer!

That statement happens at run time.


That statement happens at compile time.

compile time comes before run time, so the "use" is evaluated
before the variable has been given a value.

Didn't you get an error message like:

Empty compile time value given to use lib at ... ?
Yes, I got this error msg before and didn't get to it.
Why do you need to use this scalar variable instead of hard-coded
absolute path?
To make my toolkit portable to different machines.
 
S

Sisyphus

..
..
The $mylib value is set to undef outside the block.

Why ?
How could make the codes inside BEGIN be evaluated both during compile
time and run time?

No need to evaluate the code that's in the BEGIN at runtime - $mylib will
retain the value it was assigned in the BEGIN{} block:

--------------------------
use warnings;

BEGIN {
$mylib = '/some/place';
unshift @INC, $mylib;
}

print "@INC\n", $mylib, "\n";
--------------------------

For me that produces:

/some/place C:/perl58_M/lib C:/perl58_M/site/lib .
/some/place

On the other hand, if you assign another value to $mylib during runtime (as
you have done) then, of course, $mylib will contain that new value (which
was undef in the example you provided).

Cheers,
Rob
 
M

Michael Yang

.
.


Why ?


No need to evaluate the code that's in the BEGIN at runtime - $mylib will
retain the value it was assigned in the BEGIN{} block:

--------------------------
use warnings;

BEGIN {
$mylib = '/some/place';
unshift @INC, $mylib;

}

print "@INC\n", $mylib, "\n";
--------------------------

For me that produces:

/some/place C:/perl58_M/lib C:/perl58_M/site/lib .
/some/place

On the other hand, if you assign another value to $mylib during runtime (as
you have done) then, of course, $mylib will contain that new value (which
was undef in the example you provided).

Cheers,
Rob

Thank you so much, Rob!
Now I have got it works. I should not assign value to the $mylib, only
need to declare it.

Thanks again~
Michael.
 
M

Michael Yang

.
.


Why ?


No need to evaluate the code that's in the BEGIN at runtime - $mylib will
retain the value it was assigned in the BEGIN{} block:

--------------------------
use warnings;

BEGIN {
$mylib = '/some/place';
unshift @INC, $mylib;

}

print "@INC\n", $mylib, "\n";
--------------------------
use warnings;
BEGIN {
$mylib = '/some/place';
unshift @INC, $mylib;
}
print "@INC\n", $mylib, "\n";

Is the new value of @INC be available to the sub-process of this
script?
for example, invoking another Perl script from here. Will the script
inherit this new @INC values, containing the extra search path of
$mylib?
 
S

Sisyphus

..
..
Is the new value of @INC be available to the sub-process of this
script?
for example, invoking another Perl script from here. Will the script
inherit this new @INC values, containing the extra search path of
$mylib?

No - you can check as follows:

--- try.pl ---
use warnings;

BEGIN {
$mylib = '/some/place';
unshift @INC, $mylib;
}

print "@INC\n", $mylib, "\n";

system("perl try2.pl");
-----------

--- try2.pl ---
use warnings;

print "@INC\n";
--------------

When I run 'perl try.pl' I get:

/some/place C:/perl58_M/lib C:/perl58_M/site/lib .
/some/place
C:/perl58_M/lib C:/perl58_M/site/lib .

So clearly, the modified @INC is not inherited.

You need to rewrite try.pl and try2.pl something like:

--- try.pl ---
use warnings;

BEGIN {
$mylib = '/some/place';
unshift @INC, $mylib;
}

print "@INC\n", $mylib, "\n";

system("perl try2.pl $mylib");
-----------

--- try2.pl ---
use warnings;

BEGIN {
unshift @INC, $ARGV[0];
}

print "@INC\n";
--------------

Now when I run 'perl try.pl' I get:

/some/place C:/perl58_M/lib C:/perl58_M/site/lib .
/some/place
/some/place C:/perl58_M/lib C:/perl58_M/site/lib .

(The modified @INC has been successfully passed on to try2.pl.)

Cheers,
Rob
 
M

Michael Yang

.
.


Is the new value of @INC be available to the sub-process of this
script?
for example, invoking another Perl script from here. Will the script
inherit this new @INC values, containing the extra search path of
$mylib?

No - you can check as follows:

--- try.pl ---
use warnings;

BEGIN {
$mylib = '/some/place';
unshift @INC, $mylib;

}

print "@INC\n", $mylib, "\n";

system("perl try2.pl");
-----------

--- try2.pl ---
use warnings;

print "@INC\n";
--------------

When I run 'perl try.pl' I get:

/some/place C:/perl58_M/lib C:/perl58_M/site/lib .
/some/place
C:/perl58_M/lib C:/perl58_M/site/lib .

So clearly, the modified @INC is not inherited.

You need to rewrite try.pl and try2.pl something like:

--- try.pl ---
use warnings;

BEGIN {
$mylib = '/some/place';
unshift @INC, $mylib;

}

print "@INC\n", $mylib, "\n";

system("perl try2.pl $mylib");
-----------

--- try2.pl ---
use warnings;

BEGIN {
unshift @INC, $ARGV[0];

}

print "@INC\n";
--------------

Now when I run 'perl try.pl' I get:

/some/place C:/perl58_M/lib C:/perl58_M/site/lib .
/some/place
/some/place C:/perl58_M/lib C:/perl58_M/site/lib .

(The modified @INC has been successfully passed on to try2.pl.)

Cheers,
Rob

Thank you so much for your reply!

It seems I have to assign the values to $ENV{'PERL5LIB'} , so that it
can be inherited.
Michael.
 

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,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top