Модуль perl вызывает методы из пакета, который не импортируется - PullRequest
1 голос
/ 05 декабря 2011

Сегодня я был потрясен, обнаружив, что один из моих модулей Perl использует другой модуль, но не импортирует его.

Однако я был шокирован, когда понял, что это никогда не вызывало никаких проблем!

Код выглядит примерно так:

package This;
# no import for OTHER !!

sub new {
    ... implementation ...
    my $something = OTHER->new(@arguments); # no error!
    ... more implementation ...
}

Так что же дает? Ни один из This импорта импорта OTHER - это было первое, что я проверил.

Может ли быть так, что если код, который импортирует This, также импортирует OTHER, OTHER доступен для This?


Уточнение вопроса:

  • X, Y и Z являются модулями.
  • in X : use Y;
  • in X : use Z;
  • Y не use Z

Имеет ли Y доступ к функциям и методам в Z (и наоборот)?

Ответы [ 2 ]

4 голосов
/ 05 декабря 2011

Использование вами термина «импорт» немного вводит в заблуждение.

Имеет ли Y доступ к Z без его импорта (и наоборот)?

Да, более или менее.use модуль просто загружает его в текущий скрипт;все use d модули загружены в один и тот же скрипт, поэтому они могут видеть друг друга (при условии, что они use d в правильном порядке).

Но верно import -то, что модуль на самом деле экспортирует , так что они копируются в пространство имен модуля use - будет только копироваться в пространство имен модуля use.

Например, рассмотрим этот сценарий Perl:

use Time::HiRes 'time';

package Foo;

sub time1() { return time(); } # calls the built-in time() function
sub time2() { return Time::HiRes::time(); }


package main;

print Foo::time1(), "\n"; # prints (e.g.) 1323048440
print Foo::time2(), "\n"; # prints (e.g.) 1323048440.80571
print time(), "\n";       # prints (e.g.) 1323048440.8061

Он use s Time::HiRes модуль и говорит ему экспортировать Time::HiRes::time в текущее пространство имен (основное пространство имен), перезаписываявстроенный time.(Time::HiRes::time похоже на time, но имеет разрешение менее секунды; оно даст что-то вроде 1323048440.80571 вместо 1323048440.) Таким образом, пакет Foo может видеть Time::HiRes и все, что находится внутри Time::HiRes, например, его time;но он должен явно указать это, явно написав Time::HiRes::time.

(Примечание: я написал выше, как один сценарий, для простоты описания, но то же самое происходит, когда Foo определен вFoo.pm и загружается с использованием use Foo;.)

0 голосов
/ 05 декабря 2011

Да, по крайней мере, когда вы используете косвенный синтаксис пакета и объекта.Из вызовов типа

OtherPackage->method()
$anOtherPackageObject->method()

Perl может разрешить полное имя подпрограммы (&OtherPackage::method в обоих вышеупомянутых случаях) и вызывать подпрограмму из любого места.

...