4.1.2 les pseudo-variables true et false
La classe Object possède une
sous-classe nommée Boolean. C’est une classe abstraite, donc une classe qui
regroupe des comportements communs aux instances de ses sous-classes, mais qui
ne possède pas d’instances propres. Ses deux sous-classes sont les classes
True et False, en français: Vrai et Faux. Ce sont donc les classes des
objets vrais et des objets faux. Dans la logique des propositions, la logique
booléenne1,
il n’existe qu’un seul “objet” vrai et qu’un seul “objet” faux: vrai et faux.
SMALLTALK suit cette tradition: la classe True ne possède qu’une seule instance,
c’est l’objet true, de même, la classe False ne possède qu’une seule instance,
l’objet false.
À quoi servent ces deux instances? Naturellement, elles servent à donner des
réponses à des questions qui demandent de savoir si une chose est vrai ou faux. Et
quand avons-nous besoin de déterminer si quelque chose est vraie ou fausse?
Quand nous voulons choisir entre deux alternatives. Par exemple, la phrase «s’il
pleut, alors je prends mon parapluie» dit principalement: «est-ce qu’il pleut? Si la
réponse est oui (il est vrai qu’il pleut) alors je prends mon parapluie
(sinon, je le laisse à la maison)». En SMALLTALK, cette possibilité de
pouvoir choisir entre deux alternatives est implémentée avec ces deux
classes True et False qui décrivent ce que leurs instances, respectivement
true et false, doivent faire dans le cas où elles se trouvent receveur d’un
message de sélection entre des alternatives. La sélection la plus simple est du
style:
si qqch est vrai alors faire alternative vraie sinon faire alternative fausse
Cette phrase peut être traduite dans la pensée objet comme:
quelle est la valeur de vérité de qqch
si vrai2
faire alternative vraie
si faux3
faire alternative fausse
où “quelle est la valeur de vérité de qqch” correspond à un receveur quelconque
dont la seule chose qui nous intéresse est de savoir si la valeur de ce receveur est true
ou false.4
C’est exactement cela que nous avons fait d’une manière intuitive dans, par
exemple, la méthode aboie de la classe Chien donnée en page 120 et que nous
reproduisons ci-dessous:
aboie
"fait aboyer le chien"
self aboieBeaucoup
ifTrue: [self answer: ’bow wow, bow wow, bow wow’]
ifFalse: [self answer: ’woof’]
|
|
où nous reconnaissons aisément la correspondance entre quelle est la valeur de
vérité de qqch et self aboieBeaucoup, entre faire alternative vraie et ifTrue:
[self answer: ’bow wow, bow ...’] et entre faire alternative fausse et
ifFalse: [self answer: ’woof’].
Rappelons-nous que la variable aboieBeaucoup prenait soit la valeur true,
soit la valeur false. C’est donc une de ces deux pseudo-variables qui reçoit le
message ifTrue:ifFalse:, qui, elle, est définie dans la classe True de la manière
suivante:
ifTrue: trueAlternativeBlock ifFalse: falseAlternativeBlock
"répond la valeur de trueAlternativeBlock"
^trueAlternativeBlock value
|
|
Une méthode pour ce même sélecteur ifTrue:ifFalse: est aussi implémentée
dans la classe False comme:
ifTrue: trueAlternativeBlock ifFalse: falseAlternativeBlock
"répond la valeur de falseAlternativeBlock"
^falseAlternativeBlock value
|
|
Rappelons qu’un bloc est une expression SMALLTALK (et son contexte) en attente de son
évaluation.5
Les deux méthodes ifTrue:ifFalse: disent: si l’objet true reçoit ce
message alors, sans hésiter, il retourne la valeur du bloc vrai (la valeur du
paramètre trueAlternativeBlock), sinon, si c’est l’objet false qui reçoit ce
même message, alors, avec aussi peu d’hésitation, celui-ci retourne la
valeur du bloc faux (la valeur du paramètre falseAlternativeBlock).
L’objet true sait qu’il est vrai, de même que l’objet false sait qu’il est
faux!
Nous venons de voir comment construire des structures de
contrôle6
en SMALLTALK. Tandis que les structures de contôle sont des instructions primitives
dans la plupart des langages de programmation habituels, en SMALLTALK ce sont des
messages comme les autres: toute structure de contrôle peut être écrite en SMALLTALK
même.7
C’est la recherche de méthodes dans l’arbre d’héritage qui permet de distinguer
entre les différents cas. Autrement dit, les différents cas se matérialisent dans la
structure de l’arbre d’héritage, ou encore: la différence se matérialise dans
l’appartenance à des classes distinctes. Bien entendu, si nous ne voulons que
distinguer entre deux cas, nous n’avons besoin que de deux classes distinctes. Et
si nous voulons reconstruire des expressions booléennes, il suffit d’avoir une classe
True, décrivant ce qu’il faut faire dans le cas où un objet est vrai, et une classe
False, décrivant le comportement à exhiber dans le cas où un objet est
faux.8
Pour pouvoir utiliser ce message ifTrue:ifFalse: partout dans le système, il
suffit de s’assurer que le receveur de ce message est toujours une expression qui
s’évalue à la valeur true ou false, exactement comme nous l’avons fait dans
notre message aboie.
Muni de cette méthode ifTrue:ifFalse:, nous pouvons aisément écrire une
structure de contrôle qui ne choisit qu’une alternative: ifTrue:, qui détermine ce
qu’il y a à faire dans le cas où l’objet receveur est true, et une autre, ifFalse:,
qui, elle, indiquera l’activité à accomplir dans le cas où le receveur est l’objet
false. Pour éviter d’écrire cette méthode deux fois, une fois dans la classe True
et une autre fois dans la classe False, nous ajouterons sa définition dans la
sur-classe abstraite de ces deux classes, la classe Boolean, factorisant ainsi le
comportement commun des deux classes. Voici une manière de définir ces deux
méthodes:
ifTrue: trueAlternativeBlock
"répond la valeur de trueAlternativeBlock
si le receveur est true, sinon nil"
self ifTrue: trueAlternativeBlock ifFalse: [nil]
|
|
et
ifFalse: falseAlternativeBlock
"répond la valeur de falseAlternativeBlock
si le receveur est false, sinon nil"
self ifTrue: [nil] ifFalse: falseAlternativeBlock
|
|
Ainsi, tout le travail sera délégué aux méthodes ifTrue:ifFalse: des classes
True et False.
Mais ouvrez plutôt un explorateur de classes et admirez les
méthodes dans les classes True, False et Boolean. Ce sont
de merveilleux exemples, très simples, de la programmation
SMALLTALK.9