2009-11-09 19 views
7

mô-đun foo/bar.pmperl: những biểu tượng xuất khẩu từ mô-đun có> 1 gói

package foo::bar; 
stuff 
stuff 
package foo::wizzy; 
require Exporter; 
our @ISA=qw(Exporter); 
our @EXPORT=qw(x); 
use constant 
{ 
    x=>1 
}; 

một người tiêu dùng mà không

use Foo::bar; 

không có được foo::wizzy::x xuất khẩu

tôi biết Tôi có thể làm cho nó hai mô-đun riêng biệt, nhưng tôi vẫn có thể thực hiện công việc này, phải không?

+1

thx cho tất cả - sự đồng thuận dường như - sử dụng 2 file Tôi chỉ là lười biếng và tôi hứa sẽ nói Foo không foo – pm100

+2

Trong trường hợp đó, tôi sẽ upvote bạn! :) – Ether

Trả lời

3

Vào cuối của module, đặt:

BEGIN { $INC{'foo/wizzy.pm'} = 1 } 

Sau đó, mã này có thể chỉ nói:

use foo::bar; 
use foo::wizzy; 

để có được foo :: xuất khẩu của wizzy.

+0

ooo - thats một tốt - thx – pm100

7

Khi bạn gọi use foo::bar, những gì thực sự xảy ra chủ yếu là:

BEGIN { 
    require foo::bar; 
    foo::bar->import; 
} 

(thấy perldoc -f use)

Vì vậy import không bao giờ nhận được gọi là trên foo::wizzy. Nếu bạn cũng muốn nhập các ký hiệu đó, bạn có thể tự gọi số BEGIN { foo::wizzy->import } (sau use foo::bar). Hoặc, như bạn đã nói, chỉ cần chia hai gói này thành các tệp riêng biệt, có thể dễ đọc hơn nhiều.

(Bằng cách này, nó không phải là khuyến khích sử dụng tên gói thấp-cased, như những người thường dành cho pragmata perl.)

+1

OP cũng có thể viết một phương thức 'import' tùy chỉnh cho foo :: bar để xuất nội dung từ Foo :: wizzy. (Không phải là tôi sẽ làm theo cách đó.) –

+4

@Michael: vâng, tôi chỉ đặt các gói lại với nhau cho mã back-of-a-napkin, do đó, vào thời điểm này tôi sẽ đi "f-- nó, tôi không tiết kiệm thời gian từ việc có hai gói này trong một tệp "và tách chúng ra. – Ether

+0

+1 đặc biệt cho nhận xét ở trên. –

7

Bạn có thể làm điều đó bằng phương pháp export_to_level xuất khẩu để có "gói chính" lại -Xuất những biểu tượng "khác" gói của như vậy:

sub import { 
    my $self = shift; 
    $self->export_to_level(1, @_); 
    Some::Other::Module->export_to_level(1); 
} 

mặc dù nếu Some::Other::Module làm điều gì đó phức tạp hơn "xuất khẩu tất cả mọi thứ" có thể bạn sẽ cần xử lý fancier cho @_.

tôi thực sự phải tự hỏi tại sao , mặc dù — Tôi không thể tưởng tượng một sử dụng cho điều này đó là tương thích với dòng chữ "tốt mã" :)

+0

+1 Tôi quên về 'export_to_level' và hầu như đã tái tạo lại chức năng ;-) –

+1

Vâng, tôi luôn bắt đầu có chút phòng thủ khi tôi thấy ai đó đang làm rối tung bảng biểu tượng của tôi .. nó giống như một cuộc xâm lược không gian cá nhân: bạn tốt hơn là trong trường hợp khẩn cấp, hoặc kết hôn với tôi :) – Ether

2

Trước hết, tôi thấy hữu ích khi sử dụng kèm theo niềng răng để kiểm soát phạm vi khi nhồi nhét nhiều gói vào một tệp. Ngoài ra, kèm theo các gói trong một khối BEGIN làm cho nó hoạt động giống như một thích hợp use được sử dụng để tải nó, nhưng điều này chủ yếu là nếu tôi nhồi nhét gói vào kịch bản chính.

use Foo giống với BEGIN { require Foo; Foo->import }.

Vì vậy, bạn có hai lựa chọn:

  • gọi BEGIN{ Foo::Whizzy->import; } trong kịch bản chính của bạn.
  • làm cho Foo::Bar::import kích hoạt Foo::Whizzy::import trên mô-đun gọi điện.

Trong Foo/Bar.pm:

{ package Foo::Bar; 
    use Exporter qw(export_to_level); 

    # Special custom import. Not needed if you call Foo::Whizzy->import 
    sub import { 
    shift; 
    export_to_level('Foo::Whizzy', 1, @_); 
    } 

    # stuff 
    # stuff 
} 

{ package Foo::Whizzy; 
    require Exporter; 

    our @ISA=qw(Exporter); 
    our @EXPORT=qw(x); 
    use constant { x=>1 }; 

} 

1; # return true 

Trong mã chính của bạn:

use Foo::Bar; 

# If you don't do a custom import for Foo::Bar, add this line: 
BEGIN { Foo::Whizzy->import }; 
Các vấn đề liên quan