It’s a common problem that does not seem to have a standard solution. Sometimes you need to coerce a value to a boolean (e.g. from a web form). Here’s a simple implementation I wrote that handles common strings and numbers and gives flexibility in how to treat nils.
Here’s the behavior we want: describe "#to_boolean" do
it "converts false values" do
["no","false",false, "0", 0].each do |value|
to_boolean(value).should == false
end
end
it "converts true values" do
["yes","true",true, "1", 1].each do |value|
to_boolean(value).should == true
end
end
it "is case insensitive for strings" do
to_boolean("YeS").should == true
to_boolean("NO").should == false
to_boolean("TruE").should == true
to_boolean("FalSe").should == false
end
it "converts nil to false by default" do
to_boolean(nil).should == false
end
it "can return nil as nil" do
to_boolean(nil, nil).should == nil
end
it "converts unmatched strings to true" do
to_boolean("a string").should == true
end
end
Here’s the source code that satisfies the desired behavior:
def to_boolean(value, nil_value = false)
value.downcase! if value.class == String
case value
when "no","false",false, "0", 0
false
when "yes","true",true, "1", 1
true
when nil
nil_value
else
!!value
end
end