Comprendiendo los Tipos de Datos en Ruby

Introducción

Cuando escribes programas, utilizas tipos de datos para clasificar la información. Los tipos de datos indican a la computadora cómo manejar la información en tu programa. También determinan qué puedes hacer con la información, incluidas las operaciones que puedes realizar.

Una forma de entender los tipos de datos es considerar los diferentes tipos de información que usamos en el mundo real. Por ejemplo, utilizamos números enteros (0, 1, 2, …), enteros (…, -1, 0, 1, …) y números irracionales (π).

Generalmente, en matemáticas, podemos combinar números de diferentes tipos y obtener alguna respuesta. Por ejemplo, podemos querer sumar 5 a π:

5 + π

Podemos mantener la ecuación como respuesta para tener en cuenta el número irracional, o podemos redondear π a un número con un breve número de decimales y luego sumar los números juntos:

5 + π = 5 + 3.14 = 8.14

Pero si intentamos evaluar números con otro tipo de datos, como palabras, las cosas comienzan a no tener mucho sentido. ¿Cómo resolveríamos la siguiente ecuación?

sky + 8

Esto no es algo que sepamos cómo resolver de inmediato. Tampoco la computadora puede hacerlo porque los datos son de dos tipos diferentes. “Cielo” es una palabra y 8 es un número entero. Cuando escribimos programas, debemos tener cuidado con cómo asignamos valores y cómo los manipulamos mediante operaciones como suma, resta, multiplicación y otras.

En este tutorial, aprenderás sobre los tipos de datos más importantes nativos de Ruby: enteros, decimales, cadenas de texto, símbolos, arreglos y hash. Esta no es una investigación exhaustiva de los tipos de datos, pero te ayudará a familiarizarte con las opciones disponibles en tus programas.

Luego explorarás la tipificación dinámica. Los programas en Ruby determinan los tipos de datos según lo que contienen las variables, por lo que comprender cómo funciona la tipificación dinámica te ayudará a evitar situaciones complicadas en tus propios programas. Y debido a que las variables pueden contener cualquier valor, aprenderás a identificar el tipo de datos de una variable.

Comencemos viendo cómo trabajar con números enteros en Ruby.

Enteros

Al igual que en matemáticas, los enteros en programación de computadoras son números enteros que pueden ser positivos, negativos o 0 (…, -1, 0, 1, …). Un entero también se conoce comúnmente como un int.

Puedes imprimir un entero de esta manera:

print -25
Output
-25

También puedes almacenar el entero en una variable y luego imprimir el valor haciendo referencia a la variable:

my_int = -25
print my_int
Output
-25

También puedes realizar operaciones matemáticas con enteros. Por ejemplo, puedes calcular la suma de dos números e imprimir el resultado:

sum = 116 - 68
print sum
Output
48

Cuando escribimos números más grandes, tendemos a usar comas para hacerlos más fáciles de leer. Por ejemplo, escribiríamos 1,000,000 para “un millón”. No puedes usar comas en tu código, pero Ruby te permite usar el guión bajo (_) para hacer que los números grandes sean más legibles.

Pruébalo:

large_number.rb
large_number = 1_234_567
print large_number

Verás el entero impreso sin los guiones bajos:

Output
1234567

Los guiones bajos te permiten escribir un código más legible si tienes que representar números grandes en tus programas.

A medida que aprendas más sobre el lenguaje Ruby, tendrás muchas más oportunidades de trabajar con enteros. Veamos cómo trabajar con números reales.

Números de punto flotante

A floating-point number or a float represents a real number. Real numbers can be either a rational or an irrational number; numbers that contain a fractional part, such as 9.0 or -116.42. In other words, a float in a Ruby program is a number that contains a decimal point.

Puedes imprimir flotantes en Ruby de la misma manera que imprimes enteros:

print 17.3
Output
17.3

También puedes declarar una variable y asignar un flotante:

my_float = 17.3
print my_float
Output
17.3

Y, al igual que con los enteros, también puedes hacer cálculos con flotantes en Ruby:

sum = 564.0 + 365.24
print sum
Output
929.24

Si sumas un flotante a un entero en Ruby, obtendrás un flotante:

sum = 564 + 365.24
print sum
Output
929.24

Ruby considerará cualquier número escrito sin decimales como un entero (como en 138) y cualquier número escrito con decimales como un flotante (como en 138.0).

A continuación, veamos los booleanos en Ruby.

Tipos de datos booleanos

Los booleanos se utilizan para representar los valores de verdad que están asociados con la rama lógica de las matemáticas, lo cual informa a los algoritmos en la informática. En Ruby, representamos este tipo de datos con uno de dos valores, ya sea true o false.

Muchas operaciones en matemáticas nos dan respuestas que se evalúan como verdaderas o falsas:

  • mayor que
  • 500 > 100 true
  • 1 > 5 false
  • menor que
  • 200 < 400 true
  • 4 < 2 false
  • igual
  • 5 = 5 true
  • 500 = 400 false

Al igual que con los números, puedes almacenar un valor true o false en una variable:

result = 5 > 8

Luego puedes imprimir el valor booleano con una llamada a la función print():

print result

Dado que 5 no es mayor que 8, verás el siguiente resultado:

Output
false

A medida que escribas más programas en Ruby, te familiarizarás más con cómo funcionan los booleanos y cómo diferentes funciones y operaciones que se evalúan como true o false pueden cambiar el curso del programa.

A continuación, vamos a explorar cómo trabajar con texto en nuestros programas.

Cadenas

A string is a sequence of one or more characters, such as letters, numbers, and symbols. Strings primarily exist within either single quotes (') or double quotes (") in Ruby, so to create a string, enclose a sequence of characters in quotes, like this:

"This is a string in double quotes."

El pequeño programa “Hola, mundo!” demuestra cómo se puede usar una cadena en la programación de computadoras, ya que los caracteres que componen la frase Hola, mundo! forman una cadena.

print "Hello, World!"

Al igual que con otros tipos de datos, puedes almacenar cadenas en variables:

output = "Hello, World!"

Y mostrar la cadena llamando a la variable:

print output
Output
Hello, World!

Al igual que los números, hay muchas operaciones que podemos realizar en cadenas dentro de nuestros programas para manipularlas y lograr los resultados que buscamos. Las cadenas son importantes para comunicar información al usuario y para que el usuario comunique información de vuelta al programa.

A veces necesitas trabajar con listas de datos. Ahí es donde entran en juego los arrays.

Arrays

Un array puede contener múltiples valores dentro de una sola variable. Esto significa que puedes contener una lista de valores dentro de un array e iterar a través de ellos. Cada elemento o valor que está dentro de un array se llama un elemento.

Los arrays se definen especificando valores entre corchetes cuadrados [ ], separados por comas.

Un array de enteros se ve así:

[-3, -2, -1, 0, 1, 2, 3]

A array of floats looks like this:

[3.14, 9.23, 111.11, 312.12, 1.05]

Aquí tienes una lista de cadenas:

['shark', 'cuttlefish', 'squid', 'mantis shrimp']

Como otros tipos de datos, puedes asignar un array a una variable:

sea_creatures = ['shark', 'cuttlefish', 'squid', 'mantis shrimp']

Si imprimimos la variable, la salida se verá exactamente como el array que creamos:

print sea_creatures
['shark', 'cuttlefish', 'squid', 'mantis shrimp']

Accedes a elementos individuales en un array usando un número de índice, comenzando en 0.

puts sea_creatures[0] # tiburón
puts sea_creatures[2] # calamar

Para imprimir el último valor, puedes usar el índice -1. Ruby también proporciona los métodos .first y .last para obtener el primer y último elemento, respectivamente:

puts sea_creatures.first # tiburón
puts sea_creatures.last # camarón mantis

Los arrays en Ruby pueden contener muchos tipos diferentes de datos. Puedes almacenar cadenas, símbolos e incluso otros arrays dentro de un array:

record = [
:en,
"Sammy",
42,
[
"coral",
"reef"
]
]

Los arrays en Ruby son mutables, lo que significa que puedes añadir valores, eliminar valores e incluso modificar entradas en el array.

A veces necesitamos una forma de etiquetar cosas en un programa. Para eso son los símbolos.

Símbolos

A symbol is a special data type that acts like a label or an identifier in a Ruby program. Symbols are immutable, which means that they cannot be changed. A symbol looks like a variable declaration without a value. Here’s an example of a symbol:

:time_zone

En Ruby, normalmente se utiliza un símbolo para identificar algo importante, mientras que se usa una cadena para el texto con el que necesitas trabajar o manipular. Cada cadena en un programa Ruby es un objeto propio, con su propia ubicación única en la memoria, incluso si las cadenas son idénticas.

Pero si haces referencia al mismo símbolo varias veces, estás haciendo referencia al mismo objeto en todo tu programa, lo que significa que estás haciendo referencia a la misma ubicación de memoria.

Verás este concepto en acción cuando veamos los hashes, que te permiten asociar claves con valores.

Hashes

A hash is a dictionary-like collection of keys and values. These key-value pairs provide a useful way to store and access data. Hashes are often used to hold data that are related, such as the information about a user. You define a hash like this:

{"first_name" => "Sammy", "last_name" => "Shark"}

Puedes asignar hashes a variables al igual que otros tipos de datos:

user = {"first_name" => "Sammy", "last_name" => "Shark"}

Para recuperar valores del hash user, utilizas la clave para el valor:

print user["first_name"] # "Sammy"
print user["last_name"] # "Shark"

Puedes usar símbolos como claves en tu hash en lugar de cadenas:

user = {:first_name => "Sammy", :last_name => "Shark"}

Usar símbolos como claves de hash se prefiere siempre que sea posible. Cada instancia de un símbolo apunta al mismo objeto, mientras que cada instancia de una cadena se refiere a un objeto único. Usar símbolos como claves resulta en un rendimiento ligeramente mejor y un menor uso de memoria.

Cuando usas símbolos como claves, utilizas símbolos para recuperar los valores:

print user[:first_name] # "Sammy"
print user[:last_name] # "Shark"

También puedes usar una sintaxis ligeramente diferente al definir el hash:

user = {first_name: "Sammy", last_name: "Shark"}

Esta sintaxis es similar a la utilizada en JavaScript y otros lenguajes. Esta sintaxis define las claves como Símbolos, por lo que accederías a las entradas usando :primer_nombre y :apellido en lugar de las cadenas "primer_nombre" y "apellido".

Has examinado varios tipos de datos, así que veamos cómo Ruby trabaja con esos tipos.

Tipado Dinámico

En Ruby, no declaras explícitamente un tipo de dato antes de asignar un valor; la asignación del valor determina el tipo de dato. Ruby utiliza tipado dinámico, lo que significa que la comprobación de tipos se realiza en tiempo de ejecución en lugar de en tiempo de compilación, como en lenguajes que utilizan tipado estático. Ruby determina el tipo de dato a partir de los datos almacenados en la variable. Esto es similar a los tipos de datos en Python y a los tipos de datos en JavaScript.

La variable t en el siguiente ejemplo puede configurarse con cualquier tipo de dato disponible:

t = 42 # t is an Integer
t = "Sammy" # t is a String
t = :sammy # t is a Symbol
t = true # t is a boolean (true)
t # t is nil

Con los lenguajes de tipado dinámico, puedes reutilizar una variable existente para contener diferentes tipos de datos.

Esto es útil cuando se convierten datos de un tipo a otro. Por ejemplo, podrías tener este código que solicita al usuario un valor numérico:

print "Please enter the length of the room: "
length = gets.chop

Los datos que obtienes del teclado siempre son una cadena, así que, para realizar operaciones matemáticas, debes convertir los datos de la variable length a un número. En lenguajes de tipado estático, donde debes declarar el tipo de datos de la variable antes de asignarle un valor, necesitarías una nueva variable para contener los datos convertidos. Pero en Ruby, debido a que es de tipado dinámico, puedes reutilizar la variable length si así lo deseas.

# Convierte la cantidad a un número flotante.
length = length.to_f

El método to_f convierte la cadena a un número flotante. Ruby también proporciona el método to_i para convertir cadenas a enteros, y la mayoría de los objetos pueden convertirse a cadenas usando el método to_s:

42.to_s # "42"
(42.5).to_s # "42.5"
["Sammy", "Shark"].to_s # "[\"Sammy\", \"Shark\"]"

Ruby es de tipado dinámico, pero no te permite realizar operaciones en diferentes tipos de datos sin convertirlos al mismo tipo. Por ejemplo, este código resultará en un error:

print 5 + "5"
Output
TypeError: String can't be coerced into Integer

Lo mismo ocurrirá con este código:

print "5" + 5
Output
TypeError: no implicit conversion of Integer into String

Si deseas sumar los números para obtener 10, convierte la cadena a un entero. Si deseas concatenarlos para obtener "55", convierte el entero a una cadena.

El tipado dinámico ofrece flexibilidad, pero una desventaja es que no siempre puedes estar seguro del tipo de datos con los que estás trabajando, ya que la variable puede contener cualquier tipo disponible. Ruby proporciona formas de identificar el tipo de datos.

Identificando Tipos de Datos

En Ruby, casi todo es un objeto. Entero, flotante, array, símbolo y hash son todos objetos en Ruby, y todos tienen un método llamado class que te dirá de qué tipo son. Incluso los booleanos true y false, y el valor nil son objetos. Pruébalo por ti mismo:

42.class # Entero
(42.2).class # Flotante
["Sammy", "Shark"].class # Array
true.class # TrueClass
nil.class # NilClass

Además, puedes usar el método kind_of? para verificar un cierto tipo de datos, como este ejemplo:

42.kind_of?(Integer) # true

Esto es especialmente útil cuando tienes una variable y deseas determinar su tipo:

# en algún lugar del código...
sharks = ["Hammerhead", "Tiger", "Great White"]
...
# en otro lugar...

sharks.kind_of?(Hash) # false
sharks.kind_of?(Array) # true

También puedes utilizar esto para verificar que los datos provenientes de una fuente externa sean correctos:

if data.kind_of? String
data = data.to_f
end

Ruby también proporciona el método is_a?, que hace lo mismo que kind_of? pero puede ser un poco más fácil de leer para algunos desarrolladores:

if data.is_a? String
data = data.to_f
end

Usar class, kind_of? e is_a? puede ayudarte a asegurarte de que estás trabajando con el tipo correcto de datos. A medida que aprendas más sobre Ruby, descubrirás otras formas de manejar datos que no implican verificar explícitamente el tipo de datos.

Conclusión

Usarás muchos tipos de datos diferentes en tus programas de Ruby. Ahora tienes una mejor comprensión de los principales tipos de datos disponibles en los programas de Ruby.

Echa un vistazo a estos tutoriales para continuar tu exploración de los tipos de datos de Ruby:

Source:
https://www.digitalocean.com/community/tutorials/understanding-data-types-in-ruby