Какая польза от sub main &main(); подход (подосновной шаблон) в Perl?

Несколько лет назад я принял следующий «шаблон» для всех, кроме самого простого из моих Perl-скриптов: (я даже не помню, где я впервые увидел его, это определенно не было моей настоящей идеей.)

use strict;
...
sub main {
  ...
}
... possibly more subs ...

... at the end of the file:
#############
# Call main #
&main();
#############

Есть ли в этом какая-то польза? Я нахожу код немного чище, но в остальном я не уверен, что у него есть какая-то другая цель, кроме как осчастливить программиста на C внутри меня :-)

Приветствуются любые идеи от экспертов Perl и опытных пользователей. (Я, конечно, ни то, ни другое)


person Martin Ba    schedule 20.07.2011    source источник
comment
Иногда я успокаиваю своего внутреннего программиста на C. Но я обычно ставлю вызов main() перед определением (но после объявления) каких-либо подпрограмм.   -  person David Hammen    schedule 20.07.2011


Ответы (5)


Это известная идиома для ограничения масштаба. Это обсуждается в https://stackoverflow.com/q/1183876#comment-1012787 ff. и http://use.perl.org/comments.pl?sid=43991&cid=70918 ff.

person daxim    schedule 20.07.2011
comment
Хорошая ссылка. exit main(); кажется даже более разумным, чем мой подход. (или нет?) - person Martin Ba; 20.07.2011

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

Лично я использовал

{
   ...  # Extract command line switches from @ARGV
   ...  # Perform input validation
   exit(main(@ARGV));
}
person ikegami    schedule 20.07.2011

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

Отличие состоит в том, что такие команды, как:

my $arg = shift;

Будет влиять на @_ вместо @ARGV, а @ARGV не будет автоматически передаваться на main(). @ARGV по-прежнему будет виден внутри саба, но вам придется явно сдвинуть его shift @ARGV.

person TLP    schedule 20.07.2011
comment
Я обнаружил, что @ARGV легко доступен в моей основной подсистеме ($ARGV[0] и т. д.) - я вас неправильно понял? - person Martin Ba; 20.07.2011
comment
Он глобальный, поэтому он будет работать везде, я имел в виду, что он не передается в качестве аргумента main(). Но, возможно, это неважно. ;) Если бы это было передано, shift внутри саба имело бы ту же функциональность, так как косвенно сместило бы @ARGV - person TLP; 20.07.2011
comment
Хорошая информация. Я даже не знал, что сдвиг неявно работает на @ARGV в глобальном контексте :-) - person Martin Ba; 20.07.2011
comment
Есть много маленьких хитростей, чтобы узнать о Perl. Я думал, что знаю много, когда нашел SO несколько недель назад. Оказалось, что нет, и каждый день я узнаю что-то новое. - person TLP; 21.07.2011
comment
@TLP: совершенно верно, я получил много знаний, отвечая на вопросы здесь. - person Dallaylaen; 21.07.2011

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

person Dave Cross    schedule 20.07.2011

Проработав много Perl, я бы сказал, что это просто то, что делает вас счастливым. Сомневаюсь, что быстрее или медленнее.

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

person Cfreak    schedule 20.07.2011
comment
& не заставляет Perl передавать значение $_ подпрограмме. Это делает текущий @_ видимым для вызываемой подпрограммы. - person Eugene Yarmash; 20.07.2011
comment
&NAME() не передает @_, он просто переопределяет прототипы сабвуфера. Он передает пустой список, обозначенный () - person TLP; 20.07.2011
comment
@TLP: я говорил о синтаксисе &NAME в контексте ответа - person Eugene Yarmash; 20.07.2011
comment
@eugene Я так понял, однако, учитывая синтаксис вопроса, я почувствовал, что это правильное разъяснение, чтобы не запутать проблему. - person TLP; 20.07.2011
comment
& отключает прототипы. &name; и goto &name; не локализуют @_, но это совершенно независимо. - person ikegami; 20.07.2011