2017-10-06 43 views
1

重命名部分还没有任何代码,但其余的代码都有它的代码。制作一个带有复制,创建,删除和重命名的菜单

我总是得到复制和删除的变量没有声明,但我做到了。我究竟做错了什么?

#!/usr/bin/perl 

use warnings; 
use strict; 

sub menu { 
    my $args = shift; 
    my $title = $args->{title}; 
    my $choices = $args->{choices}; 

    while (1) { 
    print "--------------------\n"; 
    print "$title\n"; 
    print "--------------------\n"; 
    for (my $i = 1; $i <= scalar(@$choices); $i++) { 
     my $itemHeading = $choices->[$i-1][0]; 
     print "$i.\t $itemHeading\n"; 
    } 
    print "\n?: "; 
    my $i = <STDIN>; chomp $i; 
    if ($i && $i =~ m/[0-9]+/ && $i <= scalar(@$choices)) { 
     &{$choices->[$i-1][1]}(); 
    } else { 
     print "\nInvalid input.\n\n"; 
    } 
    } 
} 

my $menus = {}; 
$menus = { 
    "1" => { 
    "title" => "Menu 1 header", 
    "choices" => [ 
     [ "Create file " , sub { 
     print "Name of file you want to create: "; 
     my $createFile = <STDIN>; 
     open my $fh, ">>", "$createFile" or die "can't open\n"; 
     print $fh "Here's that file you ordered\n"; 
     close $fh; 

     print "done\n"; 
     }], 

     [ "Rename a file" , sub { 
     print "What file do you want to rename (add  ext): "; 
     my $oldName = <STDIN>; 
     print "What do you want to rename it: "; 
     my $newName = <STDIN>; 
     }], 

     [ "Copy file" , sub { 
     print "What file do you want to copy: " 
     my $copyFile = <STDIN>; 
     print "What do you want to call this file: :"; 
     my $newFile = <STDIN>; 
     copy "$copyFile" , "$newFile" || die "can't copy"; 
     }], 
     [ "Remove file" , sub { 
     print "Which file do you want to remove"; 
     my removeF = <STDIN>; 
     open my $fh; 
     unlink "$removeF"; 
     }], 
    }, 
    }; 

    menu($menus->{1}); 
+4

与陌生/不一致/缺乏压痕有什么关系?当你无法提出一个很好的格式化版本时,期待其他人阅读你的代码是很粗鲁的! –

+2

我已经清理了你的代码。请在将来自己做。一致而有意义的缩进是一个重要的自我文档工具。 –

回答

5

我清理了丢失的分号,美元符号,大括号,重复的行和格式。我还添加了缺失的use File::Copy。你的代码根本不是那么遥不可及,但我可以看到你迷失在这么多错误中。因此,这里是最重要的注意事项:

输入代码一点点的时间和确保其顺利运行和设想的作品。总是添加小部分代码并进行测试,测试和测试。首先构建小型,圆形和粗糙的功能组件,以便您可以明智地测试它们和您的设计。然后进一步发展。

然后,每个错误很容易被发现或教育。

这里是你的代码(只有两个功能),清理使其作品多一点

use warnings; 
use strict; 
use feature 'say'; 

use File::Copy qw(copy move); 

sub menu { 
    my $args = shift; 
    my $title = $args->{title}; 
    my $choices = $args->{choices}; 

    while (1) { 
     say $title, "\n", '-' x length $title; 
     for my $i ([email protected]$choices) { 
      my $itemHeading = $choices->[$i-1][0]; 
      say "$i.\t$itemHeading"; 
     } 
     print "\n?: "; 
     my $i = <STDIN>; 
     chomp $i; 
     if ($i && $i =~ m/[0-9]+/ && $i <= @$choices) { 
      $choices->[$i-1][1](); 
     } else { 
      say "\nInvalid input.\n"; 
     } 
    } 
} 

my $menus = { 
    1 => { 
     "title" => "Menu 1 header", 
     "choices" => [ 
      [ "Create file " , 
       sub { 
        print "Name of file you want to create: "; 
        my $createFile = <STDIN>; 
        chomp $createFile; 
        open my $fh, ">>", $createFile 
         or die "Can't open $createFile: $!\n"; 
        say $fh "Here's that file you ordered"; 
        close $fh; 

        say "done"; 
       } 
      ], 
      [ "Rename a file" , 
       sub { 
        print "What file do you want to rename (add ext): "; 
        my $oldName = <STDIN>; 
        chomp $oldName; 
        if (not -e $oldName) { 
         say "\n\tNo file \"$oldName\"\n"; 
         return; 
        } 
        print "What do you want to rename it: "; 
        my $newName = <STDIN>; 
        chomp $newName;   # what if it exists already? 
        move $oldName, $newName 
         or die "Can't move $oldName to $newName: $!"; 
       } 
      ], 
      [ "Quit", sub { exit } ] 
     ] 
    } 
}; 

menu($menus->{1}); 

我也加入到退出的选项,一些错误检查。

的几个注意事项

  • 很少有以往任何时候都需要一个C风格for

  • 在子名称前面的&有着非常特定的目的。通常它不需要

  • 添加$!当您打印错误实际上看它是什么,和/或使用其他error variables

  • 当数组是在标量上下文中使用它的长度,元素的数量;所以没有必要scalar在你的条件,只是[email protected]$choices$i <= @$choices

  • 不要无谓地引用,它可以导致错误。当变量被插入到字符串中时,主要需要引用。不需要报价say $var;copy $file, $new ...

  • 一个直接错误丢失chomp s。使用使用换行符的资源(文件STDIN)应该是基本的习惯。在某些情况下忽略它可能会提供更清晰的流程,但对于可能会引起调试会话的开放性,可能会远远低于代码中的“奇怪”错误。

请尽量用正确格式化的代码呈现可读的问题。

1

您对zdim的回答非常详细。这是你应该接受的。但这里是什么,我不得不为了解决让你的代码的运行列表:

  • 在第一个菜单选项子程序的末尾删除重复print "done\n"和紧随括号(我删除它们从你的问题,而重新格式化你的代码)。
  • 添加了缺少的use File::Copy
  • 在复制选项的第一个print语句的末尾添加了缺少的分号。
  • 在删除选项中为my removeF语句添加了缺少的$

所有这些都是通过运行perl -c(这是Perl的内置语法检查器)运行您的代码而找到的。

另外,您应该注意zdim提出的所有改进建议。

更仔细地格式化您的代码。

相关问题