цикл в Perl - PullRequest
       10

цикл в Perl

1 голос
/ 03 августа 2011

Я пишу этот цикл, где при инициализации я инициализирую, используя переменную, а не абсолютное значение. Почему значение не меняется? Или это не разрешено в цикле for?

enter code here
 for($i = $one, $i > $top_level,$i--)
    {  
      print $i,"\n";
      print "One is:",$one,"\n";
     }

Почему я не могу назначить $ i = $ one. Переменная $ one продолжает изменяться, поэтому я объявил $ i в $ one. Когда я печатаю отдельные значения переменных, значения верны, просто в цикле for значение не присваивается.

Ответы [ 4 ]

6 голосов
/ 03 августа 2011

Используйте точки с запятой, а не запятые.

for($i = $one; $i > $top_level; $i--)
{  
    print $i,"\n";
    print "One is:",$one,"\n";
}

Избегайте циклов в стиле C в perl , если это возможно.

for my $i (reverse $top_level..$one) {
    print $i,"\n";
    print "One is:",$one,"\n";
}
3 голосов
/ 03 августа 2011

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

    print "\$_=[$_]\n";

с $one как 1, я получаю:

$_=[0]
...
$_=[]
...
$_=[1]

И это потому, что в списке три элементов. Прежде всего то, что вы хотели сделать, выглядело бы так:

for my $i ( $one..( $top_level - 1 )) {

В этом цикле $i устанавливается для каждого члена диапазона, а затем выполняется цикл. Если мы не поддерживаем переменную, perl присваивает ее $_.

for ( $one..( $top_level - 1 )) {

И perl не ждет, чтобы скомпилировать список, поэтому, прежде чем он будет выполнен в первый раз, он проверяет все условия.

$i = $one; 
# push actual $i returned by expression $i = $one
push @a, $i;                  
# result = [ $i=1 ]
# push boolean false => ''
push @a, ( $i > $top_level ); 
# result = [ $i=1, '' ]
# push the return of $i--, NOT $i
push @a, ( $i );              
# result = [ $i=1, '', 1 ]
# decrement $i
$i--;                         
# result = [ $i=0, '', 1 ]

Вы можете узнать это, используя TIE-ed скаляр:

package Monitored;
sub TIESCALAR {
    my ( $class, $name, $value ) = @_;
    return bless { name => $name, value => $value }, $class;
}

sub FETCH {
    my $self = shift;
    Carp::carp "Reading \$$self->{name}...";
    return $self->{value};
}

sub STORE { 
    my $self = shift;
    my $value = shift;
    Carp::carp "Storing \$$self->{name}=${\(defined( $value ) ? $value : 'undef')} ";
    $self->{value} = $value;
}

И эта инициализация в основной строке:

my $one       = 1;
tie my $i,         'Monitored', 'i';
tie my $top_level, 'Monitored', 'top_level', 5;
for($i = $one, $i > $top_level,$i--) # line 30
    {  
      print "*LOOP*\n";
      #print "\$i=$i\n"; <-- commented out to reduce noise
      #print "\$one=$one\n";
      print "\$_=[$_]\n";  # line 35
     }

Тогда при запуске цикла получается:

Storing $i=1 at - line 30
Reading $top_level... at - line 30
Reading $i... at - line 30
Reading $i... at - line 30
Reading $i... at - line 30
Storing $i=0  at - line 30
*LOOP*
Reading $i... at - line 35
$_=[0]
*LOOP*
$_=[]
*LOOP*
$_=[1]

Обратите внимание, что только один раз, в строке 35, мы получаем доступ к $i после начала цикла.

3 голосов
/ 03 августа 2011

Разделителем внутри оператора for () является ";", а не ",".

1 голос
/ 03 августа 2011

Что на земле ты пытаешься сделать?Это нормальный цикл for или вы пытаетесь сделать что-то экзотическое?Обратите внимание на использование точки с запятой, а не запятой.Использование запятой в любом цикле делает что-то совершенно другое: каждый бит кода запускается каждый раз.

Обычно это будет:

$one = 1;
for($i = $one; $i > $top_level;$i--)
{  
  print $i,"\n";
  print "One is:",$one,"\n";
 }

Это Perl, верно?

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