Hemos visto diferentes métodos: puts
, gets
,
etc. (Prueba: Listar todos los métodos que hemos
visto hasta ahora!. Hay diez de ellos, la respuesta está abajo), pero no hemos
realmente hablado sobre que hacen los métodos. Sabemos que hacen, pero no lo que son.
Pero realmente, esto es lo que son: cosas que generan otras.
Si objetos (como textos, enteros y flotantes) son los sujetos en
el lenguaje Ruby, entonces los métodos son como verbos. Y, justo como en el
español, tú no puedes tener un verbo sin un sustantivo para hacer algo.
Por ejemplo, tic-tac no es algo que sólo ocurre; un reloj (o algo) tiene que hacer
esto. En español podemos decir: "El reloj hace tic-tac". En Ruby podemos decir
clock.tick
(asumiendo por supuesto que clock
es un objeto Ruby).
Los programadores pueden decir que estamos "llamando el método tick
de
clock
" o llamamos al "tick
de clock
".
Entonces, ¿has hecho la prueba? Bien. Bueno, estoy seguro que
recordarás los métodos puts
, gets
y
chomp
; dado que ya hablamos sobre ellos.
Probablemente también recuerdas los métodos de conversión
to_i
, to_f
, y to_s
. Sin embargo,
¿has visto los otros cuatro? Porque, estos no son otros que
nuestros viejos amigos para la aritmética ¡+
,
-
, *
y /
!
Entonces, como cada verbo necesita un sustantivo,
entonces cada método necesita un objeto. Esto es generalmente fácil de
indicar: es el que viene justo antes de un punto, como nuestro
ejemplo clock.tick
, o en 101.to_s
.
Algunas veces, sin embargo, esto no es tan obvio; como con los métodos
aritméticos. Como resulta, 5 + 5
es solo otra forma fácil de
escribir 5.+ 5
.
Por ejemplo:
Código:
puts 'hola '.+ 'mundo'
puts (10.* 9).+ 9
Resultado:
hola mundo
99
Esto no es muy lindo, por lo que no vamos a escribir siempre como ahora; sin embargo, es importante para entender que sucede realmente.
Esto también nos da un profundo entendimiento de porque podemos hacer
'pig'*5
pero no podemos hacer 5*'pig'
: 'pig'*5
está diciendo a 'pig'
de hacer de multiplicando, pero 5*'pig'
está diciendo a 5
de hacer de multiplicando. 'pig'
sabe como
hacer 5
copias de si mismo y agregar todos ellos juntos; sin embargo,
5
tendrá mucha más dificultad en tiempo de hacer 'pig'
copias
de si mismo y sumarlos a todos juntos.
Y, por supuesto, continuaremos teniendo puts
y gets
para explicar.
¿Dónde están sus objetos? En español, puedes algunas veces dejar fuera el sustantivo;
por ejemplo, si un villano grita "¡Muere!", el sustantivo implícito es a quien él
está gritando. En Ruby, si digo puts 'ser o no ser'
, lo que realmente estoy
diciendo es self.puts 'ser o no ser'
.
Entonces ¿qué es self
? Ésta es una variable especial que apunta al objeto en
el que estás. No siempre sabemos como estar en un objeto, pero hasta que nos
demos cuenta, siempre iremos a estar en un gran objeto que es... ¡el programa entero! (sin
embargo en este caso no es posible llamarlo en forma explícita).
Observa lo siguiente:
Código:
NoPuedoCreerQueUnaVariableConNombreTanLargoApunteA3 = 3
puts NoPuedoCreerQueUnaVariableConNombreTanLargoApunteA3
self.puts NoPuedoCreerQueUnaVariableConNombreTanLargoApunteA3
Resultado:
3
in `<main>': private method `puts' called for main:Object (NoMethodError)
Si no alcanzaste a comprender todo, está bien. Lo importante es que todo método está siendo propiedad de un objeto, incluso si no tiene un punto enfrente de éste. Si entiendes esto estás preparado.
Vamos a aprender unos pocos pero interesantes métodos. No tienes porque memorizar todos; puedes mirar esta página de nuevo si te olvidas de alguno. Yo sólo quiero mostrarte una pequeña parte de lo que puede hacer un texto. De hecho, no recuerdo ni siquiera la mitad de los métodos para textos; pero está bien, porque hay buenas referencias en internet con todo acerca de textos listados y explicados (Voy a mostrarte donde encontrar esas referencias al final del tutorial).
Realmente, tampoco quiero saber todo acerca de los métodos para textos; sino sería como tratar de conocer cada palabra en el diccionario. Puedo hablar español bien sin conocer cada una de las palabras del diccionario... ¿y no es ese realmente el objetivo del diccionario? Entonces ¿no tienes que conocer que hay en éste?
Entonces, nuestro primer método para texto es reverse
,
el cual nos da una version invertida de un texto:
Código:
var1 = 'parar'
var2 = 'subrayado'
var3 = 'Puedes pronunciar esta oración al revés?'
puts var1.reverse
puts var2.reverse
puts var3.reverse
puts var1
puts var2
puts var3
Resultado:
rarap
odayarbus
?séver la nóicaro atse raicnunorp sedeuP
parar
subrayado
Puedes pronunciar esta oración al revés?
Como puedes ver, reverse
no revierte el orden en el string original; éste
sólo hace una nueva versión de éste en reversa. Esto es porque var1
continua
'parar'
aún después de que llamamos reverse
sobre var1
.
Otro método para texto es length
, el cual nos dice el número de caracteres
(incluyendo espacios) en el texto:
Código:
puts '¿Cuál es tu nombre completo?'
name = gets.chomp
puts '¿Sabes que hay ' + name.length + ' caracteres en tu nombre, ' + name + '?'
Resultado:
¿Cuál es tu nombre completo?
Christopher David Pine
in `+': no implicit conversion of Fixnum into String (TypeError)
¡¡Uhh!! Algo salió mal, y esto parece que ocurrió después la línea
name = gets.chomp
... ¿Puedes ver el problema? Fijate si puedes darte cuenta.
El problema es con length
: esto te devuelve un número, pero nosotros queremos
un texto. Esto es fácil, necesitamos solo agregar to_s
(y cruzar nuestros dedos):
Código:
puts '¿Cuál es tu nombre completo?'
name = gets.chomp
puts '¿Sabías que hay ' + name.length.to_s + ' caracteres en tu nombre, ' + name + '?'
Resultado:
¿Cuál es tu nombre completo?
Christopher David Pine
Sabías que hay 22 caracteres en tu nombre, Christopher David Pine
No, no conocía esto. Nota: esto es el número de caracteres en mi nombre, no el número de letras. Supongo que podríamos escribir un programa el cual nos pregunte por nuestro primer nombre, segundo nombre y apellidos individualmente, y entonces sumar estos tamaños todos juntos... hey, ¡porque no haces esto! Comienza, esperaré.
¿Lo hiciste? ¡Bien! Es un lindo programa, ¿no? Después de unos pocos capítulos más, pienso, estarás sorprendido de lo que podrás hacer.
Entonces, hay también un número de métodos para texto los cuales cambian
el contenido (mayúsculas y minúsculas) de tu texto. upcase
cambian cada minúscula por mayúscula. swapcase
cambia en cada
letra en el string("Hola".swapcase #=> "hOLA"), y finalmente, capitalize
es como downcase
, excepto que esto cambia solo el primer carácter a
mayúsculas (si es una letra).
Código:
letters = 'aAbBcCdDeE'
puts letters.upcase
puts letters.downcase
puts letters.swapcase
puts letters.capitalize
puts ' a'.capitalize
puts letters
Resultado:
AABBCCDDEE
aabbccddee
AaBbCcDdEe
Aabbccddee
a
aAbBcCdDeE
Esto es bastante estándar. Como puedes ver desde la linea puts ' a'.capitalize
,
el método capitalize
sólo deja en mayúsculas el primer carácter, no
la primera letra. También, como hemos visto antes, en todas estas llamadas a
métodos, letters
permanece igual. No quiero ser pesado con esto,
pero es importante entenderlo. Hay algunos métodos los cuales hacen cambios a los
objetos asociados, pero no los hemos visto aún, y no lo haremos por algún tiempo.
El último tipo de métodos que veremos son los de formato visual. El primero es, center
,
suma espacios al comienzo y final para hacer que esté centrado. Sin embargo, sólo tienes
que decir puts
a lo que quieres imprimir, y +
a lo que quieres sumar, pero
tienes que decir a center
que ancho tiene que tener el string centrado. Entonces si quiero
centrar las lineas de un poema, debería hacer algo como esto:
Código:
lineWidth = 50
puts( 'Old Mother Hubbard'.center(lineWidth))
puts( 'Sat in her cupboard'.center(lineWidth))
puts( 'Eating her curds an whey,'.center(lineWidth))
puts( 'When along came a spider'.center(lineWidth))
puts( 'Which sat down beside her'.center(lineWidth))
puts('And scared her poor shoe dog away.'.center(lineWidth))
Resultado:
Old Mother Hubbard
Sat in her cupboard
Eating her curds an whey,
When along came a spider
Which sat down beside her
And scared her poor shoe dog away.
Mmmm.. no pienso que esto es un campamento de verano, pero estoy muy
cansado para buscar esto. (Entonces, quise alinear la parte
.center lineWidth
, entonces puse esos espacios extras antes
de los textos. Esto es así sólo porque pienso que es más lindo de
esta forma. Los programadores generalmente tienen duros conceptos acerca
de que es lindo en un programa, y a menudo confrontan acerca de esto.
Cuanto más programes, más lograrás tu propio estilo.) Hablando de ser
perezoso a la hora de programar, lo cual no es siempre algo malo en
programación. Por ejemplo, fíjate como guardé el ancho del poema en la
variable lineWidth
? Esto es que si entonces quiero regresar
más tarde y hacer el poema más ancho, solo tengo que cambiar la variable
al comienzo del programa, antes que en cada línea. Con un poema muy largo,
esto podría ahorrarme un montón de tiempo. Este tipo de pereza es realmente
una virtud en programación.
Entonces, acerca del centrado... tú te darás cuenta que esto no es muy lindo como podría serlo un procesador de texto. Si realmente quieres un perfecto centrado (y quizás una fuente más linda), entonces deberías ¡sólo usar un procesador de textos!. Ruby es una herramienta maravillosa, pero no la herramienta correcta para cualquier trabajo.
Los otros dos métodos de formato de textos son ljust
y
rjust
, lo cual significan justificado izquierdo y
justificado derecho. Estos son similares a center
,
excepto que ellos rellenan los lados derecho e izquierdo respectivamente.
Vamos a verlos en acción:
Código:
lineWidth = 40
str = '--> text <--'
puts str.ljust lineWidth
puts str.center lineWidth
puts str.rjust lineWidth
puts str.ljust(lineWidth/2) + str.rjust(lineWidth/2)
Resultado:
--> text <--
--> text <--
--> text <--
--> text <-- --> text <--
Escribe un programa Jefe Enojado
. Este debe preguntar de mala
manera qué quieres. Cualquier cosa que consultes, el Jefe Enojado deberá
devolverte la consulta de mala forma, y luego despedirte. Por ejemplo,
si tu escribes Quiero un aumento.
, deberá contestarte
PERO QUE DICES HOMBRE "¿¡¿QUIERES UN AUMENTO."?!? ¡¡ESTAS DESPEDIDO!!
Entonces aquí hay algo para que puedas jugar un poco más con
center
, ljust
, y rjust
: Escribe un programa el
cual muestre una Tabla de Contenidos que se parezca a lo siguiente:
Listado:
Tabla de Contenidos
Capítulo 1: Números página 1
Capítulo 2: Letras página 72
Capítulo 3: Variables página 118
(Esta sección es totalmente opcional. Asume un conocimiento previo de matemáticas. Si no estás interesado, puedes ir directamente al siguiente capítulo Condicionales sin problemas. Aunque, una rápida vista de esta sección sobre Números aleatorios debería venir bien.)
No hay tantos métodos numéricos como los hay para textos (pienso
que aun no los conozco a todos sin recurrir a la ayuda de documentación).
Aquí, vamos a mirar el resto de los métodos aritméticos, un generador
de números aleatorios, y el objeto Math
, con sus métodos trigonométricos
y transcendentales.
Los otros dos métodos aritméticos son **
(potencia) y %
(módulo). Entonces si quieres decir "cinco al cuadrado" en Ruby, deberías
escribir algo así 5**2
. También puedes usar flotantes para tus
exponentes, entonces si quieres una raíz cuadrada de 5, deberías escribir
5**0.5
. Los métodos módulo te dan el sobrante después de una división
por un número. Entonces, por ejemplo, si divido 7 por 3, obtengo 2 con un remanente
de 1. Vamos a ver como es que trabaja en un programa:
Código:
puts 5**2
puts 5**0.5
puts 7/3
puts 7%3
puts 365%7
Resultado:
25
2.23606797749979
2
1
1
De la última línea, aprendimos que un año (no bisiesto) tienen algún
número de semanas, más un día. Entonces si tu cumpleaños fue un Martes
este año, el próximo año será un Miércoles. Tu también puedes usar
flotantes con el método módulo (%
). Básicamente, funciona de una manera
lógica... pero voy a mostrar un poco más como trabajar con esto.
Hay un último método para mencionar: abs
. Éste sólo toma el valor
absoluto de un número:
Código:
puts((5-2).abs)
puts((2-5).abs)
Resultado:
3
3
Ruby viene con un lindo generador de números aleatorios. El método para obtener
un número aleatorio es rand
. Si llamas rand
, obtendrás un
número flotante mayor o igual a 0.0
y menor a 1.0
. Si
le proporcionas a rand
un número entero (5
por ejemplo),
esto te devolverá un entero mayor o igual a 0
y menor a 5
(entonces son cinco números posibles, de 0
a 4
).
Vamos a ver rand
en acción.
Código:
puts rand
puts rand
puts rand
puts(rand(100))
puts(rand(100))
puts(rand(100))
puts(rand(1))
puts(rand(1))
puts(rand(1))
puts(rand(99999999999999999999999999999999999999999999999999999999999))
puts('El pronosticador del tiempo dijo que hay '+rand(101).to_s+'% chances de que llueva,')
puts('pero nunca debes confiar en él.')
Resultado:
0.866769322351658
0.155609260113273
0.208355946789083
61
46
92
0
0
0
22982477508131860231954108773887523861600693989518495699862
El pronosticador del tiempo dijo que hay 47% chances de que llueva,
pero nunca debes confiar en él.
Fijate que utilicé rand(101)
para obtener números entre 0
y 100
, y que el rand(1)
siempre devuelve 0
. No
entender el rango posible de retorno de valores es el error más grande que veo
en gente que hace rand
; aún programadores profesionales, más aún en
productos finalizados que puedes comprar. Incluso tenía un reproductor de CD
que si se configuraba en "Reproducción aleatoria," reproducía
todas las canciones menos la última ... (Me pregunto ¿qué hubiera pasado si hubiera
puesto un CD con sólo una canción en ella?)
Algunas veces querrás que rand
retorne el mismo
random de números incluso en la misma secuencia en dos diferentes ejecuciones
de tu programa. (Por ejemplo, una vez estaba utilizando números generados
aleatoriamente para crear un mundo al azar para un juego de computadoras.
Encontré un mundo que realmente me gustó, quizás me hubiera gustado jugar de nuevo
con éste o enviarlo a un amigo.) Con el fin de hacer esto, tu necesitas configurar
la "generación de éste", lo que se puede hacer con srand
. Como
lo siguiente:
Código:
srand 1776
puts(rand(100))
puts(rand(100))
puts(rand(100))
puts(rand(100))
puts(rand(100))
puts ''
srand 1776
puts(rand(100))
puts(rand(100))
puts(rand(100))
puts(rand(100))
puts(rand(100))
Resultado:
24
35
36
58
70
24
35
36
58
70
Esto hará la misma cosa cada vez que inicies con el mismo número. Si quieres
obtener diferentes números (como pasaría si nunca utilizaras srand
),
entonces sólo llamas a srand 0
. Esto inicializa con un número
realmente raro, utilizando (además de otras cosas) la hora actual de tu
computadora, hasta los milisegundos.
Math
Finalmente, vamos a echar un vistazo al objeto Math
. Deberíamos
ir directamente a este:
Código:
puts(Math::PI)
puts(Math::E)
puts(Math.cos(Math::PI/3))
puts(Math.tan(Math::PI/4))
puts(Math.log(Math::E**2))
puts((1 + Math.sqrt(5))/2)
Resultado:
3.14159265358979
2.71828182845905
0.5
1.0
2.0
1.61803398874989
Como puedes ver, Math
tiene todas las cosas que podrías
esperar de una calculadora científica decente. Y como siempre, los
flotantes están realmente cerca de ser la respuesta
correcta.
Entonces ahora vamos a ver control de flujo.