Documentos de Académico
Documentos de Profesional
Documentos de Cultura
00 Introduccion Ruby
00 Introduccion Ruby
Introduccin
Ruby es un lenguaje interpretado, orientado a objetos creado por Yukihiro Matsumoto (Matz), 1995. ltima versin estable 1.9.1, 11/02/2009. Todos los tipos de datos son un objeto, incluidas las clases, tipos primitivos.
GSyC 2009
Los comentarios comienzan por "#" Otra forma: =begin cdigo comentado =end
Primer programa
# Programa en ruby puts'Hola Ruby' x=1 puts(x)
Cada instruccin se escribe en una lnea diferente, no es necesario ";"
Primer programa
Declaracin de una funcin
# Programa en ruby def hola(nombre) puts "hola #{nombre}" end hola('Ruby') x=1 puts(x)
El resultado de ejecutar este programa es: hola Ruby 1
GSyC 2009
Sustitucin de la variable
Script de Ruby
Un script de ruby debe comenzar con una primera lnea que indique dnde se encuentra el intrprete de ruby:
#!/usr/bin/ruby -w #Programa en ruby def hola(nombre) puts "hola #{nombre}" end hola('Ruby') Fichero miPrograma.rb
El fichero debe ser ejecutable. No es muy portable ya que depende del directorio donde se haya instalado ruby.
GSyC 2009
Ayuda ri
Referencia interactiva: herramienta que muestra descripciones de los mtodos, clases y mdulos predefinidos en Ruby.
~> ri String.capitalize ------------------------------------------------------ String#capitalize str.capitalize => new_str -----------------------------------------------------------------------Returns a copy of _str_ with the first character converted to uppercase and the remainder to lowercase. "hello".capitalize "HELLO".capitalize "123ABC".capitalize #=> "Hello" #=> "Hello" #=> "123abc"
GSyC 2009
puts saludo('Alicia')
GSyC 2009
Asignaciones especiales
En Ruby casi cualquier cosa devuelve un valor. As, pueden encadenarse asignaciones:
a = b = c = 4;
Asignacin paralela:
a, b = b, a # intercambia a y b
Identificadores
Variables locales, nombres de mtodos y parmetros de mtodos comienzan por letra minscula o por _:
lista, n_maximo, num
10
Ejercicio
Ej1: Realiza un programa en Ruby que defina una funcin cuyo valor de retorno sea una cadena de caracteres similar a:
El producto de x por y es z
Donde x e y pueden ser valores cualesquiera que se le pasan a la funcin como parmetros y z=x*y. El programa calcular el producto de los nmeros 5 y 6 e imprimir la cadena de caracteres: "El producto de 5 por 6 es 30"
GSyC 2009
11
Arrays
Coleccin de referencias a objetos indexados por un entero. El ndice del primer elemento es 0.
Literal:
a = [1, 'cat', 3.14] # a[0]=1; a[1]="cat"; a[2]=3.14 a = ['uno', 'dos', 'tres'] # a[0]="uno"; a[1]="dos"; a[2]="tres" a = %w(uno dos tres) # %w: array de palabras
Crear un array de cierto tamao cuyas posiciones estn incializadas como referencias a un cierto objeto.
a = Array.new(10, 'aa') a[0]<< 'b'
# a[0]="aa"; a[1]="aa"; ; a[9]="aa" # a[0]="aab"; a[1]="aab"; ; a[9]="aab"
GSyC 2009
12
=> => => => => => => => => => => => =>
[3.14, Array 3 3.14 "hola" 1 nil 1 [1, 3, [3, 5, [3, 5] [7] [5, 7,
"hola", 1]
5, 7, 9] 7]
9]
a=
3.14
"hola"
GSyC 2009
GSyC 2009
14
Array#join y String#split
["a", "b", "c"].join ["a", "b", "c"].join(" ") ["a", "b", "c"].join("-") ["a", "b", "c"].join("-*-") [1, 2, 3].join [1, 2, 3, "hola"].join "hola a todos".split "12/11/2008".split("/") => => => => => => "abc" "a b c" "a-b-c" "a-*-b-*-c" "123" "123hola"
GSyC 2009
15
Hash
Similar a un array, se puede utilizar cualquier objeto como ndice o clave.
h = {'uno' => 1, 'dos' => 2, 'tres' => 3} puts h['uno'] puts h['dos'] puts h['tres'] # Imprime 1 # Imprime 2 # Imprime 3
Un hash devuelve nil cuando se utiliza un ndice para el que no se ha definido un valor en ese hash. Un array es ms eficiente que un hash, pero un hash permite mayor flexibilidad.
GSyC 2009
16
Ejecucin condicional
IF
if a<10 then x= 'menor que 10' elsif a>=10 and a<=20 then x='entre 10 y 20' else x='mayor que 20' end x = if a<10 then 'menor elsif a>=10 and 'entre else 'mayor end que 10' a<=20 then 10 y 20' que 20'
if devuelve el valor de la ltima expresin ejecutada. la palabra then solo es obligatoria si el if se escribe en una sola lnea la palabra then puede sustituirse (si se quiere) por el carcter : Una condicin es cierta si su evaluacin es cualquier cosa salvo false o nil (objeto que representa "nada"). El valor 0 no es false, es ms, es true (sorpesa!)
GSyC 2009
17
GSyC 2009
18
La clusula else: si no se cumple alguna de las condiciones anteriores. Las clusulas when pueden llevar o no al final then o : (como el if)
x = case i when 1, 2..5 then puts "menor que when 6..10 then puts "mayor que case str when 'aaa', 'bbb' puts 'aaa or bbb' when /def/ puts "incluye /def/" else puts "Cualquier cosa" end 19
6"
6" end
GSyC 2009
Bucles
WHILE
while line = gets # end begin # end while line = gets
UNTIL
until not (line = gets) # end begin # end until c<100
FOR:
Modificadores:
c = 2 while c < 1000 c = c * c end c = 2 c = c *c while c < 1000
GSyC 2009
20
Expresiones regulares
Forma de especificar un patrn de caracteres que se encuentra en una cadena: /patrn/ Abreviaturas para clases de caracteres:
\d \D \s \S \w \W cualquier carcter cualquier carcter cualquier carcter cualquier carcter cualquier carcter minsculas) cualquier carcter numrico del 0 al 9 excepto los numricos del 0 al 9 "whitespace" (blanco, tabulador, fin de lnea, fin de fichero excepto los "whitespace" propio de una palabra (letras y nmeros, maysculas salvo los propios de una palabra
Ejemplos:
/Perl|Python/ /P(erl|ython)/ /\d\d:\d\d:\d\d/ /Perl *Python/ /Perl +Python/ # "Perl" o "Python" # "Perl" o "Python" # dd:dd:dd, ej: 12:23:45 # "Perl" 0 ms espacios "Python" # "Perl" 1 ms espacios "Python"
GSyC 2009
21
Expresiones regulares
Operador de bsqueda de una patrn: =~
Busca un determinado patrn en una cadena de caracteres. Devuelve la posicin donde lo encuentra o nil. Ejemplo, line es una cadena:
if line =~ /Perl|Python/ puts "Lenguaje #{line}" end
Extraer patrones:
/(.*) (.*)/ =~ "hola ruby" [$1, $2] re = /nombre:"(.*)"/ mr = re.match('nombre: "ruby"') mr[1] => 0 => ["hola", "ruby"] => /nombre:"(.*)"/ => #<MatchData:0x402c1fc0> => "ruby"
GSyC 2009
22
GSyC 2009
Bloques
Un bloque es un conjunto de instrucciones que puede asociarse a una llamada de un mtodo, como si fuera un parmetro. Un bloque se define entre llaves o entre las palabras reservadas doend.
Cuando el resultado es importante
Para asociar un bloque a un mtodo, el bloque se escribe a continuacin de la llamada al mtodo (despus de los parmetros que hubiera que pasar al mtodo). Dentro de un mtodo se utiliza la instruccin yield para ejecutar el bloque asociado al mtodo. Los bloques pueden tener sus propios argumentos, que se pasarn en el yield.
GSyC 2009
24
Ejemplo de bloque
Ejecuta el bloque asociado al mtodo llama_al_bloque
def llama_al_bloque puts "Comienza el mtodo" yield yield puts "Fin del mtodo" end llama_al_bloque {puts "Bloque"}
def llama_al_bloque puts "Comienza el mtodo" yield("hola",3) puts "Fin del mtodo" end
25
Iteradores
Mtodos que devuelven sucesivamente elementos pertenecientes a una coleccin, por ejemplo, un array o un rango de nmeros. Variable local que toma el valor de
for i in animales do puts i end
GSyC 2009
26
Ejemplos de iteradores
['yo', 'soy', 'un', 'pltano'].each do |entry| print entry, ' ' end fac=1 1.upto(5) do |i| fac*=i end fac => 1 => 120
Devuelve un nuevo array despus de iterar sobre los elementos del array y ejecutar el bloque con cada uno de ellos.
27
Ms ejemplos
Iteracin entre enteros desde 0 a n-1
4.times do |i| puts i*=2 end 3.upto(6) {|i| print i } ('a'.. 'e').each {|char| print char } a=%w(a b c) a.collect {|x| x.succ } a
Misma funcionalidad que map
=> ["a", "b", "c"] => ["b", "c", "d"] => ["a", "b", "c"] => ["a", "b", "c"] => ["A", "B", "C"] => ["A", "B", "C"]
28
Ms ejemplos
Pasar un bloque como parmetro de una funcin
def f(count, &block) value = 1 1.upto(count) do |i| value = value *i block.call(i, value) end end f 5 do |i, f_i| puts "f(#{i})= #{f_i}" end Ejecuta el bloque block
def f(count) value = 1 1.upto(count) do |i| value = value *i yield(i, value) end end f(5) do |i, f_i| puts "f(#{i})= #{f_i}" end
GSyC 2009
29
Ejercicios
Ej2: Escribe una funcin iterador n_times que llame a un bloque n veces.
def n_times(n) # end
Ej3: Utilizando inject de un rango de nmeros escribe una funcin que calcule n!.
def fac(n) # end
Ej4: Escribe una funcin que calcule la cadena ms larga dentro de un array.
def longest_string(array) # end
GSyC 2009 La longitud de una cadena de caracteres puede saberse utilizando: a="hola" a.length
30
Clases y Objetos
Los nombres de clases comienzan con la primera letra en mayscula. El mtodo new crea un nuevo objeto de una determinada clase.
s=String.new
Todas las clases heredan de la clase Object. En ruby todo son objetos y por tanto, pueden invocarse sus mtodos de la siguiente forma: objeto.metodo
Los hemos estado usando:
line.gsub(), 1.upto(3), x.upcase
Ruby dispone de un recolector de basura que se encarga de destruir los objetos cuando ya no se usan.
GSyC 2009
31
Ejemplos de objetos
(4.6).round (4.6).class (4.6).round.class -4.class 'hola'.length 'hola'.class 'hola'.gsub('h', 'm') ['esto', 'es', 'un', 'array'].length => => => => 5 Float Fixnum Fixnum
GSyC 2009
Clases y objetos
En algunos lenguajes de programacin orientados a objetos:
Los objetos son datos Las clases son tipos de datos
Se pueden invocar los mtodos de las clases, como se invocan los mtodos de los objetos:
String.new String.methods => "" => ["inspect", "private_class_method", "const_missing", "clone", "method", "public_methods", ]
GSyC 2009
34
Variable alicia que es un nuevo objeto de la clase Persona. Se construye llamando a initialize de Persona
GSyC 2009
35
self
Dentro de un mtodo de una clase self es una referencia al objeto sobre el que dicho mtodo se ha invocado. self puede utilizarse para invocar otros mtodos, pero no para invocar atributos Muchas veces utilizar self es redundante.
class Persona ... def nuevo_saludo_1 "Saludo 1: " + saludo end def nuevo_saludo_2 "Saludo 2: " + self.saludo end end
GSyC 2009
36
Herencia
La clase Mujer hereda de la clase Persona. Es una especializacin de Persona.
class Mujer < Persona def initialize (nombre, edad, n_partos, viva=true) super(nombre, edad, viva) @n_partos = n_partos end end puts Mujer.new("Diana", 22, 0).saludo m = Mujer.new("Marisa", 40, 1) m.inspect # devuelve el id del objeto # y las variables de instancia
Se invoca dentro de un mtodo para ejecutar el mtodo del mismo nombre en la clase padre. En este caso se llama al constructor de Persona Crea un objeto de tipo Mujer e imprime en la salida estndar "Me llamo Diana y tengo 22 aos"
37
Sobrecarga de mtodos
Ruby no permite la sobrecarga de mtodos:
Una clase no puede tener dos mtodos con el mismo nombre y diferente nmero de parmetros. Si los tiene, slo ser vlido el ltimo que tenga definido. Slo puede existir un constructor por clase.
GSyC 2009
38
Mtodos de clase
Funcionan sin necesidad de ser invocados a partir de una determinada instancia.
Mtodo new: persona= Persona.new Mtodo para borrar un fichero: File.delete("nombre")
Definicin de un mtodo de clase Otras formas de definir mtodos de clase
class Ejemplo def self.metodo_de_clase end class <<self def metodo_de_clase end end
end
GSyC 2009
39
Objetos y atributos
Los atributos de una instancia del objeto Persona son privados y slo los mtodos de una instancia tienen acceso a ellos. Para que una instancia pueda mostrar el contenido de sus atributos es necesario definir
Mtodos que muestren el valor de los atributos
class Persona def initialize(nombre, edad, viva=true) @nombre, @edad, @viva = nombre, edad, viva Definiciones equivalentes end def nombre @nombre class Persona end attr_reader :nombre, :edad, :viva def edad def initialize(nombre, edad, viva=true) @edad @nombre, @edad, @viva = nombre, edad, viva end end def viva end @viva end end 40
GSyC 2009
Objetos y atributos
Para que una instancia pueda modificar el contenido de sus atributos desde fuera de los mtodos de dicha instancia, es necesario definir
Mtodos que modifiquen el valor de los atributos
class Persona def initialize(nombre, edad, viva=true) @nombre, @edad, @viva = nombre, edad, viva end Definiciones equivalentes def edad=(nueva) @edad=nueva end class Persona end attr_writer :edad def initialize(nombre, edad, viva=true) @nombre, @edad, @viva = nombre, edad, viva end end
GSyC 2009
41
Ejemplo
class Persona attr_writer :edad attr_reader :nombre, :edad, :viva def initialize(nombre, edad, viva=true) @nombre, @edad, @viva = nombre, edad, viva end end p=Persona.new("daniel", 2) puts "El nombre es #{p.nombre}" p.edad +=1 puts "#{p.nombre} tiene #{p.edad} aos"
GSyC 2009
42
Objetos y atributos
Crear funciones de lectura y modificacin para los atributos de una clase:
class Persona attr_accessor :nombre, :edad, :viva def initialize(nombre, edad, viva=true) @nombre, @edad, @viva = nombre, edad, viva end end
GSyC 2009
43
Smbolos
Es un objeto que puede ser representado por un nmero o por una cadena de caracteres.
:abc es un objeto Symbol y se interpreta como "la cosa llamada abc"
Se utilizan para representar nombres y cadenas de caracteres. Los smbolos ahorran memoria y tiempo
Para crear una tabla hash:
h= {:nombre => "Pepe", :email => "pepe@gsyc.es"}
44
Control de acceso
En Ruby la nica forma de cambiar el estado de un objeto es a travs de sus mtodos. Controlando el acceso a los mtodos, se controla el acceso al estado del objeto. Existen 3 niveles de proteccin:
Mtodos pblicos: cualquiera puede llamarlos. Por defecto son todos pblicos (salvo initialize) Mtodos protegidos: slo pueden llamarlos los objetos de la clase definida y sus subclases. El acceso queda controlado dentro de esa familia de objetos. Mtodos privados: slo los puede invocar el propio objeto. No se puede llamar a los mtodos privados de otro objeto, incluso si el objeto que los llama es de la misma clase que el otro objeto. Por ello, slo se permite invocar un mtodo privado en la forma m(...) y no en la forma o.m(...), para ningn o (ni siquiera self!).
GSyC 2009
45
46
Ejemplo
class Persona def nombre 'Marisa' end def apellido 'Lopez' end def nombre_completo construye_nombre end def construye_nombre nombre + " " + apellido end
:nombre_completo :construye_nombre 47
GSyC 2009
Ejemplo
class Persona def nombre 'Marisa' end def apellido 'Lopez' end end protected def nombre_completo construye_nombre end private def construye_nombre nombre + " " + apellido end end 48
PersonaAccPublico tiene los mismos mtodos de Persona porque los ha heredado. Permite que se ejecute nombre_completo a travs del mtodo pblico nombre_completo_publico. Permite que se ejecute construye_nombre a travs del mtodo pblico construye_nombre_publico.
class PersonaAccPublico < Persona def nombre_completo_publico self.nombre_completo end def construye_nombre_publico construye_nombre end
GSyC 2009
Ejemplo
class Persona def nombre 'Marisa' end def apellido 'Lopez' end end protected def nombre_completo construye_nombre end private def construye_nombre nombre + " " + apellido end end 49
Por ser un mtodo privado, no puede invocarse sobre ningn objeto (ni siquiera self!).
class PersonaAccPublico < Persona def nombre_completo_publico self.nombre_completo end def construye_nombre_publico self.construye_nombre end
GSyC 2009
class Persona def nombre 'Marisa' end def apellido 'Lopez' end protected def nombre_completo construye_nombre end
Ejemplo
p = Persona.new p.igual_a?(Persona.new)
nombre_completo es un mtodo protegido y por tanto puede ser llamado desde los objetos de la clase en la que est definido y de las clases hijas.
50
class Datos def initialize(arg1, *list) puts "Arg1=#{arg1}" puts "Lista longitud=#{list.length}" puts list end end d1 = Datos.new("dato1") d2 = Datos.new("dato1", "dato2") d3 = Datos.new("dato1", "dato2", "dato3")
Arg1=dato1 Lista longitud=0 Arg1=dato1 Lista longitud=1 dato2 Arg1=dato1 Lista longitud=2 dato2 dato3
GSyC 2009
51
Objetos y variables
Una variable no es un objeto. Una variable es una referencia a un objeto. String
person1 = "Tim" person2 = person1 person1[0]='J' person1 person2 => "Jim" => "Jim"
"Tim"
person1
person2
GSyC 2009
52
El objeto nil
El objeto nil es de la clase NilClass. Ruby utiliza este valor para asignarlo a los campos sin inicializar de una clase.
GSyC 2009
53
GSyC 2009
54
Excepciones
Un cdigo bien programado debe anticiparse a los errores, en Ruby, utilizando las excepciones. Ruby predefine una jerarqua de excepciones a partir de la clase Exception. El usuario puede lanzar una de las excepciones ya definidas en Ruby o crear las suyas propias. Si un usuario quiere definir sus propias excepciones, stas deberan heredar de StandardError o alguna de sus clases hijas para que por defecto se capturen. Una excepcin tiene asociado un mensaje (cadena de caracteres) y la traza de llamadas (backtrace).
GSyC 2009
55
Capturar excepciones
begin # las excepciones lanzadas por este cdigo # sern capturadas por la siguiente instruccin rescue # # # rescue ExceptionClassA, ExceptionClassB => e1 # se ejecuta si el cdigo lanza una ExceptionClassA # o ExceptionClassB # e1 toma el valor de la excepcin que se ha lanzado rescue ExceptionClassC => e2 # se ejecuta si el cdigo lanza una ExceptionClassC # e2 toma el valor de la excepcin que se ha lanzado rescue # captura una excepcin StandardError ensure # cdigo que siempre se ejecuta end
GSyC 2009
56
Lanzar excepciones
begin # # # raise # # raise # # raise # # end
Relanza de nuevo la misma excepcin (o RuntimeError si no se haba lanzado hasta ahora ninguna excepcin) "Servidor cado" Crea una excepcin RuntimeError con el mensaje "Servidor cado" y la lanza EServerDown, "El servidor no responde" crea una excepcin de tipo EServerDown y le asocia el mensaje "El servidor no responde"
GSyC 2009
57
GSyC 2009
Del libro Pragmatic Bookshelf - Programming Ruby
58
59
Ejemplo
class MiExcepcion < Exception; end class MiExcepcionHija < MiExcepcion; end class MiOtraExcepcionHija < MiExcepcion; end def pruebaExcepciones begin puts "Prueba a lanzar MiOtraExcepcionHija" raise MiOtraExcepcionHija puts "no deberia imprimirse" rescue MiExcepcionHija puts "Capturada mi excepcion hija" raise rescue MiOtraExcepcionHija puts "Capturada mi otra excepcion hija" raise end end begin pruebaExcepciones rescue MiExcepcion => e puts "#{e} ha ocurrido" puts "Por favor, contacta con el administrador del sistema :)" GSyC 2009 end
60
Incluir ficheros
Es frecuente ver una organizacin del cdigo Ruby en diferentes ficheros, por ejemplo dividiendo las clases definidas en ficheros distintos. Para poder usar las clases definidas en otros ficheros, es necesario utiliza la instruccin require.
require 'nombreFichero'
61
Ejemplo: require
Fichero f1.rb
a=1 def b 2 end
Fichero f2.rb
a="gato" require 'f1' puts a puts b
Escribe: gato 2
GSyC 2009
62