From: ruby-core@... Date: 2018-04-27T21:24:58+00:00 Subject: [ruby-core:86737] [Ruby trunk Bug#14719][Rejected] FalseClass wrapping a SimpleDelegator evaluates to true in an IF statement Issue #14719 has been updated by marcandre (Marc-Andre Lafortune). Status changed from Open to Rejected I'm afraid you can not achieve what you want to achieve in Ruby. The only two objects that are falsy in Ruby are `nil` and `false`. No other object can "look" like `false`. This is by design and can not be changed. ---------------------------------------- Bug #14719: FalseClass wrapping a SimpleDelegator evaluates to true in an IF statement https://bugs.ruby-lang.org/issues/14719#change-71692 * Author: theirishpenguin (Declan McGrath) * Status: Rejected * Priority: Normal * Assignee: * Target version: * ruby -v: ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux] * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN ---------------------------------------- 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... ~~~ ruby 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... ~~~ ruby 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... ~~~ ruby /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 `
' ~~~ If I try an even simpler override approach as an experiment this errors too... ~~~ ruby 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... ~~~ ruby /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 `
' ~~~ 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_with_equals_override.rb (335 Bytes) simple_delegator_on_boolean_with_simple_equals_override.rb (208 Bytes) -- https://bugs.ruby-lang.org/ Unsubscribe: