About.me

lunes, 5 de mayo de 2014

Clases y objetos en Ruby (IV)

Cuando utilicemos clases y objetos, puede ser interesante tener un alcance más amplio y compartido que el del propio objeto. De esta manera, podemos compartir un mismo valor para todos los objetos de una misma clase. También podemos definir métodos que puedan ser de ámbito generalista, de modo que podemos invocarlos sin necesidad de instanciar un objeto.

VARIABLES DE CLASE

Una variable de clase es una variable que es compartida entre varios objetos de esa clase. No hay que confundir una propiedad con una variable de clase. La propiedad es una variable con una entidad y valor propios del propio objeto. Una variable de clase, sin embargo, es una entidad única y compartida para todos los objetos instanciados de esa clase.

Para declarar una variable de clase, se escribe dos arrobas (@@) antes del nombre de la variable.

En el siguiente ejemplo definimos una clase con una propiedad y una variable de clase.

class MiClase
   @@varClase = 1

   def initialize
     @propiedad = 1
   end

   def propiedad=(valor)
     @propiedad=valor
   end

   def propiedad
     @propiedad
   end

   def varClase=(valor)
     @@varClase=valor
   end

   def varClase
     @@varClase
   end
end

obj1 = MiClase.new
obj2 = MiClase.new

# Se refiere a una variable distinta en cada objeto
obj1.propiedad = 10
obj2.propiedad = 20

# Se refiere a la misma variable en todos los objetos
obj1.varClase = 25 # Valdra 25 en todos los objetos
obj2.varClase = 30 # Valdra 30 en todos los objetos (cambia 25 por 30)

puts "obj1 > @propiedad = #{obj1.propiedad} / @@varClase = #{obj1.varClase}"
puts "obj2 > @propiedad = #{obj2.propiedad} / @@varClase = #{obj2.varClase}"

El resultado será el siguiente:

obj1 > @propiedad = 10 / @@varClase = 30
obj2 > @propiedad = 20 / @@varClase = 30

Una variable de clase tiene un alcance privado, por lo que, para acceder a su valor, requiere que se escriban métodos de acceso.

METODOS DE CLASE

Un método de clase es un método que no está ligado a un objeto en particular, el cual puede ser invocado sin crear una instancia de objeto.

La utilidad de los métodos de clase es la de facilitar de herramientas de uso general y/o genéricas.

La forma de declarar y de invocar a este tipo de métodos es anteponiendo el nombre de la clase (seguido de un punto) al nombre del método.

class MiClase
   def initialize(propiedad)
     @propiedad=propiedad
   end

   # Metodo de instancia
   def calcular_cubo
     @propiedad * @propiedad
   end

   # Metodo de clase
   def MiClase.sumar(valor1, valor2)
     valor1 + valor2
   end
end

# El metodo de clase se puede invocar sin instanciar objetos
puts "La suma de 2 + 5 es #{MiClase.sumar(2, 5)}"

# El metodo de instancia requiere un objeto
obj = MiClase.new(3)
puts "El cubo de 3 es #{obj.calcular_cubo}"



TE PUEDE INTERESAR

viernes, 25 de abril de 2014

Clases y objetos en Ruby (III)

En los anteriores artículos sobre Clases y objetos en Ruby, hemos abordado los fundamentos acerca de la creación de clases, el acceso a las propiedades de un objeto y la visibilidad de las variables. En este artículo aprenderemos a aprovechar la herencia de clases y el control de acceso o visibilidad de los métodos de una clase.

HERENCIA

La herencia es una funcionalidad del paradigma de la programación orientada a objetos. Esta funcionalidad permite reutilizar el código, con el consiguiente ahorro de tiempos, esfuerzos y costes.

Gracias a la herencia podemos crear nuevas clases que hereden propiedades y métodos de otras clases. La clase de la cual se hereda se suele denominar clase padre o superclase, y la clase que hereda se suele denominar clase hija, clase especializada o subclase.

Para entenderlo mejor, aprovecharemos el ejemplo de la clase Humano. Esta clase es muy genérica y contiene las propiedades y métodos comunes a todo ser humano. Podríamos querer especializar esta clase en una nueva clase llamada Profesional, con la cual vamos a tratar un ser humano trabajador. Esta nueva clase heredará todas las propiedades de Humano, añadiendo nuevas propiedades y métodos especializados de un trabajador.

Para que una clase herede de otra ha de utilizarse la siguiente sintaxis:

class subclase < superclase
...
end

La clase Profesional quedaría así:

load "Humano.rb"

class Profesional < Humano

   def initialize(nombre, apellidos, edad, altura, peso, sexo, profesion, especialidad, experiencia)
     super(nombre, apellidos, edad, altura, peso, sexo)
     @profesion = profesion
     @especialidad = especialidad
     @experiencia = experiencia
   end

   def to_s
     super + " > Profesion: #{@profesion} - Especialidad: #{@especialidad} - Experiencia: #{@experiencia} años"
   end
end

un_profesor = Profesional.new("Andres", "Garcia Tomillar", 56, 1.82, 97.5, "hombre", "Profesor", "Literatura", 27)
puts un_profesor.to_s
un_profesor.edad = 57
puts un_profesor.to_s

La primera línea:

load "Humano.rb"

Permite cargar la clase Humano para poder ser utilizada por la subclase Profesional. Esto se realiza en el caso de que la superclase resida en otro archivo distinto al de la subclase.

En la declaración de la clase estamos indicando que la clase Profesional es una subclase de la superclase Humano.

Después, inicializamos las propiedades de esta nueva clase, por lo que hay que inicializar las propiedades de Humano (superclase) y de la propia clase Profesional (subclase).

El método initialize tiene los mismos parámetros que el constructor de la superclase, más sus parámetros propios o especializados.

La sentencia super invoca al mismo método de la superclase. En el caso del método initialize, invoca al método initialize de la clase Humano, pasando los parámetros correspondientes. En el caso del método to_s, la llamada al método retorna la cadena devuelta por método to_s de la superclase, y le concatena otra cadena con el resultado de las propiedades de la subclase, y la nueva cadena es retornada.

En la línea

un_profesor.edad = 57

se invoca al método heredado de la superclase, asignando el valor a esta propiedad heredada.

El resultado final será el siguiente:

Andres Garcia Tomillar, hombre, de 56 años, de 97.5 kg y 1.82 m > Profesion: Profesor - Especialidad: Literatura - Experiencia: 27 años
Andres Garcia Tomillar, hombre, de 57 años, de 97.5 kg y 1.82 m > Profesion: Profesor - Especialidad: Literatura - Experiencia: 27 años


VISIBILIDAD DE LOS METODOS

Al tratar una compleja aplicación con objetos, es necesario tener un control de acceso a los métodos. En artículos anteriores aprendimos la visibilidad el control de acceso a las propiedades. Ahora le toca el turno a los métodos.

ACCESO PUBLICO

Los métodos, por defecto, son declarados con una visibilidad pública. Es decir, que cualquiera puede acceder a los mismos.

La única excepción sería el método initialize, el cual tiene siempre un acceso privado.

ACCESO PROTEGIDO

Un método de acceso protegido puede ser invocado únicamente por la clase que lo define y sus subclases. Puede decirse que es un método estrictamente “familiar”, porque permanece exclusivamente dentro de su familia.

ACCESO PRIVADO

Un método de acceso privado es accesible únicamente por la clase que lo define y sus subclases directas (primer nivel de jerarquía), dentro de ese mismo objeto.

Un método privado sólo puede ser invocado dentro del contexto del objeto de llamada. No se puede acceder directamente a los métodos privados de otro objeto.

DEFINICION DE LA VISIBILIDAD

Para definir si un método tiene una determinada visibilidad, es necesario escribir el método dentro de un bloque de código mediante la palabra clave public (opcional), protected o private.

La estructura quedaría de la siguiente manera:

class Clase

   # bloque para metodos publicos
   # (la palabra public es opcional)
public

   def metodos_publicos
     ...
   end

   # bloque para metodos protegidos
protected

   def metodos_protegidos
     ...
   end

   # bloque para metodos privados
private

   def metodos_privados
     ...
   end

end

Otra forma más simple de organizar y definir el control de acceso a los métodos, es definiendo todos los métodos de forma normal, y, al final, definir qué control de acceso poseen los distintos métodos. La estructura quedaría de la siguiente manera:

class Clase

   def metodo1
     ...
   end

   def metodo2
     ...
   end

   def metodo3
     ...
   end

   def metodo4
     ...
   end

   public :metodo1, metodo3
   protected :metodo2
   private :metodo4
end

Esta estructura es una simplificación de la estructura anterior. El precompilador de Ruby organizará automáticamente el acceso como se ha visto en la primera estructura.

EJEMPLO DE CONTROL DE ACCESO

El siguiente ejemplo ilustra el funcionamiento del control de acceso a los métodos.

class Clase1

   def initialize
     @var = 1
   end

   def var
     @var
   end

   def incrementar
     @var = @var + 1
   end

   def incrementar_por(incremento)
     @var = var + incremento
   end

   def decrementar
     @var = @var - 1
   end

   public :var, :incrementar
   protected :incrementar_por
   private :decrementar

end

class Clase2 < Clase1

   def initialize
     super
     @var = var
   end

   def procesar
     @var = incrementar
     @var = incrementar_por(10)
     @var = decrementar
     @var #retorna el resultado
   end
end

class Clase3 < Clase2

   def initialize
     @var = 10
     @objeto = Clase2.new
   end

   # Este metodo accede al metodo heredado de
   # la instancia de Clase2
   def incrementar
     @objeto.incrementar
   end

   # Este metodo accede al metodo heredado de
   # la instancia de Clase2
   def incrementar_por(incremento)
     @objeto.incrementar_por(incremento)
   end

   # Este metodo accede al metodo heredado de
   # la instancia de Clase2
   # Este metodo dara un error, pues se intenta
   # acceder a un metodo privado de Clase1
   # directamente a traves de un objeto de Clase2
  # def decrementar
    # @objeto.decrementar
  # end

   # Este metodo accede a los metodos heredados
   # directamente de Clase1
   def procesar
     @var = incrementar
     @var = incrementar_por(10)
     @var = decrementar
     @var #retorna el resultado
   end
end

ejemplo = Clase2.new
puts ejemplo.procesar # Retorna 11
puts ejemplo.var # Acceso a metodo publico
# ejemplo.incrementar_por(3) # Dara un error de acceso
# ejemplo.decrementar # Dara un error de acceso

ejemplo2 = Clase3.new
puts ejemplo2.incrementar # Retorna 2
puts ejemplo2.incrementar_por(5) # Retorna 7
# puts ejemplo2.decrementar # Dara un error de acceso
puts ejemplo2.procesar #Retorna 17

Se han creado tres clases. Clase1 es la superclase. Clase2 es subclase directa de Clase1. Clase3 es subclase directa de Clase2, pero de segundo nivel con respecto a Clase1.

En Clase1 se han definido varios métodos con distinto control de acceso.

En la ejecución se crea una instancia de Clase2. Dentro de esta clase hay un método procesar, el cual accede, desde dentro de la clase, a todos los métodos heredados de Clase1, pues tiene visibilidad a sus métodos públicos, protegidos y privados.

Si intentamos acceder directamente a los métodos heredados de Clase1, a través de una instancia de Clase2, no tendremos acceso a los métodos protegidos ni privados. Éstos son sólo accesibles desde el interior de la propia Clase2.

La Clase3 hereda directamente de Clase2. Además, define una propiedad @obj que es una también una instancia de Clase2, a fin de poder comprobar el control de acceso mediante herencia y mediante instancia a esta clase. En el caso de instancia, no tendremos acceso al método privado heredado de Clase1.




TE PUEDE INTERESAR

jueves, 24 de abril de 2014

Clases y objetos en Ruby (II)

En el primer artículo sobre Clases y Objetos en Ruby, hablamos sobre las propiedades de los objetos y cómo se accedía a dichas propiedades para consultar o modificar sus valores. A modo de recordatorio, comentábamos que las propiedades de un objeto estaban gestionadas por unas variables con visibilidad de instancia, es decir que sólo podían ser accedidas desde la propia clase, y no directamente desde fuera de ella. Para acceder a estas variables había que crear e invocar a ciertos métodos para acceso de lectura (consulta) o de escritura (modificación).

En este artículo simplificaremos aún más la forma de acceder a las propiedades, y veremos en detalle la visibilidad de las variables en una clase.

SIMPLIFICANDO EL ACCESO A LAS PROPIEDADES

Recordemos el código de nuestra clase Humano:

class Humano

   def initialize(nombre, apellidos, edad, altura, peso, sexo)
     @nombre = nombre
     @apellidos = apellidos
     @edad = edad
     @altura = altura
     @peso = peso
     @sexo = sexo
   end

   def to_s
     "#{@nombre} #{@apellidos}, #{@sexo}, de #{@edad} años, de #{@peso} kg y #{@altura} m"
   end

   def nombre
     @nombre
   end

   def apellidos
     @apellidos
   end

   def edad
     @edad
   end

   def altura
     @altura
   end

   def peso
     @peso
   end

   def sexo
     @sexo
   end

   def nombre=(nombre)
     @nombre = nombre
   end

   def apellidos=(apellidos)
     @apellidos = apellidos
   end

   def edad=(edad)
     @edad = edad
   end

   def altura=(altura)
     @altura = altura
   end

   def peso=(peso)
     @peso = peso
   end

   def sexo=(sexo)
     @sexo = sexo
   end

end

un_humano = Humano.new("Adela","Sanchez Gomez", "27", 1.67, 55.7, "mujer")
otro_humano = Humano.new("Javier", "Martin Lopez", "44", 1.74, 80.5, "hombre")
puts "Valor de un_humano: " + un_humano.to_s
puts "Valor de otro_humano: " + otro_humano.to_s
un_humano.peso = 71
un_humano.edad = 32
puts un_humano.nombre + " " + un_humano.apellidos + " tiene #{un_humano.edad} años de edad y #{un_humano.peso} kg de peso"


Para consultar el valor de una propiedad utilizábamos un método que tenía el mismo nombre que la propiedad, retornando el valor de la propiedad, representado por una variable de instancia:

def nombre
   @nombre
end

Ruby permite simplificar toda esta sintaxis, mediante la siguiente abreviatura:

attr_reader :propiedad1, :propiedad2, ...

A la hora de ejecutar la aplicación, el pre-compilador de Ruby generará, automáticamente, los métodos de acceso de lectura correspondientes.

Para modificar el valor de una propiedad utilizábamos un método que tenía el mismo nombre que la propiedad más el signo igual, asignando a la propiedad el valor pasado por parámetro:

def nombre=(nombre)
   @nombre = nombre
end

Ruby permite simplificar toda esta sintaxis, mediante la siguiente abreviatura:

attr_writer :propiedad1, :propiedad2, ...

A la hora de ejecutar la aplicación, el pre-compilador de Ruby generará, automáticamente, los métodos de acceso de escritura correspondientes.

Así pues, el código final de la aplicacion se reduciría drásticamente:

class Humano
   attr_reader :nombre, :apellidos, :edad, :altura, :peso, :sexo
   attr_writer :nombre, :apellidos, :edad, :altura, :peso, :sexo

   def initialize(nombre, apellidos, edad, altura, peso, sexo)
     @nombre = nombre
     @apellidos = apellidos
     @edad = edad
     @altura = altura
     @peso = peso
     @sexo = sexo
   end

   def to_s
     "#{@nombre} #{@apellidos}, #{@sexo}, de #{@edad} años, de #{@peso} kg y #{@altura} m"
   end

end

un_humano = Humano.new("Adela","Sanchez Gomez", "27", 1.67, 55.7, "mujer")
otro_humano = Humano.new("Javier", "Martin Lopez", "44", 1.74, 80.5, "hombre")
puts "Valor de un_humano: " + un_humano.to_s
puts "Valor de otro_humano: " + otro_humano.to_s
un_humano.peso = 71
un_humano.edad = 32
puts un_humano.nombre + " " + un_humano.apellidos + " tiene #{un_humano.edad} años de edad y #{un_humano.peso} kg de peso"


VISIBILIDAD DE LAS VARIABLES

VARIABLES DE METODO

Las variables definidas en un método, ya sea como parámetro o como parte del cuerpo del propio método, solamente tienen visibilidad dentro del propio método. Es decir, se crean en el método y se destruyen cuando termina la ejecución del método.

def metodo(nombre)
   mi_nombre = nombre
end

Las variables de método tienen su propia instancia en memoria, por lo que, aunque exista una variable de visibilidad superior con idéntico nombre, éstas se asumen como diferentes:

def metodo(nombre)
   @nombre = nombre
end

En este caso, se asigna a la variable de instancia @nombre el valor de la variable de método nombre pasada por parámetro. Cuando termina la ejecución del método, la variable nombre se destruye, pero la variable @nombre sigue vigente con el valor asignado.



VARIABLES DE INSTANCIA

Las variables de instancia son variables con una visibilidad para toda la clase, es decir, que puede ser utilizada por cualquier método de la misma mientras el objeto instanciado esté vivo. Estas variables son privadas a la clase, y no pueden ser accedidas fuera de ella, a no ser que se utilicen métodos que accedan de forma explícita a los mismos.

Por ejemplo:

class Clase
   def initialize
     @var=12
   end
end

miClase = Clase.new()
puts "Valor: #{miClase.var}"

Esto generará el siguiente error:

Clase.rb:24:in '<main>': undefined method 'var' for #<Clase:0x0000000318de38 @var=12> (NoMethodError)

Tampoco permitirá acceder mediante la siguiente expresión:

puts "Valor: #{miClase.@var}"

Generará el siguiente error:

Clase.rb:24: syntax error, unexpected tIVAR, expecting '('puts "Valor: #{miClase.@var}"

Ello se debe a que al escribir el nombre del objeto y un punto, lo siguiente que espera es un método, no una variable.

Como vimos en el artículo anterior, el acceso de lectura y escritura se realizará mediante dos métodos que tienen el mismo nombre que la propiedad:

class Clase
   def initialize
     @var=12
   end

   # Metodo de consulta a propiedad
   def var
     @var
   end

   # Metodo de asignacion a propiedad
   def var=(var)
     @var=var
   end
end

miClase = Clase.new()
puts "Valor inicial: #{miClase.var}"
# Llama al metodo de asignacion a propiedad
miClase.var = 24
# Llama al metodo de consulta a propiedad
puts "Valor cambiado: #{miClase.var}"

El resultado es el siguiente:

Valor inicial: 12
Valor cambiado: 24

Podemos utilizar otros métodos para acceder a las variables de instancia de otras maneras:

class Clase
   def initialize
     @var=12
   end

   def incrementar
     @var = @var+1
   end

   def incrementar_por(incremento)
     # incremento es variable de metodo
     @var = @var+incremento
   end

   # Metodo de consulta a propiedad
   def var
     @var
   end

   # Metodo de asignacion a propiedad
   def var=(var)
     # Asignacion de variable de metodo a variable de instancia
     @var=var
   end
end

miClase = Clase.new()
puts "Valor inicial: #{miClase.var}"
# Llama al metodo de asignacion a propiedad
miClase.var = 24
# Llama al metodo de consulta a propiedad
puts "Valor cambiado: #{miClase.var}"
# Llama al metodo incrementar dos veces
miClase.incrementar
miClase.incrementar
puts "Valor incrementado: #{miClase.var}"
# Llama al metodo incrementar_por
# incremento de 10
miClase.incrementar_por(10)
puts "Valor incrementado por 10: #{miClase.var}"

El método incrementar suma 1 al valor actual de la variable de instancia.

El método incrementar_por suma el valor pasado por parámetro al valor actual de la variable de instancia.

El resultado será el siguiente

Valor inicial: 12
Valor cambiado: 24
Valor incrementado: 26
Valor incrementado por 10: 36



TE PUEDE INTERESAR

Clases y objetos en Ruby (I)

Este es el primero de una serie de artículos que revisa en profundidad el paradigma de la programación orientada a objetos mediante Ruby. Estos artículos no pretenden ser una clase magistral de este paradigma, pero sus ejemplos ayudan a entender claramente tanto sus principios como su aplicación en Ruby.

En este primer artículos aprenderemos conceptos básicos, tales como clase, objeto, propiedad y método. También aprenderemos cómo podemos consultar y modificar el valor de una propiedad.

INTRODUCCION

En un lenguaje de programación orientado a objetos, toma como concepto primordial el hecho de que todo cuanto existe se interpreta y se ve como un objeto, el cual puede tener unas propiedades o atributos, así como también unos métodos o acciones.

Todo comienza por una clase, que es una definición genérica, un molde o una abstracción de un tipo de objeto. A partir de la clase se generarán instancias u objetos, que son las entidades físicas de la clase.

EJEMPLO DE CLASE Y OBJETO

Imaginemos a un ser humano. La definición genérica de un ser humano puede tener una serie de propiedades comunes, como un nombre, unos apellidos, un sexo, una edad, una altura y un peso.

Un ser humano puede desempeñar diferentes acciones, tales como respirar, mirar, escuchar, andar, nadar, etc.

Yo, tú, él, ella, aquel, aquella... somos objetos o entidades físicas de un ser humano. Como entidades físicas, somos realidades y no abstracciones. Tenemos las propiedades comunes de un ser humano, pero los valores de nuestras propiedades son únicos e inherentes a cada uno.

Para llevar a cabo este ejemplo, crearemos el siguiente ejemplo en un fichero llamado Humano.rb:

class Humano
   def initialize
     @nombre = "Anonimo"
     @apellidos = ""
     @edad = 33
     @altura = 1.75
     @peso = 73.5
     @sexo = "hombre"
   end

   def to_s
     "#{@nombre} #{@apellidos}, #{@sexo}, de #{@edad} años, de #{@peso} kg y #{@altura} m"
   end
end

un_humano = Humano.new()
puts un_humano.to_s

Una clase en Ruby comienza con la declaración class, seguida del nombre de la clase. Al ser una definición genérica, su nombre empieza con mayúsculas.

Esta clase Humano tiene dos métodos o acciones: initialize y to_s

El método initialize es un método especial común a todas las clases. Es un método constructor, es decir, que cuando creemos una instancia o un objeto de esta clase, éste se invocará automáticamente en primer lugar para inicializar el objeto. Este método se suele utilizar para inicializar los valores de las propiedades del objeto y/o lanzar algún método de arranque. En este ejemplo, define seis variables de instancia, las cuales comienzan por el símbolo @, y representan cada una de las propiedades o atributos. Este tipo de variables sólo tienen visibilidad dentro del objeto, asegurando así la seguridad de los datos.

El método to_s es el símil del método toString de otros lenguajes de programación. Este método se utiliza para que nos devuelva una cadena de texto, que suele ser la información más relevante del objeto. En nuestro caso, retornará un texto con los valores de cada una de las propiedades del objeto. Este método es opcional.

Fuera de la definición de la clase, se han introducido dos líneas que se ejecutarán al lanzar este programa desde el intérprete de Ruby.

La primera línea crea una variable a la que se le asigna una nueva instancia de objeto. Con el método new, Ruby crea una nueva instancia de la clase Humano.

La segunda línea visualiza en pantalla la cadena retornada por el método to_s

Para ejecutar esta aplicación, ejecutaremos la siguiente línea desde la consola de comandos del sistema operativo:

ruby Humano.rb
Anonimo , hombre, de 33 años, de 73.5 kg y 1.75 m


INICIALIZANDO PROPIEDADES

En el ejemplo anterior estamos limitados, pues podemos crear múltiples objetos o instancias, pero todos tendrán los mismos valores en sus propiedades. Es decir, crearemos clones de humanos, donde, en su esencia, son objetos distintos, pero que en su apariencia son idénticos.

Para resolver esto, modificaremos el método constructor, permitiendo definir estas propiedades al mismo tiempo que se crea el objeto:

class Humano

   def initialize(nombre, apellidos, edad, altura, peso, sexo)
     @nombre = nombre
     @apellidos = apellidos
     @edad = edad
     @altura = altura
     @peso = peso
     @sexo = sexo
   end

   def to_s
     "#{@nombre} #{@apellidos}, #{@sexo}, de #{@edad} años, de #{@peso} kg y #{@altura} m"
   end

end

un_humano = Humano.new("Adela","Sanchez Gomez", "27", 1.67, 55.7, "mujer")
otro_humano = Humano.new("Javier", "Martin Lopez", "44", 1.74, 80.5, "hombre")
puts "Valor de un_humano: " + un_humano.to_s
puts "Valor de otro_humano: " + otro_humano.to_s

El método constructor tiene una lista de parámetros, los cuales son variables de ámbito del método (fuera de ella no tienen sentido). Cada una de estas variables recogerá un valor, y dicho valor se asignará, dentro del método, a una variable de ámbito de instancia. Es importante entender que una variable de método sólo tiene visibilidad dentro de un método, y que una variable de instancia tiene visibilidad en toda la clase. Aunque las variables tengan el mismo nombre, su ámbito y entidad son diferentes. Así:

@nombre = nombre

Asigna a la variable de instancia @nombre, el valor de la variable de método nombre.

El resultado será que, cada vez que se crea un objeto, se inicializará dicho objeto con los valores que pasemos como parámetros en el método new

La aplicación arrancará en la primera línea inmediatamente después de la definición de la clase. Se crearán dos objetos (un_humano y otro_humano), cada uno con unas propiedades o atributos concretos. A continuación, se visualizará los valores de dichas propiedades.

Valor de un_humano: Adela Sanchez Gomez, mujer, de 27 años, de 55.7 kg y 1.67 m
Valor de otro_humano: Javier Martin Lopez, hombre, de 44 años, de 80.5 kg y 1.74 m


ACCEDIENDO AL VALOR DE UNA PROPIEDAD

El ejemplo ha ido mejorando, pero tiene el inconveniente de que nos muestra todos los valores en el orden y el formato que el método to_s ha definido. Si queremos acceder libremente a una determinada propiedad, para cualquier propósito, hemos de definir métodos específicos dentro de la clase, con el mismo nombre que la propiedad:

def nombre
   @nombre
end

def apellidos
   @apellidos
end

def edad
   @edad
end

def altura
   @altura
end

def peso
   @peso
end

def sexo
   @sexo
end

Cada uno de los métodos retorna el valor de la propiedad que tiene su mismo nombre.

De esta manera, podemos consultar el valor de cada una de las propiedades del objeto de la siguiente manera:

nombre_objeto.nombre_propiedad

Como en la siguiente línea:

puts un_humano.nombre + " " + un_humano.apellidos + " tiene " + un_humano.edad + " años de edad"
Adela Sanchez Gomez tiene 27 años de edad


CAMBIANDO EL VALOR DE UNA PROPIEDAD

Nuestro humano va mejorando. Podemos conocer el valor de cada una de sus propiedades en cualquier momento. Sin embargo, un objeto no tiene por qué ser estático de por vida, si no que puede cambiar el valor de sus propiedades en cualquier momento. No hemos de matar a nuestro ser humano para crear un clon con los nuevos valores de sus propiedades.

La propiedad más proclive a cambiar sería su edad, su peso o su altura. Pero también es posible que quiera cambiar su nombre, sus apellidos y (¿por qué no?) su sexo.

La forma de poder asignar valores a una propiedad concreta es definiendo un método que tenga el mismo nombre de la variable más el signo = (igual), seguido de un parámetro que capture el valor y se lo asigne a la propiedad:

def nombre=(nombre)
   @nombre = nombre
end

def apellidos=(apellidos)
   @apellidos = apellidos
end

def edad=(edad)
   @edad = edad
end

def altura=(altura)
   @altura = altura
end

def peso=(peso)
   @peso = peso
end

def sexo=(sexo)
   @sexo = sexo
end

Cada uno de los métodos asigna a la propiedad con su mismo nombre, el valor pasado como parámetro.

De esta manera, podemos asignar el valor a cada una de las propiedades de la siguiente manera:

nombre_objeto.nombre_propiedad = nuevo valor

Como en las siguientes líneas:

un_humano.peso = 71
un_humano.edad = 32

Aquí podemos ver el resultado:

puts un_humano.nombre + " " + un_humano.apellidos + " tiene #{un_humano.edad} años de edad y #{un_humano.peso} kg de peso"
Adela Sanchez Gomez tiene 32 años de edad y 71 kg de peso


ENTENDIENDO EL ACCESO A LAS PROPIEDADES

En Ruby, las propiedades de un objeto son exclusivamente variables de instancia. Su visibilidad es privada y se accede estrictamente desde la propia clase. Esto asegura el encapsulamiento de éstas, así como también la seguridad de los datos.

En otros lenguajes de programación, resulta muy cómodo utilizar definir una clase de la siguiente manera:

/tr>
public class MiClase {
   public valor1 as Integer;
   public valor2 as String;
   ...
}

e instanciar la clase en objetos con acceso público a sus propiedades:

Set miObjeto As new MiClase;
miObjeto.valor1=1;
miObjeto.valor2="Valor"

Ruby contempla esta forma de gestionar los datos, gracias a los hashes o diccionarios, con mayor funcionalidad si cabe.

El problema de utilizar las clases de esta manera es la seguridad de la información, y el uso incontrolado o indebido por otras clases de una aplicación compleja. Para evitar ésto, las propiedades se definen como privadas a la clase (variables de instancia). De esta manera, su acceso está controlado de forma exclusiva por la propia clase, y para poder consultar o modificar el valor de una determinada propiedad, es necesario el uso de un método específico.

En el caso de Ruby, el uso de estos métodos ofrece una sintáxis muy similar a como si accediéramos de forma pública, lo que facilita mucho su semántica. Sin embargo, podemos hacer uso de una técnica llamada getters y setters, tal y como se realiza en otros lenguajes de programación.

Esta técnica consiste en definir un método get (obtener) y un método set (establecer) para el acceso a la propiedad. Por ejemplo, para acceder a la propiedad nombre, se utilizarían estos dos métodos:

def getNombre()
   @nombre
end

def setNombre(nombre)
   @nombre = nombre
end

A la hora de utilizar el objeto, lo realizaríamos de la siguiente manera:

objeto.setNombre(“Felipe”)
mi_nombre = objeto.getNombre()

El resultado es el mismo a como hemos visto anteriormente, aunque el nombre del método no es el mismo que el de la propiedad. La técnica vista anteriormente es más sencilla e intuitiva.




TE PUEDE INTERESAR

miércoles, 4 de diciembre de 2013

Ya disponible Linux Mint 16 Petra

Linux Mint 16 Petra acaba de salir del horno, con novedades interesantes. Esta popular distribución ocupa merecidamente el primer lugar de la lista Distrowatch, gracias a su cuidado diseño, a los detalles y a la buena respuesta que tiene hacia sus usuarios.


jueves, 21 de noviembre de 2013

martes, 12 de noviembre de 2013

Corazón de Linux, belleza de Mac

MacOS es el sistema operativo más admirado por la mayor parte de usuarios, debido a su diseño, su belleza y su simplicidad. Y es que cuando Apple abandonó su exclusividad total y construyó algo nuevo sobre lo que realmente funciona, reinventó la informática que conocemos. Recordemos que pasó de construir ordenadores con arquitectura RISC y con microprocesadores Motorola, a utilizar arquitectura de PC con microprocesarores Intel, y que pasó de un sistema operativo único, a crearlo desde una base con BSD. Y la solución fue, simplemente, genial y buena.

Linux ha prosperado muchísimo en cuanto a sistemas operativos dirigidos a usuarios normales. Las interfaces gráficas y los escritorios han aprendido y se han adaptado a los tiempos. Por ello, desde CommandCat, queremos presentaros dos distribuciones que intentan emular al sistema operativo de la manzana. Pero no os confiéis. No son simples clones. Son distribuciones con una personalidad y unas características propias, y con esencia de Linux.

Pear OS

Desde Francia nos llega esta distribución elegante y con clase, basada en Ubuntu. Es increíblemente sencilla de usar y tiene una experiencia completamente multimedia. Incluye LibreOffice y un repositorio de más de 3.000 aplicaciones. Por si esto fuera poco, provee de una sistema de almacenamiento en la nube, llamado Pear Cloud, para compartir y sincronizar tu música, fotos y archivos.

Hay disponibles versiones para 32 y 64 bits. Los requerimientos hardware no son muy altos: microprocesador a 700Mhz, 512MB RAM, 8 GB de disco duro y VGA de 1024x768.

Están trabajando en una versión para Tablets, que será posible si hay donativos suficientes para soportar el proyecto.

Enlace: Página Oficial de Pear OS

Elementary OS


Esta distribución está popularizándose desde hace un par de años, generando también apasionadas discusiones. Al igual que Pear OS, Elementary OS es una distribución basada en Ubuntu, con escritorio Gnome, pero con un aspecto Mac bastante evidente.

Luna, su última versión, es un alarde de diseño, pues, aunque esté inspirado en Mac, ha sido realizado desde cero, a fin de mejorar la experiencia del usuario, simplificar las tareas y optimizar los recursos. Esta versión ha costado dos años de trabajo, y ha sido lanzada en Agosto de 2013.

Enlace: Página Oficial de Elementary OS

martes, 15 de octubre de 2013

Un SIMO en crisis

Hoy he visitado el SIMO, la feria internacional de tecnología de España. La última vez que visité el SIMO fue en 2009, cansado de la tendencia de la feria y de la ausencia del espíritu con que se fundó. Ya en 2008, el SIMO se canceló por motivo de la crisis. Pero creo que hay otros motivos más sangrantes sobre la salud de esta feria, que en su día fue un referente y unía a tantos y tantos tecnólogos.

viernes, 28 de junio de 2013

Markdown: enfócate en el texto

Soy bloguero (acepción castellanizada de la palabra blogger). A medida que he ido evolucionando con mis artículos, he sentido la necesidad de trabajar de forma más sencilla y cómoda, minimizando las herramientas y la ergonomía del trabajo.

Voy a explicar en este artículo lo que es “Markdown” (en español, anotar), un lenguaje de marcado ligero para escribir texto con formato, pero sin perder el foco en lo importante: el texto. Markdown nos permite escribir texto plano, en el que, insertando unas marcas sencillas, puedes leer y trabajar de forma focalizada sobre el texto de forma focalizada, pero que finalmente se verá con formato en XHTML.

Por ejemplo, ¿qué te resulta más sencillo para escribir y leer, esto

<strong>Texto en negrita</strong>

o esto otro?

** Texto en negrita **

Sin lugar a dudas, el segundo texto.

Markdown fue creado por John Gruber y Aaron Swartz. En un principio fue implementado por Gruber en el lenguaje de programación Perl, pero después fue extendiéndose a otros lenguajes.

Pero lo realmente importante es que a los blogueros nos permite escribir artículos de forma que nos enfoquemos en el texto, sin perder la concentración y sin distraernos con otros elementos de marcado o de la herramienta, lo que repercute en una mayor productividad y eficiencia. A mí, por ejemplo, me gusta escribir los borradores de mis posts en una herramienta llamada Draft, la cual permite el uso de Markdown. Primero escribo el texto plano, sin marcado. En una revisión posterior realizo el marcado en aquellos puntos que me interesa o necesito. Después vuelvo a revisar todo, pero centrándome especialmente en el texto. Por último, vuelco definitivamente el texto en mi blog.



Para los programadores de páginas Web, resulta muy útil, pues en lugar de escribir tags extensos se escribe un signo. Esto también evita muchos errores y evita también confusión cuando hay mucho texto con formato.

Sintaxis de Markdown

La sintaxis de Markdown es muy sencilla. He aquí algunos ejemplos básicos:

Título de Nivel 1 (H1)
======================

Título de Nivel 2 (H2)
----------------------

# Título de nivel 1 (H1)
## Título de nivel 2 (H2)
### Título de nivel 3 (H3)

*Texto en Cursiva* (em)

**Texto en Negrita** (strong)

Utiliza comilla simple a derecha para escribir código, como `<strong>` o `&nbsp;`

* Elemento 1 en lista no ordenada (ol y li)
* Elemento 2 en lista no ordenada (se puede usar con *, + y -)

Párrafo normal

1. Elemento 1 en lista enumerada (ul y li)
2. Elemento 2 en lista enumerada

> Ejemplo de Cita (blockquote)

Enlace a [este blog](http://rafinguer.blogspot.com "Título del enlace")

![texto alternativo](http://rafaelhernamperez.files.wordpress.com/2013/05/rafa-feliz-ok.jpg "título de la imagen")





Enlaces de interés

Proyecto Markdown | Página oficial sobre Markdown de John Gruber
Sintáxis básica | Sintáxis básica de Markdown
Sintáxis completa | Guía completa de sintaxis de Markdown
Infografía | Infografía de la sintáxis de Markdown (PDF)
Dingus | Conversor online de Markdown a XHTML y vista previa
Wikipedia | Artículo sobre Markdown en la Wikipedia


lunes, 24 de junio de 2013

El escritorio productivo

Escritorio Minimalista

La productividad ha de estar en consonancia con el entorno y las herramientas de trabajo. En la era del conocimiento, el escritorio juega un papel determinante en la productividad del trabajador.