Capítulo 3. Ejemplos sencillos
Escribamos una función que calcula factoriales. La definición matemática de factorial es la siguiente:
(n==0) n! = 1
(sino) n! = n * (n-1)!
En Ruby se puede escribir así:
def fact(n)
if n == 0
1
else
n * fact(n-1)
end
end
Se puede apreciar la aparición repetida de end. Debido a esto a Ruby se le conoce como un lenguaje “tipo Algol”.
(Realmente la sintaxis de Ruby reproduce con más exactitud la del lenguaje Eiffel). También se puede apreciar la falta de la sentencia return. Es innecesaria debido a que una función Ruby devuelve lo último que haya evaluado. La utilización de return es factible aunque innecesaria.
Probemos la función factorial. Añadiendo una línea de código obtenemos un programa funcional:
# Programa para hallar el factorial de un número
# Guarda este programa como fact.rb
def fact(n)
if n == 0
1
else
n * fact(n-1)
end
end
print fact(ARGV[0].to_i), «\n»
Aquí, ARGV es un array que contiene los parámetros de la línea de comandos y to_i convierte una cadena de caracteres a un entero.
% ruby fact.rb 1
1
% ruby fact.rb 5
120
¿Funcionaría con un parámetro igual a 40? Este valor podría provocar un desbordamiento en una calculadora…
% ruby fact.rb 40
815915283247897734345611269596115894272000000000
Funciona. Además Ruby puede tratar cualquier entero que quepa en la memoria del ordenador. ¡Por lo que se puede calcular el factorial de 400!:
% ruby fact.rb 400
64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
No podemos verificar su validez a simple vista, pero lo debe ser ;-).
3.1. El bucle de entrada/evaluación
Al ejecutar Ruby sin parámetros, éste lee de la entrada estándar comandos y los ejecuta después de dar por finalizada la entrada:
% ruby
print «hola mundo\n»
print «adiós mundo\n»
^D
hola mundo
adiós mundo
Ruby incluye un programa llamado eval.rb que permite la introducción de código desde el teclado a través de un bucle iterativo que muestra los resultados a medida que se obtienen. Se utilizará ampliamente a lo largo del tutorial.
Si se tiene un terminal ANSI (esto será casi seguro si se está ejecutando alguna versión de UNIX; bajo DOS se debe instalar ANSI.SYS o ANSI.COM) se debería utilizar este eval.rb mejorado que permite autoindentación, informes sobre incidencias y resaltado por color. Si no, en el directorio sample de la distribución Ruby existe una versión no ANSI que funciona con cualquier terminal. A continuación se muestra una pequeña sesión con eval.rb:
%ruby eval.rb
ruby> print «hola mundo\n»
hola mundo.
nil
ruby> exit
print produce hola mundo. La siguiente línea, es este caso nil informa sobre lo último que se ha evaluado; Ruby no distingue entre sentencias y expresiones, por lo tanto la evaluación de una pieza de código significa básicamente lo mismo que ejecutarla. Aquí nil, indica que print no devuelve ningún valor significativo. Obsérvese que se puede salir
del bucle de interpretación con exit, aunque también funciona ^D.
A lo largo de toda esta introducción ruby> representa la petición de entrada del pequeño pero útil programa eval.rb.