Project

General

Profile

Actions

Bug #14719

closed

FalseClass wrapped in a SimpleDelegator evaluates to true in an IF statement

Added by theirishpenguin (Declan McGrath) almost 6 years ago. Updated almost 6 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
[ruby-core:86727]

Description

Hi, thanks for Ruby :-)

I have run into a problem. When I wrap the boolean false in a SimpleDelegator it breaks the semantics of the boolean when evaluated in expressions such as IF statements - returning true when I would have expected false.

Here is a test case...

class BoldBool < SimpleDelegator                                                                                        
end                                                                                                                     
                                                                                                                        
false_bool = BoldBool.new(false)                                                                                        
                                                                                                                        
if false_bool                                                                                                           
    puts "I'm evaluated as true but I should be false."                                                                 
end 

When I run it I get:
#=>I'm evaluated as true but I should be false.

Expected result:
No output.

I understand that there may be good reasons for why this is happening (eg. the class of the object false_bool may be a BoldBool and this is not a FalseClass) however it breaks the fundamental semantics of a boolean - in which case I think we should consider raising an ArgumentError in the Ruby language if a Boolean is passed to the constructor of a SimpleDelegator.

I tried to workaround the problem by overriding equals?(). I am guessing that this would be the correct approach - and that this is what is used by the IF expression to determine whether it is dealing with a truthy object or a falsey...

class BoldBool < SimpleDelegator                                                                                        
    def equal?(obj)                                                                                                     
        if __getobj__.is_a? FalseClass and obj == false                                                                 
            return true                                                                                                 
        else                                                                                                            
            __getobj__.equal?(obj)                                                                                      
        end                                                                                                             
    end                                                                                                                 
end                                                                                                                     
                                                                                                                        
false_bool = BoldBool.new(false)                                                                                        
                                                                                                                        
if false_bool                                                                                                           
    puts "I'm evaluated as true but I should be false."                                                                 
end

However this gives me the error...

/home/me/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/delegate.rb:313:in `__getobj__': not delegated (ArgumentError)
        from simple_delegator_on_boolean_with_equals_override.rb:5:in `equal?'
        from /home/me/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/delegate.rb:333:in `__setobj__'
        from /home/me/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/delegate.rb:72:in `initialize'
        from simple_delegator_on_boolean_with_equals_override.rb:13:in `new'
        from simple_delegator_on_boolean_with_equals_override.rb:13:in `<main>'

If I try an even simpler override approach as an experiment this errors too...

class BoldBool < SimpleDelegator                                                                                        
    def equal?(obj)                                                                                                     
        true                                                                                                            
    end                                                                                                                 
end                                                                                                                     
                                                                                                                        
false_bool = BoldBool.new(false)                                                                                        
                                                                                                                        
if false_bool                                                                                                           
    puts "I'm evaluated as true but I should be false."                                                                 
end      

... with the error...

/home/me/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/delegate.rb:333:in `__setobj__': cannot delegate to self (ArgumentError)
        from /home/me/.rvm/rubies/ruby-2.4.1/lib/ruby/2.4.0/delegate.rb:72:in `initialize'
        from simple_delegator_on_boolean_with_simple_equals_override.rb:9:in `new'
        from simple_delegator_on_boolean_with_simple_equals_override.rb:9:in `<main>'

Is this SimpleDelegator behaviour a bug? (downloadable files attached containing the above snippets).


Files

simple_delegator_on_boolean.rb (167 Bytes) simple_delegator_on_boolean.rb theirishpenguin (Declan McGrath), 04/27/2018 04:16 PM
simple_delegator_on_boolean_with_equals_override.rb (335 Bytes) simple_delegator_on_boolean_with_equals_override.rb theirishpenguin (Declan McGrath), 04/27/2018 04:16 PM
simple_delegator_on_boolean_with_simple_equals_override.rb (208 Bytes) simple_delegator_on_boolean_with_simple_equals_override.rb theirishpenguin (Declan McGrath), 04/27/2018 04:17 PM
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0