Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Re: Double your return!!!!

by schweini (Friar)
on Feb 19, 2003 at 06:16 UTC ( #236553=note: print w/replies, xml ) Need Help??

in reply to Double your return!!!!

Actually, i was looking for the same thing a while ago (didn't find anything)
i'm a bit surprised that everybody's soooo against thing thing. i, for one, have a Tk script littered with
sub bar { $foo = askFor( title => 'Name:' ); return undef if not defined $foo; $baz = askFor( title => 'Cigarettes:' ); return undef if not defined $baz; }
stuff. &askFor simpy pops up an entry form that offers a 'cancel', which MUST cancel the caller (&bar), so for me a double-return would be great. (a significant portion of my code is starting to be this dumb "return if .." thing
but i always remember that i started of with BASIC, and am therefore not able to grasp the horrendous evilness of this (someone once pointed out that a double return would be a GOTOism (which would be bad)).
could someone explain why this would lead to spaghetti code, and other nasty stuff?
(i'm really afraid that i'm doing things now that'll make me loose my hair in a week)

Replies are listed 'Best First'.
Re^2: Double your return!!!!
by Aristotle (Chancellor) on Feb 19, 2003 at 07:01 UTC
    Boolean logic is your friend.
    return undef unless defined($name = askFor(title => 'Name:')) and defined($cigs = askFor(title => 'Cigarettes:'));
    That return undef should probably be a plain return, unless Tk is as fastidious about return values as GtkPerl.

    Makeshifts last the longest.

      okay, i don't consider my self very 'leet, but - just to defend my honor (my parents could read this someday! :-), i DO know and.
      that one doesn't really help a lot, because then my whole script would consist of a gigantic concatenation of and clauses.
      besides - mea maxima culpa - i actually do stuff in between my user interaction things, so that one wouldn't work (should've showed that, though)

      thanks for the tip, though!

      by the way: what is the voting etiquette for situations like this? if i were an even bloodier newbie than i am, this one would have helped, and it's really nice of you to help me this way - OTOH, it didn't really help ME, and is a rather...ermm..."banal" thing (really no offense!).
      i'll ++ it, but i was just wondering how "valuable" votes are....

      kali nixta kai evxaristo
      (pardon the horrific ASCII-sation :-)
        You could still do something like
        return undef unless defined $name = askFor(title => 'Name:'); # do stuff with $name return undef unless defined $cigs = askFor(title => 'Cigarettes:'); # do stuff with $cigs # ...
        That would at least reduce your two statements to a single one. If you really insist on a "double return" you need to do something like this:
        sub askFor { # ... die if $pressed_cancel; # ... } # ... eval { $name = askFor(title => 'Name:'); # do stuff with $name $cigs = askFor(title => 'Cigarettes:'); # do stuff with $cigs }
        which, incidentally, is really the standard idiom for such cases (think DBI). Another option might be to change your askFor() so that it assigns the result itself and returns whether or not it succeeded:
        sub askFor { # ... return if $pressed_cancel; ${$arg{Var}} = $user_input; } # ... return unless askFor(title => 'Name:', Var => \$name); # do stuff with $name return unless askFor(title => 'Cigarettes:', Var => \$cigs); # do stuff with $cigs

        Plenty of ways to do what you want, really.

        Oh, and about the voting - don't sweat it. Who cares.

        Makeshifts last the longest.

Re: Re: Double your return!!!!
by pfaut (Priest) on Feb 19, 2003 at 15:01 UTC

    A called routine should not make any assumptions about the routine that called it, or the routine that called that routine, etc. As stated in the base node, if you really want to do this, the proper way would be some kind of exception signalling mechanism.

    Here's your little snippet.

    sub bar { $foo = askFor( title => 'Name:' ); return undef if not defined $foo; $baz = askFor( title => 'Cigarettes:' ); return undef if not defined $baz; }

    Now, I doubt very much that the whole point of this subroutine was to ask for a couple of pieces of information and throw them away. So, there would probably be some code after the second return that actually does something with $foo and $baz.

    Suppose there were a couple of other places in your program that needed to ask for these pieces of information. Instead of having those four lines all over your code, you decide to refactor and make a separate subroutine called getFooAndBaz() to ask for those values. Does askFor() now have to jump three call frames? Why should it care what path was taken to call it? How does that affect the procedure that calls askFor() directly?

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
      I wasn't seriously suggesting this as useful code.

      I intended the question more as a perl puzzle that I couldn't solve. The code was only to illustrate the question and the critical text was is it possible?

      Reading the responses and re-reading my initial post I obviously didn't make my intention clear enough.

      Sometimes though, a joke or japh ends up being useful.

      I don't think Quantum::Superpositions was intended seriously yet junctions (or whatever the name is now) is going to be in perl6.

        Not possible in perl5 AFAIK.

        Since parrot is supposed to support continuations something like this might be possible in perl6 I guess.

        I know of one language that supports the idiom. Pop-11 has chainfrom, chainto, exitto and exitfrom which cover the full gamut of exit variations. However, apart from using chainto to optimise tail recursion I've never used them in "real" code :-)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://236553]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2020-05-25 02:18 GMT
Find Nodes?
    Voting Booth?
    If programming languages were movie genres, Perl would be:

    Results (143 votes). Check out past polls.