Можно ли использовать модули из подпрограмм? - PullRequest
6 голосов
/ 22 сентября 2009

Недавно я начал играть с OO Perl, и я создал довольно много новых объектов для нового проекта, над которым я работаю. Поскольку я не знаком с любой лучшей практикой в ​​отношении OO Perl, и мы добросовестно пытаемся это сделать: P

Я помещаю много кода такого рода в каждую из моих функций:

sub funcx{
    use ObjectX; # i don't declare this on top of the pm file 
                 # but inside the function itself
    my $obj = new ObjectX;
}

Мне было интересно, не вызовет ли это какое-либо негативное влияние по сравнению с размещением строки use Object в верхней части модулей Perl вне какой-либо области действия функции.

Я делал это так, чтобы почувствовать, что он чище, на случай, если мне понадобится изменить функцию.

И еще одна вещь, которую я заметил, это то, что когда я пытаюсь запустить сценарий test.pl на самом сервере unix, который проверяет мои объекты, он работает очень медленно. Но когда тот же код выполняется через CGI, который подключен к серверу Apache, веб-страница загружается не так медленно.

Ответы [ 3 ]

10 голосов
/ 22 сентября 2009

Где использовать?

use происходит во время компиляции, поэтому не имеет значения, куда вы его поместите. По крайней мере, с чисто прагматической точки зрения, «будет ли это работать». Потому что это происходит во время компиляции, use всегда будет выполняться, даже если вы поместите его в условное выражение. Никогда не делай этого: if( $foo eq 'foo' ) { use SomeModule }

По моему опыту, лучше всего поместить все ваши операторы использования в начало файла. Это позволяет легко увидеть, что загружается и каковы ваши зависимости.


Обновление:

Как отмечает Брайан Д Фой , на вещи, скомпилированные до оператора use, не повлияет. Таким образом, местоположение может иметь значение. Для типичного модуля местоположение не имеет значения, однако, если оно влияет на компиляцию (например, импортирует функции с прототипами), местоположение может иметь значение.

Также Час Оуэнс указывает , что это может повлиять на компиляцию. Модули, предназначенные для изменения компиляции, называются прагмами. Прагмы, как правило, получают имена в нижнем регистре. Эти эффекты применяются только в пределах области применения модуля. Час использует прагму integer в качестве примера в своем ответе. Вы также можете отключить прагму или модуль в ограниченном объеме с ключевым словом no.

use strict;
use warnings;

my $foo;
print $foo;  # Generates a warning

{   no warnings 'unitialized`;  # turn off warnings for working with uninitialized values.

    print $foo;  # No warning here
}
print $foo; # Generates a warning

Синтаксис косвенного объекта

В вашем примере кода у вас есть my $obj = new ObjectX;. Это называется косвенным синтаксисом объекта, и его лучше избегать, поскольку это может привести к неясным ошибкам. Лучше использовать эту форму:

my $obj = ObjectX->new;

Почему ваш тестовый скрипт работает медленно на сервере?

Невозможно сообщить предоставленную вами информацию.

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

Лучшие практики

Проверьте Perl Best Practices и карточку быстрого доступа . На этой странице есть хороший совет ООП Дамиана Конвея от PBP .

Также вы можете рассмотреть возможность использования Moose . Если при вашем использовании допустимо длительное время запуска скрипта, Moose - это огромный выигрыш.

6 голосов
/ 22 сентября 2009

вопрос 1

Это зависит от того, что делает модуль. Если он имеет лексический эффект, он влияет только на область, в которой он используется:

my $x;
{
    use integer;
    $x = 5/2; #$x is now 2
}
my $y = 5/2; #$y is now 2.5

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

вопрос 2

Вещи, которые могут повлиять на скорость программы между машинами

  1. скорость процессора
  2. версия установленных модулей (некоторые модули имеют версии XS, которые намного быстрее)
  3. версия Perl
  4. количество записей в PERL5LIB
  5. скорость привода
3 голосов
/ 22 сентября 2009

даотоад и час. Оуэнс уже ответил на ту часть вашего вопроса, которая касается позиции использования. Позвольте мне отметить кое-что еще здесь:

Я делал это так, что я чувствую, что это чище на случай, если мне нужно сдвинуть функционировать вокруг.

Лично я считаю, что все используемые модули в одном месте вверху файла намного чище. Вам не придется искать операторы использования, чтобы увидеть, какие другие модули используются, и быстрый взгляд скажет вам, что используется и даже что не используется.

Относительно вашей проблемы с производительностью: с Apache и mod_perl интерпретатору Perl придется анализировать и компилировать ваши используемые модули только один раз. При следующем запуске скрипта выполнение должно быть намного быстрее. Однако в командной строке повторный запуск не дает этого преимущества.

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