Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: Re: Re: Re: where do you put your subs

by Trimbach (Curate)
on Mar 08, 2002 at 15:24 UTC ( [id://150342]=note: print w/replies, xml ) Need Help??


in reply to Re: Re: Re: where do you put your subs
in thread where do you put your subs

but I've also seen lots of good reasons why you'd want your subs at the bottom.

Really? But you dont list any.

1. It's easier to read. (IMHO)
2. It's easier to debug (this follows from #1. Again, IMHO)
3. It matches the way by brain thinks.

To elaborate, I really like the allusion to programming to writing prose. Compare this:

#!/usr/bin/perl; a_man_walks_into_a_bar(); man_says("Hello"); bartender_says("What'll ya have?"); man_says("Sasparilla. In a dirty glass"); exit; ### SUBS FOLLOW ### sub a_man_walks_into_a_bar { ... many lines of code } sub man_says { ... many lines of code } sub bartender_says { ... many more lines of code }
with this...
#!/usr/bin/perl; sub a_man_walks_into_a_bar { ... many lines of code } sub man_says { ... many lines of code } sub bartender_says { ... many more lines of code } a_man_walks_into_a_bar; man_says("Hello"); bartender_says("What'll ya have?"); man_says("Sasparilla. In a dirty glass"); exit;
I don't know about you, but in the second example I'm NOT going to read the subs first... I'm going to scroll down (...down down down down) till I get to the good bits. Then I'm going to scroll back up (...up up up) to reference the subs. The subs don't have any context until I've seen the main logic, so I want the main logic (like the main story line) to be the first thing I see.

This gets worse when you wanna declare a global, which means you'd have to either:

my $foo; ... zillions of lines of subs ... followed by your main logic
...which in itself violates the "always put your variable declarations close to variable usage" rule, or
... zillions of lines of subs our $foo; or use vars qw($foo); ... followed by your main logic
...which solves that problem, but might have other consequences.
BTW the code snippet you posted has a misnomer...
Yeah, you're right. I don't write a lot of code that changes the package in the same file (I prefer separate files for separate packages) so file-scoped-lexicals-declared-at-the-top-of-a-file act virtually identically to package-globals-when-the-package-is-Main. My bad. :-D

I completely agree that newbie advice ought to be "best practices" but I'm not sure this is one of them, especially when there doesn't seem to be universal accord as to what's right. Even Merlyn puts his subs last in his Web Techniques columns, which are deliberately aimed at instructing others on how to do things the right way. If there's a "best practice" here I think it's "put all your subs together and all your logic together" to prevent some bozo from thinking

sub foo { ... } program logic sub bar { ... } more program logic
is a good idea. (Hey, there's probably someone out there like that. :-D)

Gary Blackburn
Trained Killer

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: where do you put your subs
by Juerd (Abbot) on Mar 08, 2002 at 16:04 UTC
    You find having ALL variables used outside subs shared EASIER TO DEBUG? Might be the case for simple CGI scripts, or programs of which the entire source fits on a single screen, but it has bitten many people.

    Even Merlyn puts his subs last in his Web Techniques columns, which are deliberately aimed at instructing others on how to do things the right way.

    And I think merlyn does it the wrong way. Besides, what merlyn does isn't automatically the right way to do it. Actually, I find much of his code written in an awful style, but I guess he'd say the same when reading my code. (OTOH, it's really hard to have good style when you're writing simple stand-alone web applications.)

    As for the program logic you describe at the end of your post, I've seen real good, and very stylish programs like this:
    my $qwerty; # Description { my ($foo, $bar); code; code; code; } # And now we're going to ... { my ($xyzzy); code; code; } # Etcetera... { code; code; code; }
    , which is great to look at, easy to read and very maintaible. You could do the same with a lot of closures, and thus bundle subs with the location of use.

    44696420796F7520732F2F2F65206F
    7220756E7061636B3F202F6D736720
    6D6521203A29202D2D204A75657264
    

      And I think merlyn does it the wrong way. Besides, what merlyn does isn't automatically the right way to do it. Actually, I find much of his code written in an awful style, but I guess he'd say the same when reading my code.
      Ah, then that's the point now, isn't it... there's enough difference of opinion that it's hard to say who's "right".
      As for the program logic you describe at the end of your post, I've seen real good, and very stylish programs like this:
      Yeah, so have I... I really like the block enclosure style, but now we're not talking about subs anymore. The flow of the program is still linear in your example, and is perfectly fine in my book. When you intersperse subroutines in with logic then your program execution stops being linear and becomes non-linear, meaning you're bouncing around all over the place trying to read the dang thing. Not good. And if you're going to bundle your subs with location of use, and wrap the whole thing in a closure, you probably ought to be changing packages, too. ;-D

      Gary Blackburn
      Trained Killer

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2024-04-19 11:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found