Forum: Ruby TrueClass/FalseClass vs. Boolean

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
5b1b6c0fe28f1441f44b200434b052c8?d=identicon&s=25 PrimaryKey (Guest)
on 2006-03-30 23:31
Greetings!

I am wondering why there are two separate classes (TrueClass and
FalseClass) to deal with boolean types insead of one class (something
like Boolean?). Do you know
why the library designer desided to use this approach?

Your help will be greatly apreciated.

Thanks
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 Eric Hodel (Guest)
on 2006-03-30 23:43
(Received via mailing list)
On Mar 30, 2006, at 1:31 PM, PrimaryKey wrote:

> Greetings!
>
> I am wondering why there are two separate classes (TrueClass and
> FalseClass) to deal with boolean types insead of one class (something
> like Boolean?). Do you know
> why the library designer desided to use this approach?
>
> Your help will be greatly apreciated.

This has been discussed many, many times before.  Here's a reading list:

http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb?key=TrueClass
+FalseClass&cginame=namazu.rb&submit=Search&dbname=ruby-
talk&max=50&whence=0

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
54f9c5392e17646bc29fe6435b55f609?d=identicon&s=25 baumanj@gmail.com (Guest)
on 2006-03-30 23:46
(Received via mailing list)
Since everything in ruby is an object, there need to be objects for
representing true and false. Once you have those, why do you need a
Boolean class?
E0ed615bd6632dd23165e045e3c1df09?d=identicon&s=25 Florian GroÃ? (Guest)
on 2006-03-31 16:10
(Received via mailing list)
PrimaryKey wrote:

> I am wondering why there are two separate classes (TrueClass and
> FalseClass) to deal with boolean types insead of one class (something
> like Boolean?). Do you know
> why the library designer desided to use this approach?

I think it is because true and false don't really have anything in
common in Ruby. No way to share code.

You can always fix it pretty easily:

module Boolean; end
[true, false].each do |obj|
   obj.extend(Boolean)
end

true.is_a?(Boolean) # => true
false.is_a?(Boolean) # => true

But note that in Ruby all objects (except false and nil) can be used as
true values. And they are used for just that even in the standard
library.
7264fb16beeea92b89bb42023738259d?d=identicon&s=25 Christian Neukirchen (Guest)
on 2006-03-31 16:29
(Received via mailing list)
"baumanj@gmail.com" <baumanj@gmail.com> writes:

> Since everything in ruby is an object, there need to be objects for
> representing true and false. Once you have those, why do you need a
> Boolean class?

if a.kind_of? Boolean

case y
  when Integer
  when Boolean
end

I often wanted this shortcut...
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2006-03-31 17:15
(Received via mailing list)
On Mar 31, 2006, at 9:27 AM, Christian Neukirchen wrote:
> case y
>   when Integer
>   when Boolean
> end

case y
   when Integer
   when TrueClass,FalseClass
end

works ok, right?  I kind of wish the class names were just True and
False.


Gary Wright
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-03-31 17:24
(Received via mailing list)
On Fri, 31 Mar 2006, Christian Neukirchen wrote:

>  when Boolean
> end
>
> I often wanted this shortcut...

indeed.  i tend to use

   case obj
     when Klass
     when TrueClass, FalseClass
   end

which is ugly.

another thing a real Boolean class could give is a 'maybe' obj such that

     maybe or true                   -> maybe
     maybe or true and false or true -> maybe
     maybe and false                 -> maybe

although i can't think of anything attm to do with this it would
undoubtably
lead to some nice logical constructs that more closely parallel the way
we
think.

i've brought this up once or twice before - maybe we should just put
together
a patch and send to ruby-core?

regards.


-a
54f9c5392e17646bc29fe6435b55f609?d=identicon&s=25 baumanj@gmail.com (Guest)
on 2006-03-31 17:39
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
> On Fri, 31 Mar 2006, Christian Neukirchen wrote:
> > if a.kind_of? Boolean
> >
> > case y
> >  when Integer
> >  when Boolean
> > end

What kind of scenarios would you want to use such a construct? It seems
to me not very rubyish to be switching based on the class of an object.
As I understand it, the more conventional way to deal with potentially
diverse argument types is to use the respond_to? method. This keeps the
door open for duck typing.

> another thing a real Boolean class could give is a 'maybe' obj such that
....
> although i can't think of anything attm to do with this it would undoubtably
> lead to some nice logical constructs that more closely parallel the way we
> think.

It sounds like you're talking about a sort of restricted fuzzy logic,
which is very cool, but is not appropriate for the core of a general
purpose language. Considering that every expression can be interpreted
in a boolean context, what would a maybe value do? Either behavior
seems wrong.
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-03-31 18:19
(Received via mailing list)
On Sat, 1 Apr 2006, baumanj@gmail.com wrote:

> me not very rubyish to be switching based on the class of an object.  As I
> understand it, the more conventional way to deal with potentially diverse
> argument types is to use the respond_to? method. This keeps the door open
> for duck typing.

i generally do use duck typing, but sometimes it is simply not
appropriate or
become too verbose.  for example, consider a matrix class with the
following
behaviour

   1d

     m[true]             #=> all data returned
     m[]                 #=> all data returned
     m[true] = elems     #=> data along all dims set
     m[]     = elems     #=> data along all dims set
     m[int]              #=> treat as 1d array, return elem
     m[int] = elem       #=> treat as 1d array, set idx to elem
     m[off, len]         #=> treat as 1d array, return elems off thru
len
     m[off, len] = elem  #=> treat as 1d array, set elems off thru len
to elem
     m[a .. b]           #=> treat as 1d array, return elems in range
     m[a .. b] = elem    #=> treat as 1d array, set elems in range to
elem
     m[n]                #=> idx one matrix by another

   2d

     generalize all above so multiple indices access in
multi-dimensional
     fashion. eg

       m[0,1,2]         #= return idx x,y,z
       m[0,30..42,true] #= return column 0, rows 30 to 42, in all height
dims

now, in case you are thinking that i'm just being difficult, this is
exactly
how the narray class works

   http://narray.rubyforge.org/SPEC.en

have fun writing that with respond_to? !!  ;-)

also, when working with concrete data structures (like binary output
from C
programs) it's often quite sufficient to have a type mapping.  further
more
it's sometimes critical, for instace writing the word located at
offset=42,
len=4 with a packed int value or sending a given sequence of bytes down
a
socket that a given type is used and it's much more natural to write


   def send buf, which = nil
     case which
       when Fixnum
         socket.write [which].pack('N')
         socket.write buf
       when NilClass
         socket.write [buf.size].pack('N')
         socket.write buf
       when Range
         length = which.last - which.first
         socket.write [length].pack('N')
         socket.write buf[which]
       else
         raise TypeError, which.class
     end
   end

than something using respond_to?.

don't get me wrong - i defintely advocate duck typing, but when the
number of
possible input types becomes large and behaviour is different depending
on
that type it becomes cumbersome.  this is the price we pay for not
having c--
style polymorphism.  in fact, it's very common to see the two styles
combined:

   case arg
     when Fixnum
       ...
     when Range
       ...
     else # dunno - assume String and use in a duck type fashion
   end

> context, what would a maybe value do? Either behavior seems wrong.
i disagree - ruby (and hardware) already supports this style of logic in
several ways:

   harp:~ > irb
   irb(main):001:0> nan = 0.0/0.0
   => NaN
   irb(main):002:0> nan * 42
   => NaN
   irb(main):003:0> nan * 42 + 42.0
   => NaN
   irb(main):004:0> obj = Object.new and obj.taint
   => #<Object:0xb75a5fac>
   irb(main):005:0> (obj.to_s << "string").tainted?
   => true
   irb(main):006:0> ("string" << obj.to_s).tainted?
   => true

there's no good reason, imho, why this style of logical behaviour could
not be
part of the logical classes (TrueClass/FalseClass) and operators (and,
or,
not).

regards.

-a
7264fb16beeea92b89bb42023738259d?d=identicon&s=25 Christian Neukirchen (Guest)
on 2006-03-31 19:27
(Received via mailing list)
"baumanj@gmail.com" <baumanj@gmail.com> writes:

> to me not very rubyish to be switching based on the class of an object.
> As I understand it, the more conventional way to deal with potentially
> diverse argument types is to use the respond_to? method. This keeps the
> door open for duck typing.

Except we don't have a to_bool, either ;-).

Still, I can saw enough cases where I wanted such a "case", and
grumbly used TrueClass,FalseClass.
10d4acbfdaccb4eee687a428ca00a5d8?d=identicon&s=25 Jim Weirich (weirich)
on 2006-03-31 21:10
unknown wrote:
>      maybe or true                   -> maybe

Wouldn't maybe or true be true?

--
-- Jim Weirich
Bf6862e2a409078e13a3979c00bba1d6?d=identicon&s=25 Gregory Seidman (Guest)
on 2006-03-31 22:45
(Received via mailing list)
On Sat, Apr 01, 2006 at 12:38:43AM +0900, baumanj@gmail.com wrote:
} ara.t.howard@noaa.gov wrote:
} > On Fri, 31 Mar 2006, Christian Neukirchen wrote:
} > > if a.kind_of? Boolean
} > >
} > > case y
} > >  when Integer
} > >  when Boolean
} > > end
}
} What kind of scenarios would you want to use such a construct? It
seems
} to me not very rubyish to be switching based on the class of an
object.
} As I understand it, the more conventional way to deal with potentially
} diverse argument types is to use the respond_to? method. This keeps
the
} door open for duck typing.
[...]

The most obvious answer is that it is needed for various kinds of
serialization. I wrote something like this just the other day. I needed
to
do XML-RPC serialization (yes, I know there is XML-RPC support in the
standard library, but I needed something slightly different that was
easier
to do by hand), so I needed to know what kind of value I was
serializing.

--Greg
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-03-31 22:58
(Received via mailing list)
On Mar 31, 2006, at 10:21 AM, ara.t.howard@noaa.gov wrote:

> maybe and false                 -> maybe

Shouldn't this be false?

{true, false} and false is  going to be false regardless of what
maybe is
6ec6f77ea603dd75b3a7a7775b059e79?d=identicon&s=25 John W. Long (Guest)
on 2006-03-31 23:10
(Received via mailing list)
gwtmp01@mac.com wrote:
> end
You could always assign some new constants to them:

True = TrueClass
False = FalseClass

case y
   when Integer
   when True, False
end
D84df7c68f790e492c4ad4ec5fe65547?d=identicon&s=25 Florian Frank (Guest)
on 2006-04-01 00:02
(Received via mailing list)
John W. Long wrote:

> You could always assign some new constants to them:
>
> True = TrueClass
> False = FalseClass
>
> case y
>   when Integer
>   when True, False
> end


Or just use the literal constants, that already exist:

case y
  when Integer
  when true, false
end
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2006-04-01 00:45
(Received via mailing list)
On Mar 31, 2006, at 5:00 PM, Florian Frank wrote:
> Or just use the literal constants, that already exist:
> case y
>  when Integer
>  when true, false
> end

Another example where the Ruby 'does the right thing'.
Thanks for the reminder.


Gary Wright
A59b0b2fec8ccb513b2cf97f2d7659ac?d=identicon&s=25 Niklas Frykholm (Guest)
on 2006-04-01 13:21
(Received via mailing list)
> another thing a real Boolean class could give is a 'maybe' obj such that
>
>     maybe or true                   -> maybe
>     maybe or true and false or true -> maybe
>     maybe and false                 -> maybe

What whould this do

    print "hello" if maybe

or this

    while maybe
       print "hello"
    end

// Niklas
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-01 17:05
(Received via mailing list)
On Sat, 1 Apr 2006, Niklas Frykholm wrote:

>
> or this
>
>   while maybe
>      print "hello"
>   end

in a conditional it should evaluate to true/false radomly - compute a
random
number and look at the last bit for instance, 0 -> false, 1 -> true.

   harp:~ > cat a.rb
   def maybe() [rand].pack('f').unpack('c').first[0].zero?  end

   puts "hello" while maybe


   harp:~ > ruby a.rb
   hello
   hello


   harp:~ > ruby a.rb
   hello
   hello
   hello
   hello


   harp:~ > ruby a.rb
   hello


   harp:~ > ruby a.rb
   hello


cheers.

-a
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-04-01 22:36
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
>   def maybe() [rand].pack('f').unpack('c').first[0].zero?  end

What does

  [rand].pack('f').unpack('c').first[0]

do that

  rand(2)

doesn't?
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-01 22:51
(Received via mailing list)
On Sun, 2 Apr 2006, Joel VanderWerf wrote:

>
> doesn't?

sheesh - can't you tell it looks longer!



;-)

-a
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-04-02 01:46
(Received via mailing list)
On Apr 1, 2006, at 10:03 AM, ara.t.howard@noaa.gov wrote:

>>
> number and look at the last bit for instance, 0 -> false, 1 -> true.
>
>
> - h.h. the 14th dali lama
>

As if my code wasn't already non-deterministic
822a498b26a2cb7d1f0f2e7e37ce61b2?d=identicon&s=25 Ed Howland (Guest)
on 2007-01-19 21:20
(Received via mailing list)
On 3/31/06, gwtmp01@mac.com <gwtmp01@mac.com> wrote:
>
> On Mar 31, 2006, at 5:00 PM, Florian Frank wrote:
> > Or just use the literal constants, that already exist:
> > case y
> >  when Integer
> >  when true, false
> > end
>
> Another example where the Ruby 'does the right thing'.
> Thanks for the reminder.


Another, related issue, is the lack of  the <=> operator for either
class. This comes in handy when sorting arrays of booleans or using
sort_by on a collection returned from activerecord that has a boolean
attribute.

I know this has been covered in the archives of this list before, but
I wasn't able to find any definitive answer from Matz or someone else.
I thought it might be because in math Boolean is not really a scalar
or a quantifiable value. Or in sortable collection terms, it doesn't
implement Comparable. Other languages work with sorting on booleans
because they might bind false to 0 and true to > 0. So easily fixed by
the to_i above.

But in terms of Ruby "doing the right thing", you'd expect
 [false, true, false].sort
    --> [false, false, true]
because it does this just about everywhere else. This is such a common
idiom in CS, that I think Ruby should implement it. But then, I only
have just the 2 cents. Anyone know the main reason it does not?

Ed
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 unknown (Guest)
on 2007-01-19 22:05
(Received via mailing list)
On Jan 19, 2007, at 3:20 PM, Ed Howland wrote:
> But in terms of Ruby "doing the right thing", you'd expect
> [false, true, false].sort
>    --> [false, false, true]
> because it does this just about everywhere else. This is such a common
> idiom in CS, that I think Ruby should implement it. But then, I only
> have just the 2 cents. Anyone know the main reason it does not?

interesting observation

Since true and false are not instances of the same class it is
like asking how to compare 4 and :foobar or 6.32 and "tuesday".

One possibility would be to have <=> be defined in terms of object_id
by default similar to how == is defined.  Since false.object_id is 0
and true.object_id is 2 that does give you [false,false,true]
in your example but for an obscure, implementation dependent reason.

Gary Wright
F3b7109c91841c7106784d229418f5dd?d=identicon&s=25 Justin Collins (justincollins)
on 2007-01-19 22:27
(Received via mailing list)
Ed Howland wrote:
> Another, related issue, is the lack of  the <=> operator for either
> class. This comes in handy when sorting arrays of booleans or using
> sort_by on a collection returned from activerecord that has a boolean
> attribute.
>
> I know this has been covered in the archives of this list before, but
> I wasn't able to find any definitive answer from Matz or someone else.

The reason, IIRC, was the lack of meaning for true > false, false >
true, etc.

-Justin
This topic is locked and can not be replied to.