Re: bloated 'if' formatting
by BaldPenguin (Friar) on Oct 05, 2005 at 18:49 UTC
|
| [reply] |
Re: bloated 'if' formatting
by GrandFather (Saint) on Oct 05, 2005 at 18:50 UTC
|
if (
condition &&
condition &&
condition
)
{
...
}
unless the conditions were long in which case I'd migrate (all) the &&s to the start of the lines in similar fashion to your sample.
However that only slightly impinges on the real problem that you mention: many indentation levels. That is something that I try hard to avoid. Often early exits from a block, using modifiers and using subs can clean up mega-nesting. If not, be very consistent in your chosen style of indentation because if you're not then things get very nasty very quickly!
Perl is Huffman encoded by design.
| [reply] [d/l] |
Re: bloated 'if' formatting
by Skeeve (Parson) on Oct 05, 2005 at 18:53 UTC
|
I would not press tab after the '(' and would indent the following lins with as many tabs as are before 'if' followed by 5 spaces. So replacing a space with . here and setting a > where a tab would be:
> > if ( condition
> > .....&& condition
> > .....&& condition
> > .....xxx
> > ) {
> > > statements;
> > }
I'd do this just because one can never be sure about the tabsize someone else might use later.
OTOH: I tend to include jEdit buffer options that will others give at least a chance to set the tabs I used when creating my files.
$\=~s;s*.*;q^|D9JYJ^^qq^\//\\\///^;ex;print
| [reply] [d/l] [select] |
Re: bloated 'if' formatting
by pg (Canon) on Oct 05, 2005 at 19:02 UTC
|
"This file has many indentation levels"
Excessive indentation is often an indication of poor modulization. It might worth the time for you to further modulize it, otherwise you will carry other people's baggage for a long time ;-)
| [reply] |
Re: bloated 'if' formatting
by Nkuvu (Priest) on Oct 05, 2005 at 19:39 UTC
|
In my opinion, tabs == bad. Personally I use spaces for alignment (unless we're talking word processing, when it's likely that the font being used is not monospace).
As far as aligning the conditions above, I'm not sure if you're asking about indenting with tabs, or aligning the conditions vertically (no matter how you indent). Aligning the conditions vertically really depends on the length and complexity of said conditions. For example:
# Short conditions, I wouldn't align vertically:
if ($foo && $bar && $bat && $waffles) {
statements();
}
# Long or complex conditions, I would align vertically
# (also personally prefer binary operators at the end
# of the line rather than the beginning):
if (some_long_conditions_go_here() &&
another_one_down_here($foo) &&
($foo || $bar) &&
I_think_you_get_what_I_am_saying()) {
statements();
}
| [reply] [d/l] |
|
|
Not to start a format war, but I've never understood the tabs == bad camp. There are times when using tabs is foolish (mostly, intra-line aligntment), for example:
$opt_a = 1; # this is option a
$obt_hoo = 1; # this is option b
All the whitespace there should be spaces, not tabs.
On the other hand, I love it when code I maintain uses tabs for leftmost indentation. This is because I know many people who like an 8-space indent, where as I (for example), much prefer a 4-space indent. I have colleagues that also like a 2-space indent (!). By using tabs for left-side indents, we can all have our way by simply configuring our editor.
What's the argument against doing this?
In the case at hand, I would do:
if (
condition 1
&& condition 2
&& condition 3
...
) {
code to be executed
} #/ short desc of if code, if needed.
else {
else-block code
} #/ short desc of else code, if needed.
| [reply] [d/l] [select] |
|
|
I have to admit, the primary reason I dislike tabs is because most of the time I find tabs in a file, they're mixed in with spaces. So you get inconsistent indentation, based on tab widths. I've also seen too many instances of tabs in intra-line alignment, as you mentioned. Depending on tab widths, the columns may or may not line up.
Since I've seen more misuses of tabs than decent uses of tabs, it's pretty easy to pigeonhole them into the "bad style" camp. It's really a very mild dislike, to tell the truth.
And personally I prefer a 4 space indent for real code (i.e., code in my editor) but often I'll drop that to a 2 space indent when posting code online.
| [reply] |
|
|
That's a nice idea, but that would only work if windows aren't bounded horizontally. Think about it.
Suppose you are using a 4-character indent. You are using tabs for indentation, using a 4 character tabstop. Inside a subroutine you have an for loop, and inside its body you have a 66 character statement. On your screen, the line ends in column 74.
Now you give the code to someone who also uses 4 character wide indent, but he's using holding to the old mantra "don't change your tabstops" - his tabstops are 8 characters. Now the code he looks at not only has indents much wider than he's used to, the line that ended in column 74 on your screen will end in column 82 on his screen. Which, given a standard width of 80 characters means the code will be wrapped.
Tabs are evil, and tabstops other than 8 even more so. But if everyone is using tabstops of the same length, you might as well use spaces.
| [reply] |
|
|
Re: bloated 'if' formatting
by BrowserUk (Patriarch) on Oct 05, 2005 at 19:57 UTC
|
if( cond1
and cond2
and cond3
and cond4
){
statements;
}
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".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] [d/l] |
Re: bloated 'if' formatting
by runrig (Abbot) on Oct 05, 2005 at 20:00 UTC
|
perltidy would do it more like this (I have -i=2):
if ( some_horribly_long_thing()
&& some_horribly_long_thing()
&& some_horribly_long_thing()
&& some_horribly_long_thing()
&& some_horribly_long_thing() )
{
do_something();
}
I could live with that, though I think I might prefer:#!/usr/bin/perl
if (
some_horribly_long_thing() &&
some_horribly_long_thing() &&
some_horribly_long_thing() &&
some_horribly_long_thing() &&
some_horribly_long_thing()
) {
do_something();
}
| [reply] [d/l] [select] |
Re: bloated 'if' formatting
by jdporter (Paladin) on Oct 05, 2005 at 20:21 UTC
|
When I was a C coder I used to prefer
if ( condition
&& condition
&& condition
)
# because I like the conditions all to line up on the left.
But now, if the conditions are particularly chunky, I have no qualms about doing
if (
condition
&&
condition
&&
condition
)
| [reply] [d/l] [select] |
Re: bloated 'if' formatting
by eff_i_g (Curate) on Oct 05, 2005 at 20:33 UTC
|
Thanks for the feedback :)
Clever alignment via the ands BrowserUK; and Nkuvu, I like not breaking the ) { and adding an extra line as you did; however, for the sake of maintenance, I believe I will go with:
if ( condition
&& condition
&& condition ...
) {
# stuff;
}
| [reply] [d/l] |
Re: bloated 'if' formatting (nested)
by tye (Sage) on Oct 05, 2005 at 22:16 UTC
|
I fairly recently (months ago) finally stumbled upon an indentation format that I actually liked for conditionals, instead of the many different ones that I'd used over the years that all didn't work well in some situations (didn't "scale" well). I've had the chance to use it for a large variety of situations and I like it even more.
It is mostly the same as what appears to be the most common style in this thread. The possible difference is when you have more complex expressions. I like spacing to make code easier to understand. I try to avoid complex conditional expressions, by breaking them up when possible. But, sometimes, a fairly complex expression makes sense (especially when you want a chain of elsifs, which makes splitting up a conditional more distruptive to the flow).
Here is a fairly worst-case example (based on actual code):
} elsif( StatusEvent::CONNECT_FAILED
== $status->GetStateTransition()
&& CONNECT_TYPE_AUTO != $status->GetConnectType()
|| StatusEvent::DISCONNECTED
== $status->GetStateTransition()
&& ( $IsAutoConnectDisabled
|| 0 == $statusNotAuto->GetTotalCount() )
&& $statusNotAuto->GetTotalCount()
== statusNotAuto->GetIdleCount()
) {
The indentation makes it easy to successively break down the expression. You can see the two main chunks of the expression separated by the left-most ||. Looking at each chunk, you see the two or three chunks separated by &&s. etc. Indentation corresponds to nesting level (as is done for most types of indentation).
You can treat the == operators the same as the logical operators and get this:
} elsif( StatusEvent::CONNECT_FAILED
== $status->GetStateTransition()
&& CONNECT_TYPE_AUTO != $status->GetConnectType()
|| StatusEvent::DISCONNECTED
== $status->GetStateTransition()
&& ( $IsAutoConnectDisabled
|| 0 == $statusNotAuto->GetTotalCount() )
&& $statusNotAuto->GetTotalCount()
== statusNotAuto->GetIdleCount()
) {
And how you cuddle the "}", "elsif(", ")", and "{" offers many WTDI that I see various trade-offs among; lots of room for personal style variations.
Anyway, you asked. (: Enjoy what style you pick (whether it includes parts of the above or not) and can get your cohorts to tolerate.
| [reply] [d/l] [select] |
Re: bloated 'if' formatting
by dragonchild (Archbishop) on Oct 06, 2005 at 01:43 UTC
|
if ( A
&& B
&& C
) {
}
should be rewritten as
if ( is_AB( @stuff ) && is_C( @stuff ) ) {
}
sub is_AB {
my @stuff = @_;
return A && B;
}
sub is_C {
my @stuff = @_;
return C;
Even better would be using some set of useful objects that provide a useful interface for you.
Before anyone replies, please note that I'm saying "Decompose better and design with interfaces in mind." In other words, having read PBP, I'm agreeing with Damian's statements on the process of design. Not enough coders actually spend the 15 minutes to think through how the various pieces of their code are going to interact and then spend another 15 minutes diagramming out the separation of concerns. Long conditionals are a very smelly way of finding out that you don't understand the process you're attempting to have a computer do for you.
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [d/l] [select] |
Re: bloated 'if' formatting
by Perl Mouse (Chaplain) on Oct 06, 2005 at 05:14 UTC
|
if (condition && condition && condition) {
...
}
if (condition &&
condition &&
condition) {
...
}
if (condition
&& condition
&& condition) {
...
}
I typically use the first if it's short and fits on
one line. I choose between the latter two depending on
the phase of the moon, or the number of times my cat purrs.
Sometimes, I write:
if (condition && condition &&
and_a_very_long_condition) {
...
}
| [reply] [d/l] [select] |
|
|
if (condition &&
condition &&
condition) {
code
}
But I didn't like the effect of conditions having the same indentation level as the subsequent code (since I also use 4 column indenting), making it difficult to discern the condition from the code, at least at a first sight. So from now on, I think I'll use the other construct:
if (condition
&& condition
&& condition) {
code
}
that was unknown to me :^).
| [reply] [d/l] [select] |
Re: bloated 'if' formatting
by wfsp (Abbot) on Oct 06, 2005 at 05:47 UTC
|
I have settled on reducing horizontal indentation (code creeping across the screen) by using more vertical indentation.
if (
condition1 or
condition2 or
condition3
)
{
# do something
}
elsif (
condition4 or
condition5
)
{
# do something else
}
I like the top down feel this approach gives me.
As has been mentioned already, if the code does start creeping across more than, say, 3 'levels of indentation' it almost certainly means it'd be better off being rewritten. I can't hold that many levels of a process/sub processes in my head at a time.
I often take a similar approach to functions/objects. An extreme example:
open(
my $fh,
'<',
'text.txt',
) or die "died";
Down is better than across :-)
| [reply] [d/l] [select] |
|
|
The beauty of an if statement is that if you write if (condition), the condition starts 4 columns further to the right of the start of the if. Which, given a 4-character indent (quite common, and that's what I use) is exactly the same as indenting one level.... (well, at least for me).
| [reply] |
Re: bloated 'if' formatting
by revdiablo (Prior) on Oct 06, 2005 at 10:13 UTC
|
In cases of similarly convoluted conditionals, I usually go the route of creating self-documenting variables to store the value. I know this may trigger some Monks' "flag variables are evil" detector, but I think they're justified in [certain] cases like this:
my $foo_is_ready = (foo1 && foo2)
|| (foo3 && bar1 && baz1);
if ($foo_is_ready) {
...
}
I think it makes the actual if statement read a lot cleaner, and it gives future maintenance programmers an idea of what the condition actually is. You can even take it a step further and break up the condition into subconditions:
my $first_foo = foo1 && foo2;
my $second_foo = foo3 && bar1 && baz1;
my $foo_is_ready = $first_foo || $second_foo;
if ($foo_is_ready) {
...
}
Of course you run the risk of going overboard here, but I think the technique can be used to good effect.
Update: clarified to avoid confusion over example vs general idea. | [reply] [d/l] [select] |
|
|
From a maintainance perspective, this is the very worst thing to do. You are creating the situation whereby the setting of your flags becomes divorced from the if statement through the injection of code or during refactoring.
In your second version you have created at least half a dozen chances for errors to creep in that are not present in the original compound statement.
Take a browse at Code Smell and you'll find that you are violating many of those principles. They are only hints and guidelines, and in the end it is your code and your judgement, but you might find the read interesting anyway.
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".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
| [reply] |
|
|
You are creating the situation whereby the setting of your flags becomes divorced from the if statement through the injection of code or during refactoring.
This is a risk you always take when you break something up into multiple statements. If you can't rely on later development to keep related lines of code together, then there are greater issues to worry about. I think writing simple, clear code is one of the best ways to help maintenance, and shoving a complex condition into one statement is not always simple and clear.
That said, I'm not entirely sure the examples I used -- or those given in the original post -- are quite complex enough to benefit from this type of thing. That's why they're examples, and not actual code. There comes a point when the purpose of a condition gets lost amongst the noise, though, and that's when my advice comes into play.
Take a browse at Code Smell and you'll find that you are violating many of those principles.
I'm curious which code smell you think I'm, er, smelling of? They cover quite a wide range of different problems, so it's a bit difficult to talk about "code smells" as a whole.
| [reply] |
|
|
|
|
|
|
|
Re: bloated 'if' formatting
by ambrus (Abbot) on Oct 06, 2005 at 17:52 UTC
|
Use whatever formatting you want, but I use
condition1 &&
condition2 &&
condition3 and do {
statement1;
statement2;
}
Or, if there's only one statement,
condition1 &&
condition2 &&
condition3 and
statement;
| [reply] [d/l] [select] |