Publicado el 9 de Agosto del 2020
752 visualizaciones desde el 9 de Agosto del 2020
154,7 KB
7 paginas
Creado hace 16a (22/06/2008)
Clase práctica Objetos II
1er cuatrimestre 2006
Estructuras de control en Smalltlak
En los lenguajes de programación imperativos existen, como parte del lenguaje, estructuras de
control de flujo. Por ejemplo, el if:
If (condición) {
sentencias
}
Al programar en Smalltalk, el equivalente a esa estructura tiene la forma:
condicion ifTrue: [sentencias].
La razón de esta forma particular del if proviene de una decisión de diseño del Smalltalk: todo es un
objeto. Veamos en detalle las consecuencias de esta decisión.
Para comprender la construcción anterior, es necesario considerar, en primer lugar, que los Boolean
también son objetos. En particular, la clase Boolean tiene dos subclases, True y False, cuyas únicas
instancias son, respectivamente, las constantes true y false.
Cuando evaluamos una expresión booleana en Smalltalk, el resultado es alguna de esas constantes.
Por ejemplo si evaluamos:
a := 3.
a < 5
obtenemos true. (Recordemos además que a es un objeto de clase SmallInteger y que < es un
mensaje que SmallInteger sabe responder).
Podemos deducir que ifTrue: debe ser un mensaje keyword que la clase True sabe responder. El
argumento del mensaje no puede ser otra cosa que un objeto. Asi que el argumento [sentencias]
también es un objeto. Este tipo de objetos, llamados bloques o clausuras (son instancias de
BlockClosure), son porciones de código suspendido, sin evaluar. Responden, en particular, al
mensaje value, cuyo efecto es evaluar el código suspendido.
Antes de ver los bloques en mayor profundidad, analicemos un ejemplo de if. Consideremos que True
define su método ifTrue: como la evaluación del argumento, mientras que False no hace nada.
Cuando evaluamos:
anObject < 5 ifTrue: [Transcript show: ‘menor a cinco’].
lo que ocurrre es lo siguiente:
1. Se envia el mensaje < al objeto anObject con el argumento 5. El resultado (que dependerá de
quién sea anObject) será la constante true o false (instancias de True o False
respectivamente).
2. Al resultado (true o false) se le envia el mensaje ifTrue: con [Transcript show: ‘menor a cinco’]
3. Si el resultado de anObject < 5 fue true, el método ifTrue: definido en True indica que se
como argumento
evalúe el código entre corchetes.
4. Si el resultado fue false, el método ifTrue: definido en False no hace nada, el bloque no se
evaluará y no habrá ningún efecto, tal como se espera.
Hasta aquí hemos visto lo que parece una solución ingeniosa para una estructura del tipo if utilizando
solamente objetos y mensajes (veremos más adelante que en Smalltalk el flujo de ejecución se
controla con objetos y mensajes. No hay construcciones sintácticas especiales para esto).
Sin embargo, la introducción de los bloques en Smalltalk permite resolver muchas otras situaciones
de programación. Veamos primero algunos detalles de los bloques.
Late binding y polimorfismo
Notemos en el ejemplo anterior que ifTrue: tiene comportamientos distintos en True y en False. Esta
cualidad de poder definir distintas respuestas a un mensaje de acuerdo al receptor se denomina
polimorfismo.
Para que funcione el ejemplo anterior, es indispensable que la resolución del método que responde al
mensaje se haga en tiempo de ejecución, porque el resultado de (anObject < 5) es desconocido en
tiempo de compilación. Este mecanismo de resolución tardía del método que responde a un mensaje
se llama late-binding y es lo que permite el polimorfismo en Smalltlak.
Bloques
• Los bloques son secuencias de instrucciones cuya ejecución es diferida, es decir, el código que
representan podría no ser ejecutado nunca.
• Se notan escribiendo el código que los componen entre [].
“Todo es un objeto” (III)
• Los bloques son objetos. Por lo tanto pueden ser asignados a variables, pasados como
parámetros o devueltos como resultado
• La evaluación de un bloque se realiza enviándole el mensaje value
Ejemplos:
Expresión
[Ballena new deciAlgo]
[Ballena new deciAlgo] value
miBloque := [Ballena new deciAlgo].
miBloque value.
b := [:a | a deciAlgo].
b value: Ballena new.
b value: Perro new.
b := [:a | |nombre|
nombre := a nombre.
Transcript show: nombre; cr.].
b value: (Humano new nombre: 'Juan
Perez').
p := Humano new nombre: 'Felipe'.
[Transcript show: (p nombre);cr] value.
[Float pi * 4.
3 + 4] value
Descripción
Un bloque de código. El código dentro del bloque no
ha sido evaluado todavía.
Evalua el código dentro del bloque
Se puede almacenar en una variable la referencia a un
bloque
Los bloques pueden recibir parámetros. En ese caso
se los evalua con los mensajes value:, value:value:,
etc
Los bloques pueden tener variables temporales que se
declaran entre | |
Dentro de un bloque, las variables en scope son las
variables del scope en el que se definen los bloques.
El binding de valores a variables se produce en tiempo
de ejecución (el envío del mensaje value).
Los bloques devuelven el resultado de la evaluación de
la última sentencia. En este caso, 7.
Control del flujo de ejecución
Evaluación condicional
• La clase Boolean y sus subclases definen los métodos:
o
o
o
ifTrue:
ifTrue:ifFalse:
ifFalse:
o and: aBlock
o or: aBlock
o & aBoolean
o
| aBoolean
• AND y OR tambien son métodos de (las subclases de) Boolean:
recibe un bloque que evalua sólo si es necesario
recibe un bloque que evalua sólo si es necesario
En todos los casos los argumentos de estos mensajes son bloques que se evaluarán
dependiendo del receptor del mensaje (recordar que True y False son subclases de Boolean).
Descripción
La expresión “a < 17” devuelve un objeto Boolean. Si
el objeto resultante es true, se ejecutará el primero
bloque y si en cambio el objeto resultante es false se
ejecutará el segundo bloque
ifTrue:, ifFalse, etc. devuelven el resultado de evaluar
el bloque. En Este caso paridad tendrá el valor 0.
Cuando no se devuelve ningún valor, se devuelve la
constante especial nil (instancia de UndefinedObject).
En este caso paridad tendrá el valor nil.
nil también es un objeto. Sabe responder, entre otros:
isNil, que devuelve true (los demas objetos devuelven
false)
Ejemplos:
Expresión
a := 5.
a < 17 ifTrue:
a := 4.
paridad := a odd ifTrue: [1] ifFalse: [0].
a := 4.
paridad := a odd ifTrue: [1].
ifFalse:
[Transcript show: ‘mayor’]
[Transcript show: ‘menor’]
Ciclos
• La clase Number define los métodos:
Ejemplos:
Expresión
k := 0.
6 timesRepeat: [k := k + 1].
l := Loro new.
4 timesRepeat: [l deciAlgo].
k := 1.
1 to: 6 do: [:i | k := k * i].
k.
to:do:
to:by:do:
Que recibe otro número y un bloque con un 1 parámetro
Que recibe dos números (el segundo es el incremento) y un bloque con
1 parámetro
• La clase Integer define además el método:
timesRepeat: Que recibe un bloque sin parámetros
o
o
o
Descripción
Suma 6 veces 1 la variable k
Le pide 4 veces al loro l que diga algo
Multiplica los números del 1 al 6, es decir, calcula 6!
o whileTrue
o whileFalse
o
repeat
Que recibe un bloque sin parámetros que será ejecutado mientras el
bloque receptor devuelva true
Que recibe un bloque sin parámetros que será ejecutado mientras el
bloque receptor devuelva false
Equivale a whileTrue: []
Equivale a whileFalse: []
Que evalua el bloque receptor hasta que este interrumpa la
evaluación por la fuerza
Descripción
Suma a k el número 1 hasta que k valga 6
Idem pero escrito de otra forma
Suma todos los números impares entre 1 y 10
k := 1.
1 to: 10 by: 2 do: [:i | k := k + i].
k
Ciclos tipo ‘while’
• BlockClosure define los métodos
o whileTrue:
o whileFalse:
Ejemplos:
Expresión
k := 0.
[k < 6] whileTrue: [k := k + 1].
k.
k := 0.
[k >= 6] whileFalse: [k := k + 1].
k.
Colecciones
Colecciones básicas
Set
add:
size
includes:
Bag
(conjunto con
repeticiones)
add:
size
includes:
occurrencesOf:
Dictionary
Interval
(intervalo de
números)
(contiene valor)
includesKey:
(contiene clave)
at:put:
at:
includes:
size
keys
includes:
do:
OrderedCollection add:
at:
at:put:
first
last
addFirst:
addLast:
removeFirst:
removeLast:
indexOf:
add:
todos los de
OrderedCollection
Ejemplos
a := #(1 2 3 4) copy.
a at: 1.
a at: 2 put: $c; yourself.
a size
s := Set new.
s add: 1; add: 1; add: 2; add: $a; add: $a; yourself.
s size.
s includes: 1.
s includes: 4.
b := Bag new.
b add: 1; add: 1; add: 2; add: $a; add: $a; yourself.
b size.
b includes: 1.
b includes: 4.
b occurrencesOf: 1.
b occurrencesOf: 2.
d := Dictionary new.
d at: 'hola' put: 'hello'.
d at: 'perro' put: 'dog'.
d at: 'pitufo' put: 'smurff'.
d at: 'pitufo'.
d includes: 'perro'. “false”
d includesKey: 'perro'. “true”
d includesKey: 'loro'.
in := Interval from: 3 to: 30 by: 5.
in includes: 4.
in includes: 8.
in do: [:i | Transcript show: i displayString; cr].
oC := OrderedCollection new.
oC add: 3; add: 2; add: 5; yourself.
oC add: 4 after: 2; yourself.
"OrderedCollection sirve para implementar pilas y colas"
oC addFirst: 50; yourself.
oC addLast: 400; yourself.
oC removeLast; yourself.
x := SortedCollection new.
x add: 3; add: 2; add: 5; yourself.
"se puede cambiar el criterio de ordenamiento"
x sortBlock: [:a :b | a >= b]; yourself.
Nota: Las colecciones de Smalltalk son heterogéneas. Es decir, no es necesario que los elementos
sean todos de la misma clase.
Operaciones básicas:
Colección
Array
Operaciones
at:
at:put:
size
SortedCollection
Enumeracion de elementos
do: aBlock
select: aBlock
bloque con un parámetro
evalua el argumento aBlock para cada uno de los elementos del receptor
bloque con un parámetro, evalua en booleano
evalua el argumento aBlock para cada
Comentarios de: Estructuras de control en Smalltlak - Clase práctica Objetos II (0)
No hay comentarios