Ticket #359 (new defect)

Opened 4 years ago

Last modified 4 years ago

Confusing interaction between Object? instance and bools

Reported by: nerdzero Owned by:
Priority: minor Milestone:
Component: Cobra Compiler Version: 0.9.6
Keywords: truthiness Cc:


reported-by: kobi7

The last assertion in the following program fails

class NilableObjectAsBool
	def main
		shouldBeFalse as Object? = false
		assert shouldBeFalse == false
		shouldBeTrue = not shouldBeFalse
		assert shouldBeTrue == true

The value of shouldBeTrue actually ends up being 'false'. This is probably because the nilable object has a non-nil value so 'not shouldBeFalse' is returning false.

This is confusing when just examining the code especially if the type of the local variable is inferred from a method call that returns an Object?, It also confusing when adding 'assert shouldBeFalse == not shouldBeFalse' to the program and the assertion passes.

This may be by design or unfixable in which case this ticket can be closed.

Change History

Changed 4 years ago by kobi7

so a nilable object that has a non-nil value, is considered true by 'if', even if that value is 'false'

performing negation ("not") on this nilable value will set it to 'false'.
then this situation happens, where we had a false value, negated it, and it became false.

Changed 4 years ago by hopscc

Yes - its doing the test as you've told it on the types given

Its confusing cos you've got used to the implicit shortcut doing exactly what you want as a truth test - in this case what it does ( on a nilable )is not what you want or expected ( if you were testing non-nil it would be (:-)

so either
a) dont rely on implicit operations unless you are certain of the type and result or b) make the test explicit

shouldBeFalse as Object? = false  # bool described as a nilable Anything  
assert shouldBeFalse == false  # resolves ok
shouldBeFalseB = shouldBeFalse to bool  # make sure test item is a bool 
shouldBeTrue = not shouldBeFalseB  # know this works how I want on a bool
assert shouldBeTrue == true  # ok

shouldBeTrue =  shouldBeFalseB == false

kobi7: no
The test you are using does that - for nilable types you are testing incorrectly
for what you want

i.e the short cct test u are using doesnt do what you think it does - for Object? (nilable Object ) it tests against non-nil ( not non-nil and some truth value of the non-nilable Object

or alternatively the truth value of a nilable object is non-nil)

use instead

#shouldBeTrue = not shouldBeFalse  # nah tests against nil
shouldBeTrue =  shouldBeFalse == false
# or 
shouldBeTrue = not (shouldBeFalse to bool)

see wiki:ConditionalExpr
(which I've just extended (:-))

Note: See TracTickets for help on using tickets.