You are on page 1of 41

PROGRAMANDO CON RUBY

VICTOR GIRALDO BUESAQUILLO GÓMEZ

6 de enero de 2018
Índice general

1. Generalidades de Ruby 4
1.1. Instalando ruby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.1. Instalar en linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.2. Empezar a usar Ruby interactivo . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.3. Usando emacs como editor de código . . . . . . . . . . . . . . . . . . . . 4
1.1.4. Asignar un valor a una variable . . . . . . . . . . . . . . . . . . . . . . . 6
1.2. Operaciones matemáticas básicas . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.1. Los enteros y los reales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.2. Concatenar cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.3. Mensaje y entrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.4. Formas de expresar enteros . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.5. Formas de expresar reales . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.6. Funciones sobre enteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.7. Funciones sobre reales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2.8. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3. El módulo Math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.1. Las constantes π = PI y e = E . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.2. Funciones trigonométricas . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.3. Funciones hiperbólicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.4. Función atan2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.5. Función logarítmica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.6. Otras funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3.7. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.4. Cadenas de caracteres o strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.4.1. Definiendo cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.4.2. Definiendo números desde cadenas . . . . . . . . . . . . . . . . . . . . . 15
1.4.3. Reemplazar un valor en una cadena . . . . . . . . . . . . . . . . . . . . . 15
1.4.4. Funciones sobre cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.4.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.5. Arreglos o Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.6. Fechas y horas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.7. Hash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.8. Each y bloques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.9. Contadores y acumuladores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.10. Matrices y vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.10.1. Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.10.2. Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

1
2. Lógica 33
2.1. Lógica condicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.1.1. Expresiones condicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.1.2. Ciclo if then . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.1.3. Ciclo for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.2. Ciclo while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.2.1. Ciclo loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.2.2. Expresiones múltiples case . . . . . . . . . . . . . . . . . . . . . . . . . . 35

3. Objetos 36
3.1. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.1.1. Tipos de variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.2. Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.3. Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.3.1. Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.3.2. Llamado de propiedades y funciones . . . . . . . . . . . . . . . . . . . . 38
3.3.3. Atributos de las clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.3.4. Control de acceso a la clase . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.4. Herencia y taxonomías . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

2
Sobre el uso de las notas
10 de diciembre de 2015

La elaboración de este manuscrito tiene intereses únicamente educativos y por tal motivo
puede ser usado y distribuido por quien lo desee. El texto no ha sido revisado así que advierto
que puede contener ciertas falencias.

3
Capítulo 1

Generalidades de Ruby

1.1. Instalando ruby


1.1.1. Instalar en linux
Use el siguiente comando en una terminal:
sudo apt-get install ruby irb rdoc

1.1.2. Empezar a usar Ruby interactivo


Para ingresar o salir de Ruby interactivo se usa respectivamente:

irb

quit o exit

Después de cada comando se debe presionar la tecla enter o RET.

1.1.3. Usando emacs como editor de código


Podemos usar el editor emacs como editor de código para ruby. Se abre el archivo mipro-
grama.rb usando emacs y luego se ejecuta:
M-x term
Enter
Enter
donde miprograma.rb es el archivo donde tengo el código, M es la tecla Meta o Alt, term se
escribe tal cual y Enter es la tecla Intro.
C-x
Pulsar control más x.

ESC-x
Pulsar primero ESC y luego x independientemente. Coloca el cursor en la línea de
órdenes (en la parte inferior de la pantalla) a la espera de una orden que deberá teclearse
a continuación.

C-z
Minimizar emacs.

4
C-c
Salir de emacs.

C-g
Anular una instrucción.

C-x b
Nombre
Teclear C-x y luego b. Permite ir al buffer llamado Nombre.

C-x C-b
Lista de buffers existentes.

C-x k
Nombre
RET
Destruye el buffer Nombre.

C-x C-f
Nombre
Crea un buffer con el contenido del fichero Nombre.

C-x C-v
Nombre
Reemplaza el contenido del buffer en que nos hallamos por el del fichero Nombre.

C-x C-s
Salva el contenido del buffer en que nos encontramos en el fichero al que está conectado.
En caso de que el buffer no esté conectado a ningún fichero en particular, podemos
especificar el fichero en que deseamos que se escriba.

C-x C-w
Nombre
Escribe el contenido del buffer en el fichero Nombre.

C-v
Avanza una pantalla.

ESC-v
Retrocede una pantalla.

ESC-<
Nos lleva a la primera línea.

ESC->
Nos lleva a la última línea.

C-a
Principio de la línea.

C-e
Final de la línea.

ESC-a
Principio del párrafo.

5
ESC-e
Final del párrafo.

C-x h
Seleccionar todo.

C-x 2
Dividir en dos ventanas horizontalmente.

C-x 3
Dividir en dos ventanas verticalmente.

C-x 0
Borra la ventana del cursor.

C-x 1
Borra las ventanas salvo la del cursor.

C-s
Busca desde el cursor hacia abajo.

C-r
Busca desde el cursor hacia arriba.

ESC-x help RET


Ayuda.

1.1.4. Asignar un valor a una variable


Se usa el signo = para asignar un valor a una variable, sin embargo, no tiene el mismo
significado de igualdad matemático.
Para asignar la constante A a la variable x y la constante B a la variable y se escribe:

x=A

y=B

Por convención se usan palabras que empiezan con minúsculas para designar variables y
mayúsculas para designar constantes. Las constantes pueden ser números o cadenas de
caracteres que se incluyen con comillas.

x = −6

y = −75

nombre = “Camila00

1.2. Operaciones matemáticas básicas


Las Operaciones matemáticas básicas son la suma +, resta −, multiplicación ∗, división /
y potencia ∗∗. Con las asignaciones anteriores los resultados son los siguientes:

x + y ⇒ −81

x − y ⇒ 69

6
x ∗ y ⇒ 450

y/x ⇒ 12

5.0/4 ⇒ 1.25

y ∗ ∗x ⇒ 1/177978515625

(x ∗ y) ∗ ∗0.5 ⇒ 21.213203435596427

Uno de los resultados anteriores tiene algo que no es del todo cierto. Vamos a ver que sucede.

1.2.1. Los enteros y los reales


Todo número entero se diferencia de un real porque no tiene punto decimal y toda opera-
ción que se realice entre enteros genera otro entero que ignora el sobrante. Basta con escribir
uno de los números de la operación con punto flotante para que el resultado sea real:

5/4 ⇒ 1

5.0/4 ⇒ 1.25

1.2.2. Concatenar cadenas


Para unir cadenas de caracteres se usa el símbolo +. También se pueden unir cadenas con
números si se usa .to_s luego de la variable.

5.0+nombre ⇒ 5.0Camila

x.to_s+nombre⇒ −6Camila

nombre+nombre ⇒ “CamilaCamila00

1.2.3. Mensaje y entrada


El comando puts muestra una cadena o el resultado de un cálculo.

puts nombre
Camila

El comando gets pide un dato al usuario.

nombre = gets
Para un cadena.

x = gets.to_f
Para un número de punto flotante.

print “\n” Para generar un espacio.

7
1.2.4. Formas de expresar enteros
23_838
_ facilita la lectura del número.

043
0 al inicio indica número octal o base 8. En el sistema decimal el número es 4∗81 +3∗80 = 35

0xaa
0x al inicio indica sistema hexadecimal o base 16. En el sistema decimal el número es
10 ∗ 161 + 10 ∗ 160 = 170

0b10
0b al inicio indica sistema binario o base 2.

1.2.5. Formas de expresar reales


Es frecuente expresar números de punto flotante de la siguiente manera:
3.0e6 ⇒ 300000.0

3e20 ⇒ 3.0e + 20 = 3x1020

1.2.6. Funciones sobre enteros


i=4

j=3

i.to_s
convierte a cadena

i.to_f
convierte a real

i.next
sucesor

i == j ⇒ false
compara por igualdad

i %j ⇒ 1
módulo, devuelve el sobrante. Funciona bien con números positivos.

1.2.7. Funciones sobre reales


r = −3.1416 ⇒ −3.1416

s = 3.1416 ⇒ 3.1416

r.to_i ⇒ −3
elimina los decimales de r

-3.5.round ⇒ “ − 400
redondea a un entero usando reglas básicas. Tiene problemas cuando después del punto
decimal hay un cinco, pues no usa las reglas aceptadas de redondeo.

8
r.round(3) ⇒ “ − 3.14200 redondea con tres cifras decimales usando reglas básicas. No
aplica en versiones anteriores a 1.9.3 de ruby.

r.to_s ⇒ “ − 3.141600
convierte a cadena

r.abs ⇒ 3.1416
devuelve el valor absoluto

r == −s ⇒ true
compara por igualdad

r.ceil ⇒ −3
entero inmediato superior a r

r.floor ⇒ −4
entero inmediato inferior a r

(r/0.0).finite? ⇒ false
prueba si la operación es finita

(r/0.0).infinite? ⇒ true
prueba si la operación es infinita

(0/r).zero? ⇒ true
prueba si la operación da cero

−r %3.0 ⇒ 0.1416
módulo, retorna el sobrante

1.2.8. Ejercicios
Escribir una ecuación que convierta temperatura de Farenheit a Centígrados.
f = 32
c = (5.0/9) ∗ ( f − 32)
⇒ 0.0

Escribir una ecuación que convierta temperatura de Centrígrados a Farenheit.


c=0
f = (9.0/5) ∗ f + 32
⇒ 32

Escribir una ecuación que convierta de grados a radianes.


g = 180
r = 3.141592 ∗ g/180
⇒ 3.141592

Escribir una ecuación que convierta de radianes a grados.


r = 3.141592
g = 180 ∗ r/3.141592
s.to ⇒ 180

9
1.3. El módulo Math
El módulo Math contiene funciones trigonométricas básicas y funciones trascendentales.
El argumento se ingresa en radianes.

1.3.1. Las constantes π = PI y e = E


Math::PI
⇒ 3.141592653589793
Math::E
⇒ 2.718281828459045
Math.constants
Para ver las constantes definidas en Ruby.

1.3.2. Funciones trigonométricas


Math.cos(x)
Coseno de x
Math.sin(x)
Seno de x
Math.tan(x)
Tangente de x
Math.acos(x)
Arco coseno de x
Math.asin(x)
Arco seno de x
Math.atan(x)
Arco tangente de x

1.3.3. Funciones hiperbólicas


Math.cosh(x)
Coseno hiperbólico de x
Math.sinh(x)
Seno hiperbólico de x
Math.tanh(x)
Tangente hiperbólica de x
Math.acosh(x)
Coseno hiperbólico de x
Math.asinh(x)
Seno hiperbólico de x
Math.atanh(x)
Tangente hiperbólica de x

10
1.3.4. Función atan2
Dado que la función Math.atan(x) puede adquirir valores distintos para un mismo valor
de x, entonces aparece la función Math.atan2(y,x) para solucionar dicho problema:
−1 y
 tan y  x x>0



tan−1 x + π x < 0, y ≥ 0





  
y
tan−1 x − π x < 0, y < 0

atan2(y,x) = 


+ π2 x = 0, y > 0



− π2

x = 0, y < 0




x=y=0

Indefinido

2y
atan2(y,x) = p
x2 + y2 + x
Por lo tanto la función atan2 devuelve el ángulo de un punto en el plano.

Math.atan2(x,y)
⇒ arco
Arco del punto (x,y) sin ambigüedades.

1.3.5. Función logarítmica


Math.log(x)
Calcula el logaritmo natural de x.

Math.log(y,x)
Logaritmo en base x de y.

Math.log10(x)
Logaritmo en base 10 de x.

Math.log2(x)
Logaritmo en base 2 de x.

1.3.6. Otras funciones


Math.cbrt(x)
Raíz cúbica de x.

-2.upto(3){|x| p [x, Math.cbrt(x), Math.cbrt(x)**3]}


Operaciones recurrentes. Hace las operaciones de los corchetes desde -2 hasta 3 en pasos
de 1. Hay que respetar los espacios antes y después de p.

“a8”.upto(“b6”) {|s| print s, ” }


Otra forma.

Math.erf(x)
Calcula la función error de x. La función error calcula el área bajo la curva de la función
exp(−t2 ) desde cero hasta el valor que uno introduzca como argumento (x).

Math.erfc(x)
Calcula la función error complementaria de x. Hace lo mismo que la función error pero
calcula el área desde x hasta infinito.

11
Math.exp(x)
Función exponente de x.

Math.hypot(x,y)
Hipotenusa de un triángulo de catetos x e y.

Math.frexp(x)
⇒ [a, b]
Función fracción exponente. Arreglo de dos elementos, la fracción normalizada y el
exponente de x. Donde x=a2b .

Math.gamma(x)
Función gamma. La función gamma de n es igual a la función factorial de n − 1.

def fact(n) (1..n).inject(1) {|r,i| r*i } end


Definiendo la función factorial.

1.upto(26) {|i| p [i, Math.gamma(i), fact(i-1)] }


Operación recurrente de 1 a 26 con las funciones del corchete y la función factorial recién
definida.

Math.ldexp(a,b)
⇒x
Inversa de la función fracción exponente.

Math.lgamma(x)
⇒ [ f loat, −1 ó 1]
Calcula el logaritmo y el signo de gamma de x.

1.3.7. Ejercicios
Escribir un programa que recibe las coordenadas x,y de un objeto y devuelve el radio y
el ángulo en grados.
cat > rayangr.rb
print “Escriva el valor de x:”
x=gets.to_f
print “Escriba el valor de y:”
y=gets.to_f
print “Radio: ”
print Math.hypot(x,y)
print “\ n”
print “Angulo: ”
print Math.atan2(y,x)*180/Math::PI
print “\ n”
^D
ruby rayangr.rb
Escriva el valor de x:3
Escriba el valor de y:3
Radio: 4.242640687119285
Angulo: 45.0
Donde ^D es control-D.

12
Cambiar el programa anterior para que arroje el resultado en radianes.
Basta con quitar el factor 180/Math::PI

Añadir un if y un else para que el resultado este entre 0 y 2π en lugar de -π y π.


cat > rayanra.rb
print “Escriva el valor de x:”
x=gets.to_f
print “Escriba el valor de y:”
y=gets.to_f
print “Radio: ”
print Math.hypot(x,y)
print “\ n”
print “Angulo: ”
if Math.atan2(y.to_f,x) > 0
print Math.atan2(y.to_f,x)
else print Math.atan2(y.to_f,x)+ 2*Math::PI
end
print “\ n”
^D
ruby rayanra.rb
Escriva el valor de x:3
Escriba el valor de y:3
Radio: 4.242640687119285
Angulo: 0.7853981633974483

Hacer un código que reciba un número e indique si es par o impar.


puts “escriba un entero x: ”
x=gets
u=“1”+x.to_s
y=x.to_f
z=x.to_i
if u.to_f==10
puts “par”
elsif y==0
puts “debe escribir un numero”
elsif y %2==0 and y==z
puts “par”
elsif y>z
puts “debe escribir un entero”
else
puts “impar”
end

Hacer un código que reciba un número e indique si es múltiplo de 7.


puts “escriba un entero x: ”
x=gets.to_f
if x %7==0
puts “multiplo de 7”
else
puts “no es multiplo de 7”
end

13
Escribir un código que recibe 3 números y devuelve el mayor de los tres.
puts “escriba los numeros x,y,z: ”
x=gets.to_f
y=gets.to_f
z=gets.to_f
if x>=y and x>=z
puts x
elsif y>=x and y>=z
puts y
else
puts z
end

Escribir un código que recibe un flotante y un entero, y devuelve un flotante con el


número de decimales que indica el entero y que redondea la última cifra correctamente.
puts “escriba un flotante x: ”
x=gets.to_f
puts “escriba un entero positivo y: ” y=gets.to_i
z=x.to_i
u=(x-z).to_s
a=(u[y+1])
b=(u[y+2])
c=a.to_i+1
if u.to_f==0
puts y.to_s+“.”+“0”*y
elsif a.to_f %2==0 and b.to_f==5
puts z.to_s+u[1,y+1]
elsif (a.to_f+1) %2==0 and b.to_f==5
puts z.to_s+u[1,y]+c.to_s
elsif b.to_f<5
puts z.to_s+u[1,y+1]
elsif b.to_f>5
puts z.to_s+u[1,y]+c.to_s
end

1.4. Cadenas de caracteres o strings


1.4.1. Definiendo cadenas
Las cadenas representan palabras, grupos de palabras o concatenaciones de caracteres.

laso1=“primera concatenación”
Entre comillas dobles una cadena puede contener caracteres especiales como \t o ta-
bulador, \n o salto de linea y números en diferentes representaciones como octales y
hexadecimales.

laso2=0 otra concatenación0


La cadena no debe contener caracteres especiales.

r=4.23
r.to_s

14
⇒ “4.23”
Los números ya sea enteros o reales se pueden convertir en cadenas.

1.4.2. Definiendo números desde cadenas


Las cadenas se pueden convertir a números.

“123”.oct
⇒ “83”
Pasa una cadena octal a entero.

“0x0a”.hex
⇒ “10”
Cadena hexadecimal a entero.

“123.45e1”.to_f
⇒ “1234.5”
Convierte a real.

“1234.5”.to_i
⇒ “1234”
Convierte a entero

“0a”.to_i(16)
⇒ “10”
Convierte desde hexadecimal

“1100101”.to_i(2)
⇒ “101”
Convierte desde binario.

1.4.3. Reemplazar un valor en una cadena


La notación especial #{} reemplaza el valor de una variable dentro de una cadena:

edad = 25
“La edad es #{edad}”
⇒ “La edad es 25”

1.4.4. Funciones sobre cadenas


Suponiendo que s, s1 y s2 son cadenas:

s*3
Concatena tres copias de s.

s1+s2
Concatena las cadenas s1 y s2.

s1==s2
Compara las dos cadenas s1 y s2.

s1<<s2
Concatena s2 después de s1.

15
s1<<i
Concatena el carácter i después de s1. Donde i es un valor entre cero y 255.

s.length
Cuenta el número de caracteres de s.

s.upcase
Vuelve mayúsculas las letras de s. Use upcase! para guardar los cambios.

s.downcase
Vuelve minúsculas las letras de s. Si se adiciona un ! al final de downcase entonces se
guardan los cambios.

s.swapcase
Cambia minúsculas por mayúsculas y viceversa.

s.capitalize
Devuelve todas las letras de s en minúsculas y la primera a mayúsculas si fuera una
letra.

s.capitalize!
Modifica todas las letras de s en minúsculas y la primera la Vuelve mayúsculas si fuera
una letra. La cadena se guarda en el nuevo formato.

s[i]
Saca el carácter i de la cadena s.

s[1]=“z”
Cambia el carácter 1 de s por z.

s[1,3]
Saca tres caracteres de s a partir del segundo.

s[1..3]
Saca los caracteres de s del segundo al cuarto. El rango también puede ser con valores
negativos en el orden correcto.

s[-3,2]
Saca dos elementos a partir del tercero empezando a contar desde el último en 1.

s[“sc”]
Saca la subcadena sc de s.

s[“a”]=“z”
Cambia el carácter a de s por z si lo tuviera. Sale error si no lo contiene.

a[/[exp-reg](.) \ 1/,i]
Donde i es un número. No se que hace.

s.slice(i)
Remueve el carácter en la posición i de s. Para guardar los cambios se usa slice!

s.slice(i..j)
Remueve los caracteres en el rango.

16
s.slice(i,j)
Remueve j caracteres a partir de la posición i.

s.bytes.to_a
Devuelve el enumerador que da cada byte en la cadena.

a.length
Devuelve el número de elementos de s.

s1.casecmp(s2)
Devuelve 1 si s1 tiene más caracteres que s2 o si la cantidad es la misma pero son
distintos o si están en desorden, 0 si son iguales y en el mismo orden, o -1 si s2 tiene
más caracteres que s1.

s.center(i)
Centra s entre i espacios.

s1.center(i,s2)
Centra s1 entre i caracteres de s2.

s.chars.to_a
Crea un array de los caracteres de s.

s.chomp
Remueve \n, \r y \r\n del final de s si los tuviera.

s1.chomp(s2)
Remueve s2 del final de s1 si la hubiera.

s.chomp!
Remueve \n, \r y \r\n del final de s si los tuviera y guarda los cambios en s.

s1.chomp!(s2)
Remueve s2 del final de s1 si la hubiera y guarda los cambios en s.

s.insert(i,“a”)
Coloca el carácter a en la posición i de s.

s.reverse
Invierte el orden de los caracteres de s. Para guardar los cambios en s use reverse!

s.concat(33)
Adiciona el símbolo 33 de la lista de símbolos de 0 a 255 al arreglo a.

s.chop
Remueve el último carácter de s. También remueve \n y \r del final de s. Nota: las
funciones se pueden aplicar seguidamente (como s.chop.chop.chop).

s.chop!
Remueve el último carácter de s y guarda los cambios.

s1.count s2
Cuenta cuantas veces aparecen los caracteres de s2 en s1.

s1.count s2 s3
Cuenta los caracteres de la intersección de s2 y s3 que hay en s1.

17
s1.count s2, “^s3”
Cuenta los caracteres de s2 que están en s1 pero que no están en s3.

s.count "ej-m"
Cuenta las letras e y del intervalo cerrado j-m que hay en s.

s.delete(“a”)
Borra todos los caracteres a de s si los tuviera. Si se adiciona un ! al final de delete
entonces se guardan los cambios.

s1.delete s2, s3
Borra los caracteres de la intersección de s2 y s3 en s1.

s1.delete s2
Borra los caracteres de s2 que aparecen en s1.

s1.delete s2, “^s3”


Borra de s1 los caracteres que aparecen en s2 salvo los que aparecen en s3.

s1.delete “ej-m”
Borra los caracteres e y los del intervalo cerrado j-m en s1.

s1.eql?(s2)
Compara por igualdad las cadenas s1 y s2.

s.gsub(/[s1]/, ’s2’)
Cambia cualquiera de los elementos de s que aparecen en s1 por s2. Si se adiciona un !
al final de gsub entonces se guardan los cambios.

s.gsub(/([s1])/, ’< \1 >’)


Cambia cualquiera de los elementos de s que aparecen en s1 por el mismo elemento
encerrado en <>.

s.gsub s1 , s2
Cambia las cadenas s1 que aparecen en s por s2.

"hello".gsub(/./) |s| s[0].to_s + ”


No se que hace.

s.sub(/[s1]/, ’*’)
Reemplaza el primer elemento de s que está en s1 por *. Use sub! para guardar los
cambios en s.

s.sub(/[s1]/, ’< \ 1>’)


Reemplaza el primer elemento de s que está en s1 por el mismo elemento encerrado en
<>.

s.hash
No se que hace.

s.hex
Devuelve el hexadecimal de s.

s.include? s1
Pregunta si la cadena o número s1 aparece en s.

18
s.index(s1)
Da la posición del primer carácter de s1 en s, si aparece. Si s1 es un número binario da
la posición de la primera letra correspondiente al binario.

s.index(/[aeiou]/, -3)
No se que hace.

s.replace s1
Reemplaza los elementos de la cadena s por los de s1.

s.inspect
No se que hace.

s.intern
No se que hace.

s.to_sym
Devuelve el símbolo que corresponde a s o crea uno nuevo si la cadena no tiene asignado
uno.

“foo\n”.lines.to_a
La regla lines separa las lineas de la cadena y to_a crea un array de las lineas.

“foo\n bar”.lines.sort
Cambio de linea invertido.

s.ljust(i)
Justificar a la izquierda en un renglón de i lineas.

s.ljust(i,s1)
Justificar a la izquierda en un renglón de i caracteres de s1.

s.strip
Elimina los espacios en los extremos, los \n y los \r. Use strip! para guardar los cambios.

“ hello ”.lstrip
Justifica la cadena a la izquierda del renglón si es posible. Si se coloca ! al final de strip
se guardan los cambios.

s.succ
Cambia el último carácter de s por el que le sigue. Use succ! para guardar los cambios.

s.next
Cambia el último carácter de s por el que le sigue. Use next! para guardar cambios.

s.partition(s1)
Divide s en lo que está antes de s1, s1 y lo que está después de s1 en s. Si s1 no está en s
entonces utiliza s como primer elemento.

s1.rindex(s2)
Devuelve la posición de la primera letra de la cadena s2 empezando por la derecha.

s.rjust(i)
Justificar a la derecha.

19
s.rpartition(s1)
Dividir a partir de la última vez que aparece s1 en s.

s.rstrip
Alinear a la derecha.

s.scan(/\w+/)
Divide s por espacios en él. Crea un arreglo.

s.scan(/.../)
Divide s. No se como. Crea un arreglo.

s.scan(/(...)/)
Divide s. No se como. Crea un arreglo.

s.scan(/(..)(..)/)
Divide s. No se como. Crea un arreglo.

s.squeeze
Reemplaza los caracteres repetidos de s por solo uno.

s.squeeze(“m-z”)
Reemplaza los caracteres repetidos de s en el rango dado, por uno solo.

s.split
Parte la cadena s en un array de los elementos de s que están separados por espacios.

s.split(”)
Parte la cadena s en un array de todos sus caracteres.

s.split(//)
Parte la cadena s en un array de todos sus caracteres.

s.split(/ /)
Parte la cadena s en un array de los elementos de s que están separados por espacios. Si
hay un espacio al inicio entonces adiciona un elemento vacío al inicio del arreglo.

s.sum(i)
Suma del valor binario de cada carácter en s.

s.to_(b)
Convierte s a entero de base b.

s1.unpack(s2)
Decodifica la cadena s1 en un arreglo de acuerdo al formato s2.

s.crypt

s.each

s.each_byte

s.each_char

s.math(...)

20
s.tr(0 aeiou0 , ’*’)
Cambia los caracteres de s que están en la lista por *.

s.tr_s(0 aeiou0 , ’*’) Cambia los caracteres de s que están en la lista por * y elimina los
caracteres duplicados. Use tr! para guardar los cambios.

“abc \00\\00aabc\00\\00”".unpack(0 A6Z6’)

1.4.5. Ejercicios
Escribir un código que recibe una cadena de caracteres de una fórmula matemática
trigonométrica con variable x (ej “tan(x) + 3 ∗ cos(x)/ sin(5 ∗ x)”) y reemplaza los nombres
de las funciones trigonométricas por su equivalente en ruby, por ejemplo “cos” quedaría
“Math.cos”. Luego habiendo declarado un valor para x usar la función eval(“string”)
para evaluar la función descrita en el string.
a=“cceezzzzzz”
for i in 1..5
f=a.include? “c”
g=a.include? “e”
h=a.include? “z”
if f.to_s == “true” and g.to_s == “true” and h.to_s == “true”
a[“c”]=“w”
a[“e”]=“x”
a[“z”]=“y”
elsif f.to_s == “true” and g.to_s == “true”
a[“c”]=“w”
a[“e”]=“x”
elsif f.to_s == “true” and h.to_s == “true”
a[“c”]=“w”
a[“z”]=“y”
elsif g.to_s == “true” and h.to_s == “true”
a[“e”]=“x”
a[“z”]=“y”
elsif f.to_s == “true”
a[“c”]=“w”
elsif g.to_s == “true”
a[“e”]=“x”
elsif h.to_s == “true”
a[“z”]=“y”
else
end
end
puts a

1.5. Arreglos o Arrays


Son un conjunto de datos que pueden accesarse por índice.

Array.[]( 1, 0 a’, /^A/ )


Array[ 1, 0 a’, /^A/ ]

21
[ 1, 0 a’, /^A/ ]
Tres formas distintas de definir una misma cadena con los objetos dados.

Array.new
Array.new(2)
Array.new(5, “A”)
El primer comando crea un arreglo vacío, el segundo crea un arreglo de dos índices pero
sin elementos y el tercero crea un arreglo con cinco índices, cada uno con el elemento A.

a=[“sd”,“34”,“2”,“libertad”]
Un ejemplo de arreglo asignado a la variable a.

a.size
Devuelve el número de elementos del arreglo.

a[i]
Muestra el dato i-1 del array. Esto se debe a que el primer elemento tiene índice cero.

a[i,j]
Selecciona j elementos de a empezando en la posición i.

a[i..j]
Selecciona los elementos del i al j de a.

a[-i,j]
Selecciona j elementos empezando en la posición -i de a.

a[i]=s
Reemplaza la cadena s en la posición i de a.

a[i,j]=a1
Concatena los caracteres de a1 en a empezando en la posición i modificando j posiciones
del arreglo tantas veces como sea posible.

a[i..j]=“s”
Reemplaza los elementos de las posiciones i a j por un sólo índice con la cadena s.

a[-i]=s
Reemplaza el elemento de la posición -i por la cadena s.

a[-i..j]=a1 Reemplaza los elementos de los posiciones -i a j por los de a1 por tantas
posiciones como a1 tenga, a1 puede ser una cadena.

a1.concat(a2)
Concatena los elementos de a2 al final de a1.

a.first
Muestra el primer elemento de a.

a.first(i)
Muestra los primeros i elementos de a.

a.last
Ultimo elemento de a.

22
a.empty?
Pregunta si a tiene elementos.

c=[“a”,[“c”,“d”,“calar”],“sd”,[“a”,“f”],2,3]
Un arreglo que contiene otros arreglos. Tened en cuenta que solo los números pueden
ir sin comillas a menos que quieras que sea una cadena.

c.flatten
Destruye todos los arreglos internos de c.

c.flatten(i)
Destruye todos los arreglos internos de c en el nivel i.

a.sort
Ordena primero los números de menor a mayor y las palabras alfabéticamente.

a.sort {|x,y| y <=> x }


Ordena los elementos bajo la condición dada.

a.pop
Elimina el último elemento de a.

a.pop(n)
Elimina los últimos n elementos de a.

a.push(“e”)
Agrega el elemento e al final de a. También se puede colocar otro arreglo.

a.unshift(“Be”)
Agrega el elemento Be al inicio de a.

a.join(“i”)
Convierte los elementos de a en una cadena separados por i, donde i puede ser cualquier
símbolo, un espacio o ninguno.

cuadrados = Array.new(5) {|i| i*i}


Crea un arreglo de los cinco primeros cuadrados de i, donde i=0,1,2...

copia = Array.new(cuadrados)
Crea una copia del arreglo cuadrados.

a1 & a2
Arreglo de la intersección de a1 y a2.

a*3
Concatena tres veces el arreglo a.

a*s
Crea una cadena con los elementos de a y s entre cada elemento de a.

a1+a2
Concatena en un mismo arreglo a1 seguido de a2.

a1-a2
Arreglo de los elementos que están en a1 y no están en a2.

23
a1 << a2
Concatena a2 al final de a1, donde a2 también puede ser una cadena.

a1 <=> a2
Responde 1 si a1 tiene más elementos que a2, -1 si tiene menos o son distintos y 0 si son
iguales.

s1 <=> s2
Resulta -1 si s1 tiene menos caracteres o es más pequeño que s2, 0 si tiene idénticos
caracteres y 1 si tiene más o son de mayor tamaño.

s =∼ /\d/
Posición del primer número que aparece en la cadena s.

a1 == a2
Pregunta si las cadenas son iguales.

a = [ a1, a2, a3 ]
Hace una arreglo con los arreglos a1, a2 y a3.

a.assoc(a1[0])
Si a es un arreglo de arreglos, entonces busca el arreglo que contiene el elemento a1[0].
Si el elemento no está en un arreglo entonces el resultado es nill.

a.at(i)
Devuelve el elemento i de a.

a.clear
Elimina los elementos de a.

a.collect! {|x| x + “!” }


Le coloca ! al final de los elementos de a, solo si no tiene arreglos internos.

a.collect {|x| x + “!” }


Le coloca ! al final de los elementos de a, solo si no tiene arreglos internos.

as.combination(i).to_a
Hace un arreglo de los arreglos de las posibles combinaciones de i elementos de as.

a.compact
Elimina las posiciones sin elementos de a.

a.count
Cuenta los elementos de a.

a.count(s)
Cuenta los elementos iguales a s en a.

a.count{|x|x %2==0}
Cuenta los elementos que cumplen la condición.

a.cycle {|x| puts x }


Imprime los elementos de a indefinidamente.

a.cycle(n) {|x| puts x }


Imprime los elementos de a n veces.

24
a.delete(s)
Borra todas las cadenas s de a. Si se adiciona un ! al final de delete entonces se guardan
los cambios.

a = %w( ant bat cat dog )


Otra forma de definir un arreglo.

a.delete_at(i)
Borra el elemento en la posición i del arreglo.

a.delete_if {|x| x >= "b" }


Borra los elementos de a que cumplen la condición.

a.drop(i)
Quita los elementos que están antes de la posición i.

a.drop_while{|i| i < j }
Si a está compuesta por números ordenados entonces quita los elementos que cumplen
la condición.

a.each {|x| print x, “ - - ” }


Imprime los caracteres de a seguidos del símbolo - -.

a.each_index {|x| print x, “ - - ” }


Imprime el índice de los elementos de a seguidos del símbolo - -.

a1.eql?(a2)
Compara por igualdad los arreglos a1 y a2.

a.fetch(i)
Devuelve el elemento de índice i de a o error si i es mayor que el último índice de a.

a.fill(“x”)
Reemplaza todos los elementos de a por x.

a.fill(“x”,i,j)
Coloca x en a, j veces, a partir de la posición i.

a.fill(“x”,i..j)
Coloca x en a, de la posición i a la posición j.

a.fill {|i| i∗i}


Cambia los elementos de a por cuadrados de i, donde i=0,1,2...

a.fill(-j) {|i| i∗i∗i}


Cambia los elementos de a por cubos a partir de la posición -j.

a.index(s)
Devuelve el índice de s en a.

a.index{|x|x=="b"}
Devuelve el índice de la primera vez que aparece b en a si lo contiene.

a.include?("b")
Pregunta si a contiene a b.

25
a1.replace(a2)
Reemplaza el contenido de a1 por el de a2.

a.insert(i,s)
Inserta la cadena s en la posición i de a.

a.insert(-i, 1, 2, 3)
Inserta los elementos 1, 2 y 3 en la posición -i de a.

a.nitems
Da el número de elementos no nulos de a.

a.permutation.to_a
Arreglo de todas las posibles permutaciones de los elementos de a.

a.permutation(i).to_a
Arreglo de todas las posibles permutaciones con i elementos de a.

a1.product(a2,a3,...)
Hace un arreglo de combinaciones de los elementos de a1 con los elementos de a2, a3,
etc.

a.reverse
Invierte el orden de los elementos de a.

a.reverse_each { |x| print x, “ ” }


Separa e invierte los elementos de a.

a.rindex(“b”)
Índice del primer b por la derecha de a.

a.select { |v| v =∼ /[s]/ }


Selecciona los elementos de a que están en s.

a.shift
Elimina el primer elemento de a.

a.shift(i)
Elimina los primeros i elementos de a.

a.shuffle
Ubica aleatoriamente los elementos de a.

a.take(n)
Devuelve los primeros n elementos del arreglo a.

a.take_while {|i| i < 3 }


Devuelve los primeros elementos que cumplen la condición.

a.transpose
Transpone los elementos de arreglos internos en a.

a.uniq
Elimina los elementos duplicados de a.

26
a.values_at(1, 3, 5)
Devuelve los valores en las posiciones 1, 3 y 5 de a.

a1.zip(a2,a3)
Combina los elementos de los arreglos pero no se que regla siguen.

a1 | a2
Operación de unión entre los arreglos.

1.6. Fechas y horas


La función Time.now accede a la fecha y hora actual grabada en el ordenador.

t=Time.now
Guarda en t la fecha y hora actuales. Los valores individuales se accesan con los siguien-
tes comandos:

t.day

t.month

t.year

t.hour

t.min

t.sec

t.wday
Primer día de la semana

t.yday
Da el día del año.

t.strftime(" %B")
Nombre del mes completo.

t.strftime(" %b")
Nombre del mes abreviado.

t.strftime(" %A")
Nombre del día completo.

t.strftime(" %a")
Nombre del día abreviado.

t.strftime(" %p")
AM o PM

27
1.7. Hash
Es una estructura de datos o arreglo que permite almacenar datos indexados por palabras
y no por números naturales como el Array.
logros = Hash.new
Declara un hash nuevo llamado logros.
logros[“diploma”]=“um”
Asigna el elemento um al índice diploma del hash logros.
logros[“red”]=“tc”
Asigna el elemento tc al índice red del hash logros.
lang = {
’Perl’=> ’Larry’,
’Python’=> ’Guido’,
’Ruby’=> ’Matz’
}
Crea el hash lang, siendo los índices algunos lenguajes de programación y los elementos
son sus autores.
lang.values
Da los elementos del hash lang.
lang.keys
Da las claves del hash lang.
lang.has_key?(’Fortran’)
Pregunta si el hash lang tiene la clave Fortran.
lang.has_value?(0 Napoleon0 )
Pregunta si el hash lang tiene el valor Napoleon.
lang.sort
Ordena de acuerdo a la llave.
lang[’Ruby’] = ’Matsumoto’
Cambia el valor del índice Ruby por el de Matsumoto del hash lang.
lang.delete(’Perl’)
Elimina el par ’Perl’=>’Larry’

1.8. Each y bloques


La función “each” se puede aplicar a un Array y a un Hash, para iterar sobre sus elementos.
La sintaxis es: variable.each {bloque}. Las instrucciones que se encuentran dentro del bloque,
se aplican a cada uno de los elementos de la variable.
a.each {|i| puts i}
Imprime por separado cada elemento de a.
b = {0 sol0 =>0 dia0 , 0 luna0 =>0 noche0 }
b.each {|k,v| puts k + 00 : 00 + v}
Imprime los pares de elementos del hash b.

28
1.9. Contadores y acumuladores
Se trata de variables que se utilizan para llevar cuentas, tales como sumas, o para contar
el número de veces que ocurren las iteraciones.
cuenta += 1 ≡ cuenta = cuenta + 1
Es el contador y lo que hace es calcular cuenta +1 y luego asigna el resultado a cuenta
para repetir el proceso dentro de un ciclo.

count -= 1 ≡ count = count - 1

suma += cantidad ≡ suma ←− suma + cantidad

1.10. Matrices y vectores


Son arreglos especiales que tienen propiedades matemáticas bien definidas, algunas de
las cuales se estudian en esta sección. Para poder utilizar los métodos es necesario usar el
comando require 0 matrix0 al inicio del programa.

1.10.1. Matrices
Matrix[[a,b],[c,d]]
Crea una matriz donde los arreglos internos son filas.

Matrix.build(3,2){|row,col| 0}
Crea una matriz de tres columnas por dos filas con elementos que cumplen las condi-
ciones dadas en el bloque.

Matrix.build(3) { rand }
Crea una matriz de orden 3x3 con números al asar.

Matrx.column_vector([4,5,3])
Crea un vector columna.

Matrix.columns([[2,1],[2,3]])
Crea una matriz transpuesta de la dada en el paréntesis.

Matrix.diagonal(9, 5, -3)
Crea una matriz diagonal con los elementos del paréntesis.

Matrix.empty(2, 0)
Matriz de dos filas sin elementos.

Matrix.empty(0, 3)
Matriz sin elementos de tres columnas.

Matrix.identity(n)
Matriz identidad de orden n.

Matrix.row_vector([4,5,6])
Vector fila.

Matrix.rows([[25, 93], [-1, 66]])


Otra forma de crear una matriz.

29
Matrix.scalar(n, m)
Matriz diagonal de orden n con el elemento m en la diagonal.

Matrix.[]([3,4,5],[2,3,2])
Otra forma de crear una matriz.

Matriz.I(n)
Matriz identidad de orden n.

Matrix.unit(n)
Matriz identidad de orden n.

Matrix.zero(n)
Matriz de ceros de orden n.

m*n
Multiplicación de matrices. En este caso n también puede ser un escalar.

m**n
Potenciación de matrices. Multiplicar m con sigo misma n veces.

m±n
Suma o resta de matrices.

m/n
División de matrices. Multiplica m por su inversa.

m.[](i, j)
Elemento i,j de la matriz m.

m.clone
Retorna un clon de la matriz m.

Matrix[ [1,2], [3,4] ].collect { |e| e**2 }


Aplica la operación del bloque sobre cada elemento de la matriz.

m.column(j)
Retorna la columna j de m como vector.

m.column_vectors()
Arreglo de los vectores columna de la matriz m.

m.component(i,j)
Componente i,j de m.

m.conj
m.conjugate
m.conj()
m.det
m.determinant
Determinante de m.

m.diagonal?()
Pregunta si m es diagonal.

30
m.each { |e| puts e }
Muestra los elementos de m.

m.element(i,j)
Elemento i,j de m.

m.elements_to_f()
Vuelve flotantes los elementos de m.

m.elements_to_i()
Los pasa a enteros.

m.elements_to_r()
Los escribe racionales.

m.empty?()
Pregunta si m está vacía.

m.hermitian?()
Pregunta si m es hermítica.

m.imag()
m.imaginary()
Parte imaginaria de m.

Complex(r,i)
Número complejo.

m.inv()
m.inverse()
Inversa de m.

m.lower_triangular?()
Pregunta si m es matriz triangular inferior.

u.upper_triangular? Pregunta si m es matriz triangular superior.

m.rank()
Rango de la matriz.

m.real
Parte real de la matriz.

m.real?()
Pregunta si m es real.

m.rect
Arreglo con la matrices de la parte real e imaginaria de m.

m.round(n)
Redondea los elementos de m con n cifras significativas.

m.row(i)
Fila i de m como un vector.

31
m.tr
m.trace
Traza de m.

m.transpose
Transpuesta de m.

1.10.2. Vectores
Vector[23,23,32,34]
Forma de definir un vector.

Vector.[](23,23,32,34)
Otra forma de definir un vector.

v*s
Multiplicación de un vector por un escalar.

v±w
Suma y resta de vectores.

v/n
División de un vector por un escalar.

v.[](i)
Elemento i de v.

v.collect()
v.map

v.inner_product w
Producto interno de v y w.

v.magnitude
v.r
v.norm
Magnitud de v.

v.normalsize
Vector unitario en la dirección de v.

v.size
Número de elementos de v.

v.to_a
Crea un arreglo de los elementos de v.

v.to_s
Convierte a cadena.

32
Capítulo 2

Lógica

2.1. Lógica condicional


2.1.1. Expresiones condicionales
Se refieren a las expresiones que resultan en valores de verdad

== igualdad

<= menor o igual

>= mayor o igual

< menor, > mayor

<=> -1, 0 ó 1

or y and para expresiones compuestas

h.empty? y h.finite? Preguntas

2.1.2. Ciclo if then


. Es una estructura de control if/elsif/else/end. Se evalúa únicamente el bloque de la
expresión correcta. Las palabras then se pueden omitir y se pueden usar los dos puntos “:”,
aunque también son opcionales.

if exp1 then
. bloque1
elsif exp2 then
. bloque2
else
. bloque3
end

2.1.3. Ciclo for


Hace una operación un número determinado de veces de acuerdo a un intervalo preesta-
blecido.

33
for i in a
. expr(i)
end
Si a es un arreglo entonces se aplica la función sobre cada elemento de a. Sin embargo,
se puede utilizar un intervalo i..j o uno que excluye el último índice i...j.

Ciclo times
Se usa cuando se conoce el número de veces que se debe repetir un ciclo.

i.times do
. expr(i)
end
Donde i es el número de veces que se repite el ciclo.

Ciclo upto
Similar a times.

i.upto(j) do
. expr(i..j)
end

Ciclo downto
Ciclo decreciente.

j.downto(i) do |i|
. expr
end

Ciclo step
Ciclo a pasos diferentes de 1.

i.step(j,p) do |i|
. expr
end
Ciclo que va de i hasta j en pasos de p.

2.2. Ciclo while


Evalúa un ciclo tantas veces como se cumpla cierta expresión.

cuenta = 0
while (cuenta < 5) do
. expr
. cuenta + = 1
end

34
Ciclo until
Evalúa un ciclo tantas veces como sea falsa cierta expresión.

cuenta = 0
until (cuenta >= 0) do
. expr
. cuenta + = 1
end

2.2.1. Ciclo loop


Evalúa un ciclo potencialmente infinito.

cuenta = 0
loop
. break if cuenta >= 5
. puts cuenta
. cuenta += 1
end

2.2.2. Expresiones múltiples case


Se usa cuando se quiere comparar una variable contra una cantidad de valores.

case variable
when valor1
. bloque1
when valor2
. bloque2
else
. bloque3
end

35
Capítulo 3

Objetos

Los objetos agrupan lineas de código que cumplen funciones específicas y pueden tener
varias ramificaciones, pero para entender este concepto es necesario partir desde el concepto
más básico que es una variable.

3.1. Variables
Antes de crear un objeto es necesario crear una clase, cuya notación se verá más adelante,
la cuestión es que en una clase aparecen distintos tipos de asignaciones o variables que se
clasifican como sigue:

3.1.1. Tipos de variables


Variables de la clase
Son variables que se usan solamente en el interior de la clase y por convención se
preceden de un arroba (@variable).
Atributos
Son variables visibles desde fuera de la clase. Generalmente se usa un sustantivo como
atributo y un adjetivo o un número como valor (Perro.color).
Métodos
Se refieren a las funciones que desempeña la clase. Normalmente se usan verbos para
describir las funciones que va a desempeñar una clase (Perro.ladrar).

3.2. Funciones
Son conjuntos de lineas de código que cumplen una función específica y que se usan varias
veces en el código de una aplicación.
def miFunc(s)
. return bloque
end
Las variables que se declaran dentro de una función solo son válidas dentro de la misma
y las que se declaran fuera no son válidas dentro. Si se antecede una variable definida
fuera de la función con un $ entonces se puede usar dentro y entonces se denomina
variable global.
Una función puede ser recursiva si se define en términos de sí misma.

36
def fact(n)
if 0 == n
. return 1
else
. return n * fact(n-1)
end
end

También hay funciones que no retornan nada, pero que tienen efectos secundarios, tales como
imprimir, o alterar valores de variables externas.

3.3. Clases
Es una colección de funciones y variables que describen un determinado concepto.

class MiClase
. def initialize(nombre)
. @variabledc1 = nombre
. @variabledc2 = "accion"
. end
. def to_s
. “#{@variabledc1}: #{@variabledc2}”
. end
. def variabledc1
. @variabledc1
. end
. def <=>(miclase)
. @nombre <=> miclase.nombre
. end
. def variabledc2
. @variabledc2
. end

Por convención el nombre de la clase siempre empieza en mayúscula. Las variables que se
declaran dentro de la clase tienen alcance local, es decir, no son visibles desde afuera de la
clase, y son precedidas por el signo de arroba (@).
El método initialize() es el constructor, ya que es el primer método que se ejecuta para
crear variables de tipo de la clase. El constructor es opcional. Este método nunca se invoca
explícitamente al crear una variable de esta clase con el método new. En el paréntesis de este
método debe ir uno o varios argumentos separados por coma, que deben ser declarados a la
hora de crear un objeto.
El método “to_s” expresa la representación textual de la clase, es decir, examina las varia-
bles, contenido interno o estado de una clase.
El método de comparación <=> se define para declarar qué variable interna vamos a usar
para hacer comparaciones. En este caso, lo vamos a hacer por nombre.

3.3.1. Objetos
Una vez que ya hemos creado MiClase hay que crear objetos o instancias de la clase. Para
esto se usa la función new:

37
objeto1=MiClase.new(“nombre1”)

objeto2=MiClase.new(“nombre2”)

con el comando anterior se crean dos objetos correspondientes a MiClase. Para saber que
métodos están disponibles para un objeto se usa el comando:

objeto.instance_methods
Incluye los objetos que están definidos en las superclases.

objeto.instance_methods(false)
Elimina los métodos definidos por sus ancestros.

3.3.2. Llamado de propiedades y funciones


A los objetos creados les podemos pedir que hagan lo que saben hacer, preguntar por sus
atributos o compararlos:

objeto1.variabledc1

objeto2.variabledc2

objeto1<=>objeto2

En el ejemplo anterior, MiClase es la clase, y objeto1 y objeto2 son instancias de clase MiClase.
En si la clase consiste en la definición y los objetos o instancias son variables del tipo de la
clase.

3.3.3. Atributos de las clases


Para acceder a un atributo de una clase declaramos un método que retorne su valor:

class Perro
. def initialize(nombre)
. @nombre = nombre
. end
. def nombre
. @nombre
. end
end
f = Perro.new("fifi")
f.nombre => fifi

Para modificar un atributo se añade un método que modifique su valor:

class Perro
. def initialize(nombre)
. @nombre = nombre
. end
. def nombre
. @nombre
. end
. def nombre=(nombreNuevo)
. @nombre = nombreNuevo

38
. end
end
f = Perro.new("fifi")
f.nombre = "fifirucho"
f.nombre => fifirucho

Una manera más sencilla de acceder y modificar un atributo es usando attr_reader y attr_writer:

class Perro
. attr_reader :nombre, :edad, :color
. attr_writer :nombre, :edad, :color
. def initialize(nombre, edad, color)
. @nombre = nombre
. @edad = edad
. @color = color
. end
end
f = Perro.new(“fifi”, 5, “gris”)
f.color
f.edad=7
puts f.edad

Con esto vemos que se puede acceder a los atributos y modificarlos. Aún más sencillo es usar
attr_accessor que combina reader y writer.

3.3.4. Control de acceso a la clase


Los métodos pueden ser:

Públicos
de libre acceso para todos

Protegidos
de acceso para la clase que las define y sus subclases

Privados
de acceso únicamente para la clase que los define.

Hay dos maneras de implementar este control:

. class MiClase
. def metodo1
. end
. protected
. def metodo2
. end
. private
. def metodo3
. end
. public
. def metodo4
. end
end

39
. class MiClase
. def metodo1
. end
. def metodo2
. end
. def metodo3
. end
. def metodo4
. end
. public :metodo1, :metodo4
. protected :metodo2
. private :metodo3
end

En la primera el control se asigna antes de definir cada método y en la segunda los controles
de cada uno de los métodos se asignan al final de la clase.

3.4. Herencia y taxonomías


Taxonomía es el arte de clasificar cosas en una estructura jerárquica, de manera que
queden en una relación padre-hijo, o superclase-subclase. Ruby permite expresar relaciones
de taxonomía, al definir clases. Usando la sintaxis SubClase < SuperClase, podemos definir
clases así:

class Mamifero
. def respira
. print “inhalar y exhalar”
. end
end

class Gato < Mamifero


. def maulla
. print “miau”
. end
end

La clase gato heredará el comportamiento de la clase Mamifero dado que se ha definido Gato
como una subclase de Mamifero. Además se añade el método maulla, así nuestro gato puede
respirar y maullar.

40

You might also like