Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Re: Burned by precedence rules

by Herkum (Parson)
on Dec 23, 2008 at 15:37 UTC ( #732310=note: print w/replies, xml ) Need Help??

in reply to Burned by precedence rules

I like to use and and not in my code, but as JavaFan pointed out, they have a lower precedence. So I find it best to address this by taking the same approach. I always use a if operator and usually have at least 2 return calls. I find it is clearer what I intended to return as a valid value.

sub done { my $self = shift; return 1 if not $self->foo and not $self->bar; return; }

Replies are listed 'Best First'.
Re^2: Burned by precedence rules
by GrandFather (Sage) on Dec 26, 2008 at 04:50 UTC

    Many would find that better expressed as:

    sub done { my $self = shift; return 1 unless $self->foo or $self->bar; return; }

    because it avoids the two negations which confuse the meaning of the and.

    I used to avoid using unless, partly because none of the other languages I've used have had such a thing, but where it drops out a layer of negation I find it helps clean up intent quite nicely.

    Perl's payment curve coincides with its learning curve.
      I disagree strongly with many people then.

      When we are debugging we do not reliably do De Morgan's laws in our head. I heard this a long time ago and did not believe it until one particularly frustrating debugging session. Ever since then I've avoided using unless with any kind of logic at all no matter how nicely it reads while I'm coding.

        I absolutly agree that unless often becomes very confusing with more than one element in the condition and almost always use if in that case.

        I'm in (southern hemisphere) holiday mode at the moment so my head isn't fully in Perl space. I focused on the two nots rather than the 'and' and actually in the specific case given I think the result conveys the intent better than the if version - no De Morganizing required.

        Perl's payment curve coincides with its learning curve.

        While I understand your point and would not dream of trying to convince you to change, I usually try to use unless in very specific contexts. If there is only one condition and it would normally be expressed as a negative, I find unless {cond} much cleaner than if !{cond}.

        I can understand the point about people not being able to DeMorganize in their heads. (I knew a really, really good programmer once who regularly had problems with and and or) But, I have found that sometimes unless is clearer (just like in English.)

        G. Wade

      I think the precedence thing has been covered, but since DeMorgan's and "unless" got mentioned, a few thoughts about:

      1. reducing Not's - this is a good idea!
      2. DeMorgan's and using pictures instead of equations
      3. Table driven approaches

      I agree that factoring out negations improves readability. If you get too many "not's" in there it can get confusing.
      Without the "unless", this is another way:

      sub done { my $self = shift; return !($self->foo or $self->bar); }

      Read as: I'm not done if I've got some foo or bar. To me this is easier than I'm done if I don't have this and I don't have that, but situations vary.

      As far as converting between "AND's" and "OR's", I always draw a picture, not a table or an equation - just some little doodle on a piece of scratch paper.

      When looking at (!$self->foo && !$self->bar), I would draw an AND gate with two bubbles on the inputs, interpreted as both low's on input means a high output, then by inspection see that this means that any high input yields a low output. Well, that is a NOR gate. So I would draw an OR gate with a bubble on the output. Then I would compare pictures and verify that they really do the same thing.

      So instead of working with some De Morgan's equation, work with the picture. Ask a hardware guy to show you how they do it. 30 minutes learning how to draw and interpret these pictures (simple logic circuit diagrams) will save you a lot of grief.

      If things get too hairy to draw a simple picture, then simplify things. Maybe you combine some things together in an intermediate expression which is used in the following statement, or something like that...

      I guess I'm getting far afield, but there is another technique when things get REALLY hairy, the table driven approach. This is something to consider with "monster if's"... Depending upon the situation, it might or might not work out to be easier to understand and maintain.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://732310]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2018-04-24 03:31 GMT
Find Nodes?
    Voting Booth?