Raphael
Raphael

Reputation: 1800

Groovy Truth: string to boolean inconsistency?

In groovy:

println 'test' as Boolean //true
println 'test'.toBoolean() //false
println new Boolean('test') //false

Can anyone clarify this behavior?

Upvotes: 47

Views: 57431

Answers (6)

Marcus Voltolim
Marcus Voltolim

Reputation: 530

 
String.metaClass.asBoolean = {
    ((String) delegate).toBoolean()
}

Upvotes: 0

Dónal
Dónal

Reputation: 187529

Both of these

println 'test'.toBoolean() //false
println new Boolean('test') //false

instantiate a java.lang.Boolean using the constructor that takes a single String argument. According to the javadocs, the rule is:

Allocates a Boolean object representing the value true if the string argument is not null and is equal, ignoring case, to the string "true". Otherwise, allocate a Boolean object representing the value false.

In both of the cases above, the String does not match 'true' (case-insensitively), so the Boolean created is false.

By contrast 'test' as Boolean follows the Groovy language rules for coercion to a boolean, which allows you to write:

if ('hello') {
    println 'this string is truthy'
}

For a String, the rule is that if it's empty or null, it evaluates to false, otherwise true.

I agree that this could be considered a bit inconsistent, but given a choice between consistency with the constuctor of java.lang.Boolean and utility, I think they were right to choose the latter.

Upvotes: 71

Mohamad Fakih
Mohamad Fakih

Reputation: 101

However, when applied to other objects, an inconsistency arises:

int i = 0
String s = 'abc'

if (s)
    println 's is true' // will be printed

if (i) 
    println ' i "is true" ' // will not be printed

(Groovy 1.7.8)

You have to be explicit in the second if, if(i != null) or if (i != 0)

Some bugs can be traced to checking for non-null integer using if(i).

Upvotes: 0

jaetzold
jaetzold

Reputation: 1688

Don is right in that:

'test' as Boolean follows the Groovy language rules for coercion to a boolean

which is also known as "Groovy truth".

But String.toBoolean() in groovy does not just construct a Boolean with the String as an argument. From the groovy api docs on String.toBoolean():

String.toBoolean() Converts the given string into a Boolean object. If the trimmed string is "true", "y" or "1" (ignoring case) then the result is true otherwise it is false.

A few good examples for strings and their conversion with toBoolean():

assert "y".toBoolean()
assert 'TRUE'.toBoolean()
assert '  trUe  '.toBoolean()
assert " y".toBoolean()
assert "1".toBoolean()

assert ! 'other'.toBoolean()
assert ! '0'.toBoolean()
assert ! 'no'.toBoolean()
assert ! '  FalSe'.toBoolean()

Upvotes: 33

Thomas Nadin
Thomas Nadin

Reputation: 1207

I would tend to agree with @cdeszaq's point about the constructor, and as far as your first example is conserned, I would say it is just casting it to a bool. As long as the pointer is not null it will be true. I imagine that .toBoolean() actually attempts to parse its object value. Consider executing 'true'.toBoolean() and '1'.toBoolean() to see what they return.

I have never heard of Groovy before this question, this may all be incorrect.

Upvotes: 0

cdeszaq
cdeszaq

Reputation: 31280

The Boolean constructor is taking the string you gave it and running the toBoolean() method on that string. In a nutshell, anything it can't parse as a valid boolean value is treated as false. Or, in other words, only 'true' is true.

Upvotes: 0

Related Questions