Hola, estoy haciendo la remoción de elementos de un OrderedCollection como indica Pharo By Example:
range do: [:aNumber | aNumber isPrime ifFalse: [ range remove: aNumber ] ]
Lo que me pasa, tomando este ejemplo, es que me tira error porque me dice que aNumber es nil (la coleccion no contiene nils ya me fijé).
Ahora si hago:
range copy do: [:aNumber | aNumber isPrime ifFalse: [ range remove: aNumber ] ]
me funciona pero me mantiene igual la coleccion.
Gracias.
El primer ejemplo no funciona porque, si te fijás en la implementación del método do: de la clase OrderedCollection lo que hace es ir desde el primer índice hasta el último en el momento de inicio de la iteración. Y si vos removés un elemento en medio de la iteración entonces el método remove: internamente pone un nil al final y decrementa el último índice pero se va a seguir iterando hasta más allá de ese límite actualizado. Por eso es que aparece ese nil.
El otro ejemplo que pusiste más abajo sí funciona porque se itera sobre una copia de la colección y se actualiza la colección original. Probá este código en el Playground y fijate qué te queda en el Transcript:
| rango |
rango := (2 to: 20) asOrderedCollection.
Transcript show: rango ; cr.
rango copy do: [ :unNumero | unNumero isPrime ifFalse: [ rango remove: unNumero ] ].
Transcript show: rango.
Imprime la colección modificada. Por lo tanto si yo hiciese copy do debería funcionar, pero no funciona.
¿Por qué decís que no funciona si acabás de probar eso mismo y la colección quedó modificada?
Claro pero lo hago en mi método y no funciona, se mantiene igual y el test me tira Assertion Failed.
Entonces el problema está en otro lado y no en el ejemplo del libro. ¿Qué tiene de distinta tu implementación del ejemplo?
yo lo que hago es, en un orderedcolection de mensajes ( objetos mensaje):
mensajesrecibidos copy do: [:mensaje | (mensaje pedirEmisor = destino) ifTrue: [mensajesrecibidos remoove:mensaje ] ].
destino en este caso es un objeto grupo. Yo me fijo que el mensaje viene de un grupo con pedirEmisor, que me devuelve la referencia a un objeto Grupo.
Esa línea de código está bien (salvo el typo del final). Si después de ejecutarla la colección sigue intacta entonces la condición que estás evaluando nunca es verdadera, es decir, que el objeto que te devuelve el método pedirEmisor nunca es igual al objeto destino. El problema debe estar en la implementación del método pedirEmisor o en algún otro lado.
Revisaré eso entonces, te agradezco.
Revisaré eso entonces, te agradezco.