Re: How to no goto or gosub
by choroba (Cardinal) on Jan 15, 2016 at 21:29 UTC
|
No goto, no label, no sub needed in this case. Just negate the condition:
if (not $gas_cost < 1) {
stuff here
}
continue here
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
|
I'm curious. Every post has suggested either if (not $gas_cost < 1) or if ($gas_cost >= 1). Am I the only one who immediately thought unless ($gas_cost < 1)?
Do I just think strangely, or is unless too unclear for most people to consider using? (or is there some other reason for not using it?)
| [reply] [d/l] [select] |
|
The OP seemed as a beginner question to me. I tried not to introduce unnecessary details. On the other hand, I usually use unless in post-position only, to prevent an else from creeping in.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] |
|
|
unless ($things_went_wrong) { # do some stuff }
But, when there are multiple conditions, it gets tougher to keep straight:
unless ($result < $HIGHEST_VALUE && ! $bad_results{$result}) { # stuff
+ }
And then there is this legal, but almost much harder to follow, control structure:
unless ($result) {
## Do some stuff
}
elsif (!$result) {
## Do some other stuff
}
else {
## yet other stuff...
}
In the end, 'unless(') is just a way to type 'if (!)', but with more keystrokes and it has a better chance of making your brain hurt. And, you never have to worry about decoding double negatives, or re-writing them if your control statements need to grow down the line if you just use 'if (!)'.
| [reply] [d/l] [select] |
|
|
|
| [reply] |
|
|
| [reply] |
Re: How to no goto or gosub
by GrandFather (Saint) on Jan 15, 2016 at 21:37 UTC
|
Probably neither, but refactoring code depends a great deal on the context and you haven't given us enough to play with. Personally I make frequent use of early exit and often use exceptions to handle error recovery. Early exits tend to reduce nesting blocks and exceptions take care of "jumping out of code" on errors. Maybe something like:
for my $gas_cost (@gasCosts) {
if ($gas_cost < 1) {
print "Bad gas - $gas_cost\n";
next;
}
...
}
or:
eval {
die "Bad gas - $gas_cost\n" if $gas_cost < 1;
...
return 1;
} or do {
my $err = $@;
print "Error handling gas: $err"
};
Premature optimization is the root of all job security
| [reply] [d/l] [select] |
Re: How to no goto or gosub
by kennethk (Abbot) on Jan 16, 2016 at 00:03 UTC
|
So, important history lesson/qualification:
https://dx.doi.org/10.1145%2F362929.362947
Considered harmful
Long story short: old languages didn't have good Loop Control or early return, so they needed goto. Perl has them, so you are probably doing something bad if you need to use it. So consider how you can refactor to avoid it. This is coming from a Fortran hacker, so this warning should not be taken lightly.
To do what you have asked, the code is:
#!/usr/bin/perl
use strict;
use warnings;
use 5.012;
my $gas_cost = 1.5;
if ($gas_cost < 1) {goto ENDING_BRACE };
say "Intermediate";
ENDING_BRACE:
say "After";
which appears to be your case 1, so I think you have transcribed your problem badly. I do not know what code you are trying to emulate, but I would probably write your code as:
{
last if $gas_cost < 1;
stuff here
}
continue here
or
func();
continue here;
sub func {
return if $gas_cost < 1;
stuff here
}
or even
if ($gas_cost >= 1) {
stuff here
}
continue here
Or a myriad of variations. The difference between your proposal and any of the above is only scoping, and that can be addressed as well if you share your real code with us.
You may also find How does 'goto LABEL' search for its label? informative.
#11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.
| [reply] [d/l] [select] |
Re: How to no goto or gosub
by Mr. Muskrat (Canon) on Jan 15, 2016 at 21:29 UTC
|
if ($gas_cost >= 1) {
... # stuff here
} else {
... # continue here
}
| [reply] [d/l] |
Re: How to no goto or gosub
by stevieb (Canon) on Jan 15, 2016 at 21:35 UTC
|
| [reply] |
Re: How to no goto or gosub
by CountZero (Bishop) on Jan 16, 2016 at 10:00 UTC
|
Difficult to answer as there is no clear question.Both your code examples are not equivalent and I'm pretty sure the second doesn't even do what you think it should be doing: it does NOT jump to "continue here" if the condition $gas_cost < 1 holds.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James My blog: Imperial Deltronics
| [reply] [d/l] |
Re: How to no goto or gosub
by shmem (Chancellor) on Jan 16, 2016 at 23:25 UTC
|
Up to date 12.04.
Say what? Is that a version number of something or April 12th? or December 4th?
if ($gas_cost < 1) {goto ENDING_BRACE };
stuff here
ENDING_BRACE:
continue here
Well, I'd reverse that and check for $gas_cost >= 1 and stuff stuff here into that conditional block. No ugly goto needed, no label needed:
if ($gas_cost >= 1) {
stuff here
}
continue
Probably stuff here can be tucked away into a subroutine. But...
Have tried variations and read myself into circles.
...it looks like you are coming from C and are trying to grasp the perl goto. Well, read it up.
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] [d/l] [select] |
Re: How to no goto or gosub
by ikegami (Patriarch) on Jan 18, 2016 at 14:23 UTC
|
Though very bad form, the first code you tried does work.
| [reply] |
Re: How to no goto or gosub
by RonW (Parson) on Jan 20, 2016 at 21:30 UTC
|
Others have suggested working code you could use. I am offering an explanation.
In Perl, calling a subroutine is not like gosub label. What you wrote as sub ENDING_BRACE; is, in Perl, what's called a "forward declaration". It does not define the subroutine, it merely tells the Perl compiler that you intend to define a subroutine named "ENDING_BRACE". Your code has no definition for ENDING_BRACE.
A possible definition might be:
sub ENDING_BRACE
{
# handle ending brace
}
But, in your code as written, If $gas_cost were less than 1, the code "handle ending brace" would be executed, then ENDING_BRACE would return control to where it was called, so then "stuff here" would be executed, which is not what you want.
| [reply] [d/l] [select] |