2010-06-27 10 views
7
a > b 
ifTrue:[ 'greater' ] 
ifFalse:[ 'less or equal' ] 

Ma compréhension est que Boolean> b reçoit le ifTrue du message: [ 'plus'], puis ifFalse: [ 'inférieur ou égal'] conforme à la généralisation:Pourquoi ifTrue et ifFalse ne sont pas séparés par; dans Smalltalk?

objectInstance selector; selector2 

Mais une Le point-virgule est nécessaire pour indiquer que le destinataire de selector2 n'est pas (sélecteur objectInstance) mais objectInstance. N'est-ce pas la même chose avec l'exécution conditionnelle ci-dessus?

+0

Juste pour l'exhaustivité, le; est pour une _cascade_ - une séquence de messages envoyés au même objet. foo bar; baz. est identique au sens de foo bar. foo baz. –

+0

votre compréhension est fausse; ce n'est pas "reçoit ... ET ALORS ...", mais "reçoit un message". Voir ma réponse ci-dessous. – blabla999

Répondre

19

Le sélecteur de la méthode est Boolean>>ifTrue:ifFalse:, ce qui signifie qu'il est une méthode avec deux paramètres, pas deux méthodes avec un paramètre. Ergo, pour appeler la méthode, vous lui envoyez le message ifTrue:ifFalse: avec deux arguments de bloc.

Notez que pour des raisons de commodité, il existe aussi des méthodes Boolean>>ifFalse:ifTrue:, Boolean>>ifTrue: et Boolean>>ifFalse:.

7

Tout en question a déjà été sayd, mais juste pour votre amusement:

Comme nous l'avons dit,

rcvr ifTrue:[...] ifFalse:[...] 

est le seul et seul message # 'ifTrue: ifFalse:' avec 2 args envoyé à rcvr. La valeur de cette expression est celle de ce message envoyé. En revanche:

rcvr ifTrue:[...]; ifFalse:[...] 

est une cascade de messages séquentiels 2 (# de 'ifTrue: 'et #' ifFalse:'), chacune avec une arg envoyé à RCVR. La valeur de l'expression est celle renvoyée par le dernier envoi.

Maintenant, la chose drôle est que booléens ne comprennent ifTrue:/ifFalse: (chacun avec 1 arg), si votre code fonctionne pour l'effet secondaire (l'évaluation de ces blocs), mais pas pour sa valeur. Cela signifie que:

a > b ifTrue:[Transcript showCR:'gt'] ; ifFalse:[Transcript showCR:'le'] 

génère la même sortie que:

a > b ifTrue:[Transcript showCR:'gt'] ifFalse:[Transcript showCR:'le'] 

mais:

msg := a > b ifTrue:['gt'] ; ifFalse:['le'] 

va générer des valeurs différentes dans msg que:

msg := a > b ifTrue:['gt'] ifFalse:['le'] 

en fonction des valeurs de a et b. Essayez (a b) = (1 2) vs (a b) = (2 1) ...

Le problème de nombreux débutants Smalltalk est qu'ils pensent à ifXXX: comme syntaxe, où il s'agit en fait d'un envoi de message qui génère de la valeur. En outre, le semi n'est pas un séparateur d'instructions comme dans beaucoup de langues précédemment apprises, mais une construction d'envoi de message de séquencement.

Un piège pour les débutants, parce que le code semble fonctionner pour certaines combinaisons de valeurs particulières, alors qu'il génère des résultats amusants pour les autres. Espérons que vos tests unitaires couvrent ces ;-)

edit: pour voir où la mauvaise valeur vient, jetez un oeil à ce qui est retourné par la Boolean >> ifFalse: méthode pour un vrai récepteur ...

+0

+1 pour avis de différentes valeurs de retour –