viernes, 5 de agosto de 2016

RUBY




   RUBY


El lenguaje fue creado por Yukihiro "Matz" Matsumoto, quien empezó a trabajar en Ruby el 24 de febrero de 1993, y lo presentó al público en el año 1995. En el círculo de amigos de Matsumoto se le puso el nombre de "Ruby" (en español rubí) como broma aludiendo al lenguaje de programación "Perl" (perla). La última versión estable es la 1.8.6, publicada en diciembre de 2007. El 26 de ese mismo mes salió Ruby 1.9.0, una versión en desarrollo que incorpora mejoras sustanciales en el rendimiento del lenguaje, que se espera queden reflejadas en la próxima versión estable de producción del lenguaje, Ruby 1.9.0.1 Diferencias en rendimiento entre la actual implementación de Ruby (1.8.6) y otros lenguajes de programación más arraigados han llevado al desarrollo de varias máquinas virtuales para Ruby.
 Entre ésas se encuentra JRuby, un intento de llevar Ruby a la plataforma Java, y Rubinius, un intérprete modelado basado en las máquinas virtuales de Smalltalk. Los principales desarrolladores han apoyado la máquina virtual proporcionada por el proyecto YARV, que se fusionó en el árbol de código fuente de Ruby el 31 de diciembre de 2006, y se dará a conocer como Ruby 1.9.0.1.

Descripción
ü  Está orientado a objetos.
ü  Cuatro niveles de ámbito de variable: global, clase, instancia y local.
ü  Manejo de excepciones.
ü  Iteradores y clausuras o closures (pasando bloques de código) expresiones regulares nativas similares a las de Perl a nivel del lenguaje.
ü  Posibilidad de redefinir los operadores (sobrecarga de operadores) recolección de basura automática.
ü  Altamente portable.
ü  Hilos de ejecución simultáneos en todas las plataformas usando greenthreads.
ü  Carga dinámica de DLL/bibliotecas compartidas en la mayoría de las plataformas.
ü  Introspección, reflexión y meta programación.
ü  Amplia librería estándar.
ü  Soporta inyección de dependencias.
ü  Soporta alteración de objetos en tiempo de ejecución continuaciones y generadores.

Estructura del lenguaje
La sintaxis de Ruby es similar a la de Perl o Python. La definición de clases y métodos está definida por palabras clave. Sin embargo, en Perl, las variables no llevan prefijos. Cuando se usa, un prefijo indica el ámbito de las variables. La mayor diferencia con C y Perl es que las palabras clave son usadas para definir bloques de código sin llaves. Los saltos de línea son significativos y son interpretados como el final de una sentencia; el punto y coma tiene el mismo uso. De forma diferente que Python, la indentación no es significativa.
Una de las diferencias entre Ruby y Python y Perl es que Ruby mantiene todas sus variables de instancia privadas dentro de las clases y solo la expone a través de métodos de acceso (attr_writerattr_reader, etc.). A diferencia de los métodos "getter" y "setter" de otros lenguajes como C++ o Java, los métodos de acceso en Ruby pueden ser escritos con una sola línea de código. Como la invocación de estos métodos no requiere el uso de paréntesis, es trivial cambiar una variable de instancia en una función sin tocar una sola línea de código o refactorizar dicho código. Los descriptores de propiedades de Python son similares pero tienen una desventaja en el proceso de desarrollo. Si uno comienza en Python usando una instancia de variable expuesta públicamente y después cambia la implementación para usar una instancia de variable privada expuesta a través de un descriptor de propiedades, el código interno de la clase necesitará ser ajustado para usar la variable privada en vez de la propiedad pública. Ruby elimina está decisión de diseño obligando a todas las variables de instancia a ser privadas, pero también proporciona una manera sencilla de declarar métodos set y get. Esto mantiene el principio de que en Ruby no se puede acceder a los miembros internos de una clase desde fuera de esta; en lugar de esto se pasa un mensaje (se invoca un método) a la clase y recibe una respuesta.

Estructura semántica
Ruby es orientado a objetos: todos los tipos de datos son un objeto, incluidas las clases y tipos que otros lenguajes definen como primitivas, (como enteros, booleanos, y "nil"). Toda función es un método. Las variables siempre son referencias a objetos, no los objetos mismos. Ruby soporta herencia con enlace dinámicomixins y métodos singleton(pertenecientes y definidos por una sola instancia más que definidos por la clase). A pesar de que Ruby no soporta herencia múltiple, la clases pueden importar módulos como mixins. La sintaxis procedural está soportada, pero todos los métodos definidos fuera del ámbito de un objeto son realmente métodos de la clase Object. Como esta clase es padre de todas las demás, los cambios son visibles para todas las clases y objetos.
Ruby ha sido descrito como un lenguaje de programación multiparadigma: permite programación procedural (definiendo funciones y variables fuera de las clases haciéndolas parte del objeto raíz Object), con orientación a objetos, (todo es un objeto) o funcionalmente (tiene funciones anónimas, clausuras o closures, y continuations; todas las sentencias tiene valores, y las funciones devuelven la última evaluación). Soporta introspecciónreflexión y metaprogramación, además de soporte para hilos de ejecucióngestionados por el intérprete. Ruby tiene tipado dinámico, y soporta polimorfismo de tipos (permite tratar a subclases utilizando la interfaz de la clase padre). Ruby no requiere de polimorfismo de funciones (sobrecarga de funciones) al ser dinámicamente tipado (los parámetros de una función pueden ser de distinto tipo en cada llamada, encargándose dicha función de determinar el tipo y actuar en consecuencia).
De acuerdo con las preguntas frecuentes de Ruby, "Si te gusta Perl, te gustará Ruby y su sintaxis. Si te gusta Smalltalk, te gustará Ruby y su semántica. Si te gusta Python, la enorme diferencia de diseño entre Python y Ruby/Perl puede que te convenza o puede que no."

Inclusión de Archivos
Rutas y Directorios
Las rutas son las direcciones que nos indican cómo llegar a un archivo o directorio en el sistema.
Vamos a ver algunas cosas relativas a la administración y navegación entre directorios.
Primero que nada para el manejo de directorios tenemos la clase del Dir(el vínculo anterior los lleva a la documentación), vamos a ver algunas de las funcionalidades que nos aporta:

Con Dir.pwd podemos obtener el directorio actual.

Con Dir.chdir("/directorio") podemos navegar al directorio que especificamos en el string, por ejemplo: Dir.chdir("/home/nia/Descargas") me dejaría en el directorio "Descargas" de mi carpeta personal.

Podemos obtener un array con el contenido de un directorio utilizando Dir.entries("/directorio").
Si lo que queremos es recorrer o realizar algo (como mostrar) cada uno de los elementos (archivos o carpetas) contenidos en un directorio sin almacenar un array podemos utilizar Dir.foreach("/directorio"), por ejemplo:

Dir.foreach("/home/nia/Descargas") do |contenido|
puts contenido
end

Va a mostrar una lista del contenido de mi directorio de descargas en la consola.
Otra forma de obtener un array con el contenido, pero ésta vez con el path completo de cada elemento (y sin los elementos "." ni ".." ) es utilizando Dir["/directorio"].

Utilizando Dir.mkdir("nombre"), creamos en el directorio actual (ese que obtenemos cuando usamos Dir.pwd) un nuevo directorio con el nombre que le indiquemos; por defecto se establecen los permisos del directorio como 0777 (osealectura/escritura/ejecutabilidad para el dueño y lectura/ejecutabilidad para el grupo y otros), si queremos asignar uno diferente podemos pasarlo como segundo parámetro: 
Dir.mkdir("nombre", intPermiso).
Con Dir.glob("busqueda"), podemos realizar una búsqueda en el directorio actual, por ejemplo si queremos ver todos los ficheros .zip: Dir.glob("*.zip").
Por último para eliminar un directorio utilizamos Dir.delete("directorio").

Archivos
Una vez entendamos cómo manipular los directorios nos vamos a la gestión de archivos
Como crear un archivo:
Para abrir un archivo simplemente debemos crear un objeto de la clase File (File.new()) o utilizar el método estático open (File.open()) y esto nos devolverá un objeto de tipo File al que podremos manipular.
Para acceder a los archivos debemos pasarle un segundo valor por parámetros que nos indica cómo vamos abrir el archivo. Veamos los parámetros para abrir y crear un archivo:
  • r: (sólo lectura) Modo por defecto.
  • r+: (lectura y escritura) Comienza la escritura al principio del archivo.
  • w: (sólo escritura) Borra el contenido del archivo o crea un nuevo archivo para escritura.
  • w+: (lectura y escritura) Borra el contenido del archivo o crea un nuevo archivo para lectura y escritura.
  • a: (sólo escritura) Comienza la escritura al final del archivo si existe y si no crea uno nuevo.
  • a+: (lectura y escritura) permite leer y escribir ubicando el cursor al final del archivo si éste existe y si no crea uno nuevo.
Ejemplo:

#consultamos el directorio donde estamos trabajando
>>Dir.glob "*"
   ["test"]
#creamos y obtenemos un archivo nuevo
>>archivo =File.new("pruebaCodeHero.txt","w")
   File:pruebaCodeHero.txt
#intentamos crear un archivo pasándole por parámetro solo lectura
>>archivo =File.new("pruebaCodeHeroError.txt","r")
Errno::ENOENT: No such file ordirectory - pruebaCodeHeroError.txt
# consultamos nuevamente la carpeta
>>Dir.glob "*"
   ["pruebaCodeHero.txt", "test"]





Tipo de Datos y Declaración
Los tipos de datos son, como su nombre lo indica, los diversos datos que se pueden almacenar en la memoria usando el lenguaje de programación Ruby. Como en todo lenguaje de programación, se tiene una diferencia en cuanto a estos datos, pues la cantidad de memoria que usan no es similar, y esta diferencia hace que la distinción entre unos y otros sea importante.
Números:
En ruby, todo es tratado como un objeto, eso no excluye a los números, en forma general, ruby cuenta con diferentes clases para manejar cada tipo de números, por ejemplo:
·         Integer: La clase base de donde derivan todos los enteros.
·         Fixnum: Clase para números enteros, su tamaño depende de la arquitectura de donde se interprete el código, sin embargo, su tamaño es eso -1 bit y usa complemento 2 para su representación en memoria, si un número excede el tamaño asignado, automáticamente se convierte en bignum.

·         Bignum:Contiene valores mayores a fixnum, la restricción depende de la arquitectura pero pueden guardarse números muy grandes, tanto como de nuestra memoria, si el número ingresado cabe en un fixnum, automáticamente se convierte a esta clase.


·         Float:Almacena números con punto flotante con la arquitectura de doble precisión nativa.

·         Rational:Almacena números racionales, es decir, números con un valor de numerador y un denominador.


Strings;
Para las cadenas de caracteres, su uso es bastante similar al de cualquier lenguaje orientado a objetos, con la clase String, sin embargo cabe mencionar algunas caracteristicasmas emocionantes de ruby, por ejemplo, puedes multiplicar cadenas!
“Hola ” * 5 => “Hola HolaHolaHolaHola”
Para una vista más completa referirse al capitulo de Strings
Date/Time
Ruby ya trae librerías para manejar los tipos date y time, sin embargo para usarlos, debemos llamar a la librería correspondiente, esto con la palabra reservada require.
require ‘date’


Operadores

Aritméticos:
Los operadores aritméticos permiten realizar operaciones matemáticas, entre dos variables y/o constantes. Todas las expresiones entre paréntesis se evalúan primero. Las expresiones con paréntesis anidados se evalúan de adentro hacia afuera, el paréntesis más interno se evalúa primero. Dentro de una misma expresión los operadores se evalúan en el siguiente orden:
Operador
Descripción
**
Exponencial
*, /, %
Multiplicación, división, modulo
+, –
Suma y resta

Ejemplo:
Exponencial
5 ** 2 (el resultado sera 25)5 ** 3 (el resultado sera 125).
División
5 / 3 = 1 (la operación nos da como resultado 1, que sería el cociente de una división)
Modulo
5 % 3 = 2 (la operación nos da como resultado 2, que es el resto o residuo de una división)
Los operadores en una misma expresión con igual nivel de prioridad se evalúan de izquierda a derecha.
Ejemplo:
5 * 5 / 6 = 4 (Primero se opera 5 * 5 que seria 25 y después se divide por 6 y nos daría 4)
6 / 5 * 5 = 5 (Primero se opera 6 / 5 que seria 1 y después se multiplica por 5 y nos daría 5)
En los dos ejemplos mostrados como los dos operadores tienen el mismo nivel de prioridad se evalúan de izquierda a derecha dándonos diferente resultado en dos operaciones aparentemente iguales.
Relacionales:
Los operadores relacionales comparan valores entre sí, el resultado es verdadero o false (uno o cero).
Operador
Descripción
==
igual que
!=
diferente de
< 
menor que
> 
mayor que
<=
menor o igual que
>=
mayor o igual que









El operador == (igual que) es solo para realizar comparaciones, si deseamos asignar un valor a una variable debemos utilizar el operador = (igual)
Ejemplo:
a = 16
b = 61
a == b (el resultado sera falso, porque, 16 no es igual que 61)
a = b (el resultado de la variable a, ahora es 61, porque, se le ha asignado el valor de b)
 Lógicos:
Los operadores lógicos se utilizan para comparar dos expresiones y devolver un resultado booleano (verdadero o falso). Estos operadores unen estas expresiones devolviendo también verdadero o falso.
Operador
Descripción
&&, and
Y
||, or
O
!
No

Las expresiones conectadas con operadores && y || se evalúan de izquierda a derecha y la evaluación se detiene tan pronto como el resultado verdadero o falso es conocido.

Declaración e inicialización de variables

En Ruby no hay una declaración explícita del tipo de dato de una variable. El mismo se determina en tiempo de ejecución a partir del valor que se le ha asignado. Esto significa que las variables pueden tomar diferentes tipos de datos en diferentes partes del programa. Para determinar si un nombre hace referencia a una variable o a un método, Ruby utiliza heurística, en la cual a medida que va leyendo el código fuente va llevando control de los símbolos que ha leído, asumiendo que los mismos son variables. Cuando se encuentra con un símbolo que puede ser una variable o un método, revisa si ya se le ha asignado algo anteriormente. Si es así, entonces lo trata como variable; si no, lo trata como un método.
Ejemplo:
    #declaración de una variable de tipo String
Nombreclase = “Lenguajes de Programación”
    #declaración de una variable de tipo entero
Numeroalumnos = 30
    #declaración de un arreglo
numeros = [ 3, 4, 12, 22.5 ]

Sentencias de control Condicional
Ruby ofrece diferentes estructuras de control que nos permiten alterar el flujo de la ejecución del programa, entre ellas podemos destacar:
Ø  IF: La estructura de control IF, maneja el flujo de la aplicación dependiendo del resultado de una condición.
Siguiendo con nuestro ejemplo del "juego RPG", cuando nuestro player está muerto debemos realizar una acción, por lo general descontar un continúe y renacer en el último punto guardado.
Primer archivo: prueba_if.rb
#!/usr/bin/ruby

vida = 100
continues = 3
# pasan cosas que nos quitan vida

if vida == 0
puts"El Personaje ha muerto"
puts"Tu personaje va a revivir"
continues = continues - 1
else
puts"El juego continua con normalidad"
end


# En caso de necesitar el elseif en ruby se usa la siguiente sintaxis
numero = 3

if numero >5
puts"#{numero} es mayor que 5"
elsif numero == 3
puts"#{numero} es igual a 3"
else
puts"#{numero} es menor que 5 pero no es igual a 3"
end

Para correr el script desde la consola
ruby ~/Desktop/prueba_if.rb

El juego continua con normalidad
El número es igual a 3

Ø  UNLESS: La estructura de control UNLESS, es similar a el IF en cuanto a estructura pero solo ejecuta el código si no es igual a la condición (==FALSE)
#!/usr/bin/ruby

numero = 1
unless numero == 1
puts"El número no es el 1"
else
puts"El número es el 1"
end
La respuesta en este caso sera:
ruby ~/Desktop/prueba_unless.rb

El número es el 1

Ø  CASE: En caso de tener una variable que necesitamos comprobar muchos casos, en vez de usar muchos if con elsif, seria mas natural usar la expresion case

case variable
when [condicion]
# code
when [condicion]
# code
else
# code
End

Un ejemplo mas claro del uso del case pude ser:
#!/usr/bin/ruby

edad =  5
caseedad
when0 .. 2
puts"Bebe"
when3 .. 12
puts"Niño"
when13 .. 18
puts"Adolescente"
else
puts"Adulto"
end

Sentencias de Control Repetitivas

Ø  BUCLES: Bucles de Ruby se utilizan para ejecutar el mismo bloque de código una cantidad específica de veces. En este capítulo se detallan todas las sentencias de bucles apoyados por Ruby. Es importante tener cuidado con los bucles y asegurarse que la sentencia de parada se ejecute al menos una vez, para evitar bucles infinitos que bloqueen el sistema.

Ø  WHILE: Estos bucles o ciclos se ejecutan hasta que la condición sea verdadera. Para empezar debemos conocer la sintaxis:
whileconditional[do]
code
end
Para comprender mejor estos bucles lo demostraremos con un ejemplo fácil:
#!/usr/bin/ruby
numero=0
whilenumero<5do
puts("el número es: #{numero}")
numero=numero+1
end
Y el resultado de este Script es una recorrida por los números desde el 0 hasta que se cumpla la condición de parada, que es cuando el número sea menor a cinco.
ruby Desktop/conditionalCodehero.rb
el número es: 0
el número es: 1
el número es: 2
el número es: 3
el número es: 4

Ø  REPEAT: Estos bucles se ejecutan siempre al menos una vez, ya que entra en el bloque de código y al final se verifica la condición de salida. La sintaxis de este tipo de bucles es:
códigowhilecondición
O de la siguiente manera:
begin
código
endwhilecondición
Para demostrar el funcionamiento de estos tipos de bucles, veamos este ejemplo:
#!/usr/bin/ruby

numero=0
begin
puts("el número es: i = #{numero}")
numero+=1
endwhilenumero<5
Ejecutamos el Script obteniendo lo siguiente como resultado:
>>rubyDesktop/conditionalCodehero.rb
elnúmeroes:i=0
elnúmeroes:i=1
elnúmeroes:i=2
elnúmeroes:i=3
elnúmeroes:i=4

Ø  UNTIL LOOP: Este tipo de loop se ejecuta hasta que la condición de parada sea falsa, la sintaxis se define de la siguiente manera:
untilCondición[do]
código
end
Lo demostramos con el siguiente ejemplo, en donde el bloque de código interno al bucles se ejecuta mientras el número no sea mayor que cinco:
#!/usr/bin/ruby
numero=0
untilnumero>5do
puts("El número es #{numero}")
numero+=1
end
El resultado de este Scripts es:
rubyDesktop/conditionalCodehero.rb
Elnúmeroes0
Elnúmeroes1
Elnúmeroes2
Elnúmeroes3
Elnúmeroes4
Elnúmeroes5
Ø  FOR: Estos bucles se ejecutan una vez por cada elemento. Éstos tienen configurado un rango de valores que indican cuantas veces se va a ejecutar. Primero les definimos la sintaxis para posteriormente ir con el ejemplo y comprender mejor esto:
forvariable[,variable...]inexpresión[do]
Código
end
En el ejemplo vamos a poder ver como la variable simplemente incrementa sola, hasta cumplir con la expresión que en este caso es un objeto de tipo Rango con valores desde el 0 hasta el 3:
#!/usr/bin/ruby

foriin0..3
puts"El valor de la variable es: #{i}"
end
Dando como resultado lo siguiente:
ruby Desktop/conditionalCodehero.rb
el valor de la variable es: 0
el valor de la variable es: 1
el valor de la variable es: 2
el valor de la variable es: 3

Definición de funciones y arreglos

Las funciones: se definen por la palabra clave def.

def hola(programador)
puts "Hola #{programador}"
end

hola('Pepe')    # Hola Pepe

Los Arrays: Se pueden crear un array listando elementos entre corchetes ([ ]) y separándolos por comas. Los arrays en Ruby pueden almacenar objetos de diferentes tipos.

ruby>ary = [1, 2, "3"]
 [1, 2, "3"]

Los arrays se pueden concatenar y repetir, igual que las cadenas.
ruby>ary + ["foo", "bar"]
[1, 2, "3", "foo", "bar"]
ruby>ary * 2
 [1, 2, "3", 1, 2, "3"]

 Se pueden utilizar índices numéricos para acceder a cualquier parte del array.
ruby>ary[0]
 1
ruby>ary[0,2]
[1, 2]
ruby>ary[-2]
 2
ruby>ary[-2,2]
[2, "3"]
ruby>ary[-2..-1]
 [2, "3"]

(Los índices negativos indican que se empieza a contar desde el final del array, en vez del principio). Los arrays se pueden convertir a y obtener de cadenas utilizado join y split respectivamente:

ruby>str = ary.join(’:’)
 "1:2:3"
ruby>str.split(’:’)

["1", "2", "3"]

No hay comentarios:

Publicar un comentario