2015-07-13 1 views
1

Я использую Getopt :: Long для разбора флагов командной строки и аргументов для скрипта perl. Для некоторых флагов мне нужно объявить переменные в скрипте, которые используются только в том случае, если этот флаг выбран, иначе они никогда не будут использоваться. Я хочу объявить их условно, т. Е. Только в том случае, если используется флаг, так что у меня нет кучи неиспользуемых переменных, сидящих вокруг. Вот пример кода, который не работает, но иллюстрирует, что я хочу делать.Как объявить переменные, зависящие от флагов, используя Getopt :: Long in perl?

use Getopt::Long qw(GetOptions); 
my ($f1, $f2, $f3); 
GetOptions('f1' => \$f1, 'f2' => \$f2, 'f3' => \$f3); 

if($f2){ 
    #declare some variables needed only if $f2 is turned on 
} 

Может кто-нибудь порекомендовать правильный способ сделать это?

+6

[Использование хэш] (https: // metacpan.org/pod/Getopt::Long#Options-with-hash-values) вместо связки скаляров. – ThisSuitIsBlackNot

+3

Правильный способ - не делать микрооптимизации, которые делают ваш код менее читаемым. – mob

+0

Ах, хэш имеет смысл. Спасибо за идею. Чтобы быть ясным, толпа предлагала объявить переменные независимо от значения флага, а затем просто не использовать их, если они не нужны? – jms

ответ

0

Вы должны всегда объявлять свои переменные в наименьшей области возможно только. Область в Perl обычно является блоком.

use strict; 
use warnings; 

sub foo { 
    my $bar = 5; 
    say $bar; 
} 

sub baz { 
    my $bar = 23; 
    say $bar; 
} 

foo(); 
baz(); 
say $bar; # this will give an error 

Приведенные выше код выдаст ошибку «глобальный символ„$“бар требует явного имени пакета», поскольку вне блоков $bar не объявлен. Если вы удалите отмеченную строку, она выведет оба значения, которые отделены друг от друга.

Этот же принцип следует применять на протяжении всего кода. Объявлять переменные как можно позже и в максимально возможной области (или в самой большой необходимой).

0

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

Если с другой стороны, вы пытаетесь поймать использование глобальных переменных, которые не должны быть использованы, вы можете использовать следующие:

use Carp   qw(croak); 
use Variable::Magic qw(cast wizard); 

use constant DEBUG => 1; 

sub deny_access_to_scalar { 
    my $name = $_[0]; 

    cast($_[1], wizard(
     get => sub { croak("Variable $name accessed when it shouldn't"); }, 
     set => sub { croak("Variable $name accessed when it shouldn't"); }, 
    )); 
} 

my $f2 = 1; 

my $f2a; 
deny_access_to_scalar(f2a => $f2a) if DEBUG && $f2; 

$f2a = 123; 
+0

Это не столько о попытке сохранить память, сколько о том, чтобы сделать программу элегантной и минимальной. Я думаю, что лучший способ сделать это - только по ссылке, используя хеш, например, предложенный, или, как, например, simbabque, пытающийся сделать программу более модульной с помощью подпрограмм. – jms

+0

Это не имеет смысла. Что более минимально, чем не использовать переменную? (Использование подпрограмм не поможет вам избавиться от глобальных аргументов. Использование хэша усугубит ситуацию, уклонившись от проверки имени времени компиляции, делая код немного длиннее.) – ikegami

Смежные вопросы