2017-10-06 46 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提出的所有改進建議。

更仔細地格式化您的代碼。

相關問題