Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

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

by demerphq (Chancellor)
on Mar 08, 2002 at 13:33 UTC ( [id://150307]=note: print w/replies, xml ) Need Help??


in reply to 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.

The "unintended global" problem is often a feature, not a bug: yes, I do use global variables (judiciously, and deliberately, and with full knowledge of what I'm doing) and when I do I declare them... at the top of my program.

Then how can you call them "unintended globals"? The point I was making is that a programmer might think that by making lexical declarations in file scoped main that those lexicals are private to the main code. But they _arent_. Whereas what you are talking about is a proper global variable declaration which belongs (if they must be used) as you say at the top. BTW the code snippet you posted has a misnomer

use statements my $foo; # LOOK I'M A PACKAGE GLOBAL WOO HOO! (wrong) # NO ITS NOT ITS A FILE SCOPED LEXICAL # PRETENDING TO BE A PACKAGE GLOBAL main loop/program logic subs
The subs are all black boxes (mostly, except where they use the package globals), which means (in my mind) it shouldn't make the slightest bit of difference where they appear in code order. They aren't executed "in order" so order becomes immaterial.

On face value I agree with you. Properly written it shouldn't matter. But the issue here is best practice. And best practice should be oriented towards whatever minimizes the chance of error, especially anoying hard to trace errors like the 'unintended globals' that I mentioned before. I have no issue if someone wants and specifically uses globals. But shouldnt have to guess that they are globals and that they are intentional. It is for these types of reasons that various rules of thumb (consult tillys homenode and nodes for various lists of them, and a link to good books on this subject) have developed. These rules are not set in stone but are followed by the vast majority of professional programmers because they do minimze the possibility of error in the long run. (Examples would be that code should be indented (heh you mentioned that facetiously and here I am addressing it seriously) between 2 and 8 spaces, with the optimal being 4 spaces, trying to ensure that subroutines are no more than 1 page long, putting short parts of a conditional before the long part.)

I think that perlstyle avoid this becuase the level of programmer it was intended for is expected to know of these conventions and issues to make an educated decison (as you have, all the credit to you) as to how they wish to procede. Howeve this site has monks of every level of expertise and accordingly it is a responsibility (IMO) of those of us with the expertise to proscribe best practice and not our personal preference. When the newbies know enough to argue they probably wont argue becuase they'll know th reasons why we are saying what we are saying to the newbies...

Cheers,

Yves / DeMerphq
--
When to use Prototypes?
Advanced Sorting - GRT - Guttman Rosler Transform

Replies are listed 'Best First'.
Re: Re: Re: Re: where do you put your subs
by Trimbach (Curate) on Mar 08, 2002 at 15:24 UTC
    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

      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://150307]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (3)
As of 2024-03-29 07:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found