Sunteți pe pagina 1din 9

Ejercicios de Programacion con Ruby

Ingeniera de Sistemas de Informacion


Departamento de Sistemas Telematicos y Computacion (GSyC)
18 de septiembre de 2012

Notas:
1. Al lado de cada ejercicio aparecen una o mas cruces, en funcion de su dificultad y de la cantidad de tiempo
estimado que requiere. Cuantas m
as cruces tenga un ejercicio mas difcil es o mas tiempo puede requerir.
2. Aparte de las transparencias que estamos usando en clase, utiliza ri y la siguiente documentacion de Ruby:
Documentaci
on online de Ruby: http://ruby-doc.org/core-1.9.3/
API de la biblioteca est
andar de Ruby: http://ruby-doc.org/
Libro Programming Ruby: http://ruby-doc.org/docs/ProgrammingRuby/
3. Utiliza este resumen sobre el uso de expresiones regulares en Ruby:

Figura 1: Fuente: Engineering Long-Lasting Software. Armando Fox, David Patterson

Ejercicio 1 +
Dada esta definici
on de un metodo:
def foo(arg, hash1, hash2)
end
Cu
al de las siguientes NO es una llamada legal al metodo foo?
1. foo a, {:x=>1, :y=>2}, :z=>3
2. foo(a, :x=>1, :y=>2, :z=>3)
3. foo(a, {:x=>1, :y=>2}, {:z=>3})
4. foo(a, {:x=>1}, {:y=>2, :z=>3})

Ejercicio 2 +
Dada la siguiente declaraci
on de la clase SavingsAccount:
class SavingsAccount < Account
def initialize(starting_balance=0)
@balance = starting_balance
end
def balance
@balance
end
def balance=(new_amount)
@balance = new_amount
end
def deposit(amount)
@balance += amount
end
@@bank_name = "MyBank.com"
def self.bank_name
@@bank_name
end
end
Indica cu
ales de las siguientes lneas son correctas:
1. SavingsAccount.new.@balance
2. SavingsAccount.new.balance
3. SavingsAccount.new.balance()

Ejercicio 3 +
Dada esta asignaci
on:
rx = {:primero=>/^rub/,
primero=>[/RA(IL)$/, /ra(il)/i]}
Cu
al de las siguientes expresiones se evaluar
a correctamente, devolviendo algo que no sea nil?
1. "rubyonrails" =~ rx{:primero}
2. rx[:primero][1] =~ "RUBYONRAILS"
3. rx[primero][1] =~ "RUBYONRAIL"
4. "rubyonrails" =~ rx[primero, 1]
5. "rubyonrails" =~ rx[primero][0]

Ejercicio 4 +
Dada esta extensi
on de la clase String:
class String
def curvy?
!("AEFHIKLMNTVWXYZ".include?(self.upcase))
end
end
Cu
al de las siguientes lneas es correcta?:
1. String.curvy?("foo")
2. "foo".curvy?
3. self.curvy?("foo")
4. curvy?("foo")

Ejercicio 5 +
Se ha extendido la clase Numeric de la siguiente forma:
class Numeric
def euros
self * 1.292
end
end
Ahora se desea poder ejecutar esta lnea:
5.euros.in(:rupias)
Cu
al de los siguientes mecanismos sera m
as apropiado?
1. Cambiar Numeric.method_missing para que detecte llamadas al metodo in
2. Cambiar Numeric#method_missing para que detecte llamadas al metodo in
3. Definir un metodo Numeric#in
4. Definir un metodo Numeric.in

Ejercicio 6 +
Cu
al de los siguientes string NO aparecer
a como resultado de ejecutar este codigo?:
[banana, anana, naan].map do |food|
food.reverse
end.select { |f| f.match /^a/ }
1. "naan"
2. "ananab"
3. "anana"
4. El c
odigo no funcionar
a debido a errores de sintaxis

Ejercicio 7 +
Cu
ales de las siguientes expresiones de Ruby son equivalentes entre s?:
A) :foo
B) %q{foo}
C) %Q{foo}
D) foo.to_sym
E) :foo.to_s

Ejercicio 8 +
Que se captura en $1 buscando en el string 25 to 1 las siguientes expresiones regulares?:
/(\d+)$/
/^\d+([^0-9]+)/

Ejercicio 9 +
Cu
ando es correcto utilizar la siguiente lnea en Ruby?:
Fixnum num=3

Ejercicio 10 +
Por que al ejecutar 5.superclass se eleva una excepcion undefined method?.

Ejercicio 11 +
Escribe utilizando send las siguientes expresiones:
1. a<b
2. a==b
3. x[0]
4. x[0]=foo

Ejercicio 12 +
Imagina que el metodo foo admite dos argumentos que son dos hashes. Explica por que no podemos utilizar el modo
poetico para escribir esta llamada:
foo :a =>1, :b => 2

Ejercicio 13 +
Por que esta expresi
on es incorrecta en Ruby?:
movie.@year=1998

Ejercicio 14 ++
Time.now devuelve el n
umero de segundos que han pasado desde las 00:00 GMT del 1/1/1970, que es la forma
en que se representa una hora en Unix. Se ha extendido la clase Fixnum para poder hacer aritmetica con las horas
utilizando expresiones como las siguientes:
Time.now
# => Mon Nov 07 10:18:10 -0800 2011
5.minutes.ago
# => Mon Nov 07 10:13:15 -0800 2011
5.minutes - 4.minutes
# => 60
3.hours.from_now
# => Mon Nov 07 13:18:15 -0800 2011
A continuaci
on se muestra la extensi
on del c
odigo de la clase Fixnum que permite hacer este tipo de operaciones:
class
def
def
def
def
def
end

Fixnum
seconds
minutes
hours
ago
from_now

;
;
;
;
;

self ; end
self * 60 ; end
self * 60 * 60 ; end
Time.now - self ; end
Time.now + self ; end

Sin embargo, esta sentencia no se puede ejecutar: 1.minute.ago


La raz
on es que no existe el metodo minute.
El siguiente c
odigo soluciona este problema:
class Fixnum
def method_missing(method_id, *args)
name = method_id.to_s
if name =~ /^(second|minute|hour)$/
self.send(name + s)
else
super # se llama al mismo m
etodo (method_missing) de clases ancestro
end
end
end
Explica por que son necesarios $ y ^ en la expresion regular de la lnea 4. Una pista: piensa que ocurrira si omitimos
alguno de estos dos caracteres e intentamos hacer la siguiente llamada: 5.milliseconds o 5.secondary.

Ejercicio 15 ++
A
n
adele a la clase String un metodo palindromo? que devuelva true si la cadena es un palndromo (se lee igual del
derecho que del reves), y false si no lo es. Ejemplos:
"reconocer".palindromo?
"Reconocer".palindromo?
"Se van sus naves".palindromo?
"Pepe".palindromo?

#
#
#
#

=>
=>
=>
=>

true
true
true
false

Utiliza u
nicamente metodos de la siguiente lista (consulta la documentacion para saber que hacen):
map,
select, reject, uniq
reverse, compact, flatten, partition
sort,
sort_by, max,
min,
downcase

Ejercicio 16 +
Explica que ocurre cuando se ejecuta el siguiente codigo:
class Foo
include Enumerable
end
Foo.new.map { |e| puts e }

Ejercicio 17 ++
Explica para que sirve el siguiente c
odigo:
module Enumerable
def every_nth(count)
index = 0
self.each do |elt|
yield elt if index % count == 0
index += 1
end
end
end

Ejercicio 18 +
Cu
antas clases ancestro tiene el objeto 5? Los siguientes metodos te ayudaran: class, superclass.

Ejercicio 19 +
Sabiendo que el metodo superclass devuelve nil cuando se le manda a BasicObject, escribe el codigo del metodo
ancestros que reciba como argumento cualquier objeto y muestre en pantalla la clase del objeto y sus clases ancestro
hasta BasicObject.

Ejercicio 20 +++
Escribe c
odigo que permita que se puedan ejecutar sentencias como la siguiente:
Time.now.at_beginning_of_year + 1.day
# => 2012-01-02 00:00:00 -0800
Estudia antes el c
odigo que se proporciona en el ejercicio 14, no siendo necesario que resuelvas aquel ejercicio antes
de resolver este.
Te vendr
a bien consultar la documentaci
on de Time.local y utilizar este metodo de clase.

Ejercicio 21 +++
Define un metodo attr_accessor_with_history que proporcione la misma funcionalidad que attr_accessor pero
que lleve guarde la lista de valores que el atributo ha ido adoptando. Ejemplo de uso:
class Foo
attr_accessor_with_history :bar
end
f = Foo.new
# => #<Foo:0x127e678>
f.bar = 3
# => 3
f.bar = :wowzo # => :wowzo
f.bar = boo! # => boo!
f.history(:bar) # => [3, :wowzo, boo!]

Ejercicio 22 ++
El m
odulo Enumerable define el iterador each_with_index que devuelve cada uno de los elementos enumerable
junto a un ndice que empieza en cero. Veamos un ejemplo de su uso:
%w(alice bob carol).each_with_index do |person,index|
puts ">> #{person} is number #{index}"
end
>> alice is number 0
>> bob is number 1
>> carol is number 2
Escribe un iterador each_with_custom_index en el modulo Enumerable que permita fijar el valor inicial del ndice
que devolver
a para el primer elemento, y el n
umero de saltos que debe ir dando el ndice al ir iterando. Ejemplo de
uso:
include Enumerable
%w(alice bob carol).each_with_custom_index(3,2) do |person,index|
puts ">> #{person} is number #{index}"
end
>> alice is number 3
>> bob is number 5
>> carol is number 7

Ejercicio 23 ++
En la sucesi
on de Fibonacci los dos primeros enteros son 1 y 1, y cada n
umero sucesivo es la suma de los dos previos.
Crea una clase FibSequence que devuelva un iterador para los n primeros n
umeros de Fibonacci. Ejemplo de uso:
f = FibSequence.new(6)
f.each { |s| print(s,:) }
f.reject { |s| s.odd? }
f.map { |x| 2*x }

#
#
#
#
#

devuelve un iterador para los 6 primeros n


umeros
de la sucesi
on de Fibonacci
=> 1:1:2:3:5:8:
=> [2, 8]
=> [2, 2, 4, 6, 10, 16]

Recuerda que si la clase FibSequence implementa each, al incluir el modulo mix-in Enumerable se a
naden los
metodos definidos en este m
odulo como reject, map,...

Ejercicio 24 +++
Implementa un iterador each_with_flattening que se comporte del siguiente modo:
[1, [2, 3], 4, [[5, 6], 7]].each_with_flattening { |s| print "#{s}," }
>> 1, 2, 3, 4, 5, 6, 7

Ejercicio 25 +
A
nade al m
odulo Enumerable un nuevo iterador, each_permuted que devuelva los elementos de una colecci
on en
orden aleatorio. El iterador puede asumir que la coleccion responde al metodo each pero no debe esperar nada de
cada elemento.
Utiliza el metodo rand.
9