Sunday, November 1, 2009

Sobre editores, programación visual y demás yerbas

Perdón por la tardanza, pero acá seguimos con Ruby. :-)

La idea del tercer Post era estudiar los métodos en Ruby. Ese post quedara para la próxima semana, porque para esta me quede pensando en una duda que planteo Maximiliano en los comentarios del anterior post.


No voy a ser exhaustivo, sino tan solo explicar porque no confundir programación dentro del paradigma de objetos con la programación de Interfaces de usuario. Luego, me explayare en interesantes editores e IDEs para programar, en Linux y Windows, teniendo en cuenta los mas usados en Ruby.


Sobre la programación en objetos y la programación de GUI


El paradigma de objetos implica una visión abstracta y lógica de diversas entidades que existen en el mundo real. El paradigma de objetos obliga a ciertas reglas de construcción de objetos, manejo de memoria y técnicas o mecanismos particulares tales como envío de mensajes, herencia, polimorfismo, etc...


Todo lenguaje que soporta o implemente lo anterior, mas otras cuestiones adicionales, se considera un lenguaje que soporta el paradigma de objetos.


Con los objetos se realiza el modelo de datos y de comportamiento de una aplicación.


Por otro lado, las GUI (Interfaz Gráficas de Usuario) son una manera de representar un sistema ante los usuarios.


Pensemos en un sistema de 3 capas:


+-------------------------------------+
|---------Interfaz de usuario---------|
+-------------------------------------+
|----------Modelo de objetos----------|
+-------------------------------------+
|--------Modelo de datos físico-------|
|-----------(Base de datos)-----------|
+-------------------------------------+


El diagrama anterior nos muestra que el modelo de objetos esta entre la interfaz del usuario, y la base de datos física. Es decir, el modelo de objetos es el sistema, en memoria y trabajando. La interfaz de usuario es la forma amigable en que el usuario ingresa datos y pide que se ejecuten determinadas acciones. El modelo de datos físico es el almacenamiento permanente con alguna tecnología (Sistemas de archivos, SGBD, etc...)


De todo lo anterior podemos extraer varias conclusiones:


  • Los modelos de capas son muy ventajosos para los desarrolladores de aplicaciones, porque permite dividir el trabajo de una manera clara y natural.


  • Estudiar objetos no es estudiar las maneras que al usuario le gusta ver el sistema, sino estudiar la lógica interna de un lenguaje de objetos, como Ruby, Smalltalk, Python, etc...


  • La interfaz de usuario no solo es la GUI de ventana. Muchos grandes sistemas siguen funcionando en consolas de textos (sistemas financieros que es muy difícil o imposible dejarlos inoperativos aunque sea por un corto tiempo). La tendencia hoy en día es realizar aplicaciones Web, entonces allí la interfaz tampoco es "la ventana".
Con todo lo anterior, vemos que si estudiamos bien los objetos, la interfaz puede cambiar entre una y otra (y si esta bien hecho, debe poder cambiarse sin problemas) y puedo tener un mismo sistema en linea de comandos, en GUI y con interfaz web.


Ruby naturalmente permite realizar sistemas que interactúen con todas las interfaces. Naturalmente con las consolas de texto. Tiene Bindings para GTK, QT, WxWindows, etc... Y con Rails, su framework mas popular, se pueden desarrollar aplicaciones web.


Si se entiende bien el funcionamiento de un lenguaje, crear interfaces de usuario, sea web o sea GUI, es cuestión de agregar un modulo al lenguaje, aprender una API o mecanismo de interpretación adicional.


Editores de texto e IDEs para desarrollar con Ruby















Notepad++ (solo windows):
Es uno de los editores de software libre mas populares en plataformas Windows. Es de propósito general, con lo cual su integración con herramientas de Ruby es genérica (Resaltado de sintaxis y algún que otro plugin con funcionalidad menor).


Textmate (para rails y en OS X): Si se trabaja en plataformas MAC, Textmate es uno de los editores que mas se recomiendan para programar en Ruby, mas específicamente con Rails, por algunos elementos que hacen la tarea mucho mas sencilla. Es pago y de código cerrado.


Netbeans con plugins: Netbeans es el popular IDE desarrollado y mantenido por SUN, con una gran cantidad de plugins, entre ellos para Ruby y Rails, y también soporte para SVN nativo, ejecuciones de prueba del código, debbugin, etc... También es recomendado entre los desarrolladores de Ruby. Netbeans es multiplataforma.


Gedit con las mejoras de Textmate: Gedit es el bloc de notas del entorno de escritorio GNOME. En los últimos años este editor fue desarrollando mejoras orientadas a que se pueda usar como un editor para desarrollo. Al tener un sistema de plugins y agregados bastante interesante, desarrolladores se han orientado a mejorarlo para hacerlo mas potente. En particular, Jose ha hecho un trabajo excelente implementando plugins para que Gedit se acerque a Textmate en funcionalidad. La dirección del post principal en su blog es http://blog.nationcode.com/articles/2008/04/06/gedit-como-textmate-mejorado-para-rails-en-gnu-linux.


Komodo Editor: Editor OpenSource muy interesante. Es limitado porque hay otra versión paga y cerrada que es Komodo IDE. Se puede descargar desde su pagina http://www.openkomodo.com/


Geany: Editor ligero, bastante completo, y orientado a programadores. Otra buena alternativa a los editores usados comúnmente. Se puede descargar en http://www.geany.org/


VIM, Emacs: Clásicos editores de programación de entornos de desarrollo OpenSource. Son complicados para usuarios noveles, pero tienen muchos atajos y complementos que los hacen muy útiles para usuarios experimentados. La mayoría del desarrollo del Lenguaje Ruby fue hecho en Emacs.

En la próxima entrada, donde trataremos sobre métodos en Ruby, ya tendremos bastante mas código, así que pongan a punto esos editores ;-)

Fuentes consultadas:

http://rubytutorial.wikidot.com/introduccion

http://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_objetos

Thursday, October 29, 2009

Notas de la clase 7 y guía de trabajos prácticos

El foco de esta clase fue introducción a análisis y diseño. Vimos un conjunto de estrategias que nos permite avanzar desde una especificación de un sistema (medianamente completa) a un diseño e implementación del mismo. Las estrategias que aplicamos con una combinación de lo propuesto por varios autores (Larman en lo referente a casos de uso y identificar comportamiento para cada uno, Wirfs-Brock en lo referente a la estrategia de sustantivos para identificar clases). Aquí les resumo cuales son los pasos a seguir cuando uno todavía no sabe por donde arrancar con el diseño.


  1. Listar los casos de uso. Que cosas puede hacer el usuario con el sistema? Por ahora nos alcanza con una frase que resuma cada caso de uso, por ejemplo, "calcular el peso de un contenedor".
  2. Subrayar todos los sustantivos en la especificación (enunciado). También hacer esto en mi lista de casos de uso dado que puedo haber introducido nueva información y vocabulario.
  3. Construir una lista con todos esos sustantivos. No descartar ninguno. En la lista incluyo los calificativos que acompañan, por ejemplo "Pieza de metal", "Ciudad destino", "Usuario vip". 
  4. Vamos a utilizar esa lista para construir un modelo del dominio (Larman le llama diagrama de conceptos). Es muy parecido a un diagrama de clases, pero todavia no puedo asegurar navegabilidad de las relaciones y todavia no hablo de comportamiento. Procedemos así: hasta que la lista este vacía (o ya no me sirva porque los sustantivos que quedan no me ayudan mucho) repito lo siguiente:
    1. De la lista tomo un sustantivo que creamos que, casi sin discusión, es una clase. Uso un poco de intuición, me pregunto cuales serían sus atributos si fuera una clase, me pregunto cuan central es ese concepto al problema, etc. Incluyo en el diagrama y lo tacho de la lista. Si en la lista hay un sinónimo para esa palabra, veo cual de las dos palabras representa mejor el concepto, uso esa y tacho las dos.
    2. Busco en la lista atributos obvios para esa nueva clase. Los incluyo en el diagrama y los tacho.
    3. Si en mi diagrama hay otras clases, pienso como se relacionan con la que acabo de agregar. Si hay relación de conocimiento la indico sin hablar todavía de navegabilidad (dirección de la flecha). También indico cardinalidad. Si creo que hay relación de especialización o generalización (herencia) también la indico. Recuerden preguntar "es_un"?".
    4. Busco en la lista para ver si alguna de las palabras en la lista describe los roles de las relaciones que agregué (etiquetas en los extremos de las relaciones).
    5. Contínuo, siempre eligiendo lo mas obvio, menos discutible, hasta que tengo un diagrama que a mi entender representa bien el dominio e incluye la mayoría de los sustantivos de la lista. Puede que me queden algunos sustantivos en la lista que no se donde ubicar.
  5.  Ahora, pienso en comportamiento. Tomo alguno de los casos de uso y pienso:
    1. Como estaría instanciado mi diagrama de clases para que ejecutar ese caso de uso tenga sentido (por ejemplo, debe existir una instancia de Container, con su colección de cajas inicializada y vacía). Que objetos deberían existir, como serían sus atributos, como estarían relacionados? Si puedo lo dibujo para no olvidarme (diagrama de instancias)
    2. Luego de que el caso de uso termine, como quedaría mi diagrama de instancias? Que nuevas instancias aparecen? Que atributos cambian? Que relaciones cambian? 
    3. Ahora pienso que tendrían que hacer mis objetos para llegar del estado inicial (1) al estado final (2). A quien le envío que mensaje con que argumentos? A quienes le envía mensajes ese? Agrego esos mensajes en la lista de los mensajes que debe entender cada una de las clases involucradas. En este punto pueden utilzar un diagrama de comunicación para documentar como es la cadena de envío de mensajes (ojo que hay cosas que no voy a intentar documentar el en diagrama para no complicarlo como iteraciones, ifs, etc). Si su diseño los va convenciendo, pueden ir implementando y probando en el workspace.
Práctica

Les dejo la práctica 7 en las que repito el enunciado visto en clase para que lo diseñen e implementen completamente (además de unos ejercicios de diseño e implementación simples) para

Notas de la clase 6 y guía de trabajos prácticos

Les debía las notas de la clase 6.

En esta clase hablamos principalmente sobre colecciones. De la jerarquia de colecciones de Squeak nos concentramos en OrderedCollection (tamaño dinámico, muy flexible), Set (elimina duplicados), Array (tamaño fijo, rápida) y SortedColection (ordenada), y Dictionary (cualquier objeto puede ser una clave).
Collections esta muy bien cubierto en el capítulo 9 de Squeak by Example.

Al hablar de Set, aprovechamos y vimos la diferencia entre igualdad (el mensaje #=) e identidad (el mensaje #==). Nunca redefinimos el #==. Es comun que redefinamos el #= en nuestras clases (por ejemplo para definir que dos personas son iguales si tienen el mismo DNI aunque haya alguna diferencia entre sus nombres, por ejemplo, por un error ortográfico). El set envia el mensaje #= para ver si un nuevo objeto ya esta incluido. Si quiero que compare por identidad utilizo un IdentitySet. Para leer mas sobre identidad e igualdad, vean la página 178 (Identity and equality) del libro Squeak By Example.

Finalmente, para hacer cosas con colecciones, vimos lo importante que son los  iteradores: #do:, #collect:, #select:, #detect:ifNone:, #reject: e #inject:into:

Les dejo la práctica 6, muy enfocada en Colecciones. Es una práctica muy importante porque les va a servir de apunte para estudiar.

Thursday, October 15, 2009

D+D Engine: Un engine 2d para el desarrollo de videojuegos.

Pruebas del engine: gestion de teclado, dibujado de primitivas, sprites, tileset etc...

Antes de empezar aclaremos la primer pregunta que puede surgir ya del titulo ¿Que es un engine?


Un engine: Un engine es una especie de Framework para el desarrollo de videojuegos, y cuyo objetivo(al igual que todo Framework) es facilitarnos el trabajo y poder enfocarnos de lleno a nuestro desarrollo y olvidándonos de algunas cuestiones básicas como la gestión de gráficos, sonido, entradas etc; usando algunas estructuras de datos y funciones (o clases) que guían al diseño de nuestra aplicación.

¿Y que tiene que ver esto con la programación O.O.? Sencillo, el engine del cual vamos a hablar es de un engine desarrollado con este paradigma, y que nace justamente para pasar de una API como SDL a un mundo de objetos.

Si nuevas preguntas… ¿Qué es una API? ¿Qué es SDL?


API: Una API en pocas palabras son un conjunto de módulos, funciones, o clases que permiten el acceso a otros componentes de software como puede ser una librería para la para la gestión de gráficos, o de un controlador de Wiimote por citar algunos ejemplos.

Y ahora se preguntarán, ¿Qué diferencia hay entre una API y un Framework? Es más sencillo de lo que parece, aunque a veces se las llega a confundir.

Las API´s son simplemente una interfaz a un componente de software, y nada más, es independiente de para que se use (EJ: desde un video juego hasta una bases de datos), y no afectan al diseño de nuestro programa.

Al contrario un Framework puede incluir el uso de muchas API´s, pero el mismo Framework ya cuenta con estructuras que afectan el diseño de nuestra aplicación, y están pensados para el desarrollo de aplicaciones especificas (EJ: o para videojuegos o para Base de datos).

Por su parte, SDL Es una API que proporciona las funciones básicas para realizar operaciones de dibujado, de gestión sonido, música, y carga y gestión de imágenes.

Con más conceptos en la cabeza les digo que a partir de SDL que esta programado en C, y por tanto en programación estructurada, diseñe e implemente un simple (muy simple y no concluido) engine 2d para el desarrollo de juegos en C++.

Ya existen otros como SMFL que hacen lo mismo y mejor, pero el objetivo era reinventar la rueda para aprender un poco.


Restan dos entradas que hablan de este desarrollo. En la que sigue les voy a contar la ventaja que supone pensar aplicaciones de este tipo en objetos, y en la última les voy a contar como se complica no tener un Garbage Recollector (como tiene smalltalk), ya que como dije el engine esta programado en C++ ( y este no lo tiene).


Espero les sea de interés.

Alejandro Iglesias.

Notas de la clase 5 y guía de trabajos prácticos

Hablamos de UML y vimos en detalle lo que vamos a usar de diagramas de clase. Recomiendo que consigan UML gota a gota. Si no lo consiguen, este articulo parece estar bastante actualizado.

Anteriormente habíamos hablado de diagramas de colaboración (o de comunicación como se los llama en UML 2.0). Aqui les dejo un link que les puede servir (ademas del libro)

Confirmamos que en Smalltalk las clases son objetos y por tanto entienden mensajes. Uno de los mensajes que entienden las clases es #new. Puedo definir otros mensajes de clase, y en particular nos interesan aquellos que reciben varios parámetros y nos devuelven una instancia completamente inicializada. Los llamamos complete creation methods.


En esta clase retomamos el tema de las cuentas y vimos que para aprovechar herencia debía ser posible extender métodos heredados (no solo redefinirlos). Para eso nos viene bien super. Al final de este post les dejo un mini-apunte sobre super y self.

Ya esta disponible la práctica 5. Tiene ejercicios de UML, super y self, métodos de clase y uso del debugger de Squeak.


self y super

selfsuper son pseudovariables. No se puede asignar objetos a estas variables. Es responsabilidad de la maquina virtual asegurarse de que cada vez que se ejecuta un método, selfsuper apuntan (referencian) al objeto correcto, es decir, al objeto que se encuentra ejecutando el método.

Primer lección importante: tanto super como self apuntan (referencian) al mismo objeto: el objeto que esta ejecutando el método.

self puede pasarse como parámetro en un mensaje, puede asignarse a una variable, y puede ser receptor de mensajes.

Cuando en un método veo "self hacerAlgo"  lo leo como "el objeto se envía #hacerAlgo a si mismo". Permite entre, otras cosas, refactorizar un metodo complejo, haciendo que el objeto se delegue tareas a si mismo que se resuelven en otro método (en este caso #hacerAlgo).

Cuando en un método veo "super hacerAlgo" lo leo "TAMBIEN" como el que el objeto se envía hacerAlgo() a "si mismo". Ya veremos la diferencia.

Cuando un objeto recibe un mensaje, no importa si se lo envió otro objeto o si se lo envió él a si mismo tratándose de "self". En ambos casos pasa lo mismo. Se inicia la búsqueda de un método en la clase del objeto y si no se encuentra en esa clase se sigue buscando siguiendo las relaciones de "hereda de".

Cuando un objeto recibe un mensaje que se envió él a si mismo, pero en lugar de referirse a si mismo como self, utilizósuper (p.e., self hacerAlgo) se cambia la forma en la que se comienza a buscar el método.
  • Cuando super recibe un mensaje, la búsqueda de método comienza en la clase superior a aquella donde está el método que envió el mensaje a super. Esto no es lo mismo que decir "en la superclase", o "en la superclase del objeto".
  • Esto es independiente de la clase de super/self.
Ese cambio el mecanismo de method lookup (busqueda de método) permite enviar nuevamente el mensaje cuyo metodo se esta definiendo al objeto receptor y evitar entrar en un ciclo infinito. Esto es útil para "EXTENDER" comportamiento heredado.

Ojo que en algunas definiciones de super equivocadamente dicen que la búsqueda de método comienza en la superclase del objeto receptor! Eso no es correcto.

Sunday, October 11, 2009

Algo sobre el Lenguaje Ruby (II)

En esta segunda entrega, veremos algo sobre estilos de código en Ruby, y luego algunos ejemplos de programación de objetos básicos en Ruby, basándonos en algunos TPs de la materia Programación III.

Estilos de código:

Hay varias cuestiones a tener en cuenta a la hora de programar en objetos en Ruby. Como en Smalltalk, se sigue la convención de que la clases se definen con mayúscula en la primer letra, las instancias y sus variables con minúscula, así como los métodos.

Las constantes se escriben todo en mayúscula.

La diferencia principal con el estilo “smalltalkero” es que los nombres con mas de una palabra se escriben de manera diferente: Mientras que en Smalltalk una variable o métodos se escribe estoEsElNombreClasicoDeUnaVariableSmalltalk, Ruby tiene por convención que sea esto_es_un_nombre_tipico_en_ruby.

Las convenciones son importantes, dado que todos los métodos, funciones, módulos, clases y demás cosas de las librerías se escriben siguiendo estas reglas, con lo cual, no adaptarnos a ellas puede traer problemas.

Un ultimo detalle es que algunos nombres de métodos en Ruby terminan con el signo '?'. Cada vez que un método termina con el signo de interrogación significa que retorna siempre verdadero o falso. En el caso que el método termine con '!', implica que el objeto al cual le enviamos el mensaje sera modificado. Es como una advertencia de alerta, por decirlo de alguna manera.

Implementaciones y pruebas referidas al TP 2 de Programación III en Ruby

Abrimos nuestro editor de textos preferido y copiamos lo siguiente:

class Persona

# Definimos getters
def get_nombre()
return @nombre
end

def get_apellido()
return @apellido
end

def get_dni()
return @dni
end

def get_padre()
return @padre
end

def get_madre()
return @madre
end

# Definimos setters
def set_nombre(nombre)
@nombre = nombre
end

def set_apellido(apellido)
@apellido = apellido
end

def set_dni(dni)
@dni = dni
end

def set_padre(padre)
@padre = padre
end

def set_madre(madre)
@madre = madre
end

end


Observemos que los getters y los setters son similares, y solo cambia la variable a la que esta definida. Existen métodos dentro de Ruby que permiten automatizar la creacion de setters y getters. Ellos son:

attr_reader: Para creación de getters
attr_writer: Para creación de setters
attr_accessor: Para creación de getters y setters

El código anteriormente presentado se reduciría al siguiente

class Persona
attr_accessor :nombre, :apellido, :dni, :padre, :madre
end

Con esta ultima implementación abrimos un interprete interactivo (irb) y hacemos algunas pruebas(En negrita las lineas ingresadas por el usuario):

$ irb
irb(main):001:0> require 'Personas_con_accesors'

=> true
irb(main):002:0> p = Persona.new()

=> #
irb(main):005:0> p.methods

=> ["inspect", "tap", "clone", "public_methods", "__send__", "object_id", "instance_variable_defined?", "apellido", "equal?", "freeze", "extend", "apellido=", "send", "methods", "hash", "dup", "to_enum", "instance_variables", "dni", "eql?", "instance_eval", "id", "dni=", "singleton_methods", "taint", "enum_for", "frozen?", "instance_variable_get", "instance_of?", "padre", "display", "to_a", "method", "type", "padre=", "instance_exec", "protected_methods", "==", "===", "instance_variable_set", "kind_of?", "madre", "respond_to?", "to_s", "class", "madre=", "private_methods", "=~", "tainted?", "__id__", "nombre", "untaint", "nil?", "is_a?", "nombre="]
irb(main):010:0> p.public_methods(false)

=> ["padre", "madre=", "nombre=", "dni", "padre=", "apellido", "dni=", "madre", "nombre", "apellido="]
irb(main):011:0> p.nombre="Ana"

=> "Ana"
irb(main):012:0> p.apellido="Garcia"

=> "Garcia"
irb(main):013:0> p.dni=33221256

=> 33221256
irb(main):014:0> p.nombre

=> "Ana"
irb(main):015:0> p2 = Persona.new

=> #
irb(main):016:0> p2.nombre="Jose"

=> "Jose"
irb(main):017:0> p2.apellido="Taringa"

=> "Taringa"
irb(main):018:0> p.padre=p2

=> #
irb(main):019:0> p.inspect

=> "#>"
irb(main):020:0> exit

$

Hemos visto hasta aquí la implementación de métodos y clases en sus formas básicas.

Pasemos a definir ahora un método para inicializar el objeto. Sabemos que el método para inicializar un objeto es una función que asigna a las variables de instancia los valores adecuados para que el objeto funcione en el sistema sin problemas. Como todas las variables sin valor se inician con nil, sabemos que no es conveniente para operar, siempre es conveniente tener un mensaje de inicialización de los objetos.

class Persona

attr_accessor :nombre, :apellido, :dni, :padre, :madre

def initialize(nombre, apellido, dni, padre="", madre="")
@nombre = nombre
@apellido = apellido
@dni = dni
@padre = padre
@madre = madre
end
end

Un dato interesante es que el método initialize es automáticamente invocado cuando le enviamos el mensaje new a la clase. No debemos preocuparnos por la inicialización de los objetos una vez que implementamos el método de inicialización.

Si observamos la cabecera del método de inicialización

def initialize(nombre, apellido, dni, padre="", madre="")

vemos que padre y madre se asignan con cadenas vacías. Lo que estamos haciendo es asignar valores por defecto a esas dos variables. O sea, nombre, apellido y dni son obligatorios para crear un objeto de la clase Persona, pero padre y madre son opcionales.

$ irb
irb(main):001:0> require 'Personas_con_accesors_y_mensaje_de_inicializacion'

=> true
irb(main):002:0> p = Persona.new("Jose", "Taringa", 23456876)

=> #
irb(main):003:0> p.padre

=> ""
irb(main):004:0> p2 = Persona.new("Pedro", "Taringa", 14678384)

=> #
irb(main):005:0> p.padre= p2

=> #
irb(main):006:0> p.inspect()

=> "#>"
irb(main):007:0> exit

$

Por ultimo, observemos que la sentencia require se utiliza para importar módulos. Lo que va entre comillas simples es el nombre del archivo que desea importarse. Si encuentra un archivo con ese nombre en la carpeta local, lo carga (como en nuestro ejemplo), sino, busca en la librería estandar de Ruby. Si tampoco lo encuentra allí, lanza un error.

Recursos:

http://www.ruby-lang.org/es/documentation/quickstart/

http://tryruby.hobix.com/

Saturday, October 3, 2009

Algo sobre el Lenguaje Ruby (I)

Buenas a todos. A invitación de Alejandro, este es el primero de una serie de posts acerca de Ruby, un lenguaje interpretado y orientado a objetos que por varios motivos a cobrado renombre y se extendió su uso en el ultimo tiempo. Veamos de que se trata.

¿Que es Ruby?

Ruby es un lenguaje de alto nivel, interpretado, dinámico, de código abierto y orientado a objetos. Su autor, Yukihiro Matsumoto (Matz), se inspiro en lenguajes como Python, Perl, Lisp, Smalltalk y Eiffel, entre otros.

El lenguaje en si es un programa interprete y gran numero de bibliotecas que proveen todo tipo de funcionalidades aptas para ser usadas en desarrollo de sistemas profesionales, educativos y académicos.

Características:

  • Alto nivel: "Los lenguajes de programación de alto nivel se caracterizan por expresar los algoritmos de una manera adecuada a la capacidad cognitiva humana, en lugar de a la capacidad ejecutora de las máquinas"[1].

  • Interpretado: No es necesario un proceso de compilación. Existe un programa, llamado intérprete, el cual es invocado en el momento que se desea ejecutar un programa. Este intérprete va ejecutando cada una de las acciones programadas mediante un proceso de conversión de código Ruby a código entendible por la maquina. El proceso de interpretación se realiza a medida que se necesita ejecutar una instrucción.

  • Dinámico: Las variables en un mismo programa pueden tomar valores de diferentes tipos de datos. Si bien no es obligatorio, la gran mayoría de los lenguajes dinámicos son interpretados.

  • Software libre y código abierto: El interprete y las bibliotecas tienen una doble licencia: GPL y Ruby (Software libre y código abierto respectivamente).

  • Orientado a Objetos: Paradigma de la programación que usa estructuras conocidas como objetos, y las vincula de una manera especifica (mensajes) para establecer la construcción de un programa o sistema. La unidad mínima del paradigma es el “Objeto”, una entidad que reúne conocimiento y comportamiento. Un objeto provee un grupo de mensajes al “resto del mundo” (otros objetos) para interactuar con ellos. Los objetos se envían mensajes entre si, y dichos mensajes se vinculan con métodos específicos que implican una secuencia de acciones a realizar.

  • Multiparadigma: Se entiende con esta denominación, a toda una gama de lenguajes que permiten programar en un mismo momento en varios paradigmas de programación. Por ejemplo, usar estructuras de iteración como el while, y en otras partes del mismo programa usar objetos. Ruby es uno de los lenguajes que permite programar combinadamente en varios paradigmas de programación.

Posee una sintaxis muy similar a Python y Perl, con lo cual comenzar a trabajar con el lenguaje es muy intuitivo, pero también sirve para desarrollos avanzados.

Por ejemplo, el primer programa que podemos hacer con Ruby:

puts “hola mundo”

Si escribimos el texto anterior en un archivo, lo guardamos como “hola.rb” y desde una terminal escribimos:

$ ruby hola.rb
hola mundo
$

Como prerrequisito, se debe tener instalado el interprete Ruby y las bibliotecas del Lenguaje, el cual se descarga gratuitamente desde internet y esta soportado en diversas plataformas de desarrollo (Windows, Linux, etc...)

El interprete interactivo vs. el Workspace

Si se esta acostumbrado a trabajar en Smalltalk y su workspace, a la hora de desarrollar con Ruby se extrañara un lugar donde hacer pruebas paso a paso de un grupo de sentencias. Una solución a esto es el interprete interactivo llamado irb, el cual nos provee una interfaz para ejecutar código Ruby en el momento, y nos provee un entorno de trabajo temporal para realizar pruebas y pequeñas tareas.

Las diferencias entre el interprete interactivo y el workspace, es que en el primer caso se usa para tests y desarrollos puntuales menores, en cambio, el segundo se concibe como el ambiente donde una vez que todo funcione, quedara la aplicación definitiva. El workspace tiene además herramientas de debugging y toda una gama de aplicaciones que lo hace mucho mas completo. El interprete interactivo, por el contrario, provee por si mismo contadas instrucciones propias y facilita el ingreso de código y su evaluación.

Una sesión en el interprete interactivo[2]:

$ irb
irb(main):001:0> "Hola mundo"
=> "Hola mundo"
irb(main):002:0> puts "Hola mundo"
Hola mundo
=> nil
irb(main):003:0> 5 + 4
=> 9
irb(main):004:0> 5 * 5
=> 25
irb(main):005:0> Math.sqrt(9)
=> 3.0
irb(main):006:0> a = 3 ** 2
=> 9
irb(main):007:0> b = 4 ** 2
=> 16
irb(main):008:0> Math.sqrt(a+b)
=> 5.0
irb(main):009:0> Math.methods
=> ["private_class_method", "inspect", "name", "tap", "sinh", "clone", "public_methods", "__send__", "object_id", "method_defined?", "instance_variable_defined?", "exp", "equal?", "freeze", "acos", "extend", "ldexp", "send", "const_defined?", "methods", "instance_method", "ancestors", "module_eval", "hash", "tanh", "dup", "autoload?", "instance_variables", "to_enum", "atan2", "instance_methods", "public_method_defined?", "log", "class_variable_defined?", "eql?", "constants", "asin", "id", "instance_eval", "hypot", "singleton_methods", "module_exec", "const_missing", "acosh", "taint", "instance_variable_get", "frozen?", "enum_for", "private_method_defined?", "cos", "public_instance_methods", "display", "instance_of?", "log10", "method", "to_a", "included_modules", "atan", "const_get", "instance_exec", "type", "erf", "<", "protected_methods", "<=>", "class_eval", "==", "asinh", "class_variables", ">", "===", "instance_variable_set", "sin", "protected_instance_methods", "protected_method_defined?", "respond_to?", "kind_of?", "sqrt", ">=", "public_class_method", "to_s", "<=", "cosh", "const_set", "class", "erfc", "private_methods", "=~", "tainted?", "__id__", "class_exec", "autoload", "atanh", "untaint", "nil?", "private_instance_methods", "tan", "include?", "is_a?", "frexp"] irb(main):010:0> quit
$

El interprete es una gran herramienta para los desarrolladores, dado que permite ejecutar porciones de código mostrando sus resultados. Al igual que en Python, el uso del interprete interactivo a permitido a programadores elevar de manera notable la productividad, pues se realizan depuraciones parciales de código a medida que se tienen dudas sobre el mismo. Esto reduce la fase de depuración final que ocurría en los desarrollos con lenguajes estáticos.

Notas al pie:

[1]: http://es.wikipedia.org/wiki/Lenguaje_de_alto_nivel
[2]: Ejemplo extraído en su mayoría de http://www.ruby-lang.org/es/documentation/quickstart/

Notas de la clase 4 y guía de trabajos prácticos


Como siempre, comenzamos con ping-ping de preguntas y respuestas para recordar lo visto hasta ahora.

En la práctica (TP3) anterior utilizamos el "if" de Smalltalk como receta. Ahora vimos que se trata de un mensaje (#ifTrue:) que entienden tanto true (la única instancia de la clase True) como false (la única instancia de la clase False). Es un muy buen ejemplo de polimorfismo.

#ifTrue: es un mensaje que espera un bloque (instancia de la clase BlockContext) como parámetro. Los bloques se crean literalmente encerrando una expresión Smalltalk entre corchetes. Como son objetos podemos asignarlos a variables, pasarlos como parámetros, y enviarles mensajes. En particular los bloques entienden el mensaje #value que hace que ejecuten su expresión Smalltalk.

Avanzando sobre el ejercicio de las cuentas bancarias vimos herencia. Vimos como funciona la herencia de conocimiento (variables de instancia) y como funciona la herencia de comportamiento (vía la búsqueda de métodos siguiendo la cadena de herencia). Vimos que una subclase puede agregar nuevos métodos y variables a las que hereda. También vimos que si define nuevamente un método que hereda, este "ocultará" al heredado en la búsqueda de método. A eso le llamamos sobre-escribir métodos (override en inglés).

También hablamos sobre self, la pseudovariable que apunta al objeto que se encuentra ejecutando el método. Todavía nos queda por conocer super, una pseudovariable que también apunta al mismo objeto que self, pero que cambia la forma en la que se buscan los métodos.

Finalmente hicimos un diagrama que mostraba envió de mensajes entre instancias de distintas clases en el ejemplo de un cajero automático. El objetivo de ese diagrama es doble; por un lado introduce la notación de diagramas de comunicación de UML; por otro lado da un panorama de como se combina todo lo visto hasta ahora para construir algo mas interesante.


Práctica

Les dejé prática nueva en el grupo de google . Esta práctica tienen que entregarla resuelta antes del lunes 12 de octubre. Cuenta como nota de concepto para definir el parcial en caso de que este dudoso.



Lectura
Les recomiendo que lean el capitulo 2 (y los anteriores si todavía no los leyeron) del libro Programando con Smalltalk de Diego Gomez Deck. Repasa todo lo que vimos hasta ahora (tipos de mensajes, variables, precedencia, etc.) y en la sección 2.7 habla de bloques y del mensaje #ifTrue: y  sus variantes.


En ese mismo libro (al final del capitulo 1) pueden leer sobre herencia. 


El capitulo 3 (Syntax in a nutshell) de Squeak by Example da un panorama completo de toda la sintaxis del languaje vista hasta ahora. Como lo dice el título, tiene muchos ejemplos.


La sección Developing in Squeak de Squeak by Example presenta los principios de Smalltalk. Es recomiendo leerlo. En particular habla de herencia. 
  • Rule 1. Everything is an object.
  • Rule 2. Every object is an instance of a class.
  • Rule 3. Every class has a superclass.
  • Rule 4. Everything happens by message sends.
  • Rule 5. Method lookup follows the inheritance chain.
La notación gráfica que usaremos se llama UML. Pueden leer sobre diagramas de comunicación en el capítulo 12 del libro UML Gota a Gota de Martin Fowler 

Thursday, September 24, 2009

Notas de la clase 3 y guía de trabajos prácticos

El foco de esta clase fue entender relaciones entre objetos. Hicimos rol playing (algunos de ustedes eran objetos) para hacer bien gráficos temas como envío de mensaje, encapsulamiento, relaciones entre objetos y pasaje de parámetros.

Hablamos sobre literales y sobre magnitudes. Vimos que los operadores aritméticos son envíos de mensajes y que los números (y otras magnitudes) son objetos.

Hicimos MUCHO hincapié en el proceso de búsqueda de método (¿qué hace un objeto cuando recibe un mensaje?) y hablamos de binding dinámico. También hablamos un poco de polimorfismo con el ejemplo de las magnitudes y los mensajes de comparar. Vimos que el binding dinámico es importante para el polimorfismo.

Hablamos sobre tipos de mensajes en Smalltalk y orden de precedencia (unarios, binarios, palabra clave).

¿Que capítulos de la bibliografía recomiendan que leamos para repasar estos temas? ¿Están leyendo esto al menos? :)

Les dejo una práctica nueva para fijar algunos de los temas que vimos en clase. Esta práctica además los guía paso a paso para cargar una aplicación web que interactue con uno de sus objetos.

La práctica es un archivo zip con el enunciado y un par de archivos con objetos ya preparados para que carguen en la imagen.

Wednesday, September 16, 2009

Notas de la clase 2 y guía de trabajos prácticos

Iniciamos la clase con algunas preguntas sobre los temas vistos anteriormente. La pregunta clase es ¿qué es un objeto?

Basándonos en el (clásico) ejemplo de la cuenta bancaria reforzamos la idea de conocimiento y comportamiento de un objeto. El conocimiento de la cuenta son su saldo, titular y numero. Su comportamiento es devolverme su saldo, extraer y depositar.

Implementamos los métodos para una cuenta y simulamos el comportamiento de la misma haciendo que uno de los alumnos tomara el rol de la cuenta (sus variables estaban escritas en una hoja que el sostenía).  Luego vimos que podíamos tener otras cuentas como esta y llegamos al concepto de "la clase" como "molde" para la creación de instancias. Pueden leer mas sobre clases e instancias en el capítulo 1 del libro de Budd.

Recordamos que un objeto oculta su información y por tanto solo podemos acceder a su conocimiento enviándole mensajes.

Luego vimos como implementar clases y métodos en Squeak usando el browser. Interactuamos con instancias de Cuenta en el workspace. Para verificar que estuvieran funcionando bien, monitoreabamos su estado interno con inspectores. El libro Squeak by example seguro les sirve de ayuda para recordar todo sobre el browser y los menues de Squeak. También pueden dar una mirada al link que dejé en bibliografia "Squeak Smalltalk: language reference".

Nos dimos cuenta de que un objeto debe estar inicializado y hablamos del método #initialize. En squeak, el mensaje #initialize se envía automaticamente a las instancias tan pronto son creadas (ya veremos porque).

Resumimos todo lo que sabíamos sobre variables hasta ahora (de instancia, de workspace, parametros y temporales).

Finalmente terminanos de cerrar la idea de las variables como apuntadores a objeto. Esto implica que las variables de instancia de un objeto pueden apuntar a otros objetos. Esto nos permite hacer que un objeto  "conozca" a otro. El ejemplo que vimos en clase fue la Cuenta, que en su variable "titular" ya no tiene un String sino una Persona.

La guía de trabajos prácticos 2 que ya esta subida al grupo de google tiene preguntas y ejercicios para reforzar todo lo visto en clase. Haré algunas preguntas al principio de la clase que próxima.

Sunday, September 6, 2009

Notas de la clase 1 y guía de trabajos prácticos

El foco de la primer clase es introducir el paradigma de programación orientada a objetos y algunos de sus conceptos principales: abstracción, objeto, mensaje,  métodos, atributos, encapsulamiento. Estos temas los cubre muy bien el capítulo 1 (Thinking Object Oriented) del libro de Timothy Budd. Ojo que todavía no hablamos clases, de herencia ni de polimorfismo.

Para entender la OOP y aprender a pensar en objetos se requiere una herramienta adecuada (y mucha práctica). Squeak (Smalltalk) es esa herramienta. En la primer clase conoceremos un poco de la historia de Smalltalk, instalaremos y exploraremos Squeak y veremos como crear objetos, enviarles mensajes, y ver el resultado. En Squeak todo es un objeto. Pueden leer estos temas en español del libro de Gomez-Deck, sin embargo sigue un orden diferente al que seguimos en la materia y seguro menciona temas que todavía no vimos. El capitulo 1 (hasta la sección 1.5 inclusive) del libro Squeak By Example es otro buen punto de partida para arrancar con Squeak.

Descarguen y resuelvan la guia de trabajos prácticos correspondiente a esta clase. Es importante que se tomen un buen tiempo para entender y responder las preguntas (leyendo la bibliografía y buscando en la web). Los ejercicios en Smalltalk apuntan a que todos tengan esta semana un Squeak funcionando, sepan como instalarlo y copiarlo, y puedan utilizar un workspace para prácticar lo visto en clase. Además ya vamos fijando el vocabulario.

Horarios, aulas y fechas de evaluación

Teoría
Martes 14:30 a 17:00 (aula 411)
Responsable: Alejandro Fernández

Teoría
Martes 14:00 a 14:30 (aula 411)



Práctica
Viernes 10:00 a 12:00 (aula 411)
Responsable: David Conde

Evaluaciónes parciales (fechas tentativas)
Parcial: Martes 24 de Noviembre
Recuperatorio: Martes 1 de Diciembre

Software requerido

Squeak Smalltalk

Durante la materia vamos a utilizar el lenguaje y ambiente de programación Squeak Smalltalk. Es un ambiente puro de programación orientada a objetos.

Nos basaremos en la versión 3.10 que pueden instalar en Windows, Linux y Mac (además de muchas otras plataformas). Pueden descargarlo desde http://www.squeak.org/Download/ (ojo que necesitan descargar el ejecutable (llamado máquina virtual), la imagen virtual, y los sources.
El la primer clase de la materia veremos como instalarlo y como hacer nuestras primeras pruebas con algunos de los objetos disponibles.

Van a encontrar bastante documentación y bibliografía en inglés.
En la página  Bibliografía y material de referencia del grupo encontrarán tres libros (uno de ellos en español) para bajar en pdf.

ArgoUML
Para construir diagramas de UML recomendamos utilizar argoUML. Es muy completo y es open source. Lo pueden descargar desde la pagina oficial. Es open source y multiplataforma.

Bibliografia y material de referencia

Programación orientada a objetos

Smalltalk (en pdf)

Seaside

UML
  • Uml Gota A Gota Martin Fowler - Kendall Scott (Addison Wesley) ISBN: 9684443641. ISBN-13: 9789684443648

Friday, September 4, 2009

Programa de la materia - Programación III

OBJETIVOS
El objetivo de Programación III es introducir a los alumnos en técnicas modernas de la programación, en particular en aspectos orientada a objetos y diseño orientado a objetos.

FUNDAMENTOS

Se enfatizará en la construcción de arquitecturas de software modulares, extensibles y reusables, conceptos claves para aplicaciones de gran porte. Se introducirá también al alumno en el uso de un lenguaje de modelado gráfico orientado a objetos (UML), que le permitirá construir diagramas especificando distintos aspectos de un sistema. Los trabajos prácticos se realizarán usando el lenguaje de modelado y diferentes lenguajes de implementación, tales como Smalltalk o Java.

UNIDAD 1
La crisis del software. Problemas de las técnicas tradicionales (procedurales). Resolución de problemas complejos. El problema de la extensibilidad, el reuso y el mantenimiento.

UNIDAD 2
Conceptos básicos: Encapsulamiento. Information hiding. Objetos y Programa Orientado a Objetos. Comportamiento de un Objeto. Mensaje y Método. Clasificación: Clases e Instancias. Instanciación. Jerarquías de Clases. Relación isA. Generalización / Especialización. Herencia, Herencia Simple. Clases Abstractas. Hacia mayor genericidad de código: polimorfismo y binding dinámico.

UNIDAD 3
Diseño de objetos complejos. Relaciones entre Objetos. Relación de conocimiento. Relación isPartOf.

UNIDAD 4
Lenguajes orientados a objetos: variantes. El lenguaje Smalltalk. Tipos de Mensajes. Variables de instancia. PseudoVariables: self y super. Método new. Biblioteca de clases, jerarquías pre-definidas: class Magnitude y su protocolo.

UNIDAD 5
Estructuras de Control: Clases Boolean, False y True. Métodos: or:, and: not. Definición de bloques de código. Clase Context. Métodos: value y value:. Métodos ifTrue:, ifFalse:, ifTrue: ifFalse:, whileTrue:, whileFalse:.

UNIDAD 6
Estructuras de datos como Objetos. Objetos contenedores. Colecciones de Objetos. Clase Collection y sus subclases Array, OrderedCollection, Set, Dictionary y SortedCollection. Protocolo estándar. Iteradores: to: do:, to: by: do:, timesRepeat:. El iterador do: de Collection. Otros iteradores de Collection: select:, detect:, reject:, collect:, inject: to:.

UNIDAD 7

Lenguajes de modelado orientados a objetos: historia y variantes. El lenguaje de Modelado Unificado (Unified Modeling Language). Diagramas de Estructura Estática: Diagramas de Clases. Diagramas Dinámicos ó de Comportamiento: Diagramas de Interacción (Diagramas de Secuencia y Diagramas de Colaboración).

UNIDAD 8
Aplicación de técnicas orientadas a objetos para la construcción de aplicaciones. Separación de persistencia, modelo y presentación. Mecanismos de Dependencias. Diseño de Interfaces: Model-View-Controller. Métodos changed: y update:.. Introducción al desarrollo de aplicaciones web. Concurrencia y transacciones. Framework Seaside. Introdución a la persistencia de de objetos: serialización, bases de datos orientadas a objetos.

PLAN DE EVALUACIÓN
Para obtener la regularidad se deberá aprobar un examen parcial, teniendo como máximo una posibilidad de recuperación. Para la aprobación final, los alumnos que hayan terminado la materia en condición regular deberán rendir un examen final teórico práctico. Los alumnos en condición libre, deberán adicionalmente presentar la guía de trabajos prácticos (actualizada) correctamente resuelta.