"Can't goto subroutine outside a subroutine" [closed] - perl

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I've created a subroutine named "MENU" with a label named "INIT_MENU" at the top of the subroutine, but when i call this label i got a error : Can't goto subroutine outside a subroutine at program.pl line 15
Here is an example:
sub MENU {INIT_MENU: print "blah blah";}
and here is the line 15:
goto &MENU, INIT_MENU;
Sorry if it is a duplicated question, i searched in all possible places and even in the official site of Perl

The goto expects a single argument, so this code first executes goto &MENU and then after the comma operator it evaluates the constant INIT_MENU in a void context (drawing a warning).
The purpose of goto &NAME is to replace the subroutine in which it is encountered with subroutine NAME; it doesn't make sense calling it outside of a subroutine and this is an error. From perldiag
Can't goto subroutine outside a subroutine
(F) The deeply magical "goto subroutine" call can only replace one subroutine call for another. It can't manufacture one out of whole cloth. In general you should be calling it out of only an AUTOLOAD routine anyway. See goto.
A comment on the purpose of this.
A lot has been written on the harmfulness of goto LABEL.† Not to mention that INIT_MENU: cannot be found when hidden inside a routine. The upshot is that there are always better ways.
A sampler
Call the function and pass the parameter
MENU(INIT_MENU);
sub MENU {
my $menu = shift;
if ($menu eq 'INIT_MENU') { ... }
...
}
If, for some reason, you want to 'hide' the call to MENU use goto &MENU as intended
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
}
This altogether replaces top_level() with MENU() and passes on its #_ to it. Then process input in MENU as above (for example) to trigger the chosen block. After this "not even caller will be able to tell that this routine was called first," see goto. Normally unneeded
Why even have MENU()? Instead, have menu options in separate subs and their references can be values in a hash where keys are names of options. So you'd have a dispatch table and after the logic (or user choice) selects a menu item its code is run directly
my %do_menu_item = ( INIT_MENU => sub { code for INIT_MENU }, ... );
...
$do_menu_item{$item_name}->();
Menu systems tend to grow bigger and more complex with development. It would make sense to adopt OO from start, and then there are yet other approaches for this detail
If you find yourself considering goto it may be time to reconsider (some of) the design.
† See for instance this post and this post. It's (even) worse than that in Perl since there are specific constructs (and restrictions) for situations where goto can be argued acceptable, so there is even less room for it. One example is jumping out of nested loops: there are labels in Perl.

Related

A 'my' issue, it cannot work even in clear PL rule [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
Why my sub cannot get hidden in the scope of function such in
use strict;
sub out{
my sub this{my $n=9;print "\n$n"} my $i=7; my $j=3
}
&this;
9
Please help solve
As described in the documentation in perldoc perlsub, a lexical subroutine is only visible inside the block they are created:
These subroutines are only visible within the block in which they are declared...
You try to call the sub outside the block, therefore Perl cannot see it. This is also the entire point of using lexical scope: You are trying to restrict the range.
If you had use warnings enabled you would get the warning:
Undefined subroutine &main::this called at ...
You have to use the lexical sub inside the block -- in this case another sub -- like this:
sub out {
my sub this {
....
}
this(); # <---- visible here
}
this(); # wrong, not visible here
Also, using & when calling a sub has a special meaning. As described in perlsub:
&NAME; # Makes current #_ visible to called subroutine.
The normal way to call a sub is by adding parens after: this(). The different ways to call a sub are also listed in perldoc perlsub. Note that there is hidden functionality in the different styles.
NAME(LIST); # & is optional with parentheses.
NAME LIST; # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME; # Makes current #_ visible to called subroutine.

How to fix next in eval-like logic in Perl? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I wrote in code
my $sql = ...
my $sth = $dbh->prepare($sql);
eval {
$sth->execute;
}
or do {
# die "SQL Error: $DBI::errstr\n";
addToLog("SQL Error: $DBI::errstr\n");
sleep(30);
next mysql_recover;
};
but checker swears I can't use next inside eval. How to rewrite otherwise?
The problem is in a scope enclosing the shown code (which isn't shown). From next
next LABEL
next EXPR
next
The next command is like the continue statement in C; it starts the next iteration of the loop [...]
So the shown code should be in a loop, with the label mysql_recover. Or in a block with such a label, since a block is a loop that executes once (but then next should be last).
However, we can't tell what is wrong without more code or the actual error message. The shown code doesn't give any hints since a next LABEL; is legit only to target structures that are subject to flow control so the mere acceptance of that statement implies that next is fine.
That do block is not a part of the eval so I don't know what your checker might mean.
But, if there were a next inside of eval, then
eval BLOCK does not count as a loop, so the loop control statements next, last, or redo cannot be used to leave or restart the block.
I'd like to also comment on that eval.
The $sth->execute shown as the sole statement in the eval can return an undef, if there is an error -- and so your eval-handler (the do block) would trigger in that case. If that's your intent then fine, but that'd be confusing since an eval is meant to guard against exceptions (a die).
A full idiom is eval { ...; 1 } or do {...};, so the eval always returns success (that 1) unless a die was thrown . So or do runs only if there was an exception, not on "ordinary" errors (like an undef from DBI...).
Another way to handle that would be to explicitly check for errors from $sth->execute, what need be done anyway. (But then add that 1 as well, against an unexpected false. Why not.)
(There is still some fine print about $# but that would take us elsewhere)

Handle multiple arguments to a Perl subroutine [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
As i have read ,"There’s another problem with this subroutine.This subroutine works properly only if called with exactly two
Excess parameters are ignored—since the subroutine never looks at $_[2] "
but when I passed multiple arguments its working,so I'm not able to conclude the above statement so can anyone help me in sorting out this problem.
sub privacy{
$_[0]+$_[1]+$_[2]+$_[3];
}
$x=&privacy(3,4,5,6);
print $x,"\n";`
Expected:
7
Actual:
18
but this result is contradicting.
I think you're reading Learning Perl. We present a subroutine that finds the maximum of two arguments. It looks something like this:
sub max {
if( $_[0] > $_[1] ) { ... }
else { $_[0] }
}
If you call it with two arguments, it works out:
max( 1, 2 )
max( 5, 6 )
max( 9, 0 )
If you call it with three arguments, that particular subroutine ignores the third argument because that particular subroutine only looks at the first two:
max( 1, 2, 3 ) # ignores 3, so returns 2
You can write some other subroutine that looks at more arguments, but that's a different subroutine.
Unless you tell Perl otherwise (and I'll ignore that here), it will take as many arguments as you care to give it and they all show up in the special variable #_. How you use that is up to you.
You are misunderstanding the meaning of the sentence:
Excess parameters are ignored—since the subroutine never looks at
$_[2]
What is meant by that is that in a perl subroutine (as in any language) if you don't use a parameter then it's not used.
In the particular example that the above sentence refers to, parameter 2, etc., are not used in the code so they are 'ignored'. They're available if you want to use them, they're just not used in that particular example.
However in YOUR code you are using them.
If that's what they said, and if that's the code they were talking about, then they are wrong. The sub clearly "looks at $_[2]".
3+4+5+6 is 18, and that's exactly what the code the outputs.
$ perl -e'
sub privacy{
$_[0]+$_[1]+$_[2]+$_[3];
}
$x=&privacy(3,4,5,6);
print $x,"\n";
'
18
Note that the code has issues (& used on the sub call even though they are no prototypes to override, and $x isn't scoped), so you shouldn't be taking lessons from whomever wrote that code.

What is the difference between function call and goto &NAME in Perl?

I'm reading Perl which is quite interesting. But while reading goto from here in Perl I got a doubt.
I know that goto statement has three types.
goto LABEL.
goto EXPR.
goto &NAME.
But in this three types, what is the use of third one goto &NAME?
This is also seems to be like a function call.
Then,
What is the real difference between goto &NAME and normal function call in Perl?
When we use goto &NAME?
Can anyone please explain with example.
Thanks in advance.
It says in the goto page
The goto &NAME form is quite different from the other forms of
goto. In fact, it isn't a goto in the normal sense at all, and
doesn't have the stigma associated with other gotos.
Then follows the answer to your question
Instead, it
exits the current subroutine (losing any changes set by local())
and immediately calls in its place the named subroutine using the
current value of #_.
With a normal function call the execution continues on the next line after the function exits.
The rest of that paragraph is well worth reading as well, and answers your second question
This is used by AUTOLOAD subroutines that wish to load another subroutine and then pretend that the other subroutine had been called in the first place (except that any modifications to #_ in the current subroutine are propagated to the other subroutine.) After the goto, not even caller will be able to tell that this routine was called first.
A basic example. With a subroutine deeper defined somewhere, compare
sub func_top {
deeper( #_ ); # pass its own arguments
# The rest of the code here runs after deeper() returns
}
with
sub func_top {
goto &deeper; # #_ is passed to it, as it is at this point
# Control never returns here
}
At the statement goto &deeper the sub func_top is exited. So after deeper completes, the control returns to after the func_top call.
In a sense, func_top is replaced by deeper.
Trying to pass arguments with goto &func results in errors, even just for goto &deeper().

When should I use the & to call a Perl subroutine?

I have heard that people shouldn't be using & to call Perl subs, i.e:
function($a,$b,...);
# opposed to
&function($a,$b,...);
I know for one the argument list becomes optional, but what are some cases where it is appropriate to use the & and the cases where you should absolutely not be using it?
Also how does the performace increase come into play here when omitting the &?
I'm a frequent abuser of &, but mostly because I'm doing weird interface stuff. If you don't need one of these situations, don't use the &. Most of these are just to access a subroutine definition, not call a subroutine. It's all in perlsub.
Taking a reference to a named subroutine. This is probably the only common situation for most Perlers:
my $sub = \&foo;
Similarly, assigning to a typeglob, which allows you to call the subroutine with a different name:
*bar = \&foo;
Checking that a subroutine is defined, as you might in test suites:
if( defined &foo ) { ... }
Removing a subroutine definition, which shouldn't be common:
undef &foo;
Providing a dispatcher subroutine whose only job is to choose the right subroutine to call. This is the only situation I use & to call a subroutine, and when I expect to call the dispatcher many, many times and need to squeeze a little performance out of the operation:
sub figure_it_out_for_me {
# all of these re-use the current #_
if( ...some condition... ) { &foo }
elsif( ...some other... ) { &bar }
else { &default }
}
To jump into another subroutine using the current argument stack (and replacing the current subroutine in the call stack), an unrare operation in dispatching, especially in AUTOLOAD:
goto ⊂
Call a subroutine that you've named after a Perl built-in. The & always gives you the user-defined one. That's why we teach it in Learning Perl. You don't really want to do that normally, but it's one of the features of &.
There are some places where you could use them, but there are better ways:
To call a subroutine with the same name as a Perl built-in. Just don't have subroutines with the same name as a Perl built-in. Check perlfunc to see the list of built-in names you shouldn't use.
To disable prototypes. If you don't know what that means or why you'd want it, don't use the &. Some black magic code might need it, but in those cases you probably know what you are doing.
To dereference and execute a subroutine reference. Just use the -> notation.
IMO, the only time there's any reason to use & is if you're obtaining or calling a coderef, like:
sub foo() {
print "hi\n";
}
my $x = \&foo;
&$x();
The main time that you can use it that you absolutely shouldn't in most circumstances is when calling a sub that has a prototype that specifies any non-default call behavior. What I mean by this is that some prototypes allow reinterpretation of the argument list, for example converting #array and %hash specifications to references. So the sub will be expecting those reinterpretations to have occurred, and unless you go to whatever lengths are necessary to mimic them by hand, the sub will get inputs wildly different from those it expects.
I think mainly people are trying to tell you that you're still writing in Perl 4 style, and we have a much cleaner, nicer thing called Perl 5 now.
Regarding performance, there are various ways that Perl optimizes sub calls which & defeats, with one of the main ones being inlining of constants.
There is also one circumstance where using & provides a performance benefit: if you're forwarding a sub call with foo(#_). Using &foo is infinitesimally faster than foo(#_). I wouldn't recommend it unless you've definitively found by profiling that you need that micro-optimization.
The &subroutine() form disables prototype checking. This may or may not be what you want.
http://www.perl.com/doc/manual/html/pod/perlsub.html#Prototypes
Prototypes allow you to specify the numbers and types of your subroutine arguments, and have them checked at compile time. This can provide useful diagnostic assistance.
Prototypes don't apply to method calls, or calls made in the old-fashioned style using the & prefix.
The & is necessary to reference or dereference a subroutine or code reference
e.g.
sub foo {
# a subroutine
}
my $subref = \&foo; # take a reference to the subroutine
&$subref(#args); # make a subroutine call using the reference.
my $anon_func = sub { ... }; # anonymous code reference
&$anon_func(); # called like this
Protypes aren't applicable to subroutine references either.
The &subroutine form is also used in the so-called magic goto form.
The expression goto &subroutine replaces the current calling context with a call to the named subroutine, using the current value of #_.
In essence, you can completely switch a call to one subroutine with a call to the named one. This is commonly seen in AUTOLOAD blocks, where a deferred subroutine call can be made, perhaps with some modification to #_ , but it looks to the program entirely as if it was a call to the named sub.
e.g.
sub AUTOLOAD {
...
push #_, #extra_args; # add more arguments onto the parameter list
goto &subroutine ; # change call another subroutine, as if we were never here
}
}
Potentially this could be useful for tail call elimination, I suppose.
see detailed explanation of this technique here
I've read the arguments against using '&', but I nearly always use it. It saves me too much time not to. I spend a very large fraction of my Perl coding time looking for what parts of the code call a particular function. With a leading &, I can search and find them instantly. Without a leading &, I get the function definition, comments, and debug statements, usually tripling the amount of code I have to inspect to find what I'm looking for.
The main thing not using '&' buys you is it lets you use function prototypes. But Perl function prototypes may create errors as often as they prevent them, because they will take your argument list and reinterpret it in ways you might not expect, so that your function call no longer passes the arguments that it literally says it does.