Adding path to @INC

G

guru

Can i use following statement to push path contained in $LINK_PATH to
@INC array.

$LINK_PATH = "/usr/raja/"

BEGIN {
push @INC,"$LINK_PATH";
}

when I see contents of @INC it is not adding.

I am trying to refer the module which is in other directory.

I will give path in command line. in the script I will get this path
and try to put in to @INC so that I can find those modules.

Can I use the above statement

BEGIN {
push @INC,'$LINK_PATH';
}

or how this can be done.

Thanks & Regards
Gururaja B O
 
P

Peter Makholm

guru said:
$LINK_PATH = "/usr/raja/"

This line is outside the BEGIN block and is such executed at normal
run time.
BEGIN {
push @INC,"$LINK_PATH";

This line is inside the BEGIN block ans is as such executed at compile
time. At this time $LINK_PATH doesn't have any content. Put both lines
inside the BEGIN block or just do away with $LINK_PATH.

//Makholm
 
M

Marc Lucksch

guru said:
Can i use following statement to push path contained in $LINK_PATH to
@INC array.

$LINK_PATH = "/usr/raja/"

BEGIN {
push @INC,"$LINK_PATH";
}

You made 2 mistakes:

1. You didn't use strict or warnings.
2. BEGIN gets run before the $LINK_PATH = "/usr/raja/", strict would
have told you that.

G:\Temp\INI>perl
$LINK_PATH = "/usr/raja/";
BEGIN {
push @INC,"$LINK_PATH";
}
print @INC;
__END__
C:/usr/site/libC:/usr/lib.


G:\Temp\INI>perl
BEGIN {
LINK_PATH = "/usr/raja/";
push @INC,"$LINK_PATH";
}
print @INC;
__END__
C:/usr/site/libC:/usr/lib./usr/raja/

Alwyas use strict. ALWAYS.


G:\Temp\INI>perl
use strict;
use warnings;
$LINK_PATH = "/usr/raja/";
BEGIN {
push @INC,"$LINK_PATH";
}
Global symbol "$LINK_PATH" requires explicit package name at - line 3.
Global symbol "$LINK_PATH" requires explicit package name at - line 5.


G:\Temp\INI>perl
use strict;
use warnings;
my $LINK_PATH = "/usr/raja/";
BEGIN {
push @INC,"$LINK_PATH";
}
Use of uninitialized value $LINK_PATH in string at - line 5.

By the way: Better use lib:

use lib qw[/usr/raja/];

OR: on commandline, use the -I switch.

G:\Temp\INI>perl -I /usr/raja
print @INC;
__END__
/usr/rajaC:/usr/site/libC:/usr/lib.
 
T

Tad J McClellan

guru said:
Can i use following statement to push path contained in $LINK_PATH to
@INC array.

No.


$LINK_PATH = "/usr/raja/"

BEGIN {
push @INC,"$LINK_PATH";
}

when I see contents of @INC it is not adding.


Because the push() is executed *before* the assignment to $LINK_PATH.

See also:

perldoc -q vars

What's wrong with always quoting "$vars"?

I am trying to refer the module which is in other directory.

I will give path in command line. in the script I will get this path
and try to put in to @INC so that I can find those modules.


You should check the Perl FAQ before posting to the Perl newsgroup.

perldoc -q INC

How do I add a directory to my include path (@INC) at runtime?

or how this can be done.


use lib $ARGV[0];
 
S

szr

Marc said:
You made 2 mistakes:

1. You didn't use strict or warnings.

You cannot say this conclusively, not without seeing his real code. It
appeared to me he was just giving small example snippets (which he may
just typed out from memory,) which I would agree may not have been the
best way to go about it.

2. BEGIN gets run before the $LINK_PATH = "/usr/raja/", strict would
have told you that.

Strict tells no such thing:

$ perl -e 'use strict; use warnings; my $f = "/tmp";
BEGIN { push @INC, $f }'

This returns nothing with both perl 5.10.0 and 5.8.8. If you put double
quotes around $f in the push statement, you get a warning about the use
of an uninitialized value in a string, but this has no baring on weather
or not strict was used. (And for that matter, putting double quotes
around a lone variable like that is generally bad practice.)

In fact the only warning I get at all is from his first snippet is about
the fact "my" was omitted from $LINK_PATH, which is coming from
'warnings', not 'strict.'


[...]
By the way: Better use lib:

use lib qw[/usr/raja/];

Indeed.

If it needs to be set dynamically (ie, from a variable), one can do
something like:

$ perl -e 'use strict; use warnings; my $lib;
BEGIN { $lib = "/foo"; } use lib ($lib);
print join "\n", @INC;'
/foo
/home/szr/perllib
/usr/lib/perl5/5.10.0/i686-linux-64int-ld
/usr/lib/perl5/5.10.0
/usr/lib/perl5/site_perl/5.10.0/i686-linux-64int-ld
/usr/lib/perl5/site_perl/5.10.0
 
M

Marc Lucksch

szr said:
You cannot say this conclusively, not without seeing his real code. It
appeared to me he was just giving small example snippets (which he may
just typed out from memory,) which I would agree may not have been the
best way to go about it.

Your right,
Strict tells no such thing:

$ perl -e 'use strict; use warnings; my $f = "/tmp";

This returns nothing with both perl 5.10.0 and 5.8.8. If you put double
quotes around $f in the push statement, you get a warning about the use
of an uninitialized value in a string, but this has no baring on weather
or not strict was used. (And for that matter, putting double quotes
around a lone variable like that is generally bad practice.)

In fact the only warning I get at all is from his first snippet is about
the fact "my" was omitted from $LINK_PATH, which is coming from
'warnings', not 'strict.'

And right again. I should keep my gob shut. :(

I still think the -I switch is the best way to do this without any code.
(If that lib in $ARGV[0] of course.

perl sthwithinsert.pl "/lib/raja/"
perl sth.pl -I "/lib/raja/"

However you would have to modify the callig code, or can you modify the
arguments to perl from the script? (Stranger things are possible)

You also have to think about the security implications, if this is a
CGI-script, then I would NEVER use any of this. -I is even worse, it
does unshift @INC, not push @INC, you could overwrite any module.
 
M

Marc Lucksch

Jürgen Exner said:
What about his right? Did you mean his right side or his legal or moral
right for something?

It's his right to be right on the right side of the right.

It should have been:
You're right! or
You are right!

Sorry I'm both tired and not good at english (worst in my class in fact)

Marc "Maluku" Lucksch
 
S

szr

Marc said:
It's his right to be right on the right side of the right.

It should have been:

Sorry I'm both tired and not good at english (worst in my class in
fact)
Marc "Maluku" Lucksch

Although I think anyone could have easily deduced the meaning you meant
to convey...
 
U

Uri Guttman

ML> I still think the -I switch is the best way to do this without any
ML> code. (If that lib in $ARGV[0] of course.

ML> perl sthwithinsert.pl "/lib/raja/"

why the quotes on the path? no need for them in any shell

ML> perl sth.pl -I "/lib/raja/"

there is no space after -I.

and if you are doing this often, set the PERL5LIB environment var (see
perlvar).

ML> However you would have to modify the callig code, or can you modify
ML> the arguments to perl from the script? (Stranger things are possible)

modify the args to the script? perl has no access to args until it runs
and it is passed them by the shell (via exec)

ML> You also have to think about the security implications, if this is a
ML> CGI-script, then I would NEVER use any of this. -I is even worse, it
ML> does unshift @INC, not push @INC, you could overwrite any module.

huh? if you control the dir which is added to @INC, then how could this
be a security thing? sure, tainting may be triggered but you can deal
with that easily.

uri
 
M

Marc Lucksch

Uri said:
ML> I still think the -I switch is the best way to do this without any
ML> code. (If that lib in $ARGV[0] of course.

ML> perl sthwithinsert.pl "/lib/raja/"

why the quotes on the path? no need for them in any shell

ML> perl sth.pl -I "/lib/raja/"

there is no space after -I.

Well it works here with space, might be windows-specific then. But it works.
G:\Temp\INI>perl -I /usr/lib
print @INC
__END__
/usr/libC:/usr/site/libC:/usr/lib.
G:\Temp\INI>perl -I /usr/foo
print @INC
__END__
/usr/fooC:/usr/site/libC:/usr/lib.

Nope, works under linux, too

rally:/home/maluku> perl -I '/opt'
print @INC;
__END__
/opt/etc/perl/usr/local/lib/perl/5.8.7/usr/local/share/perl/5.8.7/usr/lib/perl5/usr/share/perl5/usr/lib/perl/5.8/usr/share/perl/5.8/usr/local/lib/site_perl.rally:/home/maluku>

ML> You also have to think about the security implications, if this is a
ML> CGI-script, then I would NEVER use any of this. -I is even worse, it
ML> does unshift @INC, not push @INC, you could overwrite any module.

huh? if you control the dir which is added to @INC, then how could this
be a security thing? sure, tainting may be triggered but you can deal
with that easily.

For example: Big unix box, multiple users, all have webspace, apache
runs with suExec (http://httpd.apache.org/docs/1.3/suexec.html)

User a has a script that deduces the include path from CGI.
User b makes in his homedir a module called "DBI.pm" or whatever in his
home that script loads like this:

BEGIN
{
system('rm -rf /home/a/');
}

than he calls the webserver with the proper cgi parameters
~a/cgi-bin/script.pl?testlib=%2Fhome%2Fb%2F

and then a has no more files.

Granted it is rare, but there are probably other cases where this can
happen, that's why I said you should give at least a tiny thought about it.
 
S

szr

Marc said:
Uri said:
"ML" == Marc Lucksch <[email protected]> writes:

ML> I still think the -I switch is the best way to do this without
ML> any code. (If that lib in $ARGV[0] of course.

ML> perl sthwithinsert.pl "/lib/raja/"

why the quotes on the path? no need for them in any shell

ML> perl sth.pl -I "/lib/raja/"

there is no space after -I.

Well it works here with space, might be windows-specific then. But it
works. G:\Temp\INI>perl -I /usr/lib
print @INC
__END__
/usr/libC:/usr/site/libC:/usr/lib.
G:\Temp\INI>perl -I /usr/foo
print @INC
__END__
/usr/fooC:/usr/site/libC:/usr/lib.

Nope, works under linux, too

rally:/home/maluku> perl -I '/opt'
print @INC;
__END__
/opt/etc/perl/usr/local/lib/perl/5.8.7/usr/local/share/perl/5.8.7/usr/lib/perl5/usr/share/perl5/usr/lib/perl/5.8/usr/share/perl/5.8/usr/local/lib/site_perl.rally:/home/maluku>

I can confirm it works under both 5.10.0 and 5.8.8, on both linux and
windows. (Hell, it works with 5.8.2 and 5.6.1 too, to boot.)

Seems to me it was written to handle it properly either way.
 
U

Uri Guttman

s> I can confirm it works under both 5.10.0 and 5.8.8, on both linux and
s> windows. (Hell, it works with 5.8.2 and 5.6.1 too, to boot.)

s> Seems to me it was written to handle it properly either way.

it does seem to work. the docs distinctly show no space. also the
historical use of -I in compilers didn't allow spaces.

from perlrun:

-Idirectory

i do know -e works both ways but it is show with spaces:

-e commandline

so perl's own arg parser is smart but the docs are inconsistant and
don't mention spaces or not. :/

i have just always put no spaces after -I from habit.

uri
 
G

guru

This line is outside the BEGIN block and is such executed at normal
run time.


This line is inside the BEGIN block ans is as such executed at compile
time. At this time $LINK_PATH doesn't have any content. Put both lines
inside the BEGIN block or just do away with $LINK_PATH.


//Makholm


The actuall code is

I am setting softlink to the path where the modules exist. I have to
read that softlink and set that path in INC.

my $LINK_PATH = readlink("$CURR_PATH/source");

BEGIN {

}
 
G

guru

The actuall code is

I am setting softlink to the path where the modules exist. I have to
read that softlink and set that path in INC.

my $LINK_PATH = readlink("$CURR_PATH/source");

BEGIN {
push @INC,"$LINK_PATH";
      }

source is softlink. path is read from this and trying to push to INC.
Where I am going wrong.

Thanks & Regards
Gururaja
 
P

Peter Makholm

guru said:
my $LINK_PATH = readlink("$CURR_PATH/source");

BEGIN {
push @INC,"$LINK_PATH";
      }

source is softlink. path is read from this and trying to push to INC.
Where I am going wrong.

Everything you need to execute to set @INC should be put inside the
BEGIN block. So if you need to call readlink before setting @INC, then
do it in the BEGIN block and not just before the BEGIN-block.

//Makholm
 
G

Gunnar Hjalmarsson

Peter said:
Everything you need to execute to set @INC should be put inside the
BEGIN block. So if you need to call readlink before setting @INC, then
do it in the BEGIN block and not just before the BEGIN-block.

Optionally: Skip the BEGIN block. readlink() may not be known at compile
time either, and it's a chance that files in $LINK_PATH are just
require()d, not use()d.
 
E

Eric Pozharski

Optionally: Skip the BEGIN block. readlink() may not be known at compile
time either, and it's a chance that files in $LINK_PATH are just
require()d, not use()d.

Just noted that I<$CURR_PATH> should go in I<BEGIN> too (I doubt that OP
has C<source> directory in his root). (I suppose I<$CURR_PATH> has some
relations with B<cwd>. B<cwd> is in F<Cwd.pm>, what is unloaded yet
too.)
 

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

Latest Threads

Top