如何更懒惰地使用Perl?以及其他关于编程习惯的各种问题

如何更懒惰地使用Perl?以及其他关于编程习惯的各种问题,perl,lazy-evaluation,Perl,Lazy Evaluation,昨晚,我写了大约200行蹩脚的perl代码,包括意大利面代码、无法调试的未定义变量,还有很多很多很多。最后,我把它放在帕尔蒙克斯上等待。我认为这是最有帮助的回答: 超过200行的意大利面代码,其中输入解析在一个子系统中进行。难怪你在调试这只小狗时遇到了麻烦!一些可能有助于清理的提示: 重构您的代码,将所有输入解析移出LHCC sub,然后将解析后的数据传递到sub。这样,您就可以编写和调试sub,而无需从正确的输入数据解析开始 不要使用goto 不要在if/elsif/else语句中使用空{}

昨晚,我写了大约200行蹩脚的perl代码,包括意大利面代码、无法调试的未定义变量,还有很多很多很多。最后,我把它放在帕尔蒙克斯上等待。我认为这是最有帮助的回答:

超过200行的意大利面代码,其中输入解析在一个子系统中进行。难怪你在调试这只小狗时遇到了麻烦!一些可能有助于清理的提示:

  • 重构您的代码,将所有输入解析移出LHCC sub,然后将解析后的数据传递到sub。这样,您就可以编写和调试sub,而无需从正确的输入数据解析开始
  • 不要使用goto
  • 不要在if/elsif/else语句中使用空{},它们会掩盖失败条件
  • 不要重复代码块-使用一个sub。它包含大量代码死亡的地方,其中包含一条长而无意义的错误消息。使用sub并传递要包含在消息中的上下文。这将清理代码并帮助调试逻辑错误
  • 不要为不可能发生的事情编写代码(n%2只能是0或1),以避免代码混乱和逻辑模糊
  • 使用“提前退出”循环旁边的。这避免了嵌套代码并使其更易于理解
  • 在使用$key(和die)之前检查它
  • 为什么我的@StatementsKeys=keys%语句;当@StatementsKeys不在任何地方使用时
我将在适当的时候继续使用您的代码的一个稍微整洁的版本,但是有很多行要删除,这需要一段时间!;)

对于Perl代码,这些都是非常好的建议。但是我在执行他的建议和真正成为一个懒惰的程序员方面遇到了问题。出于某种奇怪的原因,我无法将他所说的落实到我编写的所有程序中,我很确定这就是学习真正优秀编程的方法。我有两个问题:

首先,您将如何使这个快速脚本在代码方面得到优化和改进?我认为在我看到这个优化后,我将能够用我的代码开始向更好的方向发展。顺便说一句,这不是上面消息中提到的代码

ORIGINAL:

print "
Welcome to the Casio-Maxim Quadrilateral Identification\n
Algorithm. In order to identify said quadrilateral,\n
you must have the coordinates of all 4 vertices.\n
When you are ready to input your coordines, type\n
'ready.' Type 'quit' to exit the CMQIA.\n\n";

my $choice = <STDIN>;
if ($choice =~ /quit/i) {
  if (!&Unit6()) {
    return 0;
  }
}
elsif ($choice =~ /ready/i) {

}
else {
  print "\nCould not interpret, try again\n";
  goto ORIGINAL;
}

print
"\nFor shape ABCD, in which point A has coordinates (X1, Y1), B has coordinates\n\n(X2, Y2), C has coordinates (X3, Y3), and D has coordinates (X4, Y4),\n\nX1 = ";

my $AX = <STDIN>;
chomp $AX;
if ($AX !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n";
  goto ORIGINAL;
}
print "\nY1 = ";

my $AY = <STDIN>;
chomp $AY;
if ($AY !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n";
  goto ORIGINAL;
}
print "\nX2 = ";

my $BX = <STDIN>;
chomp $BX;
if ($BX !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n";
  goto ORIGINAL;
}
print "\nY2 = ";

my $BY = <STDIN>;
chomp $BY;
if ($BY !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n";
  goto ORIGINAL;
}
print "\nX3 = ";

my $CX = <STDIN>;
chomp $CX;
if ($CX !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n";
  goto ORIGINAL;
}
print "\nY3 = ";

my $CY = <STDIN>;
chomp $CY;
if ($CY !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n";
  goto ORIGINAL;
}
print "\nX4 = ";

my $DX = <STDIN>;
chomp $DX;
if ($DX !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n";
  goto ORIGINAL;
}
print "\nY4 = ";

my $DY = <STDIN>;
chomp $DY;
if ($DY !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n";
  goto ORIGINAL;
}

my $SAB = ($BX - $AX)**2 + ($BY - $AY)**2;
my $AB  = sqrt($SAB);
my $SBC = ($CX - $BX)**2 + ($CY - $BY)**2;
my $BC  = sqrt($SBC);
my $SCD = ($DX - $CX)**2 + ($DY - $CY)**2;
my $CD  = sqrt($SCD);
my $SDA = ($AX - $DX)**2 + ($AY - $DY)**2;
my $DA  = sqrt($SDA);
my $SAC = ($CX - $AX)**2 + ($CY - $AY)**2;
my $AC  = sqrt($SAC);
my $SBD = ($DX - $BX)**2 + ($DY - $BY)**2;
my $BD  = sqrt($SBD);

my $MAB = eval { ($BY - $AY) / { $BX - $AX } };
if ($@) {
  print "\nUndefined or No Slope. Sorry, cannot compute.\n";
  goto ORIGINAL;
}

my $MBC = eval { ($CY - $BY) / { $CX - $BX } };
if ($@) {
  print "\nUndefined or No Slope. Sorry, cannot compute.\n";
  goto ORIGINAL;
}

my $MCD = eval { ($DY - $CY) / { $DX - $CX } };
if ($@) {
  print "\nUndefined or No Slope. Sorry, cannot compute.\n";
  goto ORIGINAL;
}

my $MDA = eval { ($AY - $DY) / { $AX - $DX } };
if ($@) {
  print "\nUndefined or No Slope. Sorry, cannot compute.\n";
  goto ORIGINAL;
}

my $MAC = eval { ($CY - $AY) / { $CX - $AX } };
if ($@) {
  print "\nUndefined or No Slope. Sorry, cannot compute.\n";
  goto ORIGINAL;
}

my $MBD = eval { ($DY - $BY) / { $DX - $BX } };
if ($@) {
  print "\nUndefined or No Slope. Sorry, cannot compute.\n";
  goto ORIGINAL;
}

my $ShapeName;
if ($MAB == $MCD) {
  if ($MBC == $MDA) {
    if ((-1 / $MAB) == $MDA && (-1 / $MBC) == $MCD) {
      if ($AB == $BC) {
        $ShapeName = "square";
      }
      else {
        $ShapeName = "rectangle";
      }
    }
    else {
      if ($AB == $BC) {
        $ShapeName = "rhombus";
      }
      else {
        $ShapeName = "parallelogram";
      }
    }
  }
  else {
    if ($BC == $DA) {
      $ShapeName = "isosceles trapezoid";
    }
    else {
      $ShapeName = "trapezoid";
    }
  }
}
else {
  if ($MBC == $MDA) {
    if ($AB == $CD) {
      $ShapeName = "isosceles trapezoid";
    }
    else {
      $ShapeName = "trapezoid";
    }
  }
  else {
    if ((-1 / $MAC) == $MBD) {
      $ShapeName = "kite";
    }
    else {
      $ShapeName = "quadrilateral";
    }
  }
}

print "
Shape ABCD is a $ShapeName.\n
AB = $AB or the square root of ($SAB)\n
BC = $BC or the square root of ($SBC)\n
CD = $CD or the square root of ($SCD)\n
DA = $DA or the square root of ($SDA)\n
AC = $AC or the square root of ($SAC)\n
BD = $BD or the square root of ($SBD)\n
Slope of AB = $MAB\n
Slope of BC = $MBC\n
Slope of CD = $MCD\n
Slope of DA = $MDA\n
Slope of AC = $MAC\n
Slope of BD = $MBD\n";

goto ORIGINAL;
原件:
“打印”
欢迎使用卡西欧Maxim四边形标识\n
算法。为了识别所述四边形,\n
必须具有所有4个顶点的坐标。\n
准备好输入坐标后,键入\n
“准备就绪。”键入“退出”退出CMQIA。\n\n”;
我的$choice=;
如果($choice=~/quit/i){
if(!&Unit6()){
返回0;
}
}
elsif($choice=~/ready/i){
}
否则{
打印“\n无法解释,请重试\n”;
后藤原创;
}
打印
“\n对于形状ABCD,其中点A有坐标(X1,Y1),B有坐标\n\n(X2,Y2),C有坐标(X3,Y3),D有坐标(X4,Y4),\n\nX1=”;
我的$AX=;
咬$AX;
如果($AX!~/^-?\d+\.?\d*$/){
打印“\n必须是数值。\n”;
后藤原创;
}
打印“\nY1=”;
我的$AY=;
咀嚼$AY;
如果($AY!~/^-?\d+\.?\d*$/){
打印“\n必须是数值。\n”;
后藤原创;
}
打印“\nX2=”;
我的$BX=;
chomp$BX;
如果($BX!~/^-?\d+\.?\d*$/){
打印“\n必须是数值。\n”;
后藤原创;
}
打印“\nY2=”;
我的$BY=;
咀嚼$BY;
如果($BY!~/^-?\d+\.?\d*$/){
打印“\n必须是数值。\n”;
后藤原创;
}
打印“\nX3=”;
我的$CX=;
咀嚼$CX;
如果($CX!~/^-?\d+\.?\d*$/){
打印“\n必须是数值。\n”;
后藤原创;
}
打印“\nY3=”;
我的$CY=;
咀嚼$CY;
如果($CY!~/^-?\d+\.?\d*$/){
打印“\n必须是数值。\n”;
后藤原创;
}
打印“\nX4=”;
我的$DX=;
chomp$DX;
如果($DX!~/^-?\d+\.?\d*$/){
打印“\n必须是数值。\n”;
后藤原创;
}
打印“\nY4=”;
我的$DY=;
咀嚼$DY;
如果($DY!~/^-?\d+\.?\d*$/){
打印“\n必须是数值。\n”;
后藤原创;
}
my$SAB=($BX-$AX)**2+($BY-$AY)**2;
我的$AB=sqrt($SAB);
my$SBC=($CX-$BX)**2+($CY-$BY)**2;
我的$BC=sqrt($SBC);
my$SCD=($DX-$CX)**2+($DY-$CY)**2;
我的$CD=sqrt($SCD);
my$SDA=($AX-$DX)**2+($AY-$DY)**2;
我的$DA=sqrt($SDA);
my$SAC=($CX-$AX)**2+($CY-$AY)**2;
我的$AC=sqrt($SAC);
my$SBD=($DX-$BX)**2+($DY-$BY)**2;
my$BD=sqrt($SBD);
my$MAB=eval{($BY-$AY)/{$BX-$AX};
如果($@){
打印“\n未定义或没有坡度。对不起,无法计算。\n”;
后藤原创;
}
my$MBC=eval{($CY-$BY)/{$CX-$BX};
如果($@){
打印“\n未定义或没有坡度。对不起,无法计算。\n”;
后藤原创;
}
my$MCD=eval{($DY-$CY)/{$DX-$CX};
如果($@){
打印“\n未定义或没有坡度。对不起,无法计算。\n”;
后藤原创;
}
my$MDA=eval{($AY-$DY)/{$AX-$DX};
如果($@){
打印“\n未定义或没有坡度。对不起,无法计算。\n”;
后藤原创;
}
my$MAC=eval{($CY-$AY)/{$CX-$AX};
如果($@){
打印“\n未定义或没有坡度。对不起,无法计算。\n”;
后藤原创;
}
my$MBD=eval{($DY-$BY)/{$DX-$BX};
如果($@){
打印“\n未定义或没有坡度。对不起,无法计算。\n”;
后藤原创;
}
我的$ShapeName;
如果($MAB==$MCD){
如果($MBC==$MDA){
如果(-1/$MAB)=$MDA&(-1/$MBC)=$MCD){
如果($AB==$BC){
$ShapeName=“square”;
}
否则{
$ShapeName=“矩形”;
}
}
否则{
如果($AB==$BC){
$ShapeName=“菱形”;
}
否则{
$ShapeName=“平行四边形”;
}
}
}
否则{
如果($BC=$DA){
$ShapeName=“等腰梯形”;
}
否则{
$ShapeName=“梯形”;
}
}
}
否则{
如果($MBC==$MDA){
如果($AB==$CD){
$ShapeName=“等腰梯形”;
}
否则{
$ShapeName=“梯形”;
}
}
否则{
如果(-1/$MAC)=$MBD){
$ShapeName=“kite”;
}
否则{
$ShapeName=“四边形”;
}
}
}
“打印”
形状ABCD是$ShapeName。\n
AB=$AB或其平方根
while (1) {
  ...
  } else {
    print "\nCould not interpret, try again\n";
    continue;
  }
  ...
}
my $AX = <STDIN>;
chomp $AX;
if ($AX !~ /^-?\d+\.?\d*$/) {
  print "\nMust be numeric value.\n"; goto ORIGINAL;
}
sub parse_input {
  my $coord = shift(_@);
  chomp $coord;
  if ($coord !~ /^-?\d+\.?\d*$/) {
    print "\nMust be numeric value.\n";
    return false;
  }
  return true;
}
my $AX = <STDIN>;
continue unless (parse_input($AX));

my $AY = <STDIN>;
continue unless (parse_input($AY));

my $BX = <STDIN>;
continue unless (parse_input($BX));

my $BY = <STDIN>;
continue unless (parse_input($BY));

my $CX = <STDIN>;
continue unless (parse_input($CX));

my $CY = <STDIN>;
continue unless (parse_input($CY));

my $DX = <STDIN>;
continue unless (parse_input($DX));

my $DY = <STDIN>;
continue unless (parse_input($DY));
my $SAB = ($BX-$AX)**2 + ($BY-$AY)**2;
my $AB = sqrt($SAB);
sub pyth {
  my ($AX, $AY, $BX, $BY) = @_;
  return sqrt(($BX-$AX)**2 + ($BY-$AY)**2);
}
my $AB = pyth($AX, $AY, $BX, $BY);
my $BC = pyth($BX, $BY, $CX, $CY);
my $MAB = eval{($BY-$AY)/{$BX-$AX}}; if ($@) {print "\nUndefined or No Slope. Sorry, cannot compute.\n"; goto ORIGINAL;}
if ($BX-$AX == 0) {
  print "\nUndefined or No Slope. Sorry, cannot compute.\n";
  continue;
}

my $MAB = ($BY-$AY)/($BX-$AX);