Curso Ruby
Curso Ruby
Curso Ruby
module Pepita
@energia = 100
@ciudad = Obera
def self.ciudad
@ciudad
end
end
Para ver cuánto recorrer? Mensaje abs que entienden los números y nos retorna su valor
absoluto
> 17.abs
=> 17
> (-17).abs
=> 17
module BuenosAires
def self.kilometro
return 0
end
end
module Obera
def self.kilometro
return 1040
end
end
module Iruya
def self.kilometro
return 1710
end
end
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
@ciudad = destino
end
end
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.distancia_a(destino)
(ciudad.kilometro - destino.kilometro).abs
end
def self.gastar_energia!(destino)
@energia -= (distancia_a(destino)) / 2
end
end
Modificá la solución del ejercicio anterior para que sean las ciudades las que calculan
las distancias. Pensá que no solo Obera debe tener este método, sino
también BuenosAires e Iruya, para cuando tenga que volver.
module Obera
def self.kilometro
1040
end
def self.distancia_a(destino)
end
end
module Iruya
def self.kilometro
1710
end
def self.distancia_a(destino)
end
end
module BuenosAires
def self.kilometro
end
def self.distancia_a(destino)
end
end
module Pepita
@energia = 1000
@ciudad = Obera
def self.energia
@energia
end
def self.ciudad
@ciudad
end
def self.cantar!
end
def self.comer_lombriz!
@energia += 20
end
def self.volar_en_circulos!
@energia -= 10
end
def self.volar_hacia!(destino)
self.gastar_energia!(destino)
@ciudad = destino
end
def self.gastar_energia!(destino)
end
end
module Pepita
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
end
def self.feliz?
end
end
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
end
def self.feliz?
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!(10)
end
end
end
¿Y times qué es?
Es un mensaje que entienden los números que sirve para ejecutar una
porción de código varias veces.
Modificá la solución para que si Pepita no está débil vuele en círculos 3 veces.
module Pepita
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
end
def self.feliz?
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!(10)
else
3.times{self.volar_en_circulos!}
end
end
end
module Pepita
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 10
end
def self.comer_alpiste!(gramos)
@energia += gramos * 15
end
def self.debil?
end
def self.feliz?
end
def self.hacer_lo_que_quiera!
if self.debil?
self.comer_alpiste!(10)
5.times{self.volar_en_circulos!}
else
3.times{self.volar_en_circulos!}
end
end
end
module Pepo
@energia = 1000
def self.energia
@energia
end
def self.volar_en_circulos!
if self.pesado?
@energia -= 15
else
@energia -= 5
end
end
def self.comer_alpiste!(gramos)
@energia += gramos /2
end
def self.pesado?
end
def self.hacer_lo_que_quiera!
self.comer_alpiste!(120)
end
end
module Pachorra
def self.entrenar_ave!
10.times{Pepita.volar_en_circulos!}
Pepita.comer_alpiste!(30)
5.times{Pepita.volar_en_circulos!}
Pepita.hacer_lo_que_quiera!
end
end
Agregale a Pachorra el método firmar_contrato!(ave), de forma tal que cuando le
enviemos el mensaje entrenar_ave! haga entrenar al último ave con el que haya
firmado contrato.
module Pachorra
def self.firmar_contrato!(ave)
@ave = ave
end
def self.entrenar_ave!
10.times{@ave.volar_en_circulos!}
@ave.comer_alpiste!(30)
5.times{@ave.volar_en_circulos!}
@ave.hacer_lo_que_quiera!
end
end
Dicho de otra manera, la rutina nos define cuál debe ser la interfaz que
debe respetar un objeto para poder ser utilizado.
module Norita
@energia = 500
def self.energia
@energia
end
def self.volar_en_circulos!
@energia -= 30
end
def self.comer_alpiste!(gramos)
@energia -= gramos
end
def self.hacer_lo_que_quiera!
end
end
Emilce.ave = Pepita
module Inodoro
@cafeina_en_sangre = 90
@compinche
#get
def self.cafeina_en_sangre
@cafeina_en_sangre
end
def self.compinche
@compinche
end
#set
def self.compinche=(un_compinche)
@compinche= un_compinche
end
end
module Eulogia
@enojada = false
def self.enojada?
@enojada
end
end
module Mendieta
@ganas_de_hablar = 5
def self.ganas_de_hablar
@ganas_de_hablar
end
def self.ganas_de_hablar=(ganas)
@ganas_de_hablar = ganas
end
end
@cafeina_en_sangre = 90
def self.cafeina_en_sangre
@cafeina_en_sangre
end
def self.compinche=(nuevocompinche)
@compinche=nuevocompinche
end
def self.compinche
@compinche
end
def self.tomar_mate!
@compinche.recibir_mate!
@cafeina_en_sangre+=10
end
end
module Eulogia
@enojada = false
def self.enojada?
@enojada
end
def self.recibir_mate!
@enojada=true
end
end
module Mendieta
@ganas_de_hablar = 5
def self.recibir_mate!
@ganas_de_hablar=0
end
def self.ganas_de_hablar
@ganas_de_hablar
end
def self.ganas_de_hablar=(nuevasganas)
@ganas_de_hablar=nuevasganas
end
end
Variables:
Despedida = “adiós”
Despedida.size()
Referencias implícitas que son temporales (sólo existen durante el envío de mensajes)
"ni hao".upcase
^
+-- Acá hay una referencia implícita al objeto "ni hao"
saludo.upcase.size
^
+-- Y acá, otra referencia implícita a "HOLA"
Múltiples Referencias:
> "buen día".equal? "buen día"
> despedida.equal? "buen día"
> otro_saludo.equal? otro_saludo
> despedida.equal? otro_saludo
Equivalencia:
qué pasa si lo que quiero es comparar los objetos no por su identidad, sino
por que representen la misma cosa?
Objetos conocidos:
module Fito
@felicidad = 100
def self.comer!(calorias)
@felicidad += calorias * 0.001
end
def self.felicidad
@felicidad
end
end
module AbuelaClotilde
def self.alimentar_nieto!
Fito.comer!(2000)
Fito.comer!(1000)
end
end
Atributos y parámetros:
module Pepita
@energia = 100
def self.volar_en_circulos!
@energia -= 10
end
def self.ciudad=(una_ciudad)
@ciudad = una_ciudad
end
def self.ciudad
@ciudad
end
end
Pepita.ciudad = Iruya
1. La propia referencia Iruya
2. El atributo @ciudad de Pepita
3. una_ciudad: porque los parámetros de los métodos ¡también son
referencias! Sólo que su vida es más corta: viven lo que dure la
evaluación del método en el que se pasan.
----
def self.volar_en_circulos!
@energia = @energia - 10
end
cambiar la energía de Pepita: pasa de su valor actual, @energia, a ese valor
menos 10. Por ejemplo, pasa de 100 a 90. ¿Significa esto que el 100 se
transforma en un 90 ?
module Pepita
@energia = 100
def self.volar_en_circulos!
@energia -= 10
end
def self.ciudad=(una_ciudad)
@ciudad = una_ciudad
end
end
module Iruya
end
...si bien:
Objetos compartidos:
module Fito
def self.amigo=(un_amigo)
@amigo = un_amigo
end
def self.es_feliz_como_su_amigo?
@amigo.felicidad > 105
end
end
Creá un programa que inicialice al amigo de Fito y al nieto de AbueloGervasio de forma
que ambos conozcan al mismo objeto (Juli).
Luego, hacé que el abuelo alimente a su nieto 3 veces. ¿Qué pasará con Fito? ¿Se
pondrá feliz?
Fito.amigo = Juli
AbueloGervasio.nieto = Juli
3.times { AbueloGervasio.alimentar_nieto! }
module Fideos
@ajies = 0
def self.ajies
@ajies
end
def self.ajies=(cantidad)
@ajies = cantidad
end
def self.picantes?
@ajies > 2
end
def self.descartar_la_salsa!
@ajies = 0
end
end
module Jor
@plato_del_dia
def self.plato_del_dia=(plato)
@plato_del_dia = plato
end
def self.picantear!
@plato_del_dia.ajies = @plato_del_dia.ajies + 5
end
end
module Luchi
@plato_del_dia = plato
if @plato_del_dia.ajies > 10
@plato_del_dia.descartar_la_salsa!
end
end
end
Colecciones:
module CarlosDuty
@cantidad_logros=0
def self.jugar!(un_tiempo)
if un_tiempo>2
@cantidad_logros+=1
else
false
end
end
def self.violento?
true
end
def self.dificultad
30 - (@cantidad_logros * 0.5)
end
end
module TimbaElLeon
@dificultad =25
def self.violento?
false
end
def self.jugar!(un_tiempo)
@dificultad =25+un_tiempo
end
def self.dificultad
@dificultad
end
end
module Metroide
@nivel_espacial = 3
def self.dificultad
100
end
def self.jugar!(un_tiempo)
@nivel_espacial = @nivel_espacial +1
end
def self.violento?
@nivel_espacial > 5
end
end
Listas:
[2, 3, 3, 9]
module Juegoteca
def self.juegos
@juegos
end
end
Comandos básicos:
Podemos agregar un elemento enviándole push a la colección o quitarlo
enviándole delete:
numeros_de_la_suerte.include? 6
# Devuelve true, porque contiene al 6...
numeros_de_la_suerte.include? 8
# ...devuelve false, porque no contiene al 8.
numeros_de_la_suerte.size
# Devuelve 3, porque contiene al 6, 42 y 9
Set o No set:
tanto las listas como los sets tienen mensajes en común. Dicho de otro
modo, son polimórficos para algunos mensajes. Por
ejemplo: push, delete, include? y size.
Mejorando la juegoteca:
module Juegoteca
@puntos = 0
def self.juegos
@juegos
end
def self.puntos
@puntos
end
def self.adquirir_juego!(un_juego)
@juegos.push (un_juego)
@puntos += 150
end
def self.borrar_juego!(un_juego)
@juegos.delete (un_juego)
end
def self.completa?
end
end
end
En conclusión:
Bloques:
un_numero = 7
incrementador = proc { un_numero = un_numero + 1 }
otro_numero = 5
duplicador = proc { otro_numero = otro_numero * 2 }.call
un_numero = 3
sumar_a_otros_dos = proc { |un_sumando, otro_sumando| un_numero = un_numero +
un_sumando + otro_sumando }
> sumar_a_otros_dos.call(1,2)
=> 6
algunos_numeros = [1, 2, 3, 4, 5]
mayores_a_3 = algunos_numeros.select { |un_numero| un_numero > 3 }
> mayores_a_3
=> [4, 5]
module Juegoteca
def self.juegos
@juegos
end
def self.juegos_violentos
juegos.select{|juegos| juegos.violento?}
end
end
> uno_mayor_a_3
=> 4
module Juegoteca
def self.juegos
@juegos
end
def self.juego_mas_dificil_que(una_dificultad)
end
end
module Juegoteca
def self.juegos
@juegos
end
def self.mucha_violencia?
end
def self.muy_dificil?
end
end
module Juegoteca
def self.juegos
@juegos
end
def self.juegos_violentos
end
def self.dificultad_violenta
end
end
Dijimos que map no modifica la colección original. Pero, ¿qué ocurriría si el
mensaje dentro del bloque en el map sí tiene efecto?
module Juegoteca
def self.juegos
@juegos
end
def self.juegos_violentos
end
def self.promedio_de_violencia
self.juegos_violentos.sum {|un_juego| un_juego.dificultad} / self.juegos_violentos.count {|
un_juego| un_juego.violento?}
end
end
golondrinas
.select { |una_golondrina| una_golondrina.energia > 100 }
.each { |una_golondrina| una_golondrina.volar_hacia! Iruya }
Definí el método jugar_a_todo! en la Juegoteca, que haga jugar a cada uno de los juegos
durante 5 horas. Recordá que los juegos entienden jugar!(un_tiempo).
module Juegoteca
def self.juegos
@juegos
end
def self.jugar_a_todo!
end
end
module Bouba
@salud = 100
def self.salud
@salud
end
def self.gritar
@gritar = "¡agrrrg!"
end
def self.sabe_correr?
false
end
def self.esta_vivo?
@salud > 0
end
def self.recibir_danio!(cant_danio)
if salud <= 0
@salud = 0
end
end
end
Además cuenta con un nivel de energia, que inicia en 1000, pero todavía no
haremos nada con él. Definí un método getter para este atributo.
module Juliana
@energia = 1000
def self.energia
@energia
end
@atacar = zombie.recibir_danio!(cant_danio)
end
end
¡Bouba no está solo! Resulta que tiene un amigo, Kiki. Podríamos decir que
los dos son tal para cual: ¡el comportamiento de ambos es exactamente el
mismo! Es decir, no sabe_correr?, grita "¡agrrrg!", recibe daño de la misma
forma...
Definí otro objeto, Kiki, que se comporte de la misma forma que Bouba. ¡Te dejamos
a Bouba para que lo uses como inspiración!
module Bouba
@salud = 100
def self.salud
@salud
end
def self.gritar
@gritar = "¡agrrrg!"
end
def self.sabe_correr?
false
end
def self.esta_vivo?
@salud > 0
end
def self.recibir_danio!(cant_danio)
if salud <= 0
@salud = 0
end
end
end
module Kiki
@salud =100
def self.salud
@salud
end
def self.gritar
@gritar = "¡agrrrg!"
end
def self.sabe_correr?
false
end
def self.esta_vivo?
@salud > 0
end
def self.recibir_danio!(cant_danio)
if salud <= 0
@salud = 0
end
end
end
module Bouba
@salud = 100
def self.salud
@salud
end
def self.gritar
@gritar = "¡agrrrg!"
end
def self.sabe_correr?
false
end
def self.esta_vivo?
@salud > 0
end
def self.recibir_danio!(cant_danio)
@salud -= [cant_danio*2, 0].max
if salud <= 0
@salud = 0
end
end
def self.sin_vida?
!self.esta_vivo?
end
end
module Kiki
@salud =100
def self.salud
@salud
end
def self.gritar
@gritar = "¡agrrrg!"
end
def self.sabe_correr?
false
end
def self.esta_vivo?
@salud > 0
end
def self.recibir_danio!(cant_danio)
if salud <= 0
@salud = 0
end
end
def self.sin_vida?
!self.esta_vivo?
end
end
CLASES:
module CelularDeMaría
@saldo = 25
def self.realizar_llamada!
@saldo -= 5
end
def self.cargar_saldo!(pesos)
@saldo += pesos
end
end
module CelularDeLucrecia
@saldo = 25
def self.realizar_llamada!
@saldo -= 5
end
def self.cargar_saldo!(pesos)
@saldo += pesos
end
end
class Celular
def initialize
@saldo = 25
end
def realizar_llamada!
@saldo -= 5
end
def cargar_saldo!(pesos)
@saldo += pesos
end
end
class Zombi
def initialize
@salud = 100
end
def salud
@salud
end
def gritar
@gritar = "¡agrrrg!"
end
def sabe_correr?
false
end
def esta_vivo?
@salud > 0
end
def recibir_danio!(cant_danio)
if salud <= 0
@salud = 0
end
end
def sin_vida?
!self.esta_vivo?
end
end
INSTANCIAS:
Como habrás visto, definir una clase es muy similar a definir un objeto.
Tiene métodos, atributos... ¿cuál es su particularidad, entonces? La clase
es un objeto que nos sirve como molde para crear nuevos objetos.
Celular, al igual que todas las clases, entiende el mensaje new, que crea una
nueva instancia de esa clase.
bouba = Zombi.new
kiki = Zombi.new
Quizá hayas notado que nuestra clase Zombi tiene, al igual que tuvieron los
objetos Bouba y Kiki en su momento, un atributo @salud. Seguramente
tu Zombi se ve similar a este:
class Zombi
def initialize
@salud = 100
end
def salud
@salud
end
end
¡Averigualo! Hacé que Juliana ataque a cada zombi con distintos puntos de daño y
luego consultá la salud de ambos.
class Sobreviviente
def initialize
@energia = 1000
end
def energia
@energia
end
@atacar = zombie.recibir_danio!(cant_danio)
end
end
juliana = Sobreviviente.new
anastasia = Sobreviviente.new
Prometimos una invasión zombi pero sólo tenemos dos . Ahora que
contamos con un molde para crearlos fácilmente, la clase Zombi, podemos
hacer zombis de a montones.
¿Eso significa que tenés que pensar un nombre para referenciar a cada
uno? ¡No! Si, por ejemplo, agregamos algunas plantas a un Vivero...
Vivero.agregar_planta! Planta.new
Vivero.agregar_planta! Planta.new
Vivero.agregar_planta! Planta.new
...y el Vivero las guarda en una colección @plantas, luego las podemos regar a
todas...
def regar_todas!
@plantas.each { |planta| planta.regar! }
end
class Sobreviviente
def initialize
@energia = 1000
end
def energia
@energia
end
@atacar = zombie.recibir_danio!(cant_danio)
end
def ataque_masivo!(zombies)
end
end
juliana = Sobreviviente.new
anastasia = Sobreviviente.new
caminantes = []
class Planta
def initialize(centimetros)
@altura = centimetros
end
def regar!
@altura += 2
end
end
Ahora podemos crear plantas cuyas alturas varíen utilizando una única
clase. Internamente, los parámetros que recibe new se pasan también
a initialize:
brote = Planta.new 2
arbusto = Planta.new 45
arbolito = Planta.new 110
def initialize(salud_inicial)
@salud = salud_inicial
end
def salud
@salud
end
def gritar
@gritar = "¡agrrrg!"
end
def sabe_correr?
false
end
def esta_vivo?
@salud > 0
end
def recibir_danio!(cant_danio)
if salud <= 0
@salud = 0
end
end
def sin_vida?
!self.esta_vivo?
end
end
class SuperZombi
def initialize(salud_inicial)
@salud = salud_inicial
end
def salud
@salud
end
def gritar
@gritar = "¡agrrrg!"
end
def sabe_correr?
true
end
def esta_vivo?
@salud > 0
end
def regenerarse!
@salud = 100
end
def recibir_danio!(cant_danio)
if salud <= 0
@salud = 0
end
end
def sin_vida?
!self.esta_vivo?
end
end
Defenderse de la invasión no es para cualquiera! Las sobrevivientes
descubrieron que cada vez que realizan un ataque_masivo! su energía
disminuye a la mitad.
class Sobreviviente
def initialize
@energia = 1000
end
def energia
@energia
end
zombie.recibir_danio!(danio)
end
def ataque_masivo!(zombis)
end
def beber!
end
end
¡Nadie lo esperaba, pero igualmente llegó! Un Aliado se comporta parecido
a una Sobreviviente, pero su ataque_masivo! es más violento: brinda 20 puntos
de daño en lugar de 15.
class Aliado
def initialize
@energia = 500
end
def energia
@energia
end
zombie.recibir_danio!(danio)
end
def ataque_masivo!(zombis)
def beber!
end
end
HERENCIA:
class Celular
def initialize
@bateria = 100
end
def bateria
@bateria
end
def utilizar!(minutos)
end
def cargar_a_tope!
@bateria = 100
end
end
class Notebook
def initialize
@bateria = 100
end
def bateria
@bateria
end
def utilizar!(minutos)
@bateria -= minutos
end
def cargar_a_tope!
@bateria = 100
end
end
class Ave
def volar!
@energia -= 20
end
end
Definí la clase Dispositivo y modificá las clases que definiste anteriormente para evitar
que haya métodos repetidos entre Celular y Notebook. Es importante que en el editor
definas arriba la superclase y abajo sus subclases.
class Dispositivo
def initialize
@bateria = 100
end
def bateria
@bateria
end
def cargar_a_tope!
@bateria = 100
end
end
def utilizar!(minutos)
end
end
@bateria -= minutos
end
end
Una de las grandes molestias que nos traen los dispositivos electrónicos es
cuando se quedan sin batería.
Sabemos que tanto los celulares como las notebooks están descargados si
tienen 20 o menos de batería.
class Dispositivo
def initialize
@bateria = 100
end
def bateria
@bateria
end
def cargar_a_tope!
@bateria = 100
end
def descargado?
@bateria <= 20
end
end
def utilizar!(minutos)
end
end
def utilizar!(minutos)
@bateria -= minutos
end
end
class MedioDeTransporte
def initialize(cant_combustible)
@combustible = cant_combustible
end
def cargar_combustible!(cant_combustible)
@combustible += cant_combustible
end
def entran?(cant_personas)
end
end
def maximo_personas
end
def recorrer!(kilometro)
@combustible -= kilometro/2
end
end
def maximo_personas
end
def recorrer!(kilometro)
@combustible -= kilometro
end
end
¿Y si no tenemos Auto ni Moto? Vamos a modelar Colectivos así tenemos un
poco más de variedad.
def maximo_personas
20
end
def recorrer!(kilometro)
@combustible -= kilometro*2
end
end
def initialize
@combustible = 100
@pasajeros = 0
end
def recorrer!(distancia_kms)
@combustible -= distancia_kms*2
end
personas <= 35
end
def cargar_combustible!(cant_combustible)
super + @pasajeros = 0
end
end
class Saludo
def saludar
"Buen día"
end
end
def initialize
@combustible = 100
@pasajeros = 0
end
def recorrer!(distancia_kms)
@combustible -= distancia_kms*2
end
end
def cargar_combustible!(cant_combustible)
super + @pasajeros = 0
end
end
¿Creíste que habíamos terminado con los zombis? ¡Nada más alejado de la
realidad!
class Zombi
def initialize(salud_inicial)
@salud = salud_inicial
end
def salud
@salud
end
def gritar
"¡agrrrg!"
end
def sabe_correr?
false
end
def sin_vida?
@salud == 0
end
def recibir_danio!(puntos)
end
end
def sabe_correr?
true
end
def recibir_danio!(puntos)
end
def regenerarse!
@salud = 100
end
end
¡No, tranqui! Lo que quiere decir es que tiene sentido que existan
instancias de la clase Zombi. Esto significa que podemos tener tanto
objetos SuperZombi como Zombi.
class Zombi
def initialize(salud_inicial)
@salud = salud_inicial
end
def salud
@salud
end
def gritar
"¡agrrrg!"
end
def sabe_correr?
false
end
def sin_vida?
@salud == 0
end
def recibir_danio!(puntos)
end
def descansar!(minutos)
@salud += minutos
end
end
true
end
def recibir_danio!(puntos)
end
def regenerarse!
@salud = 100
end
end
Zombis por aquí, super zombis por allá, ¿quién podrá ayudarnos?
class Sobreviviente
def initialize
@energia = 1000
end
def energia
@energia
end
def beber!
@energia *= 1.25
end
class Aliado
def initialize
@energia = 500
end
def energia
@energia
end
def beber!
@energia *= 1.10
end
class Persona
def energia
@energia
end
zombi.recibir_danio! danio
end
end
def initialize
@energia = 1000
end
def beber!
@energia *= 1.25
end
end
def initialize
@energia = 500
end
def beber!
@energia *= 1.10
end
zombi.recibir_danio! danio
end
end