2016-09-22 1 views
7
use WWW::Mechanize; 
$mech = new WWW::Mechanize; 
$mech->get("http://www.google.com"); 
$html = HTML::TreeBuilder::XPath->new_from_content($mech->content); 
sub test 
{ 
    use HTML::TreeBuilder::XPath; 
} 

Приведенный выше код компилируется, поэтому оператор use в sub применяется глобально.Почему заявление о применении в подпрограмме применяется глобально?

Почему perl это сделать? Это не имеет никакого смысла.

ответ

4

Это то, что perldoc гласит:

Поскольку use вступает в силу во время компиляции, он не уважает обычный контроль потока кода, скомпилированного. В частности, использование внутри ложной ветви условного не препятствует ее обработке.

К сожалению, он не дает пояснений почему он спроектирован таким образом. Возможные причины:

  • Perl дает вам много о свободе во многих случаях (TIMTOWTDI)
  • use внутри подпрограммы может показать свое намерение, что вы на самом деле хотите использовать модуль только в определенном месте (даже если это загружается глобально)
  • Если вы (повторно) переместить конкретную подпрограмму (который содержит use) позже, вам не придется беспокоиться об удалении неиспользуемых use «S из других мест, как в верхней части вашего сценария
  • . ..

Несмотря на то, что эти идеи могут показаться правдоподобными, я бы избегал загружать модули в подпрограммы, потому что гораздо яснее иметь их всех в одном месте, а не разбросать по всему месту?

6

use Module; имеет два эффекта.

Первый - загрузить модуль. Очевидно, что это имеет глобальный эффект. Не хотелось бы, чтобы модуль загружался несколько раз, если его использует несколько других модулей.

Второй способ - вызвать метод import модуля. Для большинства модулей это служит для экспорта символов в пространство имен вызывающего, поэтому эти функции можно вызывать без квалификации их с полным именем пакета. Это, очевидно, влияет не только на некоторую часть, поскольку никто не дает каждому под своим собственным пространством имен. Но это действительно зависит от вас.

Метод import некоторых модулей, однако, делает что-то совсем другое. Они изменяют способ компиляции кода в лексической области, в которой присутствует директива. Они называются прагмами. use strict; - пример одного. Имеет смысл использовать эти модули в подразделе. Однако использование use HTML::TreeBuilder::XPath; в подпункте не имеет смысла.