Diferencia entre revisiones de «Programación en Ruby»

Contenido eliminado Contenido añadido
Línea 667:
Cuando escribimos acerca de Ruby, el símbolo de número(#) es utilizado algunas veces para indicar en método de instancia -por ejemplo, decimos File.chmod para denotar el método de clase chmod de la clase File y File#chmod para referirnos al método de instancia que tiene el mismo nombre. Esta notación no es parte dela sintaxis de Ruby, es sólo parte del folklore.
==Las clases abiertas de Ruby==
 
En Ruby, las clases nunca son cerradas: siempre puedes agregar métodos a una clase que ya existe. Lo anterior aplica tanto para las clases que tu escribes como para las clases estándar incluídas en Ruby. Todo lo que tienes que hacer es abrir la definición 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
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 método 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 método 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 método 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
 
Si ejecutas este programa (y has seguido paso a paso los temas anteriores), el resultado tal vez no sea lo que tu esperas:
<gallery>
Archivo:3.jpg
</gallery>
'''¿Qué está pasando?, ¿Por qué esa larga lista de métodos si en el archivo que estamos ejecutando''' (p31abreperro.rb) sólo 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 sólo la definición de la clase.
 
Observa que en el archivo p029perro.rb hacemos llamadas a métodos que imprimen a STDOUT (ed, llaman al método puts).
 
A continuación vemos otro ejemplo en donde agregamos un método a la clase String.
(p032micadena).1
 
1 class String
2 def invierte
3 puts self.reverse
4 end
5 end
6 cadena = "La ruta nos aporto otro paso natural!"
7 cadena.invierte
 
1 El método 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 están escritos.
 
Rails hace uso extenso de esta característica de Ruby en el módulo ActiveSupport. De hecho, cuando eres nuevo en Ruby y en Rails, puede ser confuso identificar qué métodos son estándar en Ruby y qué métodos son definidos por Rails.
 
Por ejemplo, en el archivo lib/core_ext/integer/even_odd.rb, dentro de ActiveSupport, se encuentra la definición del el método multiple_of? dentro del módulo EvenOdd. (En realidad, el módulo EvenOdd está anidado dentro de otros módulos 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 módulo Integer
7 # recuerda que para sipmlificar el ejemplo,
8 # eliminamos el identificador completo del módulo
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)
27
28
 
ActiveSupport '''es un ejemplo excelente de cómo podemos abrir las clases en Ruby y agregar métodos. Si quieres explorar más en este tema, analiza la librería Facets que contiene muchos ejemplos útiles, incluyendo algunos de los que se usan en Rails (en particular Facets/CORE).  '''
 
 
==Herencia==