制作包含复制,创建,删除和重命名的菜单

时间:2017-10-06 00:02:24

标签: perl

重命名部分还没有任何代码,但其余部分确实有代码可以随身携带。

我一直认为复制和删除的变量没有声明,但我做到了。我做错了什么?

Array(multipartBody)

2 个答案:

答案 0 :(得分:4)

我清理了丢失的分号,美元符号,大括号,重复的行......和格式。我还添加了缺少的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 (1..@$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,只需1..@$choices$i <= @$choices

  • 不要不必要地引用,它可能导致错误。当变量以字符串插值时,主要需要引用。无需say $var;copy $file, $new ...

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

请尽量使用格式正确的代码提出可读问题。

答案 1 :(得分:1)

zdim你有一个非常详细的答案。这是你应该接受的那个。但是这里列出了为了让代码运行我必须解决的问题:

  • 删除了第一个菜单选项子例程末尾的重复print "done\n"和以下右括号(我在重新格式化代码时将其从您的问题中删除)。
  • 添加了遗失的use File::Copy
  • 在复制选项的第一个print语句末尾添加了一个缺少的分号。
  • 在删除选项中的$语句中添加了缺少的my removeF

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

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

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