Enviar Contenido a Imageshack con PHP

Todos Conocemos muy bien el servicio de alojamiento de imagenes Imageshack pero y si les digo que por medio de php podemos enviar contenido a los servidores.
de Imageshack utilizando funciones simples bueno para eso les explicare el codigo que se tiene que utilizar para realizar el proceso.

Parte 1

<?php

/* 

Esta Funcion permitira saber cual es el mimetype de la imagen que queremos enviar a Imageshack
enviandole como parametro el nombre de el archivo.

*/

function MimeType($filename){
    $ext = pathinfo($filename);
    $ext = $ext['extension'];
    
    switch($ext){
        case "bmp": return "image/bmp"; break;
        case "gif": return "image/gif"; break;
        case "jpe": return "image/jpeg"; break;
        case "jpeg": return "image/jpeg"; break;
        case "jpg": return "image/jpeg"; break;
        case "png": return "image/png"; break;
        case "swf": return "application/x-shockwave-flash"; break;
        case "tif": return "image/tiff"; break;
        case "tiff": return "image/tiff"; break;
        default: return ""; break;
    }
}



/* A continuacion la Funcion Principal de el script es la que se utiliza para realizar el envio de la informacion */


function imageshackUpload($filename){

    $sock = @fsockopen("www.imageshack.us", 80, $errno, $errstr, 30);  // Conectamos a Imageshack via fsockopen 
      

    // Leemos el archivo a enviar y lo armamos como un binario

    $handle = fopen($filename, "r");
    $binarydata = fread($handle, filesize($filename));
    fclose($handle);
    
    
    // Identificamos el Mimetype de el archivo

    $mimetype = MimeType($filename); 



    // Armamos el contenido de la peticion 
       
    $AaB03x  = "--AaB03xrn";
    $AaB03x .="content-disposition: form-data; name="uploadtype"rnrn";
    $AaB03x .= "onrn";
    $AaB03x .= "--AaB03xrn";
    $AaB03x .= "content-disposition: form-data; name="fileupload"; filename="".basename($filename).""rn";
    $AaB03x .= "Content-Type: $mimetypern";
    $AaB03x .= "Content-Transfer-Encoding: binaryrnrn";
    $AaB03x .= "$binarydatarn";
    $AaB03x .= "--AaB03x--rn";

    // Realizamos el Construccion de las cabeceras a enviar a Imageshack

    $header  = "POST / HTTP/1.1rn";
    $header .= "Host: www.imageshack.usrn";
    $header .= "Content-type: multipart/form-data, boundary=AaB03xrn";
    $header .= "Content-Length: ".strlen($AaB03x)."rnrn";
    $header .= $AaB03x;
    


    fwrite($sock, $header); // Creamos el Archivo en ImagesHack
   
    // Procedemos a Escribir el contenido 

    while (!feof($sock)){
        $response .= fgets($sock, 128);
    }

   // Cerramos la conexion con Imageshack 
   fclose($sock);
    

   // Finalmente Creamos el enlace que necesitaremos para poder incrustar nuestra imagen en donde queramos 

    preg_match_all("#<input type="text" onclick="highlight(this)" style="width: 500px" size="70" value="[URL=http://imageshack.us][IMG](.*)[/IMG][/URL]"/>#", $response, $matches);
    return $matches[1][0];
}

?>

en esta parte esta el codigo referente al formulario en html que se va a usar para que trabaje con el script en php

parte 2 formulario

<html>
<?php if(!isset($_POST['sub'])){ ?>
    <form method="post" enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Enter path to file: <input type="text" name="test" /><br />
    <input type="submit" name="sub" />
    </form>     
<?php } else {
    echo imageshackUpload($_POST['test']);
}?>
</html>

Este Codigo no ha sido testiado, para poder usarlo tu servidor debera soportar fsockopen para la conexion

Posted on

como hacer una barra superior en html

introducción

Las nuevas tendencias web respecto a versiones móviles nos dicen que es muy cómodo tener una barra superior en HTML fija, de esta manera tenemos muchísima pantalla para cargar nuestro contenido y ocupamos un mínimo para menús.

Evidentemente todo esto también es exportable a cabecera fija en HTML y css, menú fijo superior en HTML y css o como lo quieras llamar.

Crear una barra superior fija con CSS y HMTL es realmente sencillo solo necesita 3 líneas de código css, así de simple el resto es para decorar como se puede ver en esta demo y puedes descargar desde este link

Preparando el código css para crear la barra superior

.barra-superior {
  width: 100%; /* esto hace que la barra ocupe el 100% del espacio*/
  position: fixed;/*esto hace que la barra quede fija donde está situada*/
  z-index: 10; /*la magia del código, hace que quede por encima del resto de elementos*/
}
/*La siguiente clase solo es para dar formato a la barra*/
/*Se le aplicara una ligera transparencia*/
/*Para dar el efecto que el texto pasa por debajo*/
.formato-barra-superior{
	 background: rgba(0,0,0,0.9); 
}

Codigo HTML para conseguir la barra superior fija

El código HTML para conseguir la barra superior fija es muy simple solo hay que tener en cuenta que hay que sacarlo del resto del flujo HTML

  <section class="wrapper barra-superior formato-barra-superior">
		<nav>
			<ul>
				<li><a href="#">opcion 1</a></li>
				<li><a href="#">opcion 2</a></li>
				<li><a href="#">opcion 3</a></li>
				<li><a href="#">opcion 4</a></li>
				<li><a href="#">opcion 5</a></li>
			</ul>
    </nav>
    </section>

Conclusión

Con estos sencillos códigos que se pueden copiar y pegar conseguirás headers y barras superiores fijas que no se moverán de esta manera tu visitante siempre tendrá disponible las herramientas necesarias para navegar cómodamente por tu web

Posted on

Ruby on Rails desde Cero: Instalación & Configuración

Bienvenidos a Git desde cero, esta serie de tutoriales tratará explicar y alejar el miedo que algunos de nosotros sentimos cuando comenzamos a utilizar un controlador de versiones por primera vez.

¿Qué es Git?

Git en pocas palabras es un controlador de versiones distribuido. Para ampliar este significado debemos responder primero la siguiente pregunta. ¿Qué es un controlador de versiones? Un controlador de versiones es un sistema que registra los cambios en un archivo o conjunto de archivos a través del tiempo para que se puedan recuperar versiones específicas de los mismos más adelante.

Ahora, ¿Por qué es distribuido? Cuando los usuarios descargan la última versión de los archivos no solo están descargando los archivos; sino también realizando una copia fiel y exacta (copia de seguridad) del repositorio (carpeta donde se alojan estos archivos) de esta manera si dicho repositorio muere, cualquiera de los usuarios que descargaron estos archivos pueden restaurar el estado de ese del mismo haciendo uso de su copia de seguridad. Por otra parte esto permite que se puedan tener varios repositorios remotos para poder trabajar y colaborar con diferentes grupos de personas al mismo tiempo en un mismo proyecto, cosa que no es posible con los sistemas centralizados.

Características que destacan de Git como control de versiones:

Fotografías rápidas, NO diferencias – A la hora de guardar la información de varios archivos, Git toma una fotografía rápida del estado de los mismos y guarda las referencias de esta fotografía. Luego para ser eficiente revisa los archivos que no fueron modificados y cambia las referencias de los mismos a su versión anterior.
Casi todas las operaciones son locales – Sí ya descargaste un repositorio no es necesario estar conectado a una red o conexión a internet para trabajar sobre archivos, todo lo necesario se encuentra en tu computadora.
Integridad de la data – Git antes de guardar la fotografía del estado de un archivo realiza un checksum de la data. De esta manera es imposible cambiar el contenido de cualquier archivo sin que Git lo note.
Git generalmente solo añade data – Al trabajar en cualquier archivo y almacenar los cambios se está agregando data a la base de datos de Git. Esto nos da la seguridad de que si estos cambios fueron persistidos es muy difícil que se pierdan.
Trabaja con tres estados – Lo más importante para recordar de Git son los tres(3) estados en que los archivos residen: consolidada (committed), modificados y en escenario (stage). Modificado, se han detectado cambios en el archivo pero no se han consolidado. Consolidado, el archivo y su data han sido guardados satisfactoriamente en la base de datos de Git. En escenario se han marcado las modificaciones de un archivo y su próximo paso será consolidar la data.

Instalación

Ya que conocemos un poco sobre Git, es hora de instalarlo. Dependiendo del Sistema Operativo en que nos encontremos utilizaremos la instalación apropiada.

Mac OS

Método Recomendado: Para realizar la instalación en este Sistema Operativo es recomendable tener instalado Homebrew. Haciendo uso del Terminal.app y de hombrew, escribimos el siguiente comando:

$ brew install git

Si el terminal no es de tú preferencia puede hacer uso de un cliente de interfaz gráfica para realizar la instalación de Git. El cliente de Github nos facilita esta tarea.

Linux

Si nos encontramos en distribuciones como Fedora, podemos hacer uso del manejador de paquetes de dicha distribución y mediante el siguiente comando instalaremos Git:

$ yum install git-core

Si nos encontramos en distribuciones basadas en Debian, tal como Ubuntu, utilizamos el siguiente comando:

$ apt-get install git

Windows

Si nos encontramos el Windows la manera más sencilla de realizar la instalación es descargar el Instalador y seguir los pasos.

Configuración

Ya que tenemos Git instalado, es tiempo de configurarlo. Para esto, tenemos que abrir el Terminal.
Configuración del nombre de usuario

Lo primero que de debe hacer es decirle a Git cual será nombre de la persona que hará uso de él:

$ git config --global user.name "Pedro Perez"

Configuración del email

Git hace uso del email del usuario cuando consolida la data, por esta razón necesitamos configurarlo:

$ git config --global user.email "pedroperez@ejemplo.com"

Podemos revisar que estén bien escritos haciendo uso del siguiente comando:

$ git config --list
user.name=Pedro Perez
user.email=pedroperez@ejemplo.com

También debemos conocer que Git guarda esta información dentro del archivo oculto .gitconfig en el Home del usuario. Utilizando el siguiente comando podemos observar la información suministramos durante la configuración:

$ cat ~/.gitconfig
[user]
        name = Pedro Perez
        email = pedroperez@ejemplo.com

Cuenta en Github.com

Previamente explicamos que no es necesario estar conectado a una red o tener conexión a internet para poder hacer uso de Git. Con esto no queremos decir que únicamente haremos uso de esta herramienta manera local, sino más bien queremos que nuestros archivos (código, fotos, etc.…) se encuentren tanto en nuestro computador como en un servidor remoto. Por esta razón se recomienda abrir una cuenta en Github.com de manera gratuita para el alojamiento remoto de nuestros archivos.

Comandos básicos

Tenemos Git instalado y listo para usar, ha llegado el momento de conocer los pasos necesarios para la inicialización de un repositorio, agregar archivos al escenario y consolidarlos.

Inicialización de un repositorio

Un repositorio no es más que una carpeta o conjunto de carpetas que contienen archivos.

Podemos crear una carpeta y luego iniciar el repositorio dentro, utilizando los siguientes comandos:

$ mkdir Ejemplo && cd Ejemplo
$ git init .

Con el comando git init se crea una carpeta oculta llamada .git (se encuentra dentro de la carpeta Ejemplo) y contiene toda la información necesaria para que podamos realizar las versiones (copias de seguridad) de nuestro proyecto. En este punto Git no está llevando el control de ningún archivo.

Agregar archivos al escenario

Con nuestro repositorio listo, queremos llevar el control de nuestro primer archivo. Para esto debemos crearlo dentro de nuestra carpeta Ejemplo y agregarlo al escenario:

$ touch Archivo1.txt # Creamos el archivo vacío
$ echo 'Hola Mundo' >> Archivo1.txt  # Le agregamos texto al archivo
$ git add Archivo1.txt # colocamos el archivo en escenario

Al ejecutar el comando git add Archivo1.txt estamos confirmando (agregando el archivo al escenario) que los cambios que realizamos sobre Archivo1.txt se quieren respaldar la próxima vez que consolidemos la data.

Consolidar la información.

Para consolidar el archivo previamente creado y puesto en escenario debemos utilizar el siguiente comando:

$ git commit -m "Commit Inicial"

nota: La bandera -m indica que se debe consolidar el archivo con un mensaje informativo.

Conclusión

En este capítulo aprendimos los conceptos básicos de Git; tales como instalación en múltiples Sistemas Operativos, configuración desde cero y a persistir información en su base de datos. En los próximo capítulos iremos conociendo más comandos y trataremos de enseñarle al usuario el flujo de trabajo que utilizamos en Codehero cuando hacemos uso de esta herramienta.

Posted on

Crear Carpetas con PHP y FTP

bueno amigos en esta entrada aprenderemos como hacer para crear carpetas mediante las funciones FTP que posee PHP esta ves nos vamos a usar la Conocida funcion MKDIR sino algo mas diferente ideal para trabar con archivos y carpetas en servidores externos al nuestro. ya basta de palabras y miren el codigo.


<?php
function creardir($carpeta){ 
 if (is_dir($carpeta)){
     echo "el Directorio ya existe";
 }
 else
 {
   if($ftp_c = ftp_connect ("sitio.com",21)){ 
    if(ftp_login($ftp_c,"user","pass")){ 
     ftp_chdir($ftp_c, 'barranquillamia.tollfreepage.com/music/');
     ftp_mkdir($ftp_c,$carpeta);
     ftp_chdir($ftp_c,$carpeta); 
     echo "Carpeta actual: ".ftp_pwd($ftp_c); 
    }else{
   echo "Error: En el usuario o contraseña invalida";
  } 
}
else{
   echo "Error: El servidor FTP no responde";
 }
 ftp_close($ftp_c); 
}
?>

lo podremos utilizar de la siguiente forma.

<?php

creardir(nombre de la Carpeta);

?> 

Posted on

Buscador Simple PHP

un buscador simple el cual podras utilizar en tu web para buscar articulos y demas .


<html>
<head>
<title>Buscador simple en PHP</title>
</head>
<body>

<form action="buscar.php" method="post">
Buscar: <input name="palabra">
<input type="submit" name="buscador" value="Buscar">
</form>

<?
if ($_POST['buscador'])
{ 
// Tomamos el valor ingresado
$buscar = $_POST['palabra'];

// Si está vacío, lo informamos, sino realizamos la búsqueda
if(empty($buscar))
{
echo "No se ha ingresado una cadena a buscar";
}else{
// Conexión a la base de datos y seleccion de registros
$con=mysql_connect("localhost","user","pass");
$sql = "SELECT * FROM noticias WHERE noticia like '%$buscar%' ORDER BY id DESC";
mysql_select_db("base_de_datos", $con); 

$result = mysql_query($sql, $con); 

// Tomamos el total de los resultados
$total = mysql_num_rows($result);

// Imprimimos los resultados
if ($row = mysql_fetch_array($result)){ 
echo "Resultados para: <b>$buscar</b>";
do { 
?>


<b><a href="noticia.php?id=<?=$row['id'];?>"><?=$row['titulo'];?></a></b>

<?
} while ($row = mysql_fetch_array($result)); 
echo "

Resultados: $total

";
} else { 
// En caso de no encontrar resultados
echo "No se encontraron resultados para: <b>$buscar</b>"; 
}
}
}
?>
</body>
</html>

Archivo Sql


CREATE TABLE `noticias` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`titulo` VARCHAR( 255 ) NOT NULL ,
`noticia` LONGTEXT NOT NULL
);

Posted on

Curso PHP desde Cero: Namespaces

En este nuevo capítulo de la Serie de PHP desde Cero conoceremos los famosos Namespace. Pero antes de explicarlo en PHP, veamos un ejemplo de la vida real para tener una idea de clara de que trata todo esto.

Imaginemos que trabajamos en una compañía pequeña y hay un empleado de nombre Juan. Cada vez que decimos Juan todos entienden a quien nos referimos, pero de un día para otro la compañía crece en personal y ahora hay dos empleados de nombre Juan. Esto nos crea un problema para hacer referencia a alguno de los dos y aquí es donde entran en juego los apellidos. Uno es Juan Vargas y el otro Juan Perez, lo cual nos permite diferenciarlos sin ningún problema. Esto es lo mismo que sucede con los namespaces en PHP.

Si tenemos un proyecto grande y tenemos varias clases que hemos importado o han hecho diferentes personas puede haber una colisión de nombres, pero esto se resuelve con esta característica de PHP. Anteriormente, y en realidad todavía muchas personas lo resuelve de esta manera, se usaban nombres largos para identificar las clases de manera inequívoca y así evitar las colisiones. Digo anteriormente porque los namespaces se implementaron en PHP desde la version 5.3.
Introducción a los Namespaces

Ahora vamos a ver como funcionan y como se aplican los namespaces en PHP. Primero que nada vamos a ver un ejemplo en donde haya colisión de nombre de clases:

<?php
class Usuario {
    var $nombre;
}

class Usuario{
    var $correo;
    var $clave;
}

?>

Como podemos ver tenemos dos clases Usuario que tiene funcionalidades diferentes(imaginemos que tienen muchos métodos y propiedades), pero al llamarse de la misma manera va a dar error cuando las llamemos porque PHP no sabe cual queremos instanciar. Ahora vamos a ver las mismas clases pero con unos namespace y como se pueden llamar en el mismo código sin crear colisiones.

<?php
namespace usuarioPersona;

class Usuario {
    var $nombre;
}

namespace usuarioSistema;

class Usuario{
    var $correo;
    var $clave;
}

$persona = new \usuarioPersona\Usuario();

$usu_sistema = new \usuarioSistema\Usuario();
?>

Utilizando los namespace se puede ver claramente cuando llamamos a cada una de las clases Usuario.
Sintaxis

Los namespaces se puede declarar, importar y utilizar de varias maneras, las cuales vamos a ver a continuación.

Por defecto todas las clases, funciones y variables están definidas en el entorno global, como ha sido siempre en PHP.

<?php
//para declarar un namespace se utiliza la palabra reservada namespace
//antes del nombre que se le quiera otorgar
//y debe ir al principio del archivo del script
namespace nombreDelNamespace;

// a partir de aquí se escribe todo el código
// que se quiera incluir en este entorno
?>

También se pueden definir subnamespaces para poder tener nuestro código bien organizado y estructurado. Para separar los namespaces se utiliza la barra invertida ( \ ), veamos algunos subnamespaces validos.

Proyecto\BD\MySQL
Proyecto\BD\Mongo
Proyecto\PDF\FilePDF
Proyecto\Librerias\LibreriaGraficas

Usar Namespaces

Ya que sabemos como declarar los namespace ahora tenemos que aprender como llamar clases, funciones o variables que estén en ellos. Vamos a crear una clase y definirla dentro un namespace:

<?php
//carro.php

// la clase Carro y CONSTANTE estarán en el namespace Codehero\Cursos
namespace Codehero\Cursos;

const CONSTANTE = 'Constante de Ejemplo';  

class Carro{

    static function rodar(){
        // código de la función rodar
    }
}

?>

Ahora vamos a importar el archivo de carro.php y utilizar la clase Carro y la constante.

<?php
require_once('carro.php');  

// Como no hay un namespace definido en este archivo
// tenemos que llamar a la constante y la función todo
// el namespace completo (ruta absoluta).
// Siempre que utilicemos un namespace directamente
// hay que empezar con un \ slash invertido
$carro = \Codehero\Cursos\Carro::rodar();
$constante = \Codehero\Cursos\CONSTANTE;

?>

Claro esta que cuando tenemos muchas funciones que debemos llamar de varios namespaces es muy tedioso escribir todas las rutas completas. Para esto existe la opción de importar namespaces con la sentencia use. Se pueden importar todos los que sean necesarios, veamos un ejemplo de como importarlos:

<?php
require_once('carro.php');  
use Codehero\Cursos;

// Ya no es necesario utilizar toda la ruta porque PHP intenta buscar
// en los namespaces que se esten usando, en este caso el global y el
// Codehero\Cursos.
$carro = Carro::rodar();
$constante = CONSTANTE;

?>

Conclusión

En este capítulo hemos tenido nuestro primer contacto con los namespaces, todavía falta mucho que aprender sobre los mismos y se cubrirá en el siguiente capítulo viendo ejemplos reales con un mini proyecto. Hoy en día muchos frameworks hacen uso de los namespaces y es muy importante saberlos usar cuando tengamos proyectos grandes y complejos. Cualquier comentario o duda estaré atento a la sección de comentarios.

Posted on

Curso Ruby desde Cero: Mi primera aplicación en Ruby

Bienvenidos una vez más a Ruby desde cero, curso con el cual aprendemos del lenguaje sin necesidad de tener previo conocimiento en el tema. Hasta este capítulo ya abarcamos todos los puntos del curso, lo que nos hace héroes en Ruby desde Cero.

Para finalizar con este curso desarrollaremos una pequeña aplicación en la que tocaremos muchos de los conceptos vistos en la serie. La aplicación consiste en una simple lista de estudiantes donde tendremos funcionalidad de agregar, buscar, listar y ordenar a los estudiantes guardados en un archivo plano.

NOTA: En las líneas de código se omitirán los acentos.

Estructura principal

Para empezar con nuestro proyecto final prepararemos la estructura de nuestro proyecto empezando con un archivo que inicia el sistema (la llamaremos init.rb), un controlador (llamado controlador.rb) dentro de un directorio (lib) y nuestro archivo de texto plano (estudiantes.txt), el cual funcionará como base de datos. Empecemos con el código de init.rb:

## Declaramos la ruta del proyecto
APP_ROOT = File.dirname(__FILE__)

# Agregamos la ruta del directorio lib a nuestro proyecto para despreocuparnos
# al agregarla en todo momento
# File.join(APP_ROOT, 'lib') =>  APP_ROOT/lib
$:.unshift( File.join(APP_ROOT, 'lib') )

# Le decimos a Ruby que vamos a utilizar el controlador
require 'controlador'

# Inicializamos nuestro controlador
controlador = Controlador.new('estudiantes.txt')

# Disparamos nuestro proceso principal
controlador.launch!

Luego configuramos nuestra clase controlador, que tendrá el constructor de la clase, un par de métodos para el encabezado y pie del sistema y por último el método que dispara los eventos del sistema.

class Controlador
  # constructor de la clase. En esta verificaremos
  # si existe el archivo plano con los estudiantes
  # y si no creamos uno nuevo
  def initialize(path=nil)
  end

  # launch! este metodo tiene un loop que va a recibir las acciones
  # que tendra la aplicacion para procesarlas,
  # llama al encabezado y pie de aplicacion al principio y al final
  def launch!
    introduction
    conclusion
  end

  # Encabezado de la aplicacion
  def introduction
    puts "#" * 60
    puts "\n\n--- Bienvenido a al tutorial de CODEHERO ---\n"
    puts "Este ejemplo pertenece a la serie Ruby desde Cero.\n\n"
  end

  # Pie de la aplicacion
  def conclusion
    puts "#" * 60
    puts "\n\n--- Bienvenido a al tutorial de CODEHERO ---\n\n"
    puts "Este ejemplo pertenece a la serie Ruby desde Cero.\n\n"
  end
end

Hasta este momento ya utilizamos algunos conceptos estudiados en el curso como manejo de directorios, clases y objetos. Al ejecutar nuestra aplicación, así como la tenemos, tendremos lo siguiente:

############################################################
--- Bienvenido a al tutorial de CODEHERO ---
Este ejemplo pertenece a la serie Ruby desde Cero.

--- Hasta luego y recuerda visitarnos en www.CodeHero.co! ---
############################################################

Lógica y modelos de la aplicación

Esta etapa es de las más importante de nuestra aplicación, crearemos una nueva clase modelo (“estudiante.rb“) donde tendremos toda la lógica correspondiente al estudiante y editaremos brevemente nuestro controlador para que el sistema funcione bien. Empecemos con el modelo:

class Estudiante

  # Variable de clases con la direccion del archivo plano
  @@filepath = nil
  def self.filepath=(path=nil)
    @@filepath = File.join(APP_ROOT, path)
  end

  attr_accessor :nombre, :identificador, :fecha_nacimiento

  # Verificamos que el archivo exista
  def self.existe_archivo?
    if @@filepath && File.exists?(@@filepath)
      return true
    else
      return false
    end
  end

  # Validamos que el archivo exista, sea legible y modificable
  def self.validar_archivo?
    return false unless @@filepath
    return false unless File.exists?(@@filepath)
    return false unless File.readable?(@@filepath)
    return false unless File.writable?(@@filepath)
    return true
  end

  # Crea un archivo con permisos de escritura
  def self.crear_archivo
    File.open(@@filepath, 'w') unless existe_archivo?
    return validar_archivo?
  end

  # Recorremos el archivo plano y retornamos un arreglo con los
  # objetos estudiantes que esten en el
  def self.restaurantes_guardados
    estudiantes = []
    if validar_archivo?
      file = File.new(@@filepath, 'r')
      file.each_line do |line|
        estudiantes << Estudiante.new.importar_linea(line.chomp)
      end
      file.close
    end
    return estudiantes
  end

  # Constructor de la aplicacion, recibe los datos introducidos
  # desde la aplicacion
  def initialize(args={})
    @nombre           = args[:nombre]    || ""
    @identificador    = args[:identificador] || ""
    @fecha_nacimiento = args[:fecha_nacimiento]   || ""
  end

  # Guarda el archivo el estudiante en el archivo plano
  def guardar
    return false unless Estudiante.validar_archivo?
    File.open(@@filepath, 'a') do |file|
      file.puts "#{[@nombre, @identificador, @fecha_nacimiento].join("\t")}\n"
    end
    return true
  end
end

Una vez tenemos nuestro modelo Estudiante con la funcionalidad de agregar y listar sus objetos y todas las funciones que verifican el archivo, plano donde vamos almacenar la información, modificamos nuestro controlador para agregarle funcionalidad launch! y empiece a tomar color nuestra aplicación.

# launch! este metodo tiene un loop que va a recibir las acciones
# que tendra la aplicacion para procesarlas
# llama al encabezado y pie de aplicacion al principio y al final
def launch!
  introduction

  result = nil
  until result == :quit
    action, args = acciones
    result = hacer_accion(action, args)
  end
  conclusion
end

# Nos da las acciones que vamos a utilizar en nuestro proyecto
# y nos prepara el sistema para recibir las acciones por el usuario
def acciones
  action = nil

  puts "Acciones: " + ['listar', 'buscar', 'agregar', 'salir'].join(", ")
  print "> "
  user_response = gets.chomp
  args = user_response.downcase.strip.split(' ')
  action = args.shift

  return action, args
end

# Recibe la accion que se solicito por pantalla y
# se llama a las funciones que cumplan los requisitos del usuario
def hacer_accion(action, args=[])
  case action
  when 'listar'
    puts "listamos a los estudiantes"
  when 'buscar'
    puts "Buscamos por palabra clave"
  when 'agregar'
    puts "Agregamos un estudiante"
  when 'salir'
    return :quit
  else
    puts "\nel comando no es valido\n"
  end
end

Una vez modificadas estas clases con unos ajustes extras, que podrán ver en nuestro repositorio establecido para el proyecto, tendremos el siguiente resultado.

############################################################
--- Bienvenido a al tutorial de CODEHERO ---
Este ejemplo pertenece a la serie Ruby desde Cero.

Acciones: listar, buscar, agregar, salir
> listar
listamos a los estudiantes

Acciones: listar, buscar, agregar, salir
> buscar
Buscamos por palabra clave

Acciones: listar, buscar, agregar, salir
> agregar
Agregamos un estudiante

Acciones: listar, buscar, agregar, salir
> CodeHero

El comando no es valido

Acciones: listar, buscar, agregar, salir
> salir

--- Hasta luego y recuerda visitarnos en www.CodeHero.co! ---
############################################################

Por último, le agregamos a nuestro controlador las acciones del proyecto (agregar, listar y buscar) que llaman a funciones dentro del modelo Estudiante, veamos estos métodos:

# trae todos los estudiantes que esten en la base de datos
def listar(args=[])

  puts "Listando usuarios"
  estudiantes = Estudiante.restaurantes_guardados
      prepara_tabla(estudiantes)
  puts "Ordena escribiendo: 'listar nombre' o 'listar por identificador'\n\n"
end

# primero consulta todos los estudiantes del archivo de texto
# luego busca que en alguno de sus atributos tenga la palabra clave
# que se esta buscando.
def buscar(keyword="")
  puts "Buscar usaurio"
  if keyword
    estudiantes = Estudiante.restaurantes_guardados
    found = estudiantes.select do |estd|
      estd.nombre.downcase.include?(keyword.downcase) ||
      estd.identificador.downcase.include?(keyword.downcase) ||
      estd.fecha_nacimiento.downcase.include?(keyword.downcase)
    end
    prepara_tabla(found)
  else
    puts "Examples: 'buscar Ricardo', 'buscar 12345', 'buscar sampayo'\n\n"
  end
end

# Crea la estructura para recibir los datos en una especie de formulario
# los recibe crea un objeto Estudiante y lo guarda en el archivo
def agregar
  puts "Agregar estudiante"
      args = {}
  print "Nombre del estudiante: "
  args[:nombre] = gets.chomp.strip

  print "identificador: "
  args[:identificador] = gets.chomp.strip

  print "fecha de nacimiento: "
  args[:fecha_nacimiento] = gets.chomp.strip

  estudiante = Estudiante.new(args)

  if estudiante.guardar
    puts "\nBien! Se agrego el usuario\n\n"
  else
    puts "\nError: No se agrego el usuario\n\n"
  end
end

Utilizando módulos

En este caso utilizaremos módulos para agregarle una funcionalidad extra a la clase String que nos edite nuestra cadena de caracteres para que cada palabra empiece en mayúscula. La clase para esto es la siguiente:

class String
  def titleize
    self.split(' ').collect {|word| word.capitalize}.join(" ")
  end
end

El método donde hacemos uso del módulo anterior para imprimir el nombre de los usuarios, es el siguiente:

def prepara_tabla(estudiantes=[])
print ” ” + “Identificador”.ljust(30)
print ” ” + “Nombre”.ljust(20)
print ” ” + “Fecha”.rjust(6) + “\n”
puts “-” * 60
estudiantes.each do |rest|
line = ” ” << rest.identificador.ljust(30) line << " " + rest.nombre.titleize.ljust(20) line << " " + rest.fecha_nacimiento.rjust(6) puts line end puts "No hay estudiantes" if estudiantes.empty? puts "-" * 60 end [ruby][/ruby]

Conclusión

En este último capítulo vimos cómo crear una aplicación sencilla en Ruby para listar y agregar estudiantes a una lista escolar. Este capítulo tiene grandes bloques de código donde se explica en cada uno de los comentarios la funcionalidad del código. Te invito a que te descargues el código de nuestro repositorio de GitHub para que pruebes el proyecto y estoy seguro que entenderás mucho mejor este capítulo.

Felicidades por lograr el nivel máximo en nuestra serie Ruby desde cero y te recomiendo que no te quedes solo con la teoría que aquí te damos, si no, que sigas practicando y te volverás un verdadero héroe en este lenguaje.

Te recordamos que Ruby es un lenguaje de programación potente y flexible que te recomiendo siempre tener en cuenta a la hora de cualquier desarrollo por sus características, orden, facilidad de aprendizaje y comprensión del código.

También te recomiendo si quieres seguir con este lenguaje le eches un vistazo a nuestra serie Ruby on Rails desde cero, para aprender del famoso Ruby on Rails, framework de desarrollo web de código abierto, siguiendo el paradigma de la arquitectura Modelo Vista Controlador (MVC), el cual permite un desarrollo más eficiente, desacoplado y sostenible de las aplicaciones.

¡Hasta el próximo capítulo!

Posted on

Curso Ruby desde Cero: Manejo de Archivos y Directorios

Bienvenidos una vez más a Ruby desde cero, curso con el cual aprendemos del lenguaje sin necesidad de tener previo conocimiento en el tema. En el capítulo anterior estuvimos estudiando el concepto de módulos aplicado al lenguaje. En este nuevo capítulo estaremos estudiando el manejo de archivos en Ruby, desde como abrirlo hasta como escribir y leer información del mismo.

Rutas y Directorios

La rutas son las direcciones que nos indican cómo llegar a un archivo o directorio en el sistema. Para este capítulo aprenderemos una serie de conceptos básicos para manejarnos entre directorios con Ruby.

A continuación estudiaremos una serie de comandos básicos para el manejo de rutas y directorios con Ruby.

Ruta actual pwd()

Para los que están familiarizados con comandos SHELL, seguramente reconocerán este método. pwd simplemente nos da la ruta del directorio actual donde estemos trabajando, aunque este concepto es bastante sencillo. Veamos un ejemplo para comprender mejor el concepto de ruta actual.

$ irb
>> Dir.pwd
   "/Users/ricardosampayo/Desktop"

Como ven el método pwd de la clase Dir nos da la información de la ruta actual donde se ejecute ese comando. En el caso del ejemplo está ubicado en mi escritorio.

Cambiar de Directorio chdir()

chdir simplemente nos permite movernos a un directorio siempre y cuando sepamos la ruta. Este método es similar al cd en SHELL. Veamos un ejemplo:

Todos los ejemplos utilizados en este curso son mediante el REPL irb o pry.

>> Dir.pwd              #ruta actual
   "/Users/ricardosampayo/Desktop"
#nos cambiamos al directorio test dentro del directorio actual
>> Dir.chdir "test"
   0
>> Dir.pwd              #nueva ruta actual
   "/Users/ricardosampayo/Desktop/test"

>> Dir.pwd              #ruta actual
   "/Users/ricardosampayo"
# nos cambiamos a la carptea test utilizando la ruta absoluta
>> Dir.chdir "/Users/ricardosampayo/Desktop/test"
   0
>> Dir.pwd              #nueva ruta actual
   "/Users/ricardosampayo/Desktop/test"

Como pueden ver en los ejemplos, es posible cambiarnos de directorio utilizando tanto la ruta relativa como absoluta del sistema.

Buscar en un directorio glob()

glob nos permite buscar archivos dentro del directorio de trabajo. Veamos un ejemplo para probar este método:

>> Dir.glob "*.rb"          # Consultamos todos los archivos con extensión rb
   ["codeheroRuby.rb", "codeheroRubyClases.rb", "modulo_ruby.rb"]

Como vemos en el ejemplo podemos utilizar un asterisco ** ( * ) ** como un comodín para buscar cualquier coincidencia, por eso en este caso nos lista todos los archivos que terminen en .rb, si colocáramos ** Dir.glob “*” ** nos listaría todos los archivos dentro del directorio que estemos manejando.

Crear nuevos directorios mkdir()

Al igual que en sistemas operativos basados en Unix mkdir nos crea nuevos directorios o carpetas. Este método recibe como variable la ruta y el nombre de la nueva carpeta que estamos creando, veamos el siguiente ejemplo:

# consultamos la carpeta
>> Dir.glob "*"
   []
# creamos la nueva carpeta, no colocamos ruta por lo tanto
# se crea en la carpeta donde estemos trabajando
>> Dir.mkdir "test"
   0
# consultamos nuevamente la dirección para verificar que efectivamente
# creamos una nueva carpeta o directorio
>> Dir.glob "*"
   ["test"]

Archivos

Una vez entendamos cómo manipular los directorios nos vamos a la gestión de archivos. En esta parte del capítulo aprenderemos todo lo relacionado con el manejo de archivos.

¿Cómo 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 como 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.

Veamos ejemplos de cómo crear y obtener un archivo:

#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 or directory - pruebaCodeHeroError.txt
# consultamos nuevamente la carpeta
>> Dir.glob "*"
   ["pruebaCodeHero.txt", "test"]

Como vemos en el ejemplo es importante el uso de los parámetros que nos dan los permisos para manejar los archivos. En el ejemplo vemos claramente cómo intentamos crear un archivo otorgándole permisos únicamente de lectura y éste nos da un error ya que el archivo no existe y no tiene permisos de crear uno nuevo.

¿Cómo leer un archivo?

En Ruby el comando para leer un archivo es read().

Es importante tener en cuenta que las cadenas de caracteres(strings) de Ruby pueden tener datos binarios y no sólo de texto.

Veamos un ejemplo simple para ver cómo funciona bien esto. En el ejemplo preparamos un archivo de texto con dos lineas escritas.

#tomamos el archivo (ya estaba creado con las dos lineas escritas)
>> archivo =File.new("pruebaCodeHero.txt","r")
   File:pruebaCodeHero.txt
#leemos el archivo
>> archivo.read
   "Esto es Codehero\nLa mejor herramienta para aprender a programar en espaniol"

Como vemos el read() nos da la lectura completa del archivo pero, ¿qué pasa si necesitamos más, Si necesitamos leer línea por línea?. En Ruby disponemos de una serie de métodos que nos hacen la vida fácil para leer los archivos.

rewind – Nos regresa a la primera línea del archivo
readline – Nos lee una línea y nos ubica en la siguiente línea
readlines – Nos da un arreglo de las líneas que tenemos por delante en el archivo y nos ubica al final.
lineno – Nos da la línea donde estamos ubicados.

Veamos estos métodos aplicados a nuestro ejemplo anterior:

#tomamos el archivo (ya estaba creado con las dos lineas escritas)
>> archivo =File.new("pruebaCodeHero.txt","r")
   File:pruebaCodeHero.txt
#leemos la primera linea
>> archivo.readline
  "Esto es Codehero\n"
#leemos la segunda linea
>> archivo.readline
   "La mejor herramienta para aprender a programar en espaniol"
#en que linea estamos?
>> archivo.lineno
   2
#pedimos una tercera linea (obviamente error)
>> archivo.readline
   EOFError: end of file reached
#regresamos al principio
>> archivo.rewind
   0
#pedimos todas las lineas en un array
>> archivo.readlines
   ["Esto es Codehero\n", "La mejor herramienta para aprender a programar en espaniol"]

En Ruby una vez hayamos leído una línea no la veremos más a menos que regresemos en el archivo.

¿Cómo escribir un archivo?

En Ruby para escribir información en un archivo usamos el método write() o puts(). La principal diferencia es que puts añade un salto de línea luego de escribirla y write no.

Vemos un ejemplo de cómo escribir en nuestro archivo

#tomamos el archivo (al colocar w+ lo limpia)
>> archivo =File.new("pruebaCodeHero.txt","w+")
   File:pruebaCodeHero.txt
#escribimos con un salto de linea al final
>> archivo.puts "Codehero"
   nil
#escribimos
>> archivo.write "los mejores cursos"
   18
#escribimos con un salto de linea al final
>> archivo.puts " en espaniol"
   nil
#escribimos
>> archivo.write "por Ricardo Sampayo"
   19
#regresamos al comienzo de la linea
>> archivo.rewind
   0
#imprimimos un arras con las lineas dentro del archivo
>> archivo.readlines
   ["Codehero\n", "los mejores cursos en espaniol\n", "por Ricardo Sampayo"]

¿Cómo eliminar y renombrar un archivo?

En Ruby podemos remover un archivo usando el método delete(nombre) y renombrarlo con el método rename(nombre_viejo, nombre_nuevo), Veamos un ejemplo de esto

#consultamos el directorio
>> Dir.glob "*"
   ["pruebaCodeHero.txt", "test"]
#renombramos el archivo
>> File.rename("pruebaCodeHero.txt","listoParaBorrar.txt")
   0
#consultamos nuevamente el directorio para ver los cambios
>> Dir.glob "*"
   ["listoParaBorrar.txt", "test"]
#borramos el archivo
>> File.delete("listoParaBorrar.txt")
   1
#consultamos nuevamente el directorio para ver los cambios
>> Dir.glob "*"
   ["test"]

Conclusión

En este capítulo aprendimos todo lo relacionado con el manejo de archivos y directorios en Ruby, funciones básicas como abrirlos, leerlos, editarlos y eliminarlos.

Si te surgen dudas con nuestros cursos, no te detengas y danos tus comentarios, que con gusto estamos dispuestos a resolver tus inquietudes.

¡Hasta el próximo capítulo!

Posted on

Curso Ruby desde Cero: Módulos

Bienvenidos una vez más a Ruby desde Cero. En los últimos capítulos estudiamos las clases y el paradigma orientado a objetos aplicados al lenguaje. Si aún no te has puesto al día con la serie te invito a echarle un vistazo a Ruby desde Cero

En este nuevo capítulo estaremos estudiando los módulos en Ruby, al igual que en los capítulos anteriores definiendo cada una de las características, mostrando la sintaxis y ejecutando ejemplos básicos para comprender mejor el tema.

¿Qué son los módulos?

Un módulo es una colección de métodos y constantes. Mediante el uso de módulos, podemos dividir el sistema o el programa en partes independientes para facilitarnos el uso de los métodos para reutilizarlos, es decir, los módulos podrían ser paquetes de métodos y clases relacionados que nos facilitarán encontrarlos más rápido.

Aunque el concepto de módulos se asemeja bastante al de clases que también tiene métodos, clases y constantes, se diferencian básicamente en que no se pueden crear objetos de un módulo, es decir, no se instancian los módulos.

Otra ventaja, es que podemos almacenar nuestros programas de forma modular: cada módulo añade una característica. Esto también lo permitían las clases, pero la ventaja de los módulos, es que no hace falta crear una serie de jerarquías, que podría llegar a ser engorroso.

Lo primero que debemos hacer para adentrarnos en el concepto y comenzar a elaborar algunos ejemplos es conocer la sintaxis:

module Identificador
  declaracion1
  declaracion2
  . . .
end

Al igual que con los métodos de clase, se llama a un método del módulo precediendo su nombre con el nombre módulo y un punto ( . ), y se hace referencia a una constante utilizando el nombre del módulo y el signo de dos puntos ( : ).

Principales usos de los módulos

Los módulos en Ruby básicamente se utilizan para definir espacios de nombres (‘namespace’) que básicamente nos agrupa todas las clases, métodos, variables y otros elementos, dentro de un especie de grupo o paquete. Otro de los usos es el ‘mixins’ que nos permite agregar funcionalidad extras a una clase. Ésto lo definiremos mejor a continuación:

Espacios de nombres (‘namespace’)

Cuando estamos desarrollando algún proyecto grande y las lineas de código crecen desenfrenadamente, surge la necesidad de organizar de alguna forma nuestro código para poder manipularlo con facilidad, y es aquí donde nos es útil este tipo de implementación de los módulos.

Con los módulos es posible agrupar una serie de métodos y clases relacionadas de alguna manera en un archivo independiente, de tal manera que podamos utilizar estos métodos como una librería independiente. Un caso típico de un módulo es ‘Math’: este módulo cuenta con una serie de funciones trigonométricas agrupadas en un sólo paquete.

Los espacios de nombres también evitan el problema de que surja una ambiegüedad en el caso de que haya dos componentes con un mismo nombre. Por ejemplo, podemos tener dentro de un programa varias clases con el nombre “Settings”, pero cada una estará referida a algo concreto. Incluyendo esas clases en distintos módulos, conseguimos que puedan ser identificadas de forma unívoca.

Luego de tanta descripción veamos un ejemplo y así seguramente entenderemos mejor el concepto de namespace:

module Semana
  PRIMER_DIA = "lunes"
  def Semana.semanas_en_mes
    puts "un mes tiene cuatro semanas"
    return 4
  end
  def Semana.semanas_en_anio
    puts "un anio tiene 52 semanas"
  end
end

class Codehero
  N_MESES = 10
  def n_de_meses
    puts "las semanas inician el #{Semana::PRIMER_DIA}"
    number=10 * Semana::semanas_en_mes
    puts "cantidad de semanas en 10 meses es #{number}"
  end
end

puts Semana::PRIMER_DIA
Semana.semanas_en_mes
Semana.semanas_en_anio
puts "==================="
d1=Codehero.new
d1.n_de_meses

En este ejemplo creamos un módulo ‘Semana’ que agrupa una serie de métodos y constantes relacionadas a una semana, que posteriormente utilizamos en una clase de prueba y fuera de ella. El resultado de esta ejecución lo podemos observar a continuación:

lunes
un mes tiene cuatro semanas
un anio tiene 52 semanas
===================
las semanas inician el lunes
un mes tiene cuatro semanas
cantidad de semanas en 10 meses es 40

Mixins

Esta implementación de los módulos nos da una forma bastante elegante de agregarle funcionalidad a las clases. Sin embargo, su verdadero poder viene cuando el código en el mixin comienza a interactuar con el código de la clase que lo utiliza.

Vamos a ver un ejemplo en el que añadimos un método a la clase String que elimina los espacios en blanco de principio y fin de una cadena de caracteres.

module UtilidadesString
  def quitar_espacios
    self.to_s.strip.gsub(' ', '')
  end
end

class String
  include UtilidadesString
end

puts " Hola CodeHero, El Mejor Portal De Aprendizaje En Espaniol ".quitar_espacios

El resultado de la ejecución del programa es una cadena sin espacios:

HolaCodeHero,ElMejorPortalDeAprendizajeEnEspaniol

En el ejemplo vimos como le agregamos un método de instancia a la clase String, con esta herramienta también es posible extender una clase con métodos de clases, haciendo uso del ‘extend’. Haciendo posible incluir varios módulos en una misma clase, consiguiendo un efecto similar a una herencia múltiple no permitida por Ruby. Veamos un ejemplo sencillo de esto:

module Calendario
  def self.included(base)
    base.send :include, Dia
    base.send :extend, Semana
  end

  module Dia
    def dia_en_anio
      "un anio tiene 365 dias"
    end
  end

  module Semana
    PRIMER_DIA = "lunes"

    def semanas_x_mes(number)
      "#{number} meses tiene #{number * 4} semanas"
    end
  end
end

class MiClase
  include Calendario
end

#llamada a las clases

puts MiClase.semanas_x_mes(4)
puts MiClase.new.dia_en_anio

Como podemos ver en el ejemplo al agregar en un módulo el método ‘included’, éste se ejecutará cada vez que sea incluido por otro módulo o clase. En este ejemplo, cuando se incluye el módulo, añadimos los métodos de instancia(include) y de clase(extend). Dándonos como resultado una clase con comportamientos diferentes de dos módulos, el resultado de ejecutar el programa es el siguiente:

4 meses tiene 16 semanas
un anio tiene 365 dias

Conclusión

En este capítulo aprendimos un concepto básico de Ruby como lo son los módulos, abarcando el concepto principal, ventajas, sintaxis, usos y manipulación de esta útil característica del lenguaje.

Si te surgen dudas con nuestros cursos, no te detengas y danos tus comentarios, que con gusto estamos dispuestos a resolver tus inquietudes.

¡Hasta el próximo capítulo!

Posted on

Curso Ruby desde Cero: Orientación a Objetos – Parte 2

Bienvenidos una vez más a Ruby desde Cero. En el capítulo anterior estudiamos la primera parte del paradigma orientado a objetos aplicado al lenguaje.

En este nuevo capítulo veremos un poco más sobre el manejo de clases en Ruby, detallando para cada una de ellas sintaxis y ejemplos sencillos de fácil comprensión. Les recomiendo echar un vistazo a Ruby desde Cero: Orientación a Objetos – Parte 1, ya que, continuaremos con los desarrollando el contenido.

Herencia.

Es uno de los mecanismos mas utilizados en la programación orientada a objetos que nos facilitan la reutilización y la extensibilidad del código. La herencia es la relación entre una clase general y otra más específica. Por ejemplo: Si declaramos una clase Ave derivada de una clase Animal, todos los métodos y variables asociadas con la clase Animal, serán automáticamente heredados por la subclase Ave. Veamos el siguiente gráfico para comprender mejor esto:

Como vemos en el gráfico tenemos cinco componentes que heredan del componente ‘Animal’, estas subclases heredan todos los atributos y comportamientos del padre, incluso es posible alterarlos o agregarles nuevos atributos. El beneficio de la herencia es que las clases inferiores de la jerarquía obtienen las características de los de arriba, sino que también pueden añadir características específicas propias.

En Ruby, una clase sólo puede heredar de una sola clase padre. Algunos otros idiomas admiten la herencia múltiple, una característica que permite a las clases que hereden características de varias clases, pero Ruby no lo soporta.

La sintaxis para heredar de una clase es la siguiente:

class Objeto < Objeto_padre
end

Para demostrar observemos el siguiente ejemplo:

class Animal
  attr_reader :habitat
  attr_accessor :descripcion
  attr_reader :color                  # variable publica de solo lectura

  def initialize          # este metodo se llama automaticamente al instanciar el objeto
  end

  def respiracion
    puts "Inhala y exhala"
  end

  def color
    @color
  end

  def color=(color)
    @color = color
  end
end

class Reptil < Animal
  def initialize          # este metodo se llama automaticamente al instanciar el objeto
    @habitat = "tierra"
  end
end

class Ave < Animal
  def initialize          # este metodo se llama automaticamente al instanciar el objeto
    @habitat = "Aire"
  end
end

reptil = Reptil.new
reptil.descripcion = "Lagarto"
reptil.color = "verde"

puts "El Animal es un: " + reptil.descripcion + ", color: " + reptil.color + ', habitat natural: ' +reptil.habitat
reptil.respiracion

ave = Ave.new
ave.descripcion = "Buho"
ave.color = "marron"

puts "El Animal es un: " + ave.descripcion + ", color: " + ave.color + ', habitat natural: ' +ave.habitat
ave.respiracion

En el ejemplo vemos como se componen tres clases (Animal (padre), Pez y Reptil (Subclases)). Vemos como Pez y Reptil heredan los atributos y comportamientos de la clase padre, por lo tanto desde el punto de vista del programador los Reptiles y Aves tienen una serie de atributos predefinidos (color, hábitat y descripción) y un comportamiento de respiración que simplemente inhala y exhala. Veamos el resultado de esto a continuación:

El Animal es un: Lagarto, color: verde, habitat natural: tierra
Inhala y exhala
El Animal es un: Buho, color: marron, habitat natural: Aire
Inhala y exhala

Con el manejo de herencia surgen una serie de conceptos que hacen del paradigma orientado a objetos una técnica irresistible de usar. Estos conceptos los definimos a continuación:

Sustitución de métodos (Overriding)

La programación orientada a objetos existe una característica del lenguaje que permite una una implementación específica de un método que ya está proporcionado por una de sus superclases. Las modificaciones de las subclases reemplazan la implementación de la superclase.

A continuación mostraremos un ejemplo sencillo para entender mejor el concepto:

class Principal
  def metodo_prueba
    puts 'Es un metodo de la clase principal'
  end
end

class Subclase_uno < Principal
  def metodo_prueba
    puts 'Se sustituye el metodo principal'
  end
end

class Subclase_dos < Principal
end

principal = Principal.new
principal.metodo_prueba
puts "++++----++++"
secundario = Subclase_uno.new
secundario.metodo_prueba
puts "++++----++++"
tercero = Subclase_dos.new
tercero.metodo_prueba

En este ejemplo se puede ver claramente como el objeto denominado ‘Subclase_uno’ remplaza el método ‘metodo_prueba’ del padre con otras características y como el objeto ‘subclase_dos’ simplemente hereda los métodos con el mismo comportamiento. Aquí el resultado de la ejecución del programa:

Es un metodo de la clase principal
++++----++++
Se sustituye el metodo principal
++++----++++
Es un metodo de la clase principal

Acceder a los métodos de la superclase

La programación orientada a objetos tiene una característica del lenguaje que permite que un método de una subclase poder tomar el comportamiento de la clase padre, para proporcionar características nuevas a las clases ya definidas en el método de la superclase. Las modificaciones de las subclases agregan nuevos comportamientos al método de la superclase.

Para demostrar esto veremos un ejemplo bastante sencillo, que seguramente nos ayudará a entender mejor este concepto:

class Principal
  def metodo_prueba
    puts 'Es un metodo de la clase principal'
  end
end

class Subclase_uno < Principal
  def metodo_prueba
    super()
    puts 'y se le agrega este nuevo comportamiento'
  end
end

principal = Principal.new
principal.metodo_prueba
puts "++++----++++"
secundario = Subclase_uno.new
secundario.metodo_prueba

En el ejemplo vemos como la subclase (‘Subclase_uno’) sustituye el método del padre (metodo_prueba) llamando a su implementación en la clase padre con la función ‘super()’ para así agregarle nuevos comportamientos al método. El resultado al ejecutar este pequeño programa es el siguiente:

Es un metodo de la clase principal
++++----++++
Es un metodo de la clase principal
y se le agrega este nuevo comportamiento

En conclusión la herencia permite crear una clase que es un perfeccionamiento o especialización de otra clase.

Sobrecarga de Métodos

En muchos lenguajes es posible crear dos versiones diferentes de un método con el mismo nombre. Sin embargo, una clase de Ruby sólo puede tener un método con un nombre (Si se definen dos métodos con el mismo nombre Ruby reconoce únicamente el ultimo definido). Una solución para este problema es crear un método único con una lógica para verificar cuantos y que tipos de argumentos hay. Demostremos esto con un ejemplo:

class Codehero
  def initialize(*args)
    if args.size > 1
      puts 'No se permiten dos o mas atributos'
    else
      if args.size == 0
        hola_mundo
      else
        hola(args[0])
      end
    end
  end

  def hola_mundo
    puts "Hola CodeHero"
  end

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

ejemplo1 = Codehero.new('Ricardo Sampayo')
ejemplo2 = Codehero.new
ejemplo3 = Codehero.new('Ricardo','Sampayo')

En el ejemplo vemos como creamos un único constructor (‘initialize’) y en éste colocamos una lógica para manejar argumentos, que consiste en: si el constructor recibe más de un argumento imprime un mensaje de error, si no recibe argumentos llama al método ‘hola_mundo’ y si recibe un argumento llama al método ‘hola’ con la variable recibida. El resultado de esta ejecución es la siguiente:

Hola Ricardo Sampayo
Hola CodeHero
No se permiten dos o mas atributos

Conclusión

En este capítulo hemos adquirido herramientas importantes sobre el paradigma orientado a Objetos en Ruby, cómo el uso de herencias y sus conceptos más importantes y la sobrecarga de métodos.

Si te surgen dudas con nuestros cursos, no te detengas y danos tus comentarios, que con gusto estamos dispuestos a resolver tus inquietudes.

¡Hasta el próximo capítulo!

Posted on