Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Devel-Cover CPAN distribution.

Report information
The Basics
Id: 11304
Status: resolved
Priority: 0/
Queue: Devel-Cover

People
Owner: Nobody in particular
Requestors: dagolden [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: consider context in evaluation of || and or shortcuts
(I'm using Devel::Cover 0.52. From the Changes, it looks like there have been various special cases to try to address this type of thing, but I thought I'd add a suggestion.) Not surprisingly, many of the condition coverage tests I fail are situations where I'm using an OR operator as a shortcut and I haven't tested a (0,0) case. E.g.: $self = bless ({}, ref ($class) || $class); $alias ||= $orig; This works nicely in Perl since Perl returns the last value evaluated, but it's not really a condition in this case -- it's syntactic sugar for the trinary operator (i.e. an if/else). E.g: ref($class) ? ref($class) : $class $alias = $alias ? $alias : $orig From using Want.pm, it looks like there's a way to detect whether the evaluation context is not just scalar, but boolean. (I couldn't tell you how, but the POD for Want implies its possible, anyway.) It might be worth considering whether OR operators should be treated as equivalent to the trinary operator except when called in boolean context. That might help avoid flagging a host of "false positives" involving OR operations. Regards, David
[DAGOLDEN - Mon Jan 31 20:46:26 2005]: Show quoted text
> It might be worth considering whether OR operators should be treated > as equivalent to the trinary operator except when called in boolean > context.
Absolutely not! Suppose the boolean context is: if ($a || $b) { # do something } Would you still want to ignore the (0,0) case?! While your examples could be implemented using ?: they aren't shortcuts for it. TMTOWTDI. '$a = bless({}, ref($b) || $b)' isn't shorthand for anything. It just makes use of the "return the last thing evaluated" behavior of ||. '$a ||= $b' is shorthand for '$a = $a || $b' 'A ? B : C' is itself shorthand for if (A) { B; } else { C; } Devel::Cover is doing the right thing here. The only way for DC to not show your "false positive" in these situations would be for it to know that $class and $orig were always true. While that might be true in your program, it isn't necessarily true everywhere. You have a set of conditions that you haven't tested. Either test them or analyze the results to satisfy yourself that testing isn't necessary. *** COVERAGE != CORRECTNESS *** Coverage is a tool used to achieve correctness, but coverage by itself does not tell you anything at all about whether or not something is correct.
Michael, I appreciate that you've thought about my post enough to respond, but I think that a calmer and less reactionary response would be more effective. This is not USENET. Flames don't help collaboration. I say this because, in your heated reply, you missed a major point of my post. [MJCARMAN - Mon Feb 21 09:46:30 2005]: Show quoted text
> [DAGOLDEN - Mon Jan 31 20:46:26 2005]: >
> > It might be worth considering whether OR operators should be treated > > as equivalent to the trinary operator except when called in boolean > > context.
> > Absolutely not! Suppose the boolean context is: > > if ($a || $b) { > # do something > } > > Would you still want to ignore the (0,0) case?!
If you note the "except when" clause in what I wrote, I'm clearly not suggesting ignoring the (0,0) case in your example. Whenever the || operator is used in a context that expects a true/false value, it should be tested for the full truth table. However, when this is not the case -- when the || operator is *not* being used in boolean context, the meaning of an expression using || changes from the logical question of "true or false" to the semantic question of "first value or second value". My parallel to the trinary operator is that it is a semantic equivalent outside of a boolean context and that the coverage issue is a branching one, not a conditional one. Consider: $a = $b || $c; $a = $b ? $b : $c; The only semantic question posed in the code is whether $b or $c is the result assigned to $a; the only condition that matters is whether $b evaluates to true or false. In this context, the truth/falseness of $c is irrelevant. [As a side note, I certainly agree that these constructs are not equivalent at the opcode level, as the trinary example evaluates $b twice, which could be very bad if I wasn't using a variable but rather an expression that had side effects (e.g. "--$b" ). I am merely making an analogy.] Show quoted text
> Devel::Cover is doing the right thing here.
This is the only real point of contention, I think. I would prefer that Devel::Cover "do what I mean" and adjust its logic for the semantic context of the expression. I futher hypothesize that *if* Devel::Cover can determine if an || expression is in boolean context or not (as the Want module implies is possible), then it should be able to correctly avoid false positives in this way.
I didn't want to leave this as new, so I've marked it stalled. I think there is merit to DWIM, but I'm still not sure about this. Perhaps it would be a candidate for the "uncoverable" code section. Or maybe it should default the other way. In any case, it is something more than one person has asked about, so I think it is worth looking into at some point.