How exactly do I build %INC keys?

R

Rich

According to camel p.300:

"The key will be the module filename"

I therefore tried the following to test whether Data::Dumper (for example)
had been used:

use File::Spec;
use Data::Dumper;

my $filename = File::Spec->catfile("Data", "Dumper.pm");

print $INC{$filename} ? "yes\n" : "no\n"; # Fails on Win32

But although it worked on Linux, it failed on Win32 where the key is
actually the same as under Linux:

print $INC{"Data/Dumper.pm"} ? "yes\n" : "no\n"; # OK on Win32 and Linux

I know Win32 perl allows '/' as well as '\' directory separators, but now
I'm not sure of the correct way to build %INC keys. Is it:

1) The key is actually the same on all platforms. Ie $INC{"Data/Dumper.pm"}
will work on all platforms (Mac, VMS etc).

2) The key must use the system directory separator - in that case, since
File::Spec->catfile didn't work, where is the "correct" system directory
separator defined? Equally, do I need to be careful with how I handle
".pm" extensions?

If the answer is 2), does anyone have tested code they could post here to
handle this?

Many thanks,
 
J

James E Keenan

Rich said:
According to camel p.300:

"The key will be the module filename"

I therefore tried the following to test whether Data::Dumper (for example)
had been used:

use File::Spec;
use Data::Dumper;

my $filename = File::Spec->catfile("Data", "Dumper.pm");

print $INC{$filename} ? "yes\n" : "no\n"; # Fails on Win32

But although it worked on Linux, it failed on Win32 where the key is
actually the same as under Linux:
The "failure" is actually a feature of File::Spec. File::Spec imports
routines from a system-appropriate subpackage, in this case
File::Spec::Win32, which appears to use the DOS '\' as the path separator.
If you do not need to use File::Spec to achieve your larger purpose (about
which I'm unclear), then Perl will happily use '/' throughout.
 
B

Bob Walton

Rich said:
According to camel p.300:

"The key will be the module filename"

I therefore tried the following to test whether Data::Dumper (for example)
had been used:

use File::Spec;
use Data::Dumper;

my $filename = File::Spec->catfile("Data", "Dumper.pm");

print $INC{$filename} ? "yes\n" : "no\n"; # Fails on Win32

But although it worked on Linux, it failed on Win32 where the key is
actually the same as under Linux:

print $INC{"Data/Dumper.pm"} ? "yes\n" : "no\n"; # OK on Win32 and Linux

I know Win32 perl allows '/' as well as '\' directory separators, but now
I'm not sure of the correct way to build %INC keys. Is it:

1) The key is actually the same on all platforms. Ie $INC{"Data/Dumper.pm"}
will work on all platforms (Mac, VMS etc).


It would appear that on Win32 %INC keys use / and File::Spec uses \ .

Try [tested on Windoze 98SE AS build 806]:

$filename = File::Spec::Unix->catfile("Data", "Dumper.pm");

Things work in Unix :)

But wouldn't it be easier to just say

$filename='Data/Dumper.pm';

? Also, note that %INC might contain other stuff,

like hooks and whatever the hook may have placed there.

So it is possible there could be a surprise waiting in
%INC for you.

2) The key must use the system directory separator - in that case, since
File::Spec->catfile didn't work, where is the "correct" system directory
separator defined? Equally, do I need to be careful with how I handle
".pm" extensions?

If the answer is 2), does anyone have tested code they could post here to
handle this?


....
 
T

Trent Curry

Bob said:
Rich said:
According to camel p.300:

"The key will be the module filename"

I therefore tried the following to test whether Data::Dumper (for
example) had been used:

use File::Spec;
use Data::Dumper;

my $filename = File::Spec->catfile("Data", "Dumper.pm");

print $INC{$filename} ? "yes\n" : "no\n"; # Fails on Win32

But although it worked on Linux, it failed on Win32 where the key is
actually the same as under Linux:

print $INC{"Data/Dumper.pm"} ? "yes\n" : "no\n"; # OK on Win32 and
Linux

I know Win32 perl allows '/' as well as '\' directory separators,
but now I'm not sure of the correct way to build %INC keys. Is it:

1) The key is actually the same on all platforms. Ie
$INC{"Data/Dumper.pm"} will work on all platforms (Mac, VMS etc).


It would appear that on Win32 %INC keys use / and File::Spec uses \ .

Try [tested on Windoze 98SE AS build 806]:

$filename = File::Spec::Unix->catfile("Data", "Dumper.pm");

In the man page for File::Spec::Unix, under Synopsis, it reads:

require File::Spec::Unix; # Done automatically by File::Spec
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Is this a bug in the Win32 version that it gives \ and not / as expected? Or
is file::Spec defaulting to the current OS Spec sub class?

--
Trent Curry

perl -e
'($s=qq/e29716770256864702379602c6275605/)=~s!([0-9a-f]{2})!pack("h2",$1)!eg
;print(reverse("$s")."\n");'
 
T

Tad McClellan

Rich said:
I know Win32 perl allows '/' as well as '\' directory separators,


It is not "Win32 perl" that allows / as the directory separator,
it is the Windows OS itself that allows that.

Only the command interpreter requires the use of backslash
(because forward slash is already used for something else, switches).
 
R

Rich

Tad said:
It is not "Win32 perl" that allows / as the directory separator,
it is the Windows OS itself that allows that.

Only the command interpreter requires the use of backslash
(because forward slash is already used for something else, switches).

Ok, thanks for correcting my misunderstanding there.

As the point of my initial post wasn't terribly clear, here's a beter
version:

If I want to check that Data::Dumper (for example) has been used, will:

$INC{"Data/Dumper.pm"}

Work on all platforms, not just on the platforms I've tested on (Linux and
Win32)?

Thanks,
 
R

Rafael Garcia-Suarez

Rich said:
As the point of my initial post wasn't terribly clear, here's a beter
version:

If I want to check that Data::Dumper (for example) has been used, will:

$INC{"Data/Dumper.pm"}

Work on all platforms, not just on the platforms I've tested on (Linux and
Win32)?

This is not a 100% reliable way to check whether a module has been
loaded, because if you do
require "../lib/Data/Dumper.pm";
you'll end up with $INC{"../lib/Data/Dumper.pm"} set.
(in fact perl bypasses @INC searching when the require'd filename
is absolute or begins with ./ or ../).

Moreover an @INC hook may fiddle with %INC entries as it wants.

But, to answer your original question : yes, file names in %INC are
normalized to use forward slashes.

Usually you don't have to worry about this, what's your actual problem ?
 
T

Trent Curry

Tad said:
It is not "Win32 perl" that allows / as the directory separator,
it is the Windows OS itself that allows that.

Only the command interpreter requires the use of backslash
(because forward slash is already used for something else, switches).

A "switch" is nothing more then a comand line parameter.
test.exe /1 /2 /3
works as does
test.exe \1 \2 \3
and
test.exe 1 2 3

--
Trent Curry

perl -e
'($s=qq/e29716770256864702379602c6275605/)=~s!([0-9a-f]{2})!pack("h2",$1)!eg
;print(reverse("$s")."\n");'
 
R

Rich

Rafael said:
This is not a 100% reliable way to check whether a module has been
loaded, because if you do
require "../lib/Data/Dumper.pm";
you'll end up with $INC{"../lib/Data/Dumper.pm"} set.
(in fact perl bypasses @INC searching when the require'd filename
is absolute or begins with ./ or ../).

Moreover an @INC hook may fiddle with %INC entries as it wants.

But, to answer your original question : yes, file names in %INC are
normalized to use forward slashes.

Yay - that's all I needed to know! I didn't feel the docs were 100% clear
that forward slashes are always used - could be me not RTFM properly
though.
Usually you don't have to worry about this, what's your actual problem ?

The main thing is I need to know where one of my modules is physically
located. As it's an internal module in a larger framework, I can guarantee
that it will be use'd rather than require'd in the way you describe above,
so $INC{"My/Module.pm"} should reliably give me the full filename of
My::Module.

Thanks for your help
 

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
474,141
Messages
2,570,813
Members
47,357
Latest member
sitele8746

Latest Threads

Top