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

perltidy block indentation

by saltbreez (Novice)
on Dec 02, 2013 at 16:37 UTC ( [id://1065305]=perlquestion: print w/replies, xml ) Need Help??

saltbreez has asked for the wisdom of the Perl Monks concerning the following question:

I have a question on creating a (dot)perltidyrc file for an existing perl code base. The prevailing style must be replicated or the team will not adopt perltidy. This much I feel certain the perltidyrc file must contain: Uses tabs -et=n And newline braces -bli This is where I run into trouble: the code style does not indent new code in the block beyon the new brace ie:

sub old_code { my $self = shift; my $file = shift; if (-e $file) { open(my $fh, "<", $file) or die "cannot open < $file: $!"; # Do something with the file return 1; } else { die "$file not found"; } };

How do I create a perltdyrc file that will replicate this coding style? Thanks, Saltbreez

Replies are listed 'Best First'.
Re: perltidy block indentation
by kschwab (Vicar) on Dec 02, 2013 at 20:54 UTC

    I can't tell if the pasted code is the style you want, or the style that isn't working for you. Assuming the first, perltidy -bli -i=2 -et=2 produces something close to what you posted.

    For example:

    $ echo -e "sub testing\n{\nx=1;x++;if(1){\nx--;\n}\n}\n" | perltidy -b +li -i=2 -et=2 sub testing { x = 1; x++; if (1) { x--; } } $ echo -e "sub testing\n{\nx=1;x++;if(1){\nx--;\n}\n}\n" | perltidy -b +li -i=2 -et=2|hexdump -c 0000000 s u b t e s t i n g \n \t { \n \t 0000010 x = 1 ; \n \t x + + ; \n \t i f 0000020 ( 1 ) \n \t \t { \n \t \t x - - ; \n 0000030 \t \t } \n \t } \n \n

      Hey thanks kschwab (and everyone that responded), this did what I wanted it to do.

Re: perltidy block indentation
by atcroft (Abbot) on Dec 02, 2013 at 20:46 UTC

    While I am not quite sure I understand the formatting you are wanting from the illustration, my suggestion would be to look at the Perltidy Style Key, to see if it gives you an illustration of the formatting you want.

    Also, there is mention on the Perltidy site of a program called Tidyview, which apparently lets you test configuration changes on test code to see how they would apply.

    Hope that helps.

    Update: 2013-12-02 - Add comment about Tidyview program.

Re: perltidy block indentation
by Tux (Canon) on Dec 02, 2013 at 22:18 UTC

    Apart from the style, why do you have an else block after return. I understand that you want to give an example of the style you require, but there is more than style: there should *NEVER* be an else after return, exit or die. These three exit the surrounding scope immediately, so the code *after* else is never executed. Retaining your style, that code should read:

    sub old_code { my $self = shift; my $file = shift; if (-e $file) { open(my $fh, "<", $file) or die "cannot open < $file: $!"; # Do something with the file return 1; } die "$file not found"; };

    Which I would simplify to

    sub old_code { my $self = shift; my $file = shift; -e $file or die "$file not found"; open(my $fh, "<", $file) or die "cannot open < $file: $!"; # Do something with the file return 1; }

    Enjoy, Have FUN! H.Merijn
      there should *NEVER* be an else after return, exit or die

      I'm not trying to say that you're wrong, but I'm personally struggling to understand the logic/rationale behind your claim. Based on the responses from Bloodnok and marto, there appears to be a good valid reason for doing as you are suggesting. I guess I haven't learned enough about Perl (and/or its internals) to understand what this reason is. Can you help me by providing more info on the rationale behind your suggestion so that I (and possibly others) can better understand your suggestion?

      Based on my current levels of knowledge and experience with Perl, I see the OP's code and your suggested code as being logically equivalent -- as in, both codes produce the same result. If I were responsible for maintaining the code, I would prefer the OP's code because I personally find it easier to read and follow and it will be less likely to cause me to misread what the code is doing.

      Again, I'm not trying to challenge you on this. I'm just trying to understand the logic and reasoning behind your view on what I would describe as a "best practice".

        I'll try

        sub start_working_day { if ($me->is_sick) { return undef; } elsif ($wheather->raining) { $travel->use_car; } else { $travel->use_bike; } $travel->go; $work->do; return; }

        As you can see in this snippet, there are several expressions that control the start of a working day. After the if/elsif/else the real work starts, as it is the same for all situations: it is common code. Or is it? No it is not! When I am ill, the common code is never executed, so there is no reason whatsoever to have an else block: there is no need for an alternative, as there is no intent to run that common code.

        My stance is that a function or method should be written in a way that the most likely codepath is the easiest to follow with the eye. Exceptions should exit early.

        sub start_working_day { $me->is_sick and return undef; if ($wheather->raining) { $travel->use_car; } else { $travel->use_bike; } $travel->go; $work->do; return; }

        As you can now deduce, the code after the if/else is run for all cases of the decision tree, and hence reflects the thinking logic.


        Enjoy, Have FUN! H.Merijn
      I am a fan of early exit and despise else-like structure as presented in OP myself. I don't know, however, the problems during a program run that caused you to mention "... should *NEVER* be an else after return, exit or die". Would you care to explain (how does the syntax in OP cause problem when a program runs)?
        Whilst there are no run-time problems in the OPs' code per se, there are code static analysis tools e.g. B::Lint or Perl::Critic, that will complain/warn of unreachable code - of which the return statment in the OP is a perfect example, as described by Tux. This is best/most frequently addressed using the implied else construct - again something described in Tuxs' answer - in the 1st re-implemented code block.

        A user level that continues to overstate my experience :-))

      Well, thank you for that code review! Please note that your simplified code fails to communicate the style points I was seeking wisdom on...

        They said "Apart from the style", they're not addressing the style issue but a more serious aspect of the code you posted.

Re: perltidy block indentation
by GrandFather (Saint) on Dec 03, 2013 at 12:59 UTC

    Maybe of interest: this indentation style is often known as Whitesmiths style.

    If you dig through some of my earlier posts here you'll find I used it as my default style because that's what I'd been using (for preference) with C++ and had what I considered (and still do) to be good reasons for using. I've switched to K&R for Perl to "fit in" with the community, but use PerlTidy frequently. Actually I've got PerlTidy tuned so well to my adopted Perl style that aside from cleaning up line wraps it almost never alters my code. It takes some work to get PerlTidy fully tuned, but it is a wonderful tool and one good reason to use Perl if you care about consistent style. I haven't found anything near as good for C++ :-(.

    True laziness is hard work

      Now that was both interesting and useful. Thank you.

Re: perltidy block indentation
by Khen1950fx (Canon) on Dec 02, 2013 at 21:13 UTC
    This command should replicate the the old_code style:
    perltidy -lp -cti=4 -ci=4 -nicb -bli -st testfile.pl
Re: perltidy block indentation
by Anonymous Monk on Dec 02, 2013 at 23:33 UTC
    It sounds to me like you intend to "perltidy" large blocks of existing code. You probably don't want to do that because, as far as git (or subversion or CVS or ...) is concerned, "presto, almost all of the lines of source-code in this module have just changed." Except that they really didn't, other than cosmetically. Nevertheless, you have just cut-off the future from the past. You can't trace any change to a line-of-code that occurred after that "monumental tidiness" to any line-of-code that was changed before it. You can't revert any change. You're screwed.

      It doesn't have to be that big a deal. Make the change in one commit with no other code changes. If your existing style is consistent and PerlTidy is tuned well the number of changes will be fairly small in any case. If the number of changes is large that's a clue that your style across the code base is not consistent and may be a good driver for the switch to PerlTidy and enforced consistent style.

      I've not used git, but I understand it offers very similar tools to Mercurial that would allow you to track changes to a line of interest using the file history. A "cosmetic" change set marked as such in its commit message is easy to ignore.

      The big win for a team where style matters is that PerlTidy does an excellent job of formatting Perl and provides a great deal of control on exactly how style guides are provided.

      I use PerlTidy extensively and haven't found a case yet where it has generated broken code from good code. It is likely to work well as part of a pre-commit processing hook for a revision control system to ensure committed code meets team style guides - and that may well be worth the pain of one slightly disruptive commit for a team that has a serious commitment to following their own style guidelines.

      True laziness is hard work
Re: perltidy block indentation
by sundialsvc4 (Abbot) on Dec 03, 2013 at 16:08 UTC

    I worked with a team for a while which brought in a “tidy” function, and it was very quickly a version-control train wreck:   the filter made countless “little” changes to the source-code, triggering what the VCS saw to be a massive-change commit, whereas the code had not “changed.”   The VCS wasn’t language aware, and offhand I don’t know of one that is.

    The team switched to using PerlTidy as an Eclipse plug-in but only on new code, and even that really did not last long.   (The plug-in could tidy-up a highlighted block, which was nice.)   Once people got the hang of writing “tidy” code, they simply did it themselves for their new patches and so-forth.

    In the name of version-control continuity, there were two three house-rules:

    1. Even if it’s ugly or unsightly, leave it alone unless you are actually, meaningfully, changing something.
    2. Limit the scope of your change to what needs doing to get done the job-at-hand.   Don’t make gratuitous source-changes that are not clearly related to the ticket / change-order being worked-on.
    3. Don’t be clever, e.g. in the name of “efficiency.”   Just be clear.   map and grep chains, for example, were generally verboten, because that leads to tightly-coupled code that is hard to revise, and so on.   Even a “tidy-fied” version of hard-to-understand or hard-to-change code is still ... hard to understand and hard to change.   The code was meant to be easily understood “at a glance,” and that entails far more than indentation and capitalization.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1065305]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2024-03-19 05:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found