• Inspiración
  • Tutoriales
  • Bootcamp

En1Mes

  • Inspiración
  • Tutoriales
  • Bootcamp

Entendiendo los objetos en Ruby

objetos y clases

Para muchos programadores ha sido complicado aprender a programar con objetos debido a la gran cantidad de conceptos que se introducen simultaneamente, pero a mi parecer es porque simplemente la teoría está explicada con una mala metáfora.

Se suele decir que las clases (la forma de definir objetos) son recetas, o son un esqueleto, y es mucho más fácil explicar que son los objetos y para que sirven sin entendemos a las clases como el molde, por ejemplo un molde de una pieza de lego y a los objetos como productos de este molde, o sea los legos.

Requisito (Entender funciones, paso de parámetros, return)

Los objetos tienen un identificador (por ejemplo nº serie), propiedades como el color y tamaño; y comportamientos como acoplarse y causar dolor infinito si uno los pisa.

El como se definen las clases y objetos depende del lenguaje de programación, en ruby que es un lenguaje que a mi me fascina por su simpleza se definen así:

class MoldeLego
end

Para crear un objeto a partir de ese molde hay que instanciarlo (otra palabra famosa dentro del mundo orientado a objetos), para instanciar basta con utilizar el nombre de la clase con el método new, o sea:

lego1 = MoldeLego.new

Este lego tiene un identificador, que se puede capturar en ruby con lego1.object_id pero todavía no tiene comportamiento ni propiedades, ahora el secreto para entender bien esta parte es que tanto el molde (la clase) como el objeto pueden tener comportamientos. Cuando los comportamientos son del molde se llaman métodos de clase, cuando lo son del objeto se llaman métodos de instancia.

Para agregar un método de instancia, (o sea un comportamiento del lego) lo hacemos de la siguiente forma:

class MoldeLego
  def metodoDeInstancia()
  end
end

Por ejemplo algo común sería que el lego tuviera la capacidad de acoplarse con otro lego, para eso el método tendría que ser capaz de recibir como parámetro el otro lego y devolver ahora un nuevo lego más grande.

class MoldeLego
  def acoplar(otro_lego)
    return MoldeLego.new()
  end
end

El problema es que para guardar cualquier estado del lego necesitamosvariables de instancias, y para eso necesitamos definirlas en elconstructor que en el caso de ruby se llama initialize() y si, este método también es un método de instancia, pero además tiene la gracia que se llama sólo cuando se instancia un objeto a través de new.

class MoldeLego
  def initialize()
     @size = 1 # las variables de instancia se definen con una @ 
  end
end

Cada vez que creamos un lego este tendrá tamaño 1,

lego1 = MoldeLego.new # Este Lego ahora tiene tamaño 1

Hagamos ahora un pequeño resumen:

Los objetos son instancias de una clase, cuando se utilizar la expresión clase.new entonces es cuando se instancia el objeto y automáticamente se llama al constructor, todo lo definido dentro del constructor se ejecuta.

Los constructores sirven principalmente para darle valores iniciales a las variables de instancias.

Volviendo a nuestro ejemplo, si queremos rescatar el tamaño tenemos un problema, no se puede acceder directamente a los estados internos de un objeto debido al principio de encapsulamiento, para acceder a los estados tenemos que crear getters y setters, o sea métodos para obtener los estados (getters) y métodos para cambiarlos (setters), así que nuestro MoldeLego quedaría así:

class MoldeLego
  def initialize()
     @size = 1 # las variables de instancia se definen con una @ 
  end
  def getSize()
     return @size
  end
  def setSize(new_size)
    @size = new_size
  end
end

Para usarlo, lo haríamos de la siguiente forma:

lego1 = MoldeLego.new # Este Lego ahora tiene tamaño 1
lego1.setSize(5)
lego1.getSize()

Exista una mejor forma de definir los getters y setters, que es hacerlo de tal manera que pareciera que estamos trabajando directamente sobre el atributo.

o sea:

class MoldeLego
  def initialize()
     @size = 1 # las variables de instancia se definen con una @ 
  end
  def size()
     return @size
  end
  def size=(new_size)
    @size = new_size
  end
end

de esta forma podemos ocupar el objeto así:

lego1 = MoldeLego.new # Este Lego ahora tiene tamaño 1
lego1.size # devuelve 1, pues es el tamaño original
lego1.size = 5
lego1.size # devuelve 5, ya que lo cambiamos

ahora en ruby es posible definir de forma simultánea la variable, los getters y setters a través del attr_accessor:

class MoldeLego
 attr_accessor :size
 def initialize()
     @size = 1 # las variables de instancia se definen con una @ 
  end
 end

y para ocuparlo sería exactamente que la forma anterior, ahora volvamos a la idea de acoplar:

class MoldeLego
  attr_accessor:size
  # Pasamos un valor al constructor 
  # para poder crear legos de otros tamaños
  # en caso de que se  omita es de tamaño 1
  def iniatilize(size_orig = 1) 
    @size = size_orig
  end
  def acoplar(otro_lego)
   return MoldeLego.new(self.size + otro_lego.size) # devolvemos un lego de la suma del tamaño de los otros legos
  end
end

¿Cómo se usa?

lego1 = MoldeLego.new
lego2 = MoldeLego.new
lego3 = lego1.acoplar(otro_lego)

Todavía podemos hacer una mejor más, en ruby al igual que otros lenguajes se puede redefinir una operación, en este caso vamos a redefinir la suma (sólo para los legos):

class MoldeLego
  attr_accessor:size
# Pasamos un valor al constructor 
  # para poder crear legos de otros tamaños
  # en caso de que se  omita es de tamaño 1
  def iniatilize(size_orig = 1) 
    @size = size_orig
  end
def +(otro_lego)
   return MoldeLego.new(self.size + otro_lego.size) # devolvemos un lego de la suma del tamaño de los otros legos
  end
end

Gracias a eso ahora podemos simplemente escribir:

lego1 = MoldeLego.new
lego2 = MoldeLego.new
lego3 = lego1 + lego2

¿Que pasaría si quisiéramos contar cuantos legos se han creado?

Eso no lo podemos hacer con una variable de instancia, necesitamos que sea el molde cuente, (algo así como imprimir el número de serie en el producto), o sea es una propiedad de la clase, estas se llaman formalmente variables de clase, en ruby se crean con 2 @@:

class MoldeLego
  attr_accessor:size
  @@cuenta_legos = 0
end

A diferencia de la variables de instancias estas no requieren definirse en el constructor, pues existen para la clase, independiente de si existen legos o no.

ahora si quisiéramos contar cada vez que se crea un lego nuevo, podríamos hacerlo así:

class MoldeLego
  attr_accessor:size
  @@cuenta_legos = 0
  def iniatilize(size_orig = 1) 
    @size = size_orig
    @@cuenta_legos += 1  
  end
end

si quisiéramos obtener las variables de clase toparíamos con el mismo problema de encapuslamiento, tenemos que definir getters y setters para estas, ahora lamenteblemente la sintaxis en ruby no es tan bonita, se hace asi:

class MoldeLego
  class << self; attr_accessor :cuenta_legos end 
  attr_accessor:size
  @@cuenta_legos = 0
  def iniatilize(size_orig = 1) 
    @size = size_orig
    @@cuenta_legos += 1  
  end
end

Sólo una cosa está quedando en el tintero, ¿cómo crear métodos de clase más allá de los getters y setter?

Para eso vamos a ocupar self, para este ejemplo voy a definir un getter de la forma no tan bonita para la cuenta legos, sería así:

class MoldeLego
  class << self; attr_accessor :cuenta_legos end
  def self.getCuentaLegos()
     return @@cuenta_legos
  end
end

De los legos al molde:

Una de las curiosidades que tienen los lenguajes orientados a objetos es que desde las instancias podemos rescatar las propiedades de la clase, pero desde las clase no podemos saber cuales son las propiedades de las instancias.

En la metáfora del lego podemos saber incluso de que color era el molde que lo fabricó sin embargo desde el molde no podemos saber de que color o cuantos legos se han acoplado a menos que llevemos específicamente la cuenta como en el caso del número de serie.

Para rescatar la clase a partir de la instancia basta con hacer:

lego.class.cuentaLegos

lo que es exactamente lo mismo que:

MoldeLego.cuentaLegos

Es importante no confundir esta metafora con la herencia, esta última es una característica de los objetos que les permite obtener los métodos y propiedades de sus padres, pero este tema lo tocaremos en un próximo artículo.

Con lo vista ya entendemos lo básico de objetos en Ruby (es bueno saber que con excepción de los attr_accessor este tutorial aplica a otros lenguajes orientados a objetos)

Jan 21, 2015Gonzalo Sánchez
Share Button
  • El Autor
  • Últimos Posts

About Gonzalo Sánchez

Emprendedor lean, Ingeniero civil informático dedicado al desarrollo de una mejor web con ruby on rails. Fanático de los números y las métricas y por sobre todo fundador de en1mes.
  • Mostbet guncel giris: en guncel bahis secenekleri - May 8, 2025
  • Mostbet Casino: Your Oasis of Gaming Pleasure, Always - May 6, 2025
  • Bahis ve emsallar Most Bet ile - May 6, 2025
  • Mostbet Resmi Sitesi: Bahis Severlerin Tercihi - May 3, 2025
  • MostBet Rehberi: Bahis Dunyasinda Basariya Ulasmanin Yollari - May 2, 2025
  • Basarili Bir Bahis Deneyimi Icin Ipuclari Most bet Platformunda - April 30, 2025
  • Mostbet Giris 2025: Bahis Stratejileri ve Taktikler - April 28, 2025
  • Bahis Dunyasinda Guvende Kalmanin Yollari Mostbet ile - April 25, 2025
  • Mostbet yeni giris adresi olarak sadece internet sitesi - April 23, 2025
  • Bahis Dunyasinda MostBet ile Guvenli Adimlar Atin - April 22, 2025
10 years ago Ruby, TutorialesPOO, ruby, Tutoriales5,313
7 Extensiones gratis de Chrome que todo diseñador y programador debe conocerBorrar un Scaffold en Ruby on Rails
You Might Also Like
 
Pequeño Scrapper de Wikipedia
 
SQL Joins

Leave a Reply Cancel reply

Tags
mostbetslotticamostbet UZslottica PLRuby on Railsaviatoraviator KZozwincasinoozwincasino AUemprendimientos digitalesfortunetiger BRfortunetigerTutorialesDiseñoLondonLondon UZbj88slottica BRHerramientashtml5WordpressrubyLanding Pageparty poker casinogratogana juegos en vivoแทงบอลออนไลน์Bases de datoswash serviceหวยออนไลน์gratogana entrar20bet plkudos casino no deposit bonus 2024kudos casino loginTallereshackathonkudos casino no deposit bonuspartycasino entrarHeroku1win AZ1winTipsPáginas WebNitrousInspiracióncbd
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • PADANGTOTO
  • Interesado en otros tipos de emprendimiento?

    Quieres aprender a importar y exportar productos a todo el mundo? entra aquí

  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • LOMBOKTOTO
  • No te pierdas ningún artículo.

  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • RAMALANTOTO
  • 2016 © En 1 Mes