Programacion en Ruby
Programacion en Ruby
Programacin en Ruby
Programacin en Ruby
Introduccin
Ruby es un lenguaje de programacin interpretado, reflexivo y orientado a objetos, creado por el programador
japons Yukihiro "Matz" Matsumoto, quien comenz a trabajar en Ruby en 1993, y lo present pblicamente en
1995. Combina una sintaxis inspirada en Python, Perl con caractersticas de programacin orientada a objetos
similares a Smalltalk. Comparte tambin funcionalidad con otros lenguajes de programacin como Lisp, Lua, Dylan
y CLU. Ruby es un lenguaje de programacin interpretado en una sola pasada y su implementacin oficial es
distribuida bajo una licencia de software libre.
Historia
El lenguaje fue creado por Yukihiro "Matz" Matsumoto, quien empez a trabajar en Ruby el 24 de febrero de 1993,
y lo present al pblico en el ao 1995. En el crculo de amigos de Matsumoto se le puso el nombre de "Ruby" (en
espaol rub) como broma aludiendo al lenguaje de programacin "Perl" (perla). La ltima versin estable es la
1.8.6, publicada en diciembre de 2007. El 26 de ese mismo mes sali Ruby 1.9.0, una versin en desarrollo que
incorpora mejoras sustanciales en el rendimiento del lenguaje, que se espera queden reflejadas en la prxima versin
estable de produccin del lenguaje, Ruby 1.9.0.1 Diferencias en rendimiento entre la actual implementacin de Ruby
(1.8.6) y otros lenguajes de programacin ms arraigados han llevado al desarrollo de varias mquinas virtuales para
Ruby. Entre sas se encuentra JRuby, un intento de llevar Ruby a la plataforma Java, y Rubinius, un intrprete
modelado basado en las mquinas virtuales de Smalltalk. Los principales desarrolladores han apoyado la mquina
virtual proporcionada por el proyecto YARV, que se fusion en el rbol de cdigo fuente de Ruby el 31 de diciembre
de 2006, y se dar a conocer como Ruby 1.9.0.1.
Tutorial de Instalacin
Descargando Ruby
Como lenguaje multiplataforma, Ruby ha sido portado a distintos sistemas operativos y arquitecturas. Esto significa
que si tu desarrollas un programa en un PC (por ejemplo), ser posible ejecutarlo en otra mquina distinta como es
un MAC (por poner otro ejemplo).
Las siguientes instrucciones son para instalar Ruby en una PC. Para otras plataformas, ver este captulo
Why's (poignante) guide to Ruby.
[1]
de la
La forma ms sencilla de instalar Ruby en un PC es mediante el Ruby One-Click Installer. Despus de descargarlo
instlalo aceptando todo por defecto. Al instalarse, las Variables de Entorno del Sistema son actualizadas, de tal
forma que se incluya el directorio del ejecutable de Ruby: gracias a esto, podrs ejecutarle desde cualquier drectorio
en tu PC.
La instalacin de Ruby incluye la primera edicin del libro "Programming Ruby" y el editor SciTe.
Programacin en Ruby
c:/ruby/lib/ruby/1.8 aqu estn programas escritos en ruby. Estos ficheros son libreras de Ruby: proveen
funcionalidades que puedes incorporar en tus programas.
c:/ruby/lib/ruby/1.8/i386-mswin32 contiene una serie de extensiones especficas del PC. Los ficheros en esta
terminacin acaban en .so o .dll (dependiendo de la plataforma). Estos ficheros con extensiones programadas en
lenguaje C; dicho de otra forma: son fihceros binarios, compilados durante el proceso de instalacin, que se pueden
ejecutar desde Ruby.
c:/ruby/lib/ruby/site_ruby aqu es donde el administrador de tu sistema y/o t podis almacenar las extensiones y
libreras de terceras partes: cdigo escrito por ti mismo, o por otros.
c:/ruby/lib/ruby/gems es el sistema Ruby-Gemes, encargado de la instalacin de nuevas herramientas.
c:/ruby/src es donde se halla el cdigo fuente de Ruby.
c:/ruby/samples/RubySrc-1.8.6/sample aqu podrs encontrar algunos programas ejemplo escritos en Ruby.
Ruby te obedeci!
Qu fue lo que pas? Acaso acabamos de escribir el programa Hola Mundo ms corto del mundo? No
exactamente. La segunda linea slo es la forma que tiene IRB para decirnos el resultado de la ltima expresin
evaluada. Si queremos que el programa escriba Hola Mundo necesitamos un poco ms:
irb(main):002:0> puts "Hola Mundo"
Hola Mundo
=> nil
puts es el comando bsico para escribir algo en Ruby. Pero entonces, qu es ese => nil? Ese es el resultado de la
expresin puts siempre retorna nil, que es el valor que significa absolutamente nada en Ruby.
Programacin en Ruby
Palabra Reservada
Funcin
alias
and
break
case
class
def
defined?
do
else
Ejecuta el cdigo que continua si la condicin previa no es true. Funciona con if, elsif, unless o case.
elsif
Ejecuta el cdigo que continua si la condicional previa no es true. Funciona con if o elsif.
end
ensure
false
true
for
if
in
module
next
nil
not
or
redo
rescue
Evalua una expresin despus de una excepcin es alzada. Usada despus de ensure.
retry
Cuando es llamada fuera de rescue, repite una llamada a mtodo. Dentro de rescue salta a un bloque superior.
return
self
super
then
undef
unless
until
when
while
yield
_FILE_
_LINE_
Programacin en Ruby
Programacin en Ruby
eso te pide te nombre, lo guarda en la variable name y lo utiliza para imprimir un saludo.
end
end
Para utilizar esta clase se declara una variable y se inicializa de la siguiente manera:
miLenguaje = Lenguaje.new
Declaracin de un arreglo
Un arreglo es una coleccin de elementos que pueden ser accesados por un ndice. En este caso el ndice es un valor
entero y los mismos comienzan desde cero. Se utiliza el nombre de la variable junto con brackets para referirse a un
valor especfico.
Ejemplo:
numeros = [ 3, 4, 12, 22.5 ]
colores = [ rojo, azul, verde ]
#sacando el primer elemento de numeros y el segundo de colores
puts(numeros[0])
puts(colores[1])
Programacin en Ruby
Operador
Descripcin
SI
[ ] [ ]=
SI
**
Exponente
SI
!~+-
SI
*/%
+-
Ms, menos
SI
>> <<
SI
&
Bitwise And
SI
Bitwise Or y Or regular
SI
Operadores de comparacin
SI
<=> == === != =~ !~
&&
And lgico
ll
Or lgico
.. ...
?:
If-then-else ternario
not
Negacin lgica
or and
Composicin lgica
Modificadores de expresin
begin end
Expresiones de bloque
Asignacin
*Operadores marcados con SI pueden tratarse como mtodos, y por lo tanto se pueden sobreescribir.
Programacin en Ruby
6 if var > 4
7
puts "La variable es mayor que 4"
8
puts "Puedo tener muchas declaraciones aqui"
9
if var == 5
10
puts "Es posible tener if y else anidados"
11
else
12
puts "Too cool"
13
end
14 else
15
puts "La variable no es mayor que 4"
16
puts "Puedo tener muchas declaraciones aqui"
17 end
18
19 # Loops
20 var = 0
21 while var < 10
22
puts var.to_s
23
var += 1
24 end
Un ejemplo del uso de elsif est en el programa p015elsif.rb :
1 # ejemplo del uso de elseif
2
3 # Ejemplo original
4 puts "Hola, cual es tu nombre?"
5 STDOUT.flush
6 nombre = gets.chomp
7 puts 'Hola, ' + nombre + '.'
8
9 if nombre == 'Juan'
10
puts 'Que bonito nombre!!'
11 else
12
if nombre == 'Ivan'
13
puts 'Ivan es Juan en ruso!!'
14
end
15 end
16
17 # Ejemplo modificado usando elsif
18 puts "Hola, cual es tu nombre?"
19 STDOUT.flush
20 nombre = gets.chomp
21 puts 'Hola, ' + nombre + '.'
22
23 if nombre == 'Juan'
24
puts 'Que bonito nombre!!'
25 elsif nombre == 'Ivan'
26
puts 'Ivan es Juan en ruso!!'
Programacin en Ruby
27
28
29
30
31
32
33
34
35
36
37
38
end
# Otra modificacion
puts "Hola, cual es tu nombre?"
STDOUT.flush
nombre = gets.chomp
puts 'Hola, ' + nombre + '.'
# || es el operador logico 'o'
if nombre == 'Juan' || nombre == 'Ivan'
puts 'Que bonito nombre!!'
end
Algunos operadores condicionales comunes son: ==, != <=, >=, <, > Ruby tiene tambin una forma negativa de if.
La estructura unless comienza con la palabra unless y termina con end. El cuerpo es el texto que aparece en medio de
las dos. A menos que la expresin que contine a la palabra unless sea verdadera, el cuerpo es ejecutado, de lo
contrario el intrprete lo ignora.
1 unless ARGV.length == 2
2
puts "Usage: program.rb 23 45"
3
exit
4 end
En el programa anterior, el cuerpo es ejecutado a menos que el nmero de elementos en el array sea igual a 2. El
mtodo Kernel.exit termina el programa, regresando un valor de status al sistema operativo. Loops como while estn
disponibles. Observa el siguiente ejemplo:
1
2
3
4
5
6
7
#Loops
var = 0
while var < 10
puts var.to_s
var += 1
end
1.Escribe un programa (p016bisiesto.rb) que pregunte al usuario un ao cualquiera y determine si es bisiesto o no.
2.Escribe un mtodo llamado bisiesto que acepte un ao, determine si es bisiesto y calcule el nmero total de
minutos para ese ao. (p017metodobisiesto)
Para determinar si un ao es bisiesto: 1.Si el ao es divisible ente 4, ve al paso 2. Si no, ve al paso 5. 2.Si el ao es
divisible ente 100, ve al paso 4. Si no, ve al paso 5. 3.Si el ao es divisible ente 400, ve al paso 4. Si no, ve al paso 5.
4.El ao es bisiesto. (Tiene 365 das). 5.El ao no es bisiesto. (Tiene 365 das).
Expresiones case Esta estructura funciona de manera muy similar a una serie de expresiones if: te permite enumerar
una serie de condiciones y ejecutar una expresin que corresponda al primer valor que sea verdadero. Por ejemplo,
los aos bisiestos deben ser divisibles entre 400 o entre 4 y no entre 100. Ten presente que case regresa el valor de la
ltima expresin ejecutada.
1 year = 2000
2
3 leap = case
4
when year % 400 == 0: true
Programacin en Ruby
5
when year % 100 == 0: false
6
else year % 4 == 0
7
end
8
9 puts leap
10
11 #el resultado es: true
Programacin en Ruby
10
Programacin en Ruby
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# Si ahora declaramos:
p1 = nil
# entonces el Objeto de clase perro es abandonado y es
# elegible para la recoleccion de basura (GC)
Si ejecutamos el programa, adems de la lista de mtodos con los que nace el objeto 1, obtenemos como resultado:
El id del objeto es 281140.
Lo siento el objeto no entiende el mensaje habla.
Ruff! Ruff!
Soy de la Raza Labrador y mi nombre es Benzy
Soy de la Raza Labrador y mi nombre es Benzy
El mtodo new es usado para crear un objeto de clase Perro. Los objetos son creados en el heap. La variable p es
conocida como una variable de referencia. No guarda el objeto en si, sino algo parecido a un apuntador o una
11
Programacin en Ruby
direccin del objeto. Utilizamos el operador punto (.) en una variable de referencia para decir, "utiliza lo que est
antes del punto para traerme lo que est despus del punto". Por ejemplo: p.ladra.
Si ests escribiendo una aplicacin Rails en la que uno de tus modelos es, digamos, Cliente, entonces cuando
escribes el cdigo que hace que las cosas pasen (un cliente accesando un sitio, actualizando un nmero de telfono
de un cliente, agregando un artculo a un carrito de compras), con toda seguridad estars enviando mensajes a
objetos de la clase Cliente. An recin creado, un objeto no est completamente en blanco. Tan pronto como un
objeto comienza a existir, responde a algunos mensajes. Cada objeto 'nace' con ciertas habilidades innatas. Para ver
una lista de los mtodos con los que nace un objeto, puedes usar el mtodo methods.
Es posible determinar de antemano (antes de pedirle a un objeto que haga algo) si un objeto es capaz de manejar
determinado mensaje usando el mtodo respond_to?. Este mtodo existe para todos los objetos; puedes preguntarle a
cualquier objeto si responde a cualquier mensaje. respond_to? aparece usualmente en conexin con la condicion
lgica if.
1
2
3
4
5
6
7
8
9
class Perro
def initialize(raza, nombre)
@raza = raza
@nombre = nombre
end
end
p = Perro.new('Alsacian', 'Lassie')
puts p.class.to_s
El resultado es:
RubyMate r8136 runnin Ruby r1.8.6
(/usr/local/bin/ruby)
>>> perro2.rb
perro
instance_of? regresa true si el objeto es instancia de la clase especificada.
1 num = 10 2 puts (num.instance_of? Fixnum) # true
Las clases abiertas de Ruby
En Ruby, las clases nunca son cerradas: siempre puedes agregar mtodos a una clase que ya existe. Lo anterior aplica
tanto para las clases que tu escribes como para las clases estndar includas en Ruby. Todo lo que tienes que hacer es
abrir la definicin de una clase existente y el nuevo contenido que especifiques va a ser agregado. En el ejemplo
pasado, definimos la clase Motocicleta en el archivo p030motocicleta.rb.
1 class Motocicleta
2
def initialize(marca, color)
3
# Variables de instancia
4
@marca = marca
5
@color = color
6
end
7
def arranca
8
if (@engineState)
9
puts 'Motor encendido'
10
else
12
Programacin en Ruby
11
@engineState = true
12
puts 'Motor apagado'
13
end
14
end
15 end
Posteriormente, en el archivo p031pruebamotocicleta 'abrimos' la clase Motocicleta y definimos el mtodo describe.
1 require 'p030motocicleta'
2 m = Motocicleta.new('Yamaha', 'rojo')
3 m.arranca
4
5 class Motocicleta
6
def describe
7
puts 'El color de la motocicleta es ' + @color
8
puts 'La marca de la motocicleta es ' + @marca
9
end
10 end
11 m.describe
12 m.arranca
13 puts self.class
14 puts self
15 puts Motocicleta.instance_methods(false).sort
Otro ejemplo: en el archivo p031babreperro.rb abrimos la clase Perro que definimos anteriormente en el archivo
p029perro.rb y agregamos el mtodo ladra_fuerte. (Observa que para poder abrir la clase, necesitamos requerirla
primero):
1 # primero necesitamos requerir el archivo
2 # donde se encuentra la definicion de la clase
3 # perro
4 require 'p029perro.rb'
5
6 # abrimos de la clase y definimos un mtodo nuevo
7 class Perro
8
def ladra_fuerte
9
puts 'Woof! Woof!'
10
end
11 end
12
13 # inicializamos una instancia de la clase
14 d = Perro.new('Labrador', 'Benzy')
15
16 # podemos usar los metodos previamente definidos
17 # y el que acabamos de definir
18 d.ladra
19 d.ladra_fuerte
20 d.muestra
13
Programacin en Ruby
14
Si ejecutas este programa (y has seguido paso a paso los temas anteriores), el resultado tal vez no sea lo que tu
esperas:
Intance_variables
is_a?
kind_of?
ladra
method
methods
muestra
nil
object_id
private_methods
protected_methods
public_methods
respond_to?
send
singleton_methods
taint
tainted?
to_a
to_plist
to_s
type
untaint
El id de objeto es 280360
Lo siento, el objeto no entiende el
Ruff!Ruff!
Soy de la Raza Labrador y mi nombre
Soy de la Raza Labrador y mi nombre
Ruff!Ruff!
Woof!Woof!
Soy de la Raza Labrador y mi nombre
mensaje habla.
es Benzy
es Benzy
es Benzy
Qu est pasando?, Por qu esa larga lista de mtodos si en el archivo que estamos ejecutando
(p31abreperro.rb) slo llamamos d.ladra, d.ladra_fuerte y d.muestra?.
La respuesta es simple pero importante: al inicio del programa estamos incluyendo el archivo p029perro, por lo tanto
todo el codigo de ese archivo es ejecutado, no slo la definicin de la clase.
Observa que en el archivo p029perro.rb hacemos llamadas a mtodos que imprimen a STDOUT (ed, llaman al
mtodo puts).
A continuacin vemos otro ejemplo en donde agregamos un mtodo a la clase String. (p032micadena).1
1 class String
2
def invierte
3
puts self.reverse
4
end
5 end
Programacin en Ruby
6 cadena = "La ruta nos aporto otro paso natural!"
7 cadena.invierte
1 El mtodo invierte no es en realidad muy til, pero sirve para ilustrar el punto.
La facilidad que tenemos de abrir cualquier clase, incluso las clases built-in como String y Numeric es un tema
medular en el estudio de Ruby y en la manera en que algunos programas en Ruby estn escritos.
Rails hace uso extenso de esta caracterstica de Ruby en el mdulo ActiveSupport. De hecho, cuando eres nuevo en
Ruby y en Rails, puede ser confuso identificar qu mtodos son estndar en Ruby y qu mtodos son definidos por
Rails.
Por ejemplo, en el archivo lib/core_ext/integer/even_odd.rb, dentro de ActiveSupport, se encuentra la definicin del
el mtodo multiple_of? dentro del mdulo EvenOdd. (En realidad, el mdulo EvenOdd est anidado dentro de otros
mdulos pero para simplificar el ejemplo, eliminamos la ruta completa):
1 module EvenOdd
2
def multiple_of?(number)
3
self % number == 0
4
end
5 end
6
Nota que hasta aqu, no se ha abierto ninguna clase de Ruby. Sin embargo, en el archivo
lib/core_ext/integer/integer.rb encontramos:
1 # primero el archivo even_odd es requierido
2 require 'active_support/core_ext/integer/even_odd'
3
4 # se a bre la clase Integer
5 class Integer
6
# se incluye el mdulo Integer
7
# recuerda que para sipmlificar el ejemplo,
8
# eliminamos el identificador completo del mdulo
9
# EvenOdd
10
include EvenOdd
11 end
12
13 # Toma en cuenta que esto es esencialmente lo mismo que
14 # escribir:
15 #
16 #
17 # class Integer
18 #
def multiple_of?(number)
19 #
self % number == 0
20 #
end
21 # end
22 #
23 # Los metodos definidos en un modulo
24 # son agregados como metodos de instancia
25 # a cualquier clase en la que incluyamos dicho
26 # modulo usando el keyword include. (mixins)
15
Programacin en Ruby
27
28
ActiveSupport es un ejemplo excelente de cmo podemos abrir las clases en Ruby y agregar mtodos. Si
quieres explorar ms en este tema, analiza la librera Facets que contiene muchos ejemplos tiles, incluyendo
algunos de los que se usan en Rails (en particular Facets/CORE).
Constructores Literales
Esto significa que puedes usar notacin especial en lugar de llamar new para crear objetos de una clase determinada.
Las clases con constructores literales se muestran en nla siguiente tabla. Cuando usas uno de estos constructores
literales, estas creando un nuevo objeto:
Clase
String
Symbol
Array
Hash
Range
Regexp
Constructor
Ejemplo
""
"nueva cadena" o 'nueva cadena'
:
:simbolo o :"simbolo con espacios"
[]
[1,2,3,4,5]
{}
{"Nueva York" => "NY", "Oregon" => "OR"}
.. o ...
0...10 o 0..9
//
/([a-z]+)/
Recoleccin de basura
La expresin p = nil significa que no hace referencia a nada. Si ahora escribimos p1 = nil, entonces el objeto Perro es
abandonado y es elegible para la recoleccin de basura. Garbage Collection (GC). En Ruby, el objeto llamado heap
destina un mnimo de 8MB. El recolector de basura de Ruby es del tipo llamado mark-and-sweep. Ruby usa un
mecanismo conservador del tipo mark and sweep. No hay garanta de que un objeto sea recolectado antes de que el
programa termine.
Mtodos de clase
Un mtodo de clase es enviado es enviado a la clase misma, no a una instancia de la clase. Algunas operaciones que
pertenecen a la clase no pueden ser llevadas a cabo por instancias individuales de esa clase. new es un ejemplo
excelente.
Llamamos Perro.new porque, hasta que hayamos creado una instancia de clase Perro no podemos enviarle mensajes!
Adems, el trabajo de crear un nuevo objeto lgicamente pertenece a la clase. No tiene sentido que una instancia de
la clase Perro cree a su vez instancias de su misma clase. Sin embargo, si tiene sentido que el proceso de creacin de
instancias se centralizado como una actividad de la clase Perro. Es de vital importancia entender que Dig.new es un
mtodo que podemos accessar a travs de la clase pero ne de las instancias de la clase.
Los objetos individuales "Perro" (instancias de la clase Perro) no tienen acceso a este mtodo. Una clase tiene sus
propios mtodos, su propio estado y su propia identidad y no los comparte con sus instancias.
La siguiente tabla muestra un ejemplo (tomado del libru Ruby for Rails) de la notacin que se utiliza:
Notacin Se refiere a Boleto#precio El mtodo de instancia precio de la clase Boleto Boleto.mas_caro El mtodo de
clase mas_caro de la clase Boleto Boleto::mas_caro Otra manera de referirse al mtodo de clase mas_caro
Cuando escribimos acerca de Ruby, el smbolo de nmero(#) es utilizado algunas veces para indicar en mtodo de
instancia -por ejemplo, decimos File.chmod para denotar el mtodo de clase chmod de la clase File y File#chmod
para referirnos al mtodo de instancia que tiene el mismo nombre. Esta notacin no es parte dela sintaxis de Ruby, es
slo parte del folklore.
16
Programacin en Ruby
Herencia
En ruby, la herencia se maneja herencia, pero no soporta multiple herencia, por lo que cada clase solo puede tener
una superclase de la que herede comportamintos.
la sintaxis es la siguiente:
class ClasePadre
def a_method
puts 'b'
end
end
class ClaseCualquiera < ClasePadre
# < significa hereda
def another_method
puts 'a'
end
end
en esta sentencia se declara una ClasePadre,con un mtodo, luego ClaseCualquiera, hija de ClasePadre con otro
mtodo, si hacemos lo siguiente:
instance = SomeClass.new
instance.another_method
instance.a_method
Salida
ab
vemos que se aplica la herencia de mtodos correctamente al llamar desde una instancia hija un mtodo de la clase
padre
Polimorfismo
Si queremos redefinir un mtodo de la clase padre en la hija, solo sobrescribimos el mtodo que deseamos redefinir
en la clase hija, de esta manera, dependiendo de el tipo de la instancia desde la cual llamamos al mtodo, se utilizar
la correspondiente definicin
Ademas, para llamar a la clase padre en cualquier momento desde un hija utilizamos la palabra reservada super, sin
embargo, si quieres acceder a un clase superior a el padre en la jerarqua de herencia(como un abuelo, digamos), no
se puede directamente, sin embargo hay una salida puedes darles nombre afiliados a los mtodos que deseas usar
luego, como un alias!, de hecho es exactamente esto, veamos
class X
def foo
"hello"
end
end
class Y < X
alias xFoo foo
def foo
xFoo + "y"
17
Programacin en Ruby
18
end
end
puts X.new.foo
puts Y.new.foo
Salida
hello
helloy
Implementacin de Co-Rutinas
El manejo de threads(Corrutinas) en ruby es muy sencillo, la creacin de threads se basa en pasar un bloque a la
creacin de un objeto de la clase thread.
t1 = Thread.new do
10.times do
puts "hello from thread 1"
sleep(0.2)
end
end
t2 = Thread.new do
10.times do
puts "hello from thread 2"
sleep(0.2)
end
end
t1.join
t2.join
Para pasar parmetros se hace de la siguiente forma:
t1 = Thread.new(1)
10.times do
puts "hello from
sleep(0.2)
end
end
t2 = Thread.new(2)
10.times do
puts "hello from
sleep(0.2)
end
end
t1.join
t2.join
do |id|
thread #{id}"
do |id|
thread #{id}"
Programacin en Ruby
19
Para controlar las secciones crticas tan solo hay que cambiar la variable de clase critical a true:
counter = 0;
t1 = Thread.new do
100000.times do
Thread.critical =
counter += 1
Thread.critical =
end
end
t2 = Thread.new do
100000.times do
Thread.critical =
counter -= 1
Thread.critical =
end
end
t1.join
t2.join
puts counter
true
false
true
false
Manejo de Excepciones
Una excepcin es una clase de objeto especial, una instancia de la clase Exception o de una clase descendiente de esa
clase que representa una condicin especial; indica que algo ha salido mal. Cuando esto ocurre, se genera una
excepcin. Por defecto, los programas Ruby terminan cuando una excepcin ocurre pero es posible escribir cdigo
que maneje estas excepciones.
Generar una excepcin significa detener la ejecucin normal del programa y transferir el control al cdigo que
maneja la excepcin en donde puedes ocuparte del problema que ha sido encontrado o bien, terminar la ejecucin del
programa. Una de estas dos opciones (solucionar el problema de alguna manera o detener la ejecucin de programa)
ocurre dependiendo de si has proporcionado una clusula rescue. Si no has proporcionado dicha clusula, el
programa termina, por el contrario, si la clusula existe, el control de ejecucin fluye hacia esta.
Ruby tiene algunas clases predefinidas -descendientes de la clase Exception- que te ayudan a manejar errores que
ocurren en tu programa.
El siguiente mtodo genera una excepcin cada vez que es llamado. El segundo mensaje nunca va a ser mostrado.
1 def genera_excepcion
2
puts 'Antes de la excepcion.'
3
raise 'Ha ocurrido un error'
4
puts 'Despues de la excepcion'
5 end
6
7 genera_excepcion
El mtodo raise est definido en el mdulo Kernel. Por defecto, raise genera una excepcin de la clase RuntimeError.
Para generar una excepcin de una clase en especfico, puedes pasar el nombre de la clase como argumento al
mtodo raise.
Programacin en Ruby
1
2
3
4
5
6
def inverse(x)
raise ArgumentError, 'El argumento no es un numero' unless x.is_a? Numeric
1.0 / x
end
puts inverse(2)
puts inverse('hola')
Manejando una excepcin Para manejar excepciones (handle exceptions), inclumos el cdigo que pueda generar una
excepcin en un bloque begin-end y usamos una o ms clusulas rescue para indicarle a Ruby los tipos de excepcin
que queremos manejar. Es importante notar que el cuerpo de la definicin de un mtodo es un bloque begin-end
explcito; begin es omitido y todo el cuerpo de la definicin del mtodo est sujeto al manejo de excepciones hasta
que aparezca la palabra end.
1 def genera_y_rescata
2
begin
3
puts 'Estoy antes de raise.'
4
raise 'Ha ocurrido un error.'
5
puts 'Estoy despues de raise.'
6
rescue
7
puts 'He sido rescatado.'
8
end
9
puts 'Estoy despues de begin.'
10 end
11 genera_y_rescata
Observa que el cdigo interrumpido por la excepcin nunca es ejecutado. Una vez que la excepcin es rescatada, la
ejecucin contina inmediatamente despus del bloque begin que la gener.
Puedes apilar clusulas rescue en un bloque begin-end. Las excepciones que no sean manejadas por una clusula
rescue fluirn hacia la siguiente:
1
2
3
4
5
6
7
8
9
begin
# ...
rescue UnTipoDeExcepcion
# ...
rescue OtroTipoDeExcepcion
# ..
else
# Otras excepciones
end
Para cada clusula rescue en el bloque begin, Ruby compara la excepcin generada con cada uno de los parmetros
en turno. La ocurrencia tiene xito si la excepcin nombrada en la clusula rescue es del mismo tipo que la
excepcin generada. El cdigo en una clusula else es ejecutado si el cdigo en la expresin begin es ejecutado sin
excepciones. Si una excepcin ocurre, entonces la clusula else no es ejecutada. El uso de una clusula eles no es
particularmente comn en Ruby. Si quieres interrogar a una excepcin rescatada, puedes asignar el objeto de clase
Exception a una variable en la clusula rescue, como se muestra en el programa p046excpvar.rb
1 begin
2
raise 'Una excepcion.'
3 rescue Exception => e
20
Programacin en Ruby
4
puts e.message
5
puts e.backtrace.inspect
6 end
La clase Exception define dos mtodos que regresan detalles acerca de la excepcin. El mtodo message regresa una
cadena que puede proporcionar detalles legibles acerca de lo que ocurri mal. El otro mtodo importante es
backtrace. Este mtodo regresa un array de cadenas que representa la pila de ejecucin hasta el punto en que la
excepcin fue generada. Si necesitas garantizar que algn proceso es ejecutado al final de un bloque de cdigo sin
importar si se gener una excepcin o no, puedes usar la clusula ensure. ensure va al final de la ltima clusula
rescue y contiene un bloque de cdigo que siempre va a ser ejecutado.
Excepciones con Manejo de Archivos
Ejemplo:
1 # Abrir un archivo y leer su contenido
2 # Nota que ya que est presente un bloque, el archivo
3 # es cerrado automaticamente cuando se termina la ejecucion
4 # del bloque
5 begin
6
File.open('p014estructuras.rb', 'r') do |f1|
7
while linea = f1.gets
8
puts linea
9
end
10
end
11
12
# Crer un archivo y escribir en el
13
File.open('prueba.txt', 'w') do |f2|
14
f2.puts "Creado desde un programa Ruby!"
15
end
16 rescue Exception => msg
17
# mostar el mensaje de error generado por el sistema
18
puts msg
19 end
21
Programacin en Ruby
-La apariencia visual de Ruby
A pesar de que Ruby utiliza la puntuacin muy limitadamente y se prefieren las palabras clave en ingls, se utiliza
algo de puntuacin para decorar el cdigo. Ruby no necesita declaraciones de variables. Se utilizan convenciones
simples para nombrar y determinar el alcance de las mismas.
var puede ser una variable local.
@var es una variable de instancia.
$var es una variable global
Estos detalles mejoran la legibilidad permitiendo que el desarrollador identifique fcilmente los roles de las
variables. Tambin se hace innecesario el uso del molesto self. como prefijo de todos los miembros de instancia.
-Ademas Ruby ademas posee otras funcionalidades para aclarar la vida los programadores, entre la cuales estan:
Manejo de Excepciones
Mark and Sweep Garbage collector
Mucho soporte para comunicacin con C, con un agradable API para utilizar Ruby desde C
Manejo de multitareas (Threads) independiente del sistema operativo, puedes incluso usar threads en DOS!
Gran Portabilidad, corre en toda clase de sistemas Linux/Unix, Windows, OS/2, dos, etc
22
Programacin en Ruby
end
end
class Pinguino<Ave
def vuela
puts "Lo siento, prefiero nadar."
end
end
class Aguila<Ave
end
puts "Pinguino"
p = Pinguino.new
p.acicala
p.vuela
puts "Aguila"
a = Aguila.new
a.acicala
a.vuela
begin
File.open('p014estructuras.rb', 'r') do |f1|
while linea = f1.gets
puts linea
end
end
# Crer un archivo y escribir en el
File.open('prueba.txt', 'w') do |f2|
f2.puts "Creado desde un programa Ruby!"
end
rescue Exception => msg
# mostar el mensaje de error generado por el sistema
puts msg
end
p014estructuras.rb
var = 5
if var > 4
puts "La variable es mayor que 4"
puts "Puedo tener muchas declaraciones aqui"
if var == 5
puts "Es posible tener if y else anidados"
else
puts "Too cool"
end
else
puts "La variable no es mayor que 4"
puts "Puedo tener muchas declaraciones aqui"
23
Programacin en Ruby
end
# Loops
var = 0
while var < 10
puts var.to_s
var += 1
end
Enlaces Externos
Referencias
[1] http:/ / poignantguide. net/ ruby/ expansion-pak-1. html
[2] http:/ / www. ruby-lang. org
[3] http:/ / www. rubycentral. com
[4] http:/ / ruby. org. es
[5] http:/ / rubytutorial. wikidot. com/
[6] http:/ / www. rubycentral. com/ book/
[7] http:/ / rubyargentina. soveran. com/ home
[8] http:/ / www. rubylit. com. ar/ wiki/ show/ HomePage
[9] http:/ / www. meshplex. org/ wiki/ Ruby/ Ruby_on_Rails_programming_tutorials
[10] http:/ / www. netbeans. org/ features/ ruby/ index. html
[11] http:/ / rubytutorial. wikidot. com/ primer-programa
[12] http:/ / www. ruby-lang. org/ es/ documentation/ quickstart/
[13] http:/ / todoruby. blogspot. com/ 2009/ 03/ palabras-reservadas-en-ruby. html
24
Licencia
Creative Commons Attribution-Share Alike 3.0 Unported
http:/ / creativecommons. org/ licenses/ by-sa/ 3. 0/
25