Le but d'une classe est à grouper des objets ou des objets avec des comportements similaires ensemble. 1
et 2
sont très similaires, donc il est parfaitement logique pour eux d'être dans la même classe. true
et false
sont cependant pas similaires. En fait, leur point de l'ensemble , c'est qu'ils sont exactement à l' opposé les uns des autres et ont opposé du comportement. Par conséquent, ils n'appartiennent pas à la même classe.
Pouvez-vous donner un exemple de ce genre de comportement, vous pouvez implémenter dans un Boolean
classe? Je ne peux pas penser à quelque chose.
Examinons le comportement qu' TrueClass
et FalseClass
ont: il y a exactement quatre méthodes. Pas plus. Et dans tous les cas, les deux méthodes pour faire exactement le contraire. Comment et pourquoi voudriez-vous mettre que dans une seule catégorie?
Voici comment mettre en œuvre toutes ces méthodes:
class TrueClass
def &(other)
other
end
def |(_)
self
end
def ^(other)
!other
end
def to_s
'true'
end
end
Et maintenant dans l'autre sens:
class FalseClass
def &(_)
self
end
def |(other)
other
end
def ^(other)
other
end
def to_s
'false'
end
end
Accordé, en Ruby, il y a beaucoup de "magie" qui se passe derrière les coulisses, et qui n'est pas réellement traitée par TrueClass
et FalseClass
mais plutôt programmés dans l'interprète. Des trucs comme if
, &&
, ||
et !
. Toutefois, en Smalltalk, à partir de laquelle Ruby emprunté beaucoup de choses, y compris le concept de l' FalseClass
et TrueClass
, tous ces éléments sont mis en œuvre que les méthodes, et vous pouvez faire la même chose en 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
Et de nouveau dans l'autre sens:
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
Il y A quelques années, j'ai écrit ci-dessus, juste pour le plaisir et même publié. Outre le fait que la syntaxe est différente parce que Ruby a recours à des opérateurs alors que je n'utilise que des méthodes, il se comporte exactement comme le Rubis est builtin opérateurs. En fait, j'ai effectivement pris le RubySpec conformité testsuite et porté à ma syntaxe et ça passe.