-
-
Save alecmce/1088960 to your computer and use it in GitHub Desktop.
// a difference is not a difference unless it *makes* a difference | |
public function add(item:*):Boolean | |
{ | |
if (contains(item)) | |
return false; | |
push(item); | |
return true; | |
} | |
public function add(item:*):Boolean | |
{ | |
var notContained:Boolean = !contains(item); | |
if (notContained) | |
push(item); | |
return notContained; | |
} |
oh and of course i'd go as far as to extract method on age < 21 as is_under_drinking_age - and please try to read past the fact that my particular example is a simple logical AND of two boolean states.
A problem with guards like that is when do you stop?
def allowed_to_drink
if underage
return false
if is_alcoholic
return false
if pregnant
return false
if muslim
return false
if alchohol_intolerant
return false;
return true;
end
At what stage do you stop adding guard statements and refactor? I doubt there can be much debate that
def allowed_to_drink
return !(underage || alchoholic || pregnant || muslim || alchohol_intolerant)
end
is better than the above, but at what stage does it become better if you allow multiple returns?
I did ask that you didnt bother with the boolean logic of the example. I nearly always end with 2 returns in a method, so that is the natural progression, yes. My point holds, with :
def allowed_to_drink
return !(underage || alchoholic || pregnant || muslim || alchohol_intolerant)
end
You don't rename it "is_underage_or_alcoholioc_or_pregnant... "
Interesting point David. I agree that there is a point at which adding guard statements stops making sense, and that your definition is much better than the one with all the guards. I don't see why acceding that there is a point at which one becomes more readable than the other means you must deny the readability of guards under any circumstances.
I'm starting to frame this debate in my mind with you and squeedee at opposite ends of a spectrum. I'm not taking sides in this except to acknowledge that I lean a little more towards squeedee's approach than to yours, but I am curious about why both of you strongly feel the need to take an aggressive position about this.
well we have two issues now.. On the original one, I never claimed that Guards are outright the right way. Just that they are awesome.
I originally got concerned that Tanya thought they're "Bad" and then was as amazed as you were at the outright position that Dave took.
If i can read it and make sense of it quickly, then i love it. Ergo, i have no issue with Dave's version... except... issue 2:
What I take to be a misunderstanding of Bob Martin's attempt to explain "when has extract method stopped being useful" and "how to name a function"
Describing the behaviour of the method does not necessarily make it an 'and'. I think i've outlined why I think this above?
I'm with squeedee. Guard clauses rule; conditional slaloms drool.
The collection's rule that it is a unique set (no duplicates) does not require the method to be called addIfNotInCollection.
All it requires is a rename to 'include'' or 'ensureIncludes', but that would be more of a suprise to a consumer than "add" so I don't think it offers anything.
Meanwhile, the guard reads beautifully, but more so when there is an other test to follow.
Makes it easier to add guards, they are the right guards.. 'allowed_to_drink' is the question, not the joint conditions. You wouldn't call it is_over_21_and_not_in_alcoholics_anonymous. I think this is a common misunderstanding of 'does it do two things'. In both cases, no. 'add' does one thing, it "adds to a duplicate free set". And that's not suprising.