Perl 更好的变量命名系统?

Perl 更好的变量命名系统?,perl,foreach,Perl,Foreach,编程新手。任务是从字符串中提取特定数据,我选择按如下方式编写代码- while ($line =<IN>) { chomp $line; @tmp=(split /\t/, $line); next if ($tmp[0] !~ /ch/); @tgt1=@tmp[8..11]; @tgt2=@tmp[12..14]; @tgt3=@tmp[15..17]; @tgt4=@tmp[18..21]; foreach (

编程新手。任务是从字符串中提取特定数据,我选择按如下方式编写代码-

while ($line =<IN>) {
    chomp $line;
    @tmp=(split /\t/, $line); 
    next if ($tmp[0] !~ /ch/); 
    @tgt1=@tmp[8..11];
    @tgt2=@tmp[12..14];
    @tgt3=@tmp[15..17];
    @tgt4=@tmp[18..21];
    foreach (1..4) {
            print @tgt($_), "\n";
            }
while($line=){
chomp$行;
@tmp=(拆分/\t/,$line);
下一个if($tmp[0]!~/ch/);
@tgt1=@tmp[8..11];
@tgt2=@tmp[12..14];
@tgt3=@tmp[15..17];
@tgt4=@tmp[18..21];
foreach(1..4){
打印@tgt($),“\n”;
}
我原以为
@tgt($\u)
会被解释为
@tgt1、@tgt2、@tgt3、@tgt4
,但我仍然收到错误消息,
@tgt
是一个全局符号(@tgt1、@tgt2、@tgt3、@tgt4`已经声明)

我是否误解了foreach循环

问题2.为什么perl不能将
@tgt($)
看作@tgt1、@tgt2..等等

问题2.根据经验,这可能是一种不好的变量命名方法。对于具有类似功能的变量,首选的命名方法是什么

  • 问题2.为什么perl不能将@tgt($41;视为@tgt1、@tgt2..等等

  • 问题2.根据经验,这可能是一种不好的变量命名方法。对于具有类似功能的变量,首选的命名方法是什么

我将一起回答这两个问题

@tgt($\ux)
并不是你所希望的意思

  • 首先,它是一个无效语法(不能在数组名后使用(),perl interpeter将产生编译错误)

  • 您试图做的是通过一个表达式访问一个变量,从而得到它的名称(aka),从而访问不同的变量。这是可以做到的;但这通常是一个坏主意和糟糕的Perl风格(如,您可以但不应该这样做,没有很好的理由)

  • 要以您尝试的方式访问元素$,可以使用
    @{“tgt$\}
    语法。但我重复-不要这样做,即使可以

  • 正确的惯用解决方案:使用arrayrefs数组,1-4(或者更确切地说是0-3)索引外部数组:

     # Old bad code: @tgt1=@tmp[8..11];
    
     # New correct code:
     $tgt[0]=[ @tmp[8..11] ]; # [] creates an array reference from a list.
     # etc... repeat 4 times - you can even do it in a smart loop later.
    
    这样做的目的是,它将对数组切片的引用存储到单个
    @tgt
    数组的第0个元素中

    最后,
    @tgt
    数组有4个元素,每个元素都是对包含一个切片的数组的数组引用


  • 我是否误解了foreach循环
您的foreach循环(与其内容相反-请参见上文)是正确的,但有一个样式警告-同样,虽然您可以使用默认的
$\uuu
变量,但您几乎不应该使用它,而是始终使用命名变量以提高可读性

您可以按如下方式打印上面提到的arrayrefs数组(如果语法不清楚,请单独询问-这是一个中级数据结构处理,不适合初学者):


始终使用
use strict;use warnings;
对不起,Ikegami,我确实使用了strict和warnings,但我只粘贴了我认为相关的部分代码(正如警告和错误所建议的那样)。@BChen-我很惊讶
@tgt($)
甚至编译:)@B Chen,使用
use strict;
的原因之一是必须声明变量,以便它们的作用域正确。由于变量的作用域不正确,您似乎没有抓住要点。变量的作用域应限制在需要变量的位置(合理范围内),也就是说变量应该在循环中声明。@ikegame,是的。现在我记得我在某个地方读过,变量应该限制在需要的地方。我将学习如何将它们保持在正确的循环中。感谢您指出。非常感谢!!对初学者的精彩解释!!(你应该试着写一本书/类似的教程!!)我确实读了一些关于参考的书,但还没有意识到它对我的编码有用。@BChen-:)谢谢你的好话。别着急,Perl是超级强大的,诀窍是知道什么时候不要滥用它的功能,以产生无法阅读的代码为代价而没有明显的收获。通常有很多方法可以做事情,有些方法更适合不同的目标。
foreach my $index (0..3) { 
    print join(",", @{ $tgt[$index]}) . "\n";
}