2009-10-29 7 views
8

Sto provando a confrontare due stringhe in Smalltalk, ma sembra che stia facendo qualcosa di sbagliato.Smalltalk - Confronta due stringhe per l'uguaglianza

Continuo a ricevere questo errore:

Eccezione non gestita: ricevitore non booleano. Procedi per la verità.

stringOne := 'hello'. 
stringTwo := 'hello'. 
myNumber := 10. 

[stringOne = stringTwo ] ifTrue:[ 
    myNumber := 20]. 

Qualche idea di cosa sto facendo male?

risposta

16

Prova

stringOne = stringTwo 
    ifTrue: [myNumber := 20]` 

Non credo che avete bisogno di parentesi quadre nella prima riga

Trovato grande spiegazione. Tutta thing is here

In Smalltalk, booleani (vale a dire, vero o falso) sono oggetti: in particolare, sono istanze della classe base astratta booleano, o meglio dei suoi due sottoclassi vero e falso. Quindi ogni booleano ha tipo True o False e nessun dato membro effettivo. Bool ha due funzioni virtuali, ifTrue: e ifFalse:, che prendono come argomento un blocco di codice. Sia True che False annullano queste funzioni; La versione di True di ifTrue: chiama il codice che è passato e la versione di False non fa nulla (e viceversa per ifFalse :). Ecco un esempio:

a < b 
    ifTrue: [^'a is less than b'] 
    ifFalse: [^'a is greater than or equal to b'] 

Quelle cose tra parentesi quadre sono essenzialmente funzioni anonime, tra l'altro. Tranne che sono oggetti, perché tutto è un oggetto in Smalltalk. Ora, quello che succede è che chiamiamo il metodo "<", con argomento b; questo restituisce un valore booleano. Chiamiamo i suoi ifTrue: e ifFalse: metodi, passando come argomenti il ​​codice che vogliamo venga eseguito in entrambi i casi. L'effetto è uguale a quello del codice Ruby

if a < b then 
    puts "a is less than b" 
else 
    puts "a is greater than or equal to b" 
end 
+0

Grazie il mio compagni di Android. Questo era il problema – user69514

+0

Woof - Non sono così familiare w Smalltalk ma mi ricordo che le parentesi quadre sono per la valutazione e se valuti l'operatore '=' non avrai un booleano :) – Bostone

+0

sigh - volevo aggiungere l'esempio di codice qui, ma era malformato Dimenticalo, ho aggiunto una risposta ... – blabla999

0

Se si sta bloccando il confronto? Avrei pensato:

(stringOne = stringTwo) ifTrue: [ myNumber := 20 ] 

sarebbe sufficiente.

+1

I paren ci sono sia inutili che atipici. In effetti, trovo che se sto scrivendo espressioni che hanno bisogno di parents (specialmente parents annidati), probabilmente sto rendendo le cose troppo complicate e lo rifattiamo con una chiamata di metodo temporanea o separata. –

1

[stringOne = stringTwo] è un blocco, non un booleano. Quando viene richiamato il blocco, forse si tradurrà in un booleano. Ma non stai invocando il blocco qui. Invece, stai semplicemente facendo in modo che il blocco sia il ricevitore di ifTrue.

Invece, provare:

(stringOne = stringTwo) ifTrue: [ 
    myNumber := 20 ]. 
4

Come altri hanno detto, che funzionerà nel modo desiderato Se sbarazzarsi della prima serie di parentesi quadre.

Ma per spiegare il problema si stesse eseguendo in meglio:

[stringOne = stringTwo ] ifTrue:[myNumber := 20] 

sta passando il messaggio ifTrue: ad un blocco, e blocchi non capiscono che il metodo, solo gli oggetti booleani fanno.

Se si valuta prima del blocco, si valuterà a un vero e proprio oggetto, che poi sa come rispondere:

[stringOne = stringTwo] value ifTrue:[myNumber := 20] 

O che cosa si dovrebbe davvero fare, come altri hanno fatto notare:

stringOne = stringTwo ifTrue:[myNumber := 20] 

entrambi valutano stringOne = stringTwo a true prima di inviare ifTrue:[...] ad esso.

0

but I seem to be doing something wrong

Dato che si sta utilizzando VisualWorks vostra installazione dovrebbe includere una cartella doc.

sguardo al AppDevGuide.pdf - ha un sacco di informazioni sulla programmazione con VisualWorks e più al punto che ha un sacco di informazioni introduttive sulla programmazione Smalltalk.

Guardare attraverso il tavolo Contenuto all'inizio, fino Capitolo 7 "Strutture di controllo", fare clic su "Branching" o "test condizionali" e ti verrà portato alla sezione appropriata nel PDF che si dice tutto Smalltalk if-then-else e fornisce esempi che ti avrebbero aiutato a vedere cosa stavi facendo male.

0

desidero aggiungere il seguente 50Cent:

come blocchi sono in realtà lambda che possono essere passate intorno, un altro buon esempio potrebbe essere il seguente metodo:

do:aBlock ifCondition:aCondition 
    ... some more code ... 
    aCondition value ifTrue: aBlock. 
    ... some more code ... 
    aBlock value 
    ... 

così l'argomento ifTrue:/ifFalse: può effettivamente venire da qualcun altro. Questo tipo di condizioni passate è spesso utile nel tipo di metodi "..ifAbsent:" o "..onErrore:".

(originariamente inteso come un commento, ma non ho potuto ottenere l'esempio di codice per essere formattato)