Professional Documents
Culture Documents
Hola mundo
Asignaciones
# Toda asignacin devuelve su valor a = 4 # 4 # Las asignaciones se pueden usar en cadena a = b = 4 # 4 a + b # 8 # y usados en un test fichero = File.open('../tutor.txt') # #<File:../tutor.txt> cont_linea = 0 # 0 cont_linea += 1 while (line = fichero.gets)# nil # Atajos a += 2 a = a+2 # 6 # 8
# Asignacin en paralelo a, b = b, a # [4, 8] # Dividiendo arrays array = [1, 2] # [1, 2] a, b = *array # [1, 2]
irb y ri
irb: es el intrprete interactivo de ruby, donde se pueden probar al vuelo porciones de cdigo. ri: herramienta para acceder a la documentacin. Por ejemplo, para documentarnos sobre el mtodo tr de la clase String, ponemos en la lnea de comandos:
ri String#tr
Sintaxis
variables, constantes, mtodos,..
Variables / Mtodos: estudiante, i, epsilon, piso_grande Las variables y los mtodos se parecen. Esto es lgico, puesto que una variable se puede sustitur por un mtodo. Las variables y los mtodos deben ser escritos en minsculas, que empiecen por una letra, y que contengan cualquier carcter alfanumrico o el guin bajo. Por ej: piso_grande. Sin embargo, las clases deben empezar por
mayscula. Adems, a diferencia de los mtodos/variables, no se usa el guin bajo para nombres compuestos. Por ej: PisoGrande. Las clases deben empezar por mayscula. Adems, a diferencia de los mtodos/variables, no se usa el guin bajo para nombres compuestos. Constantes: PDF_KEY, R2D2, PERSONA_VIAJE Las constantes slo se pueden definir una vez. Las constantes deben ser escritas en letras maysculas. Variables de objeto: @nombre, @maximo, @hora_comer Las variables de objeto (o variables de instancia) slo pueden ser ledas/escritas por el propio objeto. Variables de clase: objeto, llave_maestra Las variables de clase no pertenecen a los objetos, si no a la clase. Existen nicamente en la clase, y son compartidas por todos los objetos. Variables globlales: $global, $1, $contador El uso de las variables globales ha sido declarado un crimen capital por la escuela del buen diseo. Smbolos: :nombre, :edad, :Clase Los smbolos son identificadores nicos que los encontraremos en varios sitios.
Definicin de funciones
Las funciones se definen por la palabra clave def
def hola(programador)
Clases y objetos
Todo es un objeto
acostmbrate a usar la notacin del .mtodo
# 6 # Float # Fixnum
'un string'.length # 9 'un string'.class # String 'pepe dice'.gsub('p','t') # 'tete dice' 'abc'.gsub('b','xxx').length # 5 ['algunas', 'cosas', 'array'].length ['algunas', 'cosas', 'array'].reverse # 3 # ['array', 'cosas', 'array']
# Al ser un objeto, el mtodo suma es: 1.+(2) # 3 # pero para estos casos hay un azcar sintctico: 1 + 2 # 3
Definicin de clases
class Persona def initialize(nombre) @nombre = nombre end def saludar "Hola, mi nombre es #{@nombre}." end end pepe = Person.new('Pepe') puts pepe.saludar # Hola, mi nombre es Pepe
Herencia de clases
class Matz < Persona def initialize super('Yukihiro Matsumoto') end end puts Matz.new.saludar # Hola, mi nombre es Yukihiro Matusmoto
Accesores
Los accesores son funciones que permiten el acceso a los atributos de un objeto.
class Perro def initialize(nombre, raza) @nombre = nombre @raza = raza end # para leer las propiedades de un objeto def nombre @nombre end def raza @raza end end perro1 = Perro.new('Trampas', 'palleiro') perro1.nombre # Trampas perro1.raza # palleiro
Esto es equivalente a:
class Perro def initialize(nombre, raza) @nombre = nombre @raza = raza end attr_reader :nombre, :raza end perro1 = Perro.new('Trampas', 'palleiro') perro1.nombre # Trampas perro1.raza # palleiro
Esta es la tabla con el tipo de accesores, y su funcin:
En Ruby las clases nunca se consideran cerradas, y se pueden modificar al vuelo, aadiendo mtodos, variables, Por ejemplo, veamos como aadir una nueva funcionalidad a la clase Integer:
class Integer def fac raise "Factorizacin no definida para #{self}" if self < 0 return (1..self).inject(1) {|result,i| result*i} end end puts(0..5).map{|i| i.fac}.join(', ') # 1, 1, 3, 6, 24, 120
Excepciones
La captura se hace mediante rescue previo uso de begin:
begin # Cdigo que puede dar problemas rescue ClaseExcepcion1 => exception1 # Se ejecuta si se lanza una ClaseExcepcion1 rescue ClaseExcepcion2 => exception2 # Se ejecuta si se lanza una ClaseExcepcion2 rescue # Captura cualquier excepcin ensure # Cdigo que siempre se ejecuta end
Para lanzar una exepcin, usaremos raise
Mdulos
Definicin
Los mdulos son similares a las clases en que contienen una coleccin de mtodos, constantes y otros mdulos y definiciones. Pero a diferencia de las clases, no se pueden crear clases derivadas de los mdulos.
# trig.rb module Trig PI = 3.1416 # mtodos def Trig.sin(x) # ... end def Trig.cos(x) # ... end end require 'trig' Trig.sin(Trig::PI/4) # "::" -> PI/4 de la clas Trig
Herencia mltiple
Podemos aadir funcionalidades de distintos mdulos:
module D1 ... end module D2 ... end class ClaseCualquiera include D1 include D2 end
Arrays
# Array literal ['Un', 'array', 'con', 5, 'entradas'].join(' ') # Un array con 5 entradas # Nuevo array a = Array.new a << 'algunas' << 'cosas' a[2] a[0] = 3 a # # # # # [] algunas cosas cosas 3 3 cosas
# Se pueden usar valores por defecto... Array.new(4, 0) # [0, 0, 0, 0] # ...pero ten cuidado a = Array.new(2, 'Silke') a[0] << 'Amberg' a # ['Silke', 'Silke'] # Silke Amberg # ['Silke Amberg', 'Silke Amberg']
Hashes (diccionarios)
# Hash literal h0 = {'uno' => 1, 'dos' => 2} h0['uno'] # 1 # Rellenando un hash h1 = Hash.new #{} h1['joya'] = 'ruby' h1['fruta'] = 'banana' h1 # {"joya"=>"ruby", "fruta"=> "banana"} # A menudo, los smbolos se usan como llaves h2 = {:junio => 'perl', :julio => 'ruby'} h2[:julio] # ruby
Bloques e iteradores
Bloques: definicin
Un bloque es una pieza de cdigo, similar a un funcin annima. Una funcin puede usar un bloque como argumento.
# Un iterador sencillo, llamando al bloque por cada elemento del array ['soy', 'un', 'platano'].each do |elemento| print elemento, ' ' end #soy un platano # Otro iterador muy usado. El bloque modifica el contexto done fue creado fac = 1 1.upto(5) do |i| fac *= i end fac # 120 # El resultado del bloque puede ser usado por quin lo usa... [1,2,3,4,5].map{ |num| num*num} # [1,4,9,16,25] # ...y puede usarse ms de un argumento (0..100).inject(0){ |resultado, num| result + num} #5050
Bloques: sintaxis
# Los bloques son encerrados por do || ... end [1,2,3,4,5].each do |e| puts e end # o por parntesis {|| ... } [1,2,3,4,5].map{ |e| e*e}
Por convencin:
#[1,4,9,15,25]
usa do || end donde las modificaciones sean importantes y {|| } donde el valor de retorno sea importante
Iteradores
def f(cont, &bloque) valor = 1
1.upto(cont) do |i| valor = valor * i block.call(i, valor) end end f(5).do |i, f_i| puts "f(#{i}) = #{f_i}" end f(1) f(2) f(3) f(4) f(5) = = = = = 1 2 6 24 120
Estructuras de control
case
def saludar(*nombres) # * indica nmero indefinido de argumentos case nombres.length when 0 "Que triste, nadie ha leido mi tutorial" when 1 "Hola #{nombres}. Por lo menos una persona quiere saber Ruby" when 2..5 "Hola #{nombres.join(', ')}. Gracias por venir" when 6..12 "#{nombres.length} lectores. Bienvenidos a Ruby!" else "Wow #{nombres.length} lectores. Cuanta gente!" end end puts saludar('Alejandro', 'Luis', 'Pedro', 'Antonio', 'Guido', 'Matz, 'Satish')
condicionales
Ruby tiene todas las estructuras de control estndar. Y adems, se pueden anexar a una expresin.
# Estructura de control habitual... if (1+1 == 2) "Me gusta la escuela" else "Menuda sorpresa!" end #...que podemos anexar a la derecha "Me gusta la escuela." if (1+1 == 2) "Menuda sorpresa!" unless (1+1 == 2) (1+1 == 2) ? 'Correcto':'Incorrecto' # "Me gusta la escuela" # nil # Correcto
prob_lluvia = rand(100) # 64 (por ejemplo) case prob_lluvia when 0...10 then "Probabilidad ms baja" when 10...50 then "Baja probabilidad" when 50...90 then "Alta probabilidad" when 90...100 then "Probabilidad ms alta" end # Alta probabilidad
verdadero y falso
nicamente nil y false son falsos; todo lo dems, es verdadero.
def es_true(valor) puts valor ? true : false end # nil es_true(false) es_true(nil) es_true(true) es_true(1) es_true(0) es_true([0,1,2]) es_true('a'..'z') es_true('') es_true(:un_simbolo) # # # # # # # # # false false true true true true true true true
bucles
Ruby tiene donde elegir en las construcciones de bucles, pero no hay que olvidarse de los bloques!
i = 1
# 1
puts i
# 16 # nil # 128
i *= 2 while (i < 100) puts i begin i *= 2 end while (i < 100) puts i
# nil # 256
i *=2 until (i >= 1000) # nil puts i # 1024 loop do break i if (i >= 4000) i *= 2 end puts i 4.times do i *= 2 end puts i r = [] for i in 0..7 next if i % 2 == 0 r << i end puts r
# 0..7 # [1, 3, 5, 7]
Expresiones regulares
En las expresiones regulares:
Se ponen entre / / Cualquier caracter concuerda con si mismo, excepto \/^$|.+*?()[]\{\} que tienen distintas funciones dentro de las expresiones. Para poder buscarlos, hay que usar la secuencia de escape \. P. ej: \\, \/, ^ busca el principio de una lnea, $ busca el final de una lnea . busca cualquier carcter Si a,b son expresiones regulares, entonces: o ab es tambin una expresin regular o a* es una expresin regular que busca el caparazn de a o a+ es equivalente a aa* o a|b busca a b o Las expresiones pueden ser agrupadas por parntesis. P. ej:
/(a|b)c/ /a|bc/
/[a-zA-Z0-9]/
[^caracteres] busca los caracteres que NO pertenecen al rango. Atajos para los rangos:
atajo \w \W \s \S
Unidades de Testeo
El testeo de unidades es un mtodo para testear el cdigo en pequeos trozos.
Por qu
Significa que nunca tendrs el problema de crear un error mientras solucionas otro. Significa que no tendrs que ejecutar tu programa y jugar con l (lo que es lento) para arreglar los errores. El testeo de unidades es mucho ms rpido que el "testeo manual". Conociendo cmo usar las unidades de test, abre el mundo al driven development.
Requisitos
Cargar la biblioteca 'test/unit' Hacer que la clase a testear sea una subclase de Test::Unit::TestCase Escribir los mtodos con el prefijo test_ Afirmar (assert) las cosas que decidas que sean ciertas. Ejecutar los tests y corregir los errores hasta que desaparezcan.
require 'test/unit' class MiPrimerTest < Test::Unit::TestCase def test_de_verdad assert true end end