perl - 如何在 Perl 中构建一个简单的菜单?

标签 perl user-interface oop menu submenu

我正在编写一个需要一些基本菜单功能的 Perl 脚本。最终,我希望每个菜单都有几个选项,然后可以选择返回上一个菜单或退出。

例子:

这是一个菜单:

  • 选择 1
  • 选择2
  • 返回上一级菜单
  • 退出

  • 选择一个选项:

    我目前有一个菜单子(monad)程序制作菜单,但没有允许它返回上一个菜单的功能。
        sub menu
        {
            for (;;) {
                print "--------------------\n";
                print "$_[0]\n";
                print "--------------------\n";
                for (my $i = 0; $i < scalar(@{ $_[1]}); $i++) {
                    print $i + 1, "\.\t ${ $_[1] }[$i]\n";
                }
                print "\n?: ";
                my $i = <STDIN>; chomp $i;
                if ($i && $i =~ m/[0-9]+/ && $i <= scalar(@{ $_[1]})) {
                    return ${ $_[1] }[$i - 1];
                } else {
                    print "\nInvalid input.\n\n";
                }
            }
        }
    
        # Using the menu
        my $choice1  = menu('Menu1 header', \@list_of_choices1);
    
        # I would like this menu to give the option to go back to
        # the first menu to change $choice1
        my $choice2 = menu('Menu2 header', \@list_of_choices2);
    

    我不想硬编码所有的菜单并使用 if/elsif 语句进行所有处理,所以我将菜单变成了一个函数。

    我的菜单目前看起来像这样......

    菜单标题:
  • 选择1
  • 选择2
  • 选择3

  • ?:(在此处输入输入)

    此解决方案仍然不允许用户返回上一个菜单或退出。我正在考虑制作一个菜单类来处理菜单,但我仍然不太擅长面向对象的 Perl。这是一个只有几个菜单的小程序,因此使用复杂的菜单构建模块可能是矫枉过正。我想让我的代码尽可能的简洁。

    编辑:

    感谢您的快速回复!但是,仍然存在一个问题。当我从“Menu1”中选择一个选项并进入“Menu2”时,我希望保存“Menu1”中的选择以供以后使用:

    菜单1:
  • Choice1 <-- 如果选中则存储值并转到下一个菜单
  • 选择2 <-- ...
  • 退出<--退出

  • 菜单2:
  • Choice1 <-- 如果选中则存储值并转到下一个菜单
  • 选择2 <-- ...
  • 返回<--返回上一级菜单重新选择值
  • 退出<--退出

  • 选择 Choice1 或 Choice2 应将值存储在变量中以供以后使用 进入下一个菜单。然后,如果您选择从 Menu2 返回到第一个菜单,它将为您提供重新选择选项并重新定义变量的选项。我试图避免使用全局变量,这使得这非常困难。

    在完成所有菜单并设置所有这些变量的值之后,我想运行一个子程序来处理所有选择并打印最终输出。
     sub main () {
    
       # DO MENU STUFF HERE
    
       # PROCESS RESULTS FROM MENU CHOICES
       my $output = process($menu1_choice, $menu2_choice, $menu3_choice, ... );
     }
    

    此外,如果有人使用类或其他一些数据结构对此有面向对象的方法,尽管它可能有点矫枉过正,但我​​仍然希望看到它并尝试将我的头脑围绕这个想法!

    最佳答案

    您可以使用模块,例如 Term::Choose :

    use Term::Choose qw( choose );
    
    my $submenus = {
        menu1 => [ qw( s_1 s_2 s_3 ) ],
        menu2 => [ qw( s_4 s_5 s_6 s_7) ],
        menu3 => [ qw( s_8 s_9 ) ],
    };
    my @menus = ( qw( menu1 menu2 menu3 ) );
    my $mm = 0;
    MAIN: while ( 1 ) {
        my $i = choose( 
            [ undef, @menus ],
            { layout => 3, undef => 'quit', index => 1, default => $mm }
        );
        last if ! $i;
        if ( $mm == $i ) {
            $mm = 0;
            next MAIN;
        }
        else {
            $mm = $i;
        }
        $i--;
        SUB: while ( 1 ) {
            my $choice = choose(
                [ undef, @{$submenus->{$menus[$i]}} ],
                { layout => 3, undef => 'back' }
            );
            last SUB if ! defined $choice;
            say "choice: $choice";
        }
    }
    

    关于perl - 如何在 Perl 中构建一个简单的菜单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25438475/

    相关文章:

    perl - 强制 Time::Piece strftime 使用特定的语言环境

    regex - Perl:使用变量传递正则表达式搜索和替换

    javascript - 将 Python 后端与桌面应用程序的 HTML/CSS/JS 用户界面集成?

    perl - Perl 运行时是否有实际的派生类?

    java - 分配为对象的属性时不保留数组元素

    html - 无法通过包 "links"定位对象方法 "mech"

    perl:使用字符串作为代码片段

    Java:从静态类访问 Jframe 标签

    c# - Metro 风格的数据输入表单应用程序

    oop - 用于管理对象依赖关系的设计模式