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
640345228466238952623479703195030058507025830260029594586844459428023971691868314
362784786474632646762943505750358568108482981628835174352289619886468029979373416
541508381624264619423523070462443250151144486708906627739149181173319559964407095
496713452904770203224349112107975932807951015453726672516278778900093497637657103
263503315339653498683868313393520243737881577867915063118587026182701698197400629
830253085912983461622723045583395207596115053022360868104332972551948526744322324
386699484224042325998055516106359423769613992319171340638589965379701478272066063
202173794720103213566246138090779423045973606995675958360961587151299138222865785
795493616176544804532220078258184008484364155912294542753848035583745180226759000
613995601455952061272111929181050324910080000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000

No podemos verificar su validez a simple vista, pero lo debe ser ;-).

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.