A long time ago, in a node far, far away, a fellow Monk pointed me at the Perlish Coding Style. For those not familiar, the PCS is all about having a left column that clearly indicates program structure. To shamelessly steal the first example from the site above:

; sub capture (&;*) { my $code = shift ; my $fh = shift || select ; local $output ; no strict 'refs' ; if ( my $to = tied *$fh ) { my $tc = ref $to ; bless $to, __PACKAGE__ ; &{$code}() ; bless $to, $tc } else { tie *$fh , __PACKAGE__ ; &{$code}() ; untie *$fh } ; \$output }

Certain things about this appeal to me, but I can't help thinking "I'd never use this for published code", and the proponent of this style agrees with me. However, I have found one piece -- the idea of the semicolon as a separator rather than a terminator -- to be useful when debugging.

Essentially, I use the leading-punctuation style encouraged in PCS to mark code that's inserted for debugging purposes:

use strict; use warnings; use XML::Simple; ; use Data::Dumper::Simple; my $struct = XMLin('test.xml'); ; print Dumper($struct); if (defined $struct) { my $result_set = process_data($struct); ; print Dumper($result_set); send($result_set); } #...

Note how debugging lines stand out, but no change to indenting is required. Of course, you'll note that instead of putting the semicolon only in front like PCS, I "sandwich" the statements -- this is necessary, and is in fact easier since I'm used to ending lines with semicolons anyhow.

The additional advantage to this is that debugging statements can be programatically filtered out:

perl -ne 'next if m{^\s*;\s*[^#]}; print $_' debugging.pl > stripped.p +l

Of course, one has to be a little more careful about heredocs:

print <<HEREDOC Some lines go here HEREDOC ; #this would be filtered out if I didn't leave a comment

Thoughts?

<-radiant.matrix->
A collection of thoughts and links from the minds of geeks
The Code that can be seen is not the true Code
I haven't found a problem yet that can't be solved by a well-placed trebuchet

Replies are listed 'Best First'.
Re: Perlish Debugging Style
by BrowserUk (Patriarch) on Mar 01, 2006 at 19:20 UTC

    Have you looked at Smart::Comments?

    C:\test>perl use strict; use warnings; use XML::Simple; use Smart::Comments; sub process_data{ return @_ } sub send{ ### Entering send... ### Exiting send... } my $struct = XMLin('test.xml'); ### $struct if (defined $struct) { my $result_set = process_data($struct); ### $result_set &send($result_set); } ^Z ### $struct: { ### base => 'http://www.google.com' ### } ### $result_set: 1 ### Entering send... ### Exiting send...

    It even loads Data::Dumper for you, and to completely remove all the debug code, you simple comment out the use Smart::Commant; line. It does a whole lot more besides and avoids the problems with heredocs and the __DATA__ section.

    I'm not keen on it retaining the ### marks in the output, and I would prefer a simple numeric argument to indicate which levels I want traced, but it's (IMO) the perfect use for source filters.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Perlish Debugging Style
by diotalevi (Canon) on Mar 01, 2006 at 19:21 UTC

    You've just reinvented Smart::Comments but in a style that looks like lisp/assembly comments to me. It's really confusing to have leading semi-colons because I'm so used to that having meaning in other languages.

    use Smart::Comments; use strict; use warnings; use XML::Simple; use if $ENV{DEBUG}, 'Smart::Comments'; my $struct = XMLin('test.xml'); ### $struct; if (defined $struct) { my $result_set = process_data($struct); ### $result_set; send($result_set); } #...

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      I'm confused.

      Why is there both

      use Smart::Comments;
      and

      use if $ENV{DEBUG},'Smart::Comments';

      I thought the "if" module did conditional inclusion of another module; but you've already included "Smart::Comments" at the beginning, haven't you? Or am I missing something clever?(I probably am :-( ).

      --
      Ytrew

        It's a thinko. I saw only one at a time.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      BrowserUk had a similar comment, so please consider this a response to both your remarks.

      Smart::Comments is cool -- I hadn't seen that before. It does satisfy a similar itch, but not the *same* itch. My interest is not in having debugging code that only runs while I'm in debugging mode (though there are times when I want that, and Smart::Comments will scratch that itch nicely).

      Instead, my interest is solely in being able to add temporary code which will be physically removed from the source -- whether programatically or not -- before it is released to anyone. It's a stylistic question, and that's all. Many people marks such temporary lines of code by outdenting, surrounding them with special comments, using DEBUG: { } style labeled blocks, etc. Whatever works, you should use. The purpose of the Meditation is a style of highlighting this type of code visually that I've found interesting, with the hope that others who think in a similar way will benefit.

      So, when you say "It's really confusing to have leading semi-colons because I'm so used to that having meaning in other languages.", my only real response is: this meditation is not for you then, use whatever works for you. In fact, I was sort of hoping that other people would share their preferred style for such things.

      Just to be painfully clear, since I get the feeling people are reading more into this meditation than intended: this is not a suggestion for a standard, an assumption that this is better than any other method, etc., nor am I suggesting that these lines be left in any code that is shared with other people.

      I hope that clears things up a bit. ;-) But thank you for pointing me at Smart::Comments, as that will be useful to me for conditional debugging code I *do* want left in.

      <-radiant.matrix->
      A collection of thoughts and links from the minds of geeks
      The Code that can be seen is not the true Code
      I haven't found a problem yet that can't be solved by a well-placed trebuchet

        Well... then pass your source through a s/^\s*#{3,}.+/mg filter. You get Smart::Comments *and* you get your redacted distribution. I'd just as soon leave the Smart Comments in there though. You can get better bug reports that way.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re: Perlish Debugging Style
by merlyn (Sage) on Mar 02, 2006 at 01:41 UTC
    I won't comment on the so-called "perlish" style in general, except to make a loud gagging sound and mutter "over my dead body".

    However, I don't know why you don't write:

    print <<HEREDOC Some lines go here HEREDOC ; #this would be filtered out if I didn't leave a comment
    as merely
    print <<HEREDOC; Some lines go here HEREDOC
    The lone semicolon would scare me, and likely get edited away.

    Keep in mind that the heredoc indicator is standing in for a complete string at the given location. For example:

    print <<DOUBLE_QUOTED . <<'SINGLE_QUOTED' . <<DOUBLE_QUOTED_AGAIN; This stuff is double quoted so I can see my $ENV{HOME} for home. DOUBLE_QUOTED This stuff is single quoted. I can make $10 really fast! SINGLE_QUOTED This stuff is also double quoted now. \a \a \a ding ding ding! DOUBLE_QUOTED_AGAIN
    The statement acts as if I had said:
    print "XXX" . 'YYY' . "ZZZ";
    With XXX, YYY, and ZZZ being replaced literally with the following lines not counting the ending delimiter.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      To be clear, I agree with your HEREDOC style, but I've seen many instances of the lone, trailing HEREDOC.

      Also, in response to:

      I won't comment on the so-called "perlish" style in general, except to make a loud gagging sound and mutter "over my dead body".
      I wish to reiterate that I would never allow these into code I release to anyone -- it's only to mark statements I want to remove later in a way that's (a)easy to manage programmatically {as compared to, say, indentation changes}, yet (b)provides visual distinction.
      <-radiant.matrix->
      A collection of thoughts and links from the minds of geeks
      The Code that can be seen is not the true Code
      I haven't found a problem yet that can't be solved by a well-placed trebuchet
Re: Perlish Debugging Style
by samizdat (Vicar) on Mar 01, 2006 at 17:23 UTC
    My assembly language days have me thinking "now why is he commenting out all those lines of code...?" Bringing my Perl brain cells back on line, I'd say that the tiny decrease in interpreter speed is well worth it for the additional clarity of delineating debugging code. radiantmatrix++

    Don Wilde
    "There's more than one level to any answer."
      What tiny decrease? Once its compiled, the empty statements don't show up anymore. Or do you mean compilation speed?
        Initial parse, yes.

        Don Wilde
        "There's more than one level to any answer."
Re: Perlish Debugging Style
by duckyd (Hermit) on Mar 03, 2006 at 00:11 UTC
    I would be wary of thinking it's so easy to filter out such lines, consider
    my $foo =~ m{ # match things between ;;s ; (.+) ; }x;