Diapositivas de la introducción al lenguaje ruby en el curso de extensión universitaria "Desarrollo Web Avanzado" del programa de Extensión Universitaria de la Universidad de Oviedo (2010)
3. Ruby es un lenguaje...
Orientado a objetos
Dinámico
Funcional
Productivo
4. Ruby es Orientado a Objetos
No existen tipos primitivos. Todos los literales son objetos
-199.abs # 199
"ruby no está nada mal".length # 21
["G", "A", "T", "T", "A", "C", "A"].uniq.sort.join # "ACGT"
{:hielo=>"frío", :fuego=>"caliente"}.values # [“frío”,”caliente”]
El estado y comportamiento de los objetos se define a través
de clases
class Punto
attr_accessor :x,:y
def initialize(x,y)
@x=x
origen=Punto.new(0,0)
@y=y
origen.x+=1 #igual que origen.x=origen.x+1
end
puts origen #=> Punto (1,0)
def to_s
"Punto (#{@x},#{@y})"
end
end
ruby_oo.rb
5. Ruby es dinámico
No hay declaraciones explícitas de tipos
lista=[1,2,3,"Hola"] #ruby
List<? extends Object> lista= Arrays.asList(1,2,"Hola"); //java
El tipo de los objetos viene determinado por su conjunto de
métodos y no por la clase a la que pertenezca.*
*Duck typing: a way of thinking about ruby programming - duck_typing.rb
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/78502
6. Ruby es funcional
En ruby todas las funciones pueden recibir un bloque, que es
una función anónima.
[1,2,3].map{ |x| x**2 } #[1, 4, 9]
10.downto(1){ |x| puts x } # imprime los números del 10 al 1
Los bloques permiten parametrizar el comportamiento de la
función que la recibe (patrón Strategy)
%w(ruby es ruby, no c++).sort do |una_palabra,otra_palabra|
una_palabra.size - otra_palabra.size
end #["no", "es", "c++", "ruby", "ruby,"]
blocks.rb
anonymous.java
7. Ruby es funcional
block_given? permite conocer si se ha pasado un bloque
a una función y yield permite invocarlo.
class Array
def filtra
[1,2,3,4].filtra do
filtrados=[]
|elemento| elemento % 2 == 0
if block_given?
end
each do |elemento|
#=> [2,4]
filtrados << elemento if yield elemento
end
colores=%w{rojo amarillo azul verde}
filtrados
%w{el cielo es azul}.filtra do
else
|palabra| colores.member? palabra
self
end
end
#=>["azul"]
end
end
blocks.rb
8. Ruby es un lenguaje productivo
El carácter dinámico y funcional del lenguaje, unido a una API
completa, hacen que el código sea más compacto y legible.
Ruby es reflectivo. El código puede ser observado y modificado
en tiempo de ejecución ➔ El propio programa puede crear
código por nosotros (metaprogramación)
reflection.rb
9. Core API (at a glance)
Números
Cadenas y Símbolos
Rangos, Listas y Diccionarios
Expresiones regulares
http://www.ruby-doc.org/core/
11. Cadenas (String)
A diferencia de la mayoría de los lenguajes de alto nivel, son
objetos mutables
# Comillas simples: no se evaluarán las expresiones #{} "Hip,"*2 + "hurray!"
'una cadena entre comillas #{"simples".upcase}'
#=> Hip,Hip,hurray
#=> una cadena entre comillas #{"simples".upcase}
"Ruby, no es ... ".length
# Comillas dobles sí se evaluarán las expresiones #{}
# => 16
"una cadena entre comillas #{"dobles".upcase}" "Ruby, no es... ".split(/s*/)
#=> una cadena entre comillas DOBLES # => ["R", "u", "b", "y", ",", "n", "o",
"e", "s", ".", ".", "."]
#Varias líneas "Ruby, no es python".scan(/ruby|python/i)
s=<<END # => ["Ruby", "python"]
Hola esto "Ruby, no es python".include?("python")
es un documento #=>true
de texto
"Ruby, no es python".end_with?("python")
en varias lineas
#=>true
END
Ruby, no es python".gsub(/Ruby, no/i,
#Troceado de palabras "Python sí ") # => Python sí es python
%w{Hola mundo} #=> ["Hola", "mundo"]
✍ http://ruby-doc.org/core/classes/String.html ranges.rb
12. Símbolos (Symbol)
Representan símbolos en la tabla símbolos del intérprete. Sólo
existe una única instancia de cada símbolo durante la ejecución de
un programa. a=:hola a= "hola"
b=:hola b= "hola"
a.equal? b # => true a.equal? b # => false
a==b # => true a==b # => true
Se usan por eficiencia para representar cadenas constantes o
nombres. A diferencia de los strings, cada vez que se usa no se
crea una nueva instancia.
link_to("View Article", :controller => "articles", :action => "show", :method
=>:get)
"Hola".method(:to_s).call
class Persona
attr_reader :nobre,:edad
end
✍ http://ruby-doc.org/core/classes/Symbol.html
13. Rangos (Range)
Representan conjuntos de valores (no sólo numéricos).
Sólo almacenan los extremos
1..10 #Números del 1 al 10
1...10 #Números el 1 al 9 (extremo superior no incluido)
'A'..'Z' #Letras de la A a la Z
require 'date'
hoy=Date.today
hace_un_mes = hoy << 1 # Date#<<(n) Resta n meses a la fecha
hace_un_mes...hoy # => 2010-02-20...2010-03-20
Métodos útiles
digits=0..9
digits.include? 5 # => true
digits.min # => 0
digits.max # => 9
digits.minmax # => [0,9]
digits.reject {|digit| digit % 2 == 0} # => [1, 3, 5, 7, 9]
digits.select {|digit| digit < 5 } # => [0, 1, 2, 3, 4]
digits.each {|digit| print digit," "} # 0 1 2 3 4 5 6 7 8 9
digits.to_a #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
✍ http://ruby-doc.org/core/classes/Range.html
18. if / unless
Toda expresión evalúa a true, excepto false y nil
if [expresion] #leer "si"
unless [expresion] #leer "a menos que"
"acción si expresión evalua a true"
"accion si expresion evalua a false"
elsif [expresion2]
else
"acción si expresion2 se evalua a true"
"acción si expresión se evalua a true"
else
end
"acción si no si expresion y expresion 2 son falsas"
end
#Asignar sólo si nombre tiene un valor
def name=(name)
@name = name if name
end
def name=(name)
@name = name unless name.nil?
end
✍ http://ruby-doc.org/core/classes/Hash.html
19. case - when
case retorna la expresión del primer when que evalúa a
true. score=75
result = case score
when 0...50 then "Fail"
when 50...70 then "Pass"
when 70...90 then "Pass with Merit"
when 90..100 then "Pass with Distinction"
else "Invalid Score"
end
puts result #Pass with Merit
El criterio del when puede ser cualquier instancia, ésta se comparará
con el argumento del case usando el método ===.
------------------------------------------------------------- Object#===
obj === other => true or false
------------------------------------------------------------------------
Case Equality---For class +Object+, effectively the same as calling
+#==+, but typically overridden by descendents to provide
meaningful semantics in +case+ statements.
20. for / while / until
array= ["fresa", "platano", "piña"]
for i in (0...array.length)
puts "En la posicion #{i}, #{array[i]}"
end
i=0
while i < array.legth
puts "En la posicion #{i}, #{array[i]}"
i+=1
end
i=0
until i==array.legth
puts "En la posicion #{i}, #{array[i]}"
i+=1
end
21. Gestión de excepciones
Lanzamiento
def invert(x)
raise ArgumentError, "#{x} no es un numero" unless x.is_a? Numeric
1.0 / x
end
*Ejecutar en terminal $ri Kernel#raise
Gestión
require "open-uri"
def check_connection(max_tries=2, url="http://www.ruby-lang.org")
tries=0
begin
tries+=1
puts "Comprobando conexión"
open(url){puts "Ok!"}
rescue Exception => e
puts "Conexión fallida: #{e.message}"
retry unless tries >= max_tries
end
end
22. Módulos y Mix-ins
Los módulos son una primitiva del lenguaje que permite
agrupar métodos, clases, constantes, etc.
• Crean espacios de nombres y previenen colisiones
módulos permiten articular mixins (herencia múltiple de
• Los
comportamiento)
modules.rb
23. Train yourself
Crear un programa que dado un número, calcule su
representación en forma de displays de 7 segmentos. El
programa recibirá el número a representar, y el tamaño
del dígito.
> lcd.rb -s 1 6789 > lcd.rb -s 2 012345
- - - - -- -- -- --
| | | | | | | | | | | | | |
- - - | | | | | | | |
| | | | | | -- -- -- --
- - - | | | | | | |
| | | | | | |
-- -- -- --
http://www.rubyquiz.com/
Como potencialmente un objeto puede tener cualquier conjunto de m&#xE9;todos podemos invocar cualquier \nm&#xE9;todo sobre cualquier objeto. No hay comprobaciones en tiempo de compilaci&#xF3;n y tampoco en tiempo de carga (cuando se parsea un fichero fuente)\n\nHacer DEMO.\n
\n
\n
\n
\n
\n
\n
* Object#equal? y Object#== Se comportan al rev&#xE9;s que en Java\n
\n
\n
\n
\n
\n
\n
\n
\n
Comentar que raise es un m&#xE9;todo privado del mixin Kernel, que es mezclado por Object, y por tanto est&#xE1; disponible para todos los objetos.\n