2009-10-29 90 views
8

Estoy tratando de comparar dos cadenas en Smalltalk, pero parece que estoy haciendo algo mal.Smalltalk - Comparar dos cadenas para la igualdad

sigo recibiendo este error:

Excepción no controlada: el receptor no booleana. Proceda por la verdad.

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

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

¿Alguna idea de lo que estoy haciendo mal?

Respuesta

16

Trate

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

No creo que necesita corchetes en la primera línea

encontrado gran explicación. thing is here

En Smalltalk, booleanos (es decir, verdadero o falso) son objetos: específicamente, son instancias de la clase base abstracta Boolean, o más bien de sus dos subclases True y False. Por lo tanto, cada booleano tiene un tipo True o False, y no tiene datos de miembros reales. Bool tiene dos funciones virtuales, ifTrue: y ifFalse :, que toman como argumento un bloque de código. True y False anulan estas funciones; La versión de True de ifTrue: llama al código que ha pasado, y la versión de False no hace nada (y viceversa para ifFalse :). Aquí hay un ejemplo:

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

Esas cosas entre corchetes son funciones esencialmente anónimas, por cierto. Excepto que son objetos, porque todo es un objeto en Smalltalk. Ahora, lo que sucede allí es que llamamos a un método "<", con el argumento b; esto devuelve un booleano. Llamamos a sus métodos if True: e ifFalse: pasando como argumentos el código que queremos ejecutar en cualquier caso. El efecto es el mismo que el del código de Ruby

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

Gracias a mi compañero Android. Ese fue el problema. – user69514

+0

Woof - No estoy familiarizado con Smalltalk pero recuerdo que los corchetes son para evaluación y si evalúas el operador '=' no obtendrás un boolean :) – Bostone

+0

suspiro - quería agregar el ejemplo de acode aquí, pero estaba mal formateado. Olvídalo, agregué una respuesta ... – blabla999

0

¿Debería estar bloqueando la comparación? Yo hubiera pensado que:

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

sería suficiente.

+1

Los parens son innecesarios y atípicos. De hecho, me parece que si estoy escribiendo expresiones que necesitan parens (especialmente parens anidados), probablemente estoy haciendo las cosas demasiado complicadas, y lo refactorizo ​​a una llamada temporal con nombre o llamada de método separada. –

1

[stringOne = stringTwo] es un bloque, no un booleano. Cuando se invoca el bloque, quizás resultará en un booleano. Pero no estás invocando el bloque aquí. En cambio, simplemente está causando que el bloque sea el receptor de ifTrue.

su lugar, tratar:

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

Como han dicho otros, que funcionará de la manera deseada si se deshace de la primera serie de corchetes.

Pero para explicar el problema que se estaba ejecutando en una mejor:

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

está pasando el mensaje ifTrue: a un bloque, y los bloques no entienden ese método, sólo los objetos booleanos hacen.

Si primero evaluar el bloque, se evaluará a un objeto real, que luego saber cómo responder:

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

O lo que realmente debe hacer, como otros han señalado:

stringOne = stringTwo ifTrue:[myNumber := 20] 

que evalúan stringOne = stringTwo a true antes de enviar ifTrue:[...] a él.

0

but I seem to be doing something wrong

Dado que está utilizando VisualWorks su instalación debe incluir una carpeta doc.

Mire AppDevGuide.pdf - tiene mucha información acerca de la programación con VisualWorks y más al punto que tiene mucha información introductoria sobre la programación de Smalltalk.

Mire la tabla de contenido al principio, hasta Capítulo 7 "Estructuras de control", haga clic en "Ramificación" o "Pruebas condicionales" y accederá a la sección correspondiente en el pdf que le informa sobre Smalltalk if-then-else y da ejemplos que lo habrían ayudado a ver lo que estaba haciendo mal.

0

me gustaría añadir lo siguiente 50Cent:

como bloques son en realidad lambdas cuales se pueden pasar alrededor, otro buen ejemplo sería el siguiente método:

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

por lo que el argumento para ifTrue:/ifFalse: en realidad puede provenir de otra persona. Este tipo de condiciones aprobadas a menudo es útil en el tipo de métodos ".. si está presente:" o "..onError:".

(originalmente pensado como un comentario, pero no pude conseguir el ejemplo de código para ser formateada)

Cuestiones relacionadas