Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Ruby have TrueClass and FalseClass instead of a single Boolean class?

I was working on serializing values when found out about this one. Ruby has a TrueClass class, and a FalseClass class, but it has no Boolean class. I'd like to know why is this.

I see some advantages in using a Boolean; for example, string parsing could be centralized on it.

Ruby developers are smarter than me, so there must be a lot of good reasons that I just don't see. But right now it looks to me like having OneClass and a TwoClass instead of Fixnum.

like image 725
kikito Avatar asked Jul 07 '10 08:07

kikito


People also ask

What is TrueClass in Ruby?

The global value true is the only instance of class TrueClass and represents a logically true value in boolean expressions. The class provides operators allowing true to be used in logical expressions.

Is FalseClass false in Ruby?

The global value false is the only instance of class FalseClass and represents a logically false value in boolean expressions. The class provides operators allowing false to participate correctly in logical expressions.

Is boolean a ruby?

Ruby is a bit of an oddball in that while it has explicit values to represent true and false, there is no Boolean data type.


2 Answers

The purpose of a class is to group similar objects, or objects with similar behavior together. 1 and 2 are very similar, therefore it makes perfect sense for them to be in the same class. true and false however are not similar. In fact, their whole point is that they are exactly the opposite of each other and have opposite behavior. Therefore, they don't belong in the same class.

Can you give an example of what sort of common behavior you would implement in a Boolean class? I can't think of anything.

Let's just look at the behavior that TrueClass and FalseClass have: there's exactly four methods there. No more. And in every single case, the two methods do exactly the opposite. How and why would you put that in a single class?

Here's how you implement all those methods:

class TrueClass   def &(other)     other   end    def |(_)     self   end    def ^(other)     !other   end    def to_s     'true'   end end 

And now the other way around:

class FalseClass   def &(_)     self   end    def |(other)     other   end    def ^(other)     other   end    def to_s     'false'   end end 

Granted, in Ruby, there is a lot of "magic" that is going on behind the scenes and that is not actually handled by TrueClass and FalseClass but rather hardwired into the interpreter. Stuff like if, &&, || and !. However, in Smalltalk, from which Ruby borrowed a lot including the concept of FalseClass and TrueClass, all of these are implemented as methods as well, and you can do the same thing in Ruby:

class TrueClass   def if     yield   end    def ifelse(then_branch=->{}, _=nil)     then_branch.()   end    def unless   end    def unlesselse(_=nil, else_branch=->{})     ifelse(else_branch, _)   end    def and     yield   end    def or     self   end    def not     false   end end 

And again the other way around:

class FalseClass   def if   end    def ifelse(_=nil, else_branch=->{})     else_branch.()   end    def unless     yield   end    def unlesselse(unless_branch=->{}, _=nil)     ifelse(_, unless_branch)   end    def and     self   end    def or     yield   end    def not     true   end end 

A couple of years ago, I wrote the above just for fun and even published it. Apart from the fact that the syntax looks different because Ruby uses special operators while I use only methods, it behaves exactly like Ruby's builtin operators. In fact, I actually took the RubySpec conformance testsuite and ported it over to my syntax and it passes.

like image 164
Jörg W Mittag Avatar answered Sep 16 '22 11:09

Jörg W Mittag


It seems that Matz himself answered this question on a mailing list message in 2004.

Short version of his answer: "right now it works ok, adding a Boolean doesn't give any advantage".

Personally I don't agree with that; the aforementioned "string parsing" is one example. Another one is that when you are applying different treatment to a variable depending on its type, (i.e. a yml parser) having a "Boolean" class is handy - it removes one "if". It also looks more correct, but that's a personal opinion.

like image 25
kikito Avatar answered Sep 18 '22 11:09

kikito