Introducción a Ruby
Jose Emilio Labra Gayo
Depto. Informática
Universidad de Oviedo
Ruby
Creado en 1995 por Yukihiro Matsumoto (Matz)
Lenguaje Orientado a Objetos puro
Interpretado (desde 1.9 se compila a M...
Ecosistema
Página: https://www.ruby-lang.org
Implementaciones:
MRI (Matz Ruby Interpreter), JRuby, Rubinius, mruby...
Vers...
Ecosistema
Intérprete/compilador: ruby
Intérprete interactivo: irb, pry
Gestión de paquetes: gem (rubygems.org)
Ayuda: rub...
TDD - BDD
TDD (Test Driven Development)
Desarrollo basado en pruebas
BDD (Behaviour Driven Development)
Desarrollo basado ...
RSpec
Crear los siguientes métodos
par(n) compruebe si un número es par
fact(n) devuelve el factorial de un nº
https://gis...
Conceptos básicos
Ruby = Orientado a Objetos puro
Todo lo que se manipula son objetos
Herencia universal (... < Object < B...
No hay tipos primitivos
Todo son objetos
23, "Hola", [1,2,3] son objetos
class: clase a la que pertenecen
superclass: supe...
Tipos
Ruby = tipado dinámico
Las variables no declaran el tipo
Las variables de instancia = nil hasta que se asignen
Tipos...
Sintaxis básica
Ruby = lenguaje orientado a una línea (scripting)
En general, expresiones terminan al final de la línea
; ...
Sintaxis básica
Todo consiste en enviar mensajes a objetos
objeto.send(mensaje,parámetros...)
Muchas simplificaciones para...
Comentarios
Comentarios
Hasta fin de línea: # hasta fin de línea
Varias líneas (no es muy popular en Ruby)
=begin
varias l...
Identificadores
Clases y constantes = empiezan por mayúscula
String ActiveRecord DEBUG MAX_ROWS
Variables y métodos = empi...
Convenciones
Variables y métodos: snake_case
Clases: CamelCase
Métodos booleanos suelen terminar en ?
empty?
Métodos pelig...
Objetos
Mediante constructor new se puede crear un objeto
class: devuelve la clase a la que pertenece
superclass: la super...
Ejemplo creación objeto (sin clase)
Variables de instancia empiezan por @
juan = Object.new
juan.instance_variable_set(:@n...
Clases
Clase = plantilla para generar objetos
Variables de instancia, empiezan por @
class Persona
def initialize(nombre, ...
Herencia simple
Mediante <
class Usuario < Persona
def initialize(nombre, edad, email)
super(nombre,edad)
@email = email
e...
Ejercicio: Figuras
Crear una clase Figura con 2 atributos (x,y)
Método que permita mover la figura
Crear una clase Rect pa...
Estructuras de control
if...else...elsif..., unless
while
for
bloques/iteradores
Condicional
if...elsif...else...end
hoy = Time.now
if hoy.saturday?
puts "Salir"
elsif hoy.sunday?
puts "Dormir"
else
puts...
Condicional
Varias posibilidades
if...then...else...end en una línea
if al final
if !today.monday?
puts "Juerga"
end
if !t...
Case
case...when...
edad = Random.rand(100)
case edad
when 0 .. 2
puts "bebé"
when 3 .. 6
puts "niño"
when 7 .. 12
puts "a...
while
while...end
while linea = gets
puts linea.upcase
end
En una sola línea
x = 2
while x < 1000
x = x * x
end
x = 2
x = ...
Ejercicio
Calcular los factores primos de un número
Ejemplo:
factores 1 = [1]
factores 2 = [1,2]
factores 3 = [1,3]
factor...
Métodos
Los métodos se definen mediante def
Paso de parámetros por referencia
Puede haber parámetros por defecto
También s...
Bloques de código
Fragmentos de código entre {...} ó do...end
Se asocian a un método
Pueden tener parámetros. Sintaxis: |x...
Iteradores
Iterador = método que devuelve sucesivos
elementos a partir de una colección
Ejemplo each
[ 'juan', 'pepe', 'lu...
Excepciones
raise: lanza una excepción
rescue: captura una excepción
def divide(x,y)
x = x / y
rescue ZeroDivisionError
"N...
Clases predefinidas
Números
String
Arrays
Hash
nil
Expresiones regulares
Nota: Object, Class, Module son también clases
Números
FixNum: enteros (longitud fija)
BigNum: enteros (sin longitud determinada)
Float
También hay números racionales y ...
Números
Las operaciones convierten al tipo más general
1 + 2 # => 3
1 + 2.0 # => 3.0
1.0 + 2 # => 3.0
1.0 + Complex(1,2) #...
Números
Bucles mediante números
3.times { print "X " } # => X X X
1.upto(5) {|i| print i, " " } # => 1 2 3 4 5
99.downto(9...
String
Varias formas de declarar cadenas:
Mediante "", '', %q, %Q
Interpolación #{ }
Delimitadores %
Cadenas HERE
pepe = "...
String
Múltiples métodos
downcase
uppercase
capitalize
chop
center
split
...
Métodos con ! cambian la cadena
Más informaci...
Colecciones: Arrays y Hashes
Colecciones indexadas de objetos
Diferencia:
Array: índice es un entero
Hash: índice es cualq...
Arrays
Clase Array
Inicializar: Array.new(nº elementos,valorInicial)
Sintaxis especial mediante [ ]
frutas = ["Melocotones...
Arrays
Los elementos pueden ser de tipos diferentes
x = [1, 'gato', 3.14]
Ejercicio con Arrays
Modelar cursos con alumnos
Una clase curso compuesta por:
Nombre del curso
Lista de alumnos
Una clase...
Hashes
Arrays asociativos
Clave => Valor
No están ordenados
Simplificación sintáctica
Cuando es el último argumento de un ...
Hashes
notas = { "juan" => 2.3, "luis" => 5.7 }
notas["pepe"] = 4
p notas # => {"juan"=>2.3, "luis"=>5.7, "pepe"=>4}
suma ...
Ejercicio Hashes y Arrays
Corregir exámenes. Aciertos: +1, fallos: -0.25
[ {"pregunta" => 1, "correcta" => "a"},
{"pregunt...
nil
Valor equivalente a falso
Las variables no inicializadas toman valor nil
x = Array.new
if x[1] then
puts "hay valor"
e...
Expresiones regulares
Valores entre / y / son expresiones regulares
=~ intenta encajar
$1, $2,... toman el valor de los gr...
Simplificaciones
attr_accessor, attr_reader, attr_writer
class Persona
attr_reader :nombre
attr_accessor :edad
def initial...
traits mediante módulos
module Saludador
def saluda(msg)
puts "Hola: " + msg
end
end
class Persona
include Saludador
def i...
Variables estáticas (de clase)
Mediante @@
class Persona
@@cuentaPersonas = 0
def initialize(nombre)
@nombre = nombre
@@cu...
Métodos estáticos (de clase)
Se indican mediante self.método
class Persona
def initialize(nombre)
@nombre = nombre
end
def...
Programación funcional en Ruby
Objetos Proc pueden invocarse mediante call
lambda = simplificación
suma3 = Proc.new { |x| ...
Modularización
Módulos permiten separar espacio de nombres
M::a = elemento a de módulo M
module Universidad
class Profesor...
Gestión de dependencias
Inclusión de módulos
require
require_relative
Gestión de dependencias mediante gem
gem install
gem...
Organización y distribución
Estructura habitual de directorios
saluda/
bin/
saluda
lib/
saluda/
options.rb
main.rb
test/
s...
Metaprogramación
Programas que tratan otros programas como datos
Pueden acceder a partes de otros programas
Conocer aspect...
Reflectividad
ObjectSpace información sobre objetos existentes
respond_to? chequea si admite mensaje
kind_of?, is_a? si pe...
Ejemplo de Metaprogramación
Añadir un atributo que recuerda los valores
class Class
def atributo_con_memoria(nombre)
nombr...
Ejemplo de metaprogramación
method_missing se ejecuta cuando no se encuentra un método
class Numeric
@@monedas = { 'euro' ...
Usos de metaprogramación
attr_accessor, attr_reader, etc.
ActiveRecord en Ruby on Rails
class Album < ActiveRecord::Base
h...
Técnicas Web en Ruby
Librerías: json, open-uri,...
Micro-framework: Sinatra
Web framework: Ruby on Rails
Referencias
Próxima SlideShare
Cargando en…5
×

2 Introducción al lenguaje Ruby

462 visualizaciones

Publicado el

Curso: Programación Orientada a Objetos
Máster Ingeniería Web - Universidad de Oviedo

Publicado en: Ingeniería
0 comentarios
0 recomendaciones
Estadísticas
Notas
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

Sin descargas
Visualizaciones
Visualizaciones totales
462
En SlideShare
0
De insertados
0
Número de insertados
6
Acciones
Compartido
0
Descargas
4
Comentarios
0
Recomendaciones
0
Insertados 0
No insertados

No hay notas en la diapositiva.

2 Introducción al lenguaje Ruby

  1. 1. Introducción a Ruby Jose Emilio Labra Gayo Depto. Informática Universidad de Oviedo
  2. 2. Ruby Creado en 1995 por Yukihiro Matsumoto (Matz) Lenguaje Orientado a Objetos puro Interpretado (desde 1.9 se compila a MV) Tipos dinámicos Matz, Fuente: Wikipedia "Ruby is designed for programmer productivity and fun" Compromiso +Simplicidad -seguridad +Productividad -rendimiento
  3. 3. Ecosistema Página: https://www.ruby-lang.org Implementaciones: MRI (Matz Ruby Interpreter), JRuby, Rubinius, mruby... Versiones en funcionamiento: 1.8 (2003), 1.9 (2007) , 2.0 (2013), 2.1 (2014) Instalación: RubyInstaller (Windows) Bitnami Ruby Stack (bitnami.com)
  4. 4. Ecosistema Intérprete/compilador: ruby Intérprete interactivo: irb, pry Gestión de paquetes: gem (rubygems.org) Ayuda: ruby-doc.org Entorno desarrollo: Extensión Eclipse: Aptana Rubymine
  5. 5. TDD - BDD TDD (Test Driven Development) Desarrollo basado en pruebas BDD (Behaviour Driven Development) Desarrollo basado en comportamiento Especificaciones mediante ejemplos Varios frameworks: Cucumber, RSpec, etc.
  6. 6. RSpec Crear los siguientes métodos par(n) compruebe si un número es par fact(n) devuelve el factorial de un nº https://gist.github.com/labra/6fa18dc87cb72ed1f82d
  7. 7. Conceptos básicos Ruby = Orientado a Objetos puro Todo lo que se manipula son objetos Herencia universal (... < Object < BasicObject) ...y mensajes entre objetos (aunque no lo parezca) Ruby tiende a camuflar algunas cosas para ser más intuitivo pepe.saluda("Hola")  pepe.send(:saluda,"Hola") pepe.edad  pepe.send(:edad) pepe.edad = 2  pepe.send(:edad=,2)
  8. 8. No hay tipos primitivos Todo son objetos 23, "Hola", [1,2,3] son objetos class: clase a la que pertenecen superclass: superclase "Hola".class # => String "Hola".class.superclass # => Object 2.class # => FixNum 2.class.superclass # => Integer [1,2,3].class # => Array [1,2,3].class.superclass # => Object
  9. 9. Tipos Ruby = tipado dinámico Las variables no declaran el tipo Las variables de instancia = nil hasta que se asignen Tipos dinámicos: chequeo en tiempo de ejecución x = "Hola" # => "Hola" x.class # => String x = 2 # => 2 x.class # => FixNum x = 2 + "Pepe" # => TypeError: String can't be # coerced into Fixnum
  10. 10. Sintaxis básica Ruby = lenguaje orientado a una línea (scripting) En general, expresiones terminan al final de la línea ; puede usarse para separar varias sentencias No es necesario al final de las sentencias Bloques de varias líneas indica que se necesita contenido en siguientes líneas Algunas expresiones indicant que hace falta contenido puts 2 # => 2 puts 2 + 3 # => 5 puts 2 + 3 # => 5 (no necesita ) puts 2 + 3 + 4 # => 9 (necesita )
  11. 11. Sintaxis básica Todo consiste en enviar mensajes a objetos objeto.send(mensaje,parámetros...) Muchas simplificaciones para mayor claridad pepe.crece  pepe.crece()  pepe.send(:crece) f 2  f(2)  self.send(:f,2) 2 + 3  2.+(3)  2.send(:+,3) a.should be >= 7  a.should(be() >= 7)  a.should(be.send(:>=,7))
  12. 12. Comentarios Comentarios Hasta fin de línea: # hasta fin de línea Varias líneas (no es muy popular en Ruby) =begin varias líneas =end rdoc genera documentación
  13. 13. Identificadores Clases y constantes = empiezan por mayúscula String ActiveRecord DEBUG MAX_ROWS Variables y métodos = empiezan por minúscula Variables globales: empiezan por $ $nombre Variables de instancia: por @ @nombre Variables de clase (estáticos): por @@ @@cuentaPersonas Símbolos (cadenas immutables): por : :action
  14. 14. Convenciones Variables y métodos: snake_case Clases: CamelCase Métodos booleanos suelen terminar en ? empty? Métodos peligrosos: terminan en ! reverse!, sort! La definición de "peligrosos" es relativa Suelen ser métodos que modifican objeto actual pero no siempre es así...es una convención Más información: http://goo.gl/VlPKhe
  15. 15. Objetos Mediante constructor new se puede crear un objeto class: devuelve la clase a la que pertenece superclass: la superclase de una clase methods: devuelve los métodos que tiene def: permite definer métodos self se refiere al objeto actual objeto = Object.new # => #<Object:0x28f0458> objeto.class #=> Object objeto.class.superclass #=> BasicObject objeto.methods #=> [:nil?, :class,...] def objeto.saluda(nombre) puts "Hola #{nombre}" end # => nil objeto.saluda("pepe") # => Hola pepe
  16. 16. Ejemplo creación objeto (sin clase) Variables de instancia empiezan por @ juan = Object.new juan.instance_variable_set(:@nombre,"Juan Manuel") juan.instance_variable_set(:@edad,34) def juan.crece @edad = @edad + 1 end def juan.getEdad @edad end def juan.masViejo?(otro) self.getEdad > otro.getEdad end
  17. 17. Clases Clase = plantilla para generar objetos Variables de instancia, empiezan por @ class Persona def initialize(nombre, edad) @nombre = nombre @edad = Integer(edad) end def to_s "Persona: #{@nombre}, edad: #{@edad}" end def envejece @edad = @edad + 1 end end juan = Persona.new("Juan", 30) juan.envejece puts juan #=> Persona: Juan, edad: 31
  18. 18. Herencia simple Mediante < class Usuario < Persona def initialize(nombre, edad, email) super(nombre,edad) @email = email end def to_s "Usuario: #{@nombre}, edad: #{@edad}, email: #{@email}" end def login(email) email == @email end end luis = Usuario.new("Luis", 24,"luis@mail.com") luis.envejece puts luis.login("luigi@mail.com") #=> false
  19. 19. Ejercicio: Figuras Crear una clase Figura con 2 atributos (x,y) Método que permita mover la figura Crear una clase Rect para representar Rectángulos Atributos a (ancho) y b (altura) Crear una clase Circulo para representar Círculos Atributo r (radio) Crear método area para calcular el area Crear método areas que calcula el area de una lista de figuras https://gist.github.com/labra/731f261deb9cc9c112a1
  20. 20. Estructuras de control if...else...elsif..., unless while for bloques/iteradores
  21. 21. Condicional if...elsif...else...end hoy = Time.now if hoy.saturday? puts "Salir" elsif hoy.sunday? puts "Dormir" else puts "Trabajar" end
  22. 22. Condicional Varias posibilidades if...then...else...end en una línea if al final if !today.monday? puts "Juerga" end if !today.monday? then puts "Juerga" end puts "Juerga" if !today.monday? unless today.monday? puts "Juerga" end puts "Juerga" unless today.monday? unless = if not
  23. 23. Case case...when... edad = Random.rand(100) case edad when 0 .. 2 puts "bebé" when 3 .. 6 puts "niño" when 7 .. 12 puts "adolescente" when 13 .. 18 puts "joven" else puts "adulto" end
  24. 24. while while...end while linea = gets puts linea.upcase end En una sola línea x = 2 while x < 1000 x = x * x end x = 2 x = x * x while x < 1000 =
  25. 25. Ejercicio Calcular los factores primos de un número Ejemplo: factores 1 = [1] factores 2 = [1,2] factores 3 = [1,3] factores 4 = [1,2,2] factores 5 = [1,5] factores 6 = [1,2,3] ... https://gist.github.com/labra/4a8b03b7dd5680eb09e1
  26. 26. Métodos Los métodos se definen mediante def Paso de parámetros por referencia Puede haber parámetros por defecto También se permite número variable de parámetros Devuelve valor última sentencia No suele necesitarse return def tlfno(num, prefijo = "34") prefijo + "-" + num end puts tlfno("985103000") puts tlfno("234567781","01") 34-985103000 01-985103000
  27. 27. Bloques de código Fragmentos de código entre {...} ó do...end Se asocian a un método Pueden tener parámetros. Sintaxis: |x| yield: invoca el bloque asociado Puede pasar argumentos def saluda(nombre) puts "Hola " + nombre yield 1 yield 2 end saluda("Pepe") {|n| puts "Recibo #{n}" } Hola Pepe Recibo un 1 Recibo un 2 Hola Juan Recibo un 1 Recibo un 2 saluda("Juan") do |n| puts "Recibo un #{n}" end
  28. 28. Iteradores Iterador = método que devuelve sucesivos elementos a partir de una colección Ejemplo each [ 'juan', 'pepe', 'luis' ].each {|nombre| puts nombre } 3.times { puts "*" } 3.upto(6) {|i| puts i } ('a'..'d').each {|char| puts char }
  29. 29. Excepciones raise: lanza una excepción rescue: captura una excepción def divide(x,y) x = x / y rescue ZeroDivisionError "No se puede dividir por 0" end def divide(x,y) if y == 0 raise "No puedo dividir por 0" end x / y end NOTA: Existen catch/throw pero tienen otro propósito
  30. 30. Clases predefinidas Números String Arrays Hash nil Expresiones regulares Nota: Object, Class, Module son también clases
  31. 31. Números FixNum: enteros (longitud fija) BigNum: enteros (sin longitud determinada) Float También hay números racionales y complejos num = 10001 4.times do puts "#{num.class}: #{num}" num *= num end Fixnum: 10001 Fixnum: 100020001 Bignum: 10004000600040001 Bignum: 100080028005600700056002800080001
  32. 32. Números Las operaciones convierten al tipo más general 1 + 2 # => 3 1 + 2.0 # => 3.0 1.0 + 2 # => 3.0 1.0 + Complex(1,2) # => (2.0+2i) 1 + Rational(2,3) # => (5/3) 1.0 + Rational(2,3) # => 1.6666666666666665 NOTA: La division entre enteros devuelve un entero por defecto 1.0 / 2 # => 0.5 1 / 2.0 # => 0.5 1 / 2 # => 0
  33. 33. Números Bucles mediante números 3.times { print "X " } # => X X X 1.upto(5) {|i| print i, " " } # => 1 2 3 4 5 99.downto(95) {|i| print i, " " } # => 99 98 97 96 95 50.step(80, 5) {|i| print i, " " } # => 50 55 60 65 70 75 80
  34. 34. String Varias formas de declarar cadenas: Mediante "", '', %q, %Q Interpolación #{ } Delimitadores % Cadenas HERE pepe = "Jose Luis" puts "hola #{pepe}" puts 'hola #{pepe}' cadena1 = %( cadena de texto con salto) cadena2 = <<HERE cadena de texto literal HERE
  35. 35. String Múltiples métodos downcase uppercase capitalize chop center split ... Métodos con ! cambian la cadena Más información: http://ruby-doc.org/core-2.1.3/String.html
  36. 36. Colecciones: Arrays y Hashes Colecciones indexadas de objetos Diferencia: Array: índice es un entero Hash: índice es cualquier otro valor (array asociativo) a = [23, 'gato', 3.14] h = { :nombre => "Jose", :edad => 23, 0 => 5} a[0] # => 23 a[4] # => nil h[:nombre] # => "Jose" h[0] # => 5
  37. 37. Arrays Clase Array Inicializar: Array.new(nº elementos,valorInicial) Sintaxis especial mediante [ ] frutas = ["Melocotones","Limones"] frutas << "Manzanas" frutas.push("Peras") puts frutas[2] # => Manzanas frutas.unshift("Naranjas") p frutas #=> ["Naranjas", "Melocotones", "Limones", "Manzanas", "Peras"] p frutas.sort #=> ["Limones", "Manzanas", "Melocotones", "Naranjas", "Peras"] p frutas #=> ["Naranjas", "Melocotones", "Limones", "Manzanas", "Peras"] frutas.sort! p frutas #=> ["Limones", "Manzanas", "Melocotones", "Naranjas", "Peras"] Más información: http://www.ruby-doc.org/core-2.1.3/Array.html
  38. 38. Arrays Los elementos pueden ser de tipos diferentes x = [1, 'gato', 3.14]
  39. 39. Ejercicio con Arrays Modelar cursos con alumnos Una clase curso compuesta por: Nombre del curso Lista de alumnos Una clase alumno compuesta por id del alumno nota del alumno Definir métodos de curso: getNota(id) ponNota(id,nota) media Curso Alumno 1..n1 https://gist.github.com/labra/7773beaf06a66fcd5424
  40. 40. Hashes Arrays asociativos Clave => Valor No están ordenados Simplificación sintáctica Cuando es el último argumento de un método link_to('Edit',{:controller=>'students', :action=>'edit'}) link_to 'Edit', :controller => 'students', :action => 'edit' Más información: http://ruby-doc.org/core-2.1.3/Hash.html
  41. 41. Hashes notas = { "juan" => 2.3, "luis" => 5.7 } notas["pepe"] = 4 p notas # => {"juan"=>2.3, "luis"=>5.7, "pepe"=>4} suma = 0 notas.each {|k,v| suma += v } media = suma / notas.length puts "Nota media: " + media.to_s # => Nota media: 4.0
  42. 42. Ejercicio Hashes y Arrays Corregir exámenes. Aciertos: +1, fallos: -0.25 [ {"pregunta" => 1, "correcta" => "a"}, {"pregunta" => 2, "correcta" => "b"}] [ {"alumno" => 2456, "respuestas" => [{ "pregunta" => 1, "respuesta" => "a"}, { "pregunta" => 2, "respuesta" => "b"}]}, {"alumno" => 4321, "respuestas" => [{ "pregunta" => 1, "respuesta" => "b"}, { "pregunta" => 2, "respuesta" => "b"}]}] [ {"alumno" => 2456, "nota" => 2}, {"alumno" => 4321, "nota" => 0.75}] https://gist.github.com/labra/c7209d569156bf3c9176
  43. 43. nil Valor equivalente a falso Las variables no inicializadas toman valor nil x = Array.new if x[1] then puts "hay valor" else puts "No hay valor" end
  44. 44. Expresiones regulares Valores entre / y / son expresiones regulares =~ intenta encajar $1, $2,... toman el valor de los grupos encajados email = "pepe@gmail.com" if email =~ /^(.*)@(.*).com$/i puts "encaja " + $1 + ' y ' + $2 else puts "no encaja" end
  45. 45. Simplificaciones attr_accessor, attr_reader, attr_writer class Persona attr_reader :nombre attr_accessor :edad def initialize(nombre,edad) @nombre = nombre @edad = edad end end pepe = Persona.new("Jose",23) puts pepe.nombre # => Jose puts pepe.edad # => 23 pepe.edad = 34 puts pepe.edad # => 34 pepe.nombre = "Juan" # undefined method `nombre='
  46. 46. traits mediante módulos module Saludador def saluda(msg) puts "Hola: " + msg end end class Persona include Saludador def initialize(nombre) @nombre = nombre end end pepe = Persona.new("Jose") pepe.saluda("¿Qué tal?")
  47. 47. Variables estáticas (de clase) Mediante @@ class Persona @@cuentaPersonas = 0 def initialize(nombre) @nombre = nombre @@cuentaPersonas += 1 puts "#Personas: " + @@cuentaPersonas.to_s end end pepe = Persona.new("Jose") luis = Persona.new("Kiko") mario = Persona.new("Mario")
  48. 48. Métodos estáticos (de clase) Se indican mediante self.método class Persona def initialize(nombre) @nombre = nombre end def self.doctor(nombre) Persona.new("Doctor " + nombre) end def to_s @nombre end end pepe = Persona.doctor("Jose Luis") puts pepe # => Doctor Jose Luis
  49. 49. Programación funcional en Ruby Objetos Proc pueden invocarse mediante call lambda = simplificación suma3 = Proc.new { |x| x + 3 } puts suma3.call(2) # => 5 suma3 = lambda { |x| x + 3 } ≡ aplica2 = lambda { |f,x| f.call(f.call(x)) } puts aplica2(suma3,2) # => 8 suma3 = ->(x){ x + 3 }
  50. 50. Modularización Módulos permiten separar espacio de nombres M::a = elemento a de módulo M module Universidad class Profesor def initialize(nombre) @nombre = nombre end def to_s @nombre end end end module Ayuntamiento pepe = Universidad::Profesor.new("Jose") puts pepe end module Ciudad include Universidad juan = Profesor.new("Juan") puts juan end
  51. 51. Gestión de dependencias Inclusión de módulos require require_relative Gestión de dependencias mediante gem gem install gem list Gestión de tareas rake
  52. 52. Organización y distribución Estructura habitual de directorios saluda/ bin/ saluda lib/ saluda/ options.rb main.rb test/ saluda_spec.rb saluda.gemspec Ejemplo: https://github.com/cursosLabra/saludaRuby Creación de gema: gem build saluda.gemspec
  53. 53. Metaprogramación Programas que tratan otros programas como datos Pueden acceder a partes de otros programas Conocer aspectos del Sistema Métodos tiene una clase, objetos existentes, etc. Crear/modificar métodos o atributos en ejecución "Métodos mágicos" que se invocan al vuelo Asociar callbacks (hooks) a determinadas acciones Cuando se crea una instancia, una subclase, etc. ...
  54. 54. Reflectividad ObjectSpace información sobre objetos existentes respond_to? chequea si admite mensaje kind_of?, is_a? si pertenece a una clase (superclase) instance_of? si es una instancia exacta de una clase ...y muchos más: class, superclass, instance_methods, private_instance_methods, class_variables, constants, instance_variables,
  55. 55. Ejemplo de Metaprogramación Añadir un atributo que recuerda los valores class Class def atributo_con_memoria(nombre) nombre = nombre.to_s attr_reader nombre attr_reader nombre+"_valores" class_eval %( def #{nombre}=(val) if @#{nombre+"_valores"}== nil @#{nombre+"_valores"} = [nil, val] else @#{nombre+"_valores"} << val end @#{nombre}=val end ) end end class Persona atributo_con_memoria :nombre atributo_con_memoria :edad end juan = Persona.new juan.nombre = "Juan" juan.edad = 3 juan.nombre = "Juan Manuel" print juan.nombre_valores print juan.edad_valores [nil, "Juan", "Juan Manuel"] [nil, 3 ]
  56. 56. Ejemplo de metaprogramación method_missing se ejecuta cuando no se encuentra un método class Numeric @@monedas = { 'euro' => 1, 'dolar' => 1.27 } def method_missing(nombre_metodo) moneda_singular = en_singular(nombre_metodo) if @@monedas.has_key?(moneda_singular) self * @@monedas[moneda_singular] else super end end def en(moneda) nombre = en_singular(moneda) if @@monedas.has_key?(nombre) self / @@monedas[nombre] else super end end def en_singular(cadena) cadena.to_s.gsub(/s$|es$/,'') end end puts 5.dolares.en("euros") #=> 6.35 puts 20.euros.en("dolares") #=> 15.74
  57. 57. Usos de metaprogramación attr_accessor, attr_reader, etc. ActiveRecord en Ruby on Rails class Album < ActiveRecord::Base has_many :tracks end
  58. 58. Técnicas Web en Ruby Librerías: json, open-uri,... Micro-framework: Sinatra Web framework: Ruby on Rails
  59. 59. Referencias

×