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

Re: Re: where do you put your subs

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


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

Subs at the top? Subs at the bottom? What's next? Should we discuss whether toilet paper should roll from the top or bottom? :-D Seriously, DeMerphq gives some excellent reasons why you might put your subs at the top, but I've also seen lots of good reasons why you'd want your subs at the bottom. 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. This makes perfect sense to me, as the order of events is:
use statements my $foo; # LOOK I'M A PACKAGE GLOBAL WOO HOO! 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.

But you know, that's what makes sense to me. Some people are completely allergic to () so they declare their subs first. I don't mind typing "foo()" so I don't care. If you don't like globals (and want to go whatever means necesary to keep from using them, either on purpose or accidentally) hey, more power to ya. I think they're kinda spiffy, and my code is brutally consistent as to how and when I declare them and use them.

All in all I think perlstyle is silent on this because it really is a matter of taste, and TMTOWTDI.

Perhaps next we'll discuss proper tab indentation. :-D

Gary Blackburn
Trained Killer

Replies are listed 'Best First'.
Re: Re: Re: where do you put your subs
by demerphq (Chancellor) on Mar 08, 2002 at 13:33 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.

    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

      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
        

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-04-24 05:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found