2010-02-23 26 views
6

Tôi muốn lấy tên đầy đủ của một mô-đun đi kèm. Hãy xem xét mã này:Các khóa và giá trị của% INC có phụ thuộc vào nền tảng hay không?

package MyTest; 

my $path = join '/', split /::/, __PACKAGE__; 
$path .= ".pm"; 

print "$INC{$path}\n"; 

1; 

$ perl -Ipath/to/module -MMyTest -e0 
path/to/module/MyTest.pm 

Nó sẽ làm việc trên tất cả các nền tảng?

perlvar

Các băm %INC chứa mục cho mỗi tên tập tin bao gồm thông qua do, require, hoặc use nhà khai thác. Khóa là tên tệp bạn đã chỉ định (với tên mô-đun được chuyển đổi thành tên đường dẫn), và giá trị là vị trí của tệp được tìm thấy.

Các phím này có phụ thuộc vào nền tảng hay không? Tôi có nên sử dụng File::Spec hay không? Ít nhất ActivePerl trên win32 sử dụng / thay vì \.

Cập nhật: Còn giá trị %INC thì sao? Họ phụ thuộc vào nền tảng?

+1

Bạn muốn làm gì với đường dẫn? Vui lòng cung cấp thêm ngữ cảnh! –

+0

Nói, tôi muốn bao gồm nhiều mô-đun hơn từ đó. – codeholic

Trả lời

2

Cho rằng đó là một mô-đun chuẩn, với cách tiếp cận từ Module::Loaded:

sub is_loaded (*) { 
    my $pm  = shift; 
    my $file = __PACKAGE__->_pm_to_file($pm) or return; 

    return $INC{$file} if exists $INC{$file}; 

    return; 
} 

sub _pm_to_file { 
    my $pkg = shift; 
    my $pm = shift or return; 

    my $file = join '/', split '::', $pm; 
    $file .= '.pm'; 

    return $file; 
} 
+1

Trên thực tế đây là mã rất giống tôi đã viết. Và có vẻ như, mô-đun này hoạt động trên hầu hết các nền tảng. Cảm ơn bạn. http://www.cpantesters.org/distro/M/Module-Loaded.html#Module-Loaded-0.06 Bạn có thể nói bất cứ điều gì về tính di động của các giá trị '% INC' không? – codeholic

+2

@codeholic Bạn nghĩ gì về nền tảng nào? Hãy nhớ rằng '/' là một dấu phân tách đường dẫn hợp lệ trên Win32, và trông đẹp hơn nhiều so với hai backwhacks đáng ghét. Đừng để giao diện geb0rken * của trình lệnh Windows * đánh lừa bạn. –

+1

Tôi muốn làm mã đa nền tảng nhất có thể, vì tôi mong được đăng lên CPAN cuối cùng. – codeholic

1

Dưới đây là một việc thực hiện mạnh mẽ một cách hợp lý cũng sẽ làm việc cho module chưa được nạp được nêu ra.

use File::Find; 
use File::Spec; 

sub pkg2path (*) { 
    my $file = join '[\\\/:]' => 
       map "\Q$_" => 
       split /::|'/ => "$_[0].pm";   # ' 

    /$file$/ and return File::Spec->rel2abs($INC{$_}) 
     for keys %INC; 

    # omit the rest to only find loaded modules 

    my $path; find { 
     no_chdir => 1, 
     wanted => sub { 
      $path = $_ and goto found if /$file$/ 
     } 
    } => @INC; 

    found: File::Spec->rel2abs($path or return) 
} 

say pkg2path Benchmark; 
say pkg2path Devel::Trace; 
+0

Cùng một mã được viết tốt hơn trong 'Mô-đun :: Tìm'. Nhưng nó không trả lời câu hỏi của tôi. – codeholic

+0

dòng đầu tiên của pkg2path có câu trả lời của bạn. không, không an toàn để tin tưởng rằng các mục trong% INC sẽ có một mẫu cụ thể (nếu chỉ vì% INC là người dùng có thể ghi). Đó là lý do tại sao tôi đã viết builder regex (không tìm thấy trong Module :: Find, và nó thậm chí không sử dụng% INC btw). Rất vui được biết bạn đánh giá cao vài người đã dành thời gian để suy nghĩ và trả lời câu hỏi của bạn –

Các vấn đề liên quan