Gug*_*ira 1 perl label goto subroutine
我已经创建了一个名为"MENU"的子程序,在子程序的顶部有一个名为"INIT_MENU"的标签,但是当我调用这个标签时我得到一个错误:无法在program.pl第15行的子程序之外转到子程序
这是一个例子:
sub MENU {INIT_MENU: print "blah blah";}
Run Code Online (Sandbox Code Playgroud)
这是第15行:
goto &MENU, INIT_MENU;
Run Code Online (Sandbox Code Playgroud)
很抱歉,如果这是一个重复的问题,我搜索了所有可能的地方,甚至在Perl的官方网站
在转到希望的单个参数,因此,此代码首先执行goto &MENU,然后将后逗号运算它计算常数INIT_MENU在无效的情况下(绘制一个警告).
目的goto &NAME是用子程序替换遇到它的子程序NAME; 在子程序之外调用它是没有意义的,这是一个错误.来自perldiag
- 无法转到子程序外的子程序
(F)深刻神奇的"goto子程序"调用只能替换另一个子程序调用.它不能用整块布制造一块.通常,您应该仅使用AUTOLOAD例程调用它.见goto.
评论此目的.
已经写了很多关于有害性的文章goto LABEL.†更不用说INIT_MENU:隐藏在例程中时无法找到.结果是总有其他更好的方法.
一个采样器
调用该函数并传递参数
MENU(INIT_MENU);
sub MENU {
my $menu = shift;
if ($menu eq 'INIT_MENU') { ... }
...
}
Run Code Online (Sandbox Code Playgroud)如果出于某种原因,您希望"隐藏" 要按预期MENU使用的呼叫goto &MENU
sub top_level { # pass INIT_MENU to this sub
...
goto &MENU; # also passes its @_ as it is at this point
# the control doesn't return here; MENU took place of this sub
}
Run Code Online (Sandbox Code Playgroud)
这完全取代了top_level()用MENU()并将其@_给它.然后MENU如上所述处理输入(例如)以触发所选择的块.在此之后" 甚至连调用者都无法告诉该例程被称为第一个 ",请参阅goto.但这通常是不必要的.
为什么甚至有MENU()?相反,在单独的subs中有菜单选项,它们的引用可以是散列中的值,其中键是选项的名称.所以你有一个调度表,在逻辑(或用户选择)选择一个菜单项后,它的代码直接运行
my %do_menu_item = ( INIT_MENU => sub { code for INIT_MENU }, ... );
...
$do_menu_item{$item_name}->();
Run Code Online (Sandbox Code Playgroud)菜单系统往往随着开发而变得越来越大,越来越复杂.从一开始就采用OO是有意义的,然后还有其他方法来处理这个细节.
如果您发现自己正在考虑goto,可能是时候重新考虑(某些)设计了.
† 例如,请参阅此帖和此帖.它在Perl中(甚至)更糟,因为对于goto可以认为可以接受的情况,存在特定的构造(和限制).一个例子是跳出嵌套循环:Perl中有标签.
| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |