Blog de Abelardo Jara Berrocal: Ubuntu, electronica y software libre

Noviembre 23, 2007

Chequeando tipos en tiempo de compilacion: Tipeado estatico en C++ y Java

Archivado en: Temas Ingenieria de Computadoras y Electronica — Abelardo Jara @ 8:47 pm

The process of verifying and enforcing the constraints of types – type checking – may occur either at compile-time (a static check) or run-time (a dynamic check). If a language enforces type rules strongly (that is, generally allowing only those automatic type conversions which do not lose information), one can refer to the process as strongly typed, if not, as weakly typed.

[edit] Static typing

In most compiled computer languages, such as C, C++, Java and Pascal, the data type of every variable, parameter and function return value is known at compile time. The programmer has to provide the type information through declarations. This is known as static typing (but some statically typed languages may include implicit declarations). A programming language is statically typed if type checking may be performed without testing equivalence of run-time expressions. A statically typed programming language respects the distinction between run-time and compile-time phases of processing. A language has a compile-time phase if separate modules of a program can be type checked separately (separate compilation), without information about all modules that exist at run time. Static type-checking becomes a primary task of the semantic analysis carried out by a compiler.

[edit] Dynamic typing

In languages with dynamic data typing, such as Lisp, Perl, Python, Ruby, and JavaScript, type information for data is associated with data rather than the variables through which the data is accessed. Variables may, if needed, refer to data of different types during the execution of a program when necessary. The advantages of dynamic data typing can include more flexibility and quicker development for the programmer. But programmers from a static and manifestly typed language background are used to using data type declarations to help in organizing and understanding a program, and this prop is lost.

In dynamic typing, type checking often takes place at runtime because the value bound to a variable could be of different types dependent on the programs execution path.

To see how dynamic typing works, consider the fileObject parameter and f variable in the following pseudocode example:

// Print the First line of a File
function printFirstLine(fileObject){
print fileObject.getline();
}
f = File(“path”); // return a file object
printFirstLine(f);
f = StringAsFile(“First Line \n More”) // Return a file-like object
printFirstLine(f);

In the first call to printFirstLine, f and fileObject are associated with an instance of File. In the second call they are associated with an instance of StringAsFile. Dynamic typing helps in allowing the one function, printFirstLine, to work reliably with both object types. (Duck typing allows the getline method call to be checked).

Note that the opposite of dynamically typed is statically typed, and is a separate and orthogonal consideration to strong typing/weak typing.

Generar archivo distribuible JAR en Netbeans

Archivado en: Programacion en Java — Abelardo Jara @ 8:07 pm

Presionar Mayusculas+F11

o en el menu Build escojes Clean and Build Main Project

en tu carpeta de proyecto se creará una carpeta de nombre dist en la cual se coloca el archivo jar que seria el ejecutable de tu aplicacion.

si usas librerias externas debes modificar el archivo de manifiesto (MANIFEST.MF) que se encuentra dentro del jar. eso lo puedes hacer con winrar

wxWidgets: un framework libre para desarrollar aplicaciones con GUI nativas en Windows y Linux

Archivado en: Programacion C++ en Linux, Programacion C++ en Windows — Abelardo Jara @ 7:23 pm

Al desarrollar aplicaciones muchas veces nos encontramos con el hecho de que nuestros usuarios no siempre van a usar el mismo sistema operativo. Para que nadie se sienta discriminado, como a veces nos sentimos discriminados los usuarios de GNU/Linux cuando se desarrollan programas que solo sirven en sistemas de Microsoft, es una buena idea tratar de hacer que nuestra aplicación pueda funcionar en varias plataformas, o al menos sea fácil de portar.

Hace poco tuve que realizar una aplicación que funcionara perfectamente tanto en GNU/Linux, como en Microsoft Windows. Para resolver el problema decidí analizar varias alternativas:

* Java. La primera alternativa que se me vino a la mente fue Java, funciona perfectamente en varias plataformas sin necesidad de recompilar, tiene un Framework muy bien diseñado, avanzado y potente. Sin embargo, existen algunos inconvenientes que me hicieron desistir de java: el primero es que, aunque es gratuito, el JDK no es software libre y mi intención era construir una aplicación completamente con herramientas libres. Por otro lado, Java no está diseñado para construir aplicaciones rápidas, el hecho de correr bajo una máquina virtual, y utilizar en exceso herramientas como polimorfismo dinámico y RTTI hacen que las aplicaciones Java tiendan a ser lentas, algo que definitivamente no deseaba para mi aplicación.
* Qt. La otra alternativa a considerar es el Framework Qt, en el cual se basa el escritorio de GNU/Linux KDE. Como ventajas tiene el hecho de tener una buena velocidad, debido a que está escrito en C++ y tener un muy buen diseño orientado a objetos que hacen muy placentero programar con Qt. Por otro lado, el problema con Qt consiste principalmente en que solo es software libre en su versión para GNU/Linux [1], todas las demás versiones (Win32, MacOS y otros) son propietarias (y además con alto costo), lo que hizo que descartara inmediatamente a Qt.
* GTK+. Otra librería importante a considerar era GTK+. Tiene varias ventajas, como por ejemplo que está disponible para muchísimos sistemas operativos y es completamente libre, con licencia LGPL. Sin embargo, GTK+ tenía algunos inconvenientes que me hicieron desistir de usarlo: En primer lugar, GTK+ solo posee funcionalidad para desarrollar interfaces gráficas de usuario y deja un lugar vacio a aspectos como bases de datos, redes, etc. Por otro lado, el API de GTK+ está escrito de forma estructurada en lenguaje C, y mi intención era trabajar de forma orientada a objetos. Aunque existe GTKmm[2], me parece que tiene el mismo diseño estructurado pero usando clases en C++.

La última opción que consideré fue wxWidgets, un framework antes conocido como wxWindows [3], especializado en el desarrollo de aplicaciones multiplataforma en lenguaje C++. Fue en definitiva el que escogí para realizar mi aplicación, por las siguientes razones:

* Soporta varios sistemas operativos, pero con una pequeña particularidad: de acuerdo a la plataforma en que se ejecute la aplicación, esta tomara el look and feel del SO donde se esté ejecutando. Por ejemplo, si se ejecuta en MS-Windows, la aplicación tendrá la apariencia de una aplicación hecha con el API de Windows, pero si se ejecuta en GNU/Linux, tendrá la apariencia de una aplicación GTK2. Es decir que la parte de GUI es solo una capa para el API nativa de cada SO. Además de lo anterior, wxWidgets cuenta con una versión embebida [4] para dispositivos como PDAs y teléfonos celulares.
* Es cien por ciento libre en todas las plataformas que soporta, con una licencia LGPL modificada [5].
* Tiene un API orientada a objetos que es, en extremo, fácil de aprender y utilizar. Creo que ninguna otra de las opciones mencionadas anteriormente tiene una curva de aprendizaje tan suave.
* Posee funcionalidades para muchos aspectos aparte de la construcción de interfaces gráficas. Como gráficos 2D, 3D con OpenGL, Bases de Datos (ODBC), Redes, Impresión, Hilos, entre muchas otras.

Pese a todas estas ventajas, wxWidgets también tiene algunas desventajas: Su diseño orientado a objetos no es el mejor que uno pueda ver. A veces abusa de la utilización de macros para realizar ciertas operaciones (como las tablas de eventos), aunque esto hace que codificar sea más fácil, también complica la labor de depuración, especialmente para los mismos desarrolladores de wxWidgets. Por otro lado, debido a que el framework se comenzó a desarrollar hace bastante tiempo, no cuenta con soporte para algunas características relativamente modernas [6] del lenguaje C++ como por ejemplo el manejo de excepciones, y la STL.

Debido a sus grandes pros y sus pocos contras, puedo decir que recomiendo ampliamente wxWidgets como una herramienta para el desarrollo de aplicaciones sean o no sean multiplataforma. Y tal vez en un artículo posterior pueda profundizar un poco más en los detalles de este extraordinario Framework.

Los problemas que genera herencia multiple en C++

Archivado en: Programacion C++ en Linux — Abelardo Jara @ 2:57 pm

La herencia múltiple es uno de los puntos peliagudos del lenguaje C++ (y de otros que también implementan este tipo de herencia). Hasta el extremo que algunos teóricos consideran que esta característica debe evitarse, ya que además de las teóricas, presenta también una gran dificultad técnica para su implementación en los compiladores.

Por ejemplo, surge la cuestión: si dos clases A y B conforman la composición de una subclase D, y ambas tienen propiedades con el mismo nombre, ¿Que debe resultar en la subclase D? Miembros duplicados, o un miembro que sean la agregación de las propiedades de A y B?. Como veremos a continuación, el creador del C++ optó por un diseño que despeja cualquier posible ambigüedad, aunque ciertamente deriva en una serie de reglas y condiciones bastante intrincadas.

Por eso en Java y en C++ se prefiere usar agregacion o composicion: es decir crear una clase cuyos miembros son las otras clases de quienes necesitamos usar sus propiedades y metodos. Como sabemos en agregacion los objetos miembro pueden existir antes o despues que el objeto que los agrega este existente (se pasan por referencia o punteros) y en el caso de composicion los objetos miembro no pueden existir si el objeto que los engloba no existe (son declarados como variables o creados y destruidos en el constructor y destructor de la clase que engloba).

Asi por ejemplo:
Un caballo tiene un rabo
Un caballo tiene 4 patas

Mediante agregacion, los objetos miembro rabo y patas viven solo mientras en objeto caballo vive.

Por ejemplo un caso confuso de agregacion:

class B { … };

class C1 : public B { … };

class C2 : public B { … };

class D : public C1, C2 { … };

Aqui D hereda de B por 2 lados. Por eso es preferible usar agregacion.

Elegir que version de Java usar por defecto

Archivado en: Programacion en Java — Abelardo Jara @ 2:04 pm

A veces podemos instalar varias versiones de Java en nuestro sistema, siendo un problema elegir cual sera la por defecto para utilizarla en compilacion.

El comando para elegir la heramienta java por defecto es:

sudo update-alternatives –config java

Diferencias entre C++ y Java

Archivado en: Programacion C++ en Linux — Abelardo Jara @ 1:29 pm

Sintaxis:
Prácticamente idéntica en C++ y Java

Orientación a objetos:
En C++ se pueden escribir programas orientados a objetos, no
orientados a objetos, o mezcla de ambos (por ejemplo, tener clases
con funciones globales en el mismo programa)

Java es puramente orientado a objetos; cualquier función debe pertenecer
a alguna clase (es un método). Existe la función main, pero es un método,
pero es un método estático de una clase (la clase principal)

Control sobre la plataforma (hardware+S.O.):
C y C++: el programador tiene control del procesador.
Java: el programa se ejecuta sobre un procesador virtual (JVM) que
abstrae al programador de la plataforma concreta

Código de máquina generado:
C y C++: el compilador genera código de máquina para una plataforma
concreta
Java: el compilador genera código de máquina (bytecode) para el
procesador JVM; dicho código debe ser interpretado a posteriori

Liberación de Memoria:
C y C++: a cargo del programador (delete)
Java: automática; los objetos creados son destruidos automáticamente
ente cuando se quedan sin referencias. Un proceso de la JVM llamado
recolector de basura (garbage collector)

Punteros:
C y C++: existen punteros con una aritmética bien definida, y entre otras
cosas, permiten programador explorar la memoria del computador físico
Java: no existe el concepto de puntero; los objetos son accedidos
mediante referencias (una referencia se puede considerar como el propio
propio identificador del objeto); no existe aritmética de referencias.

Paquetes:
C y C++: no existe tal concepto; lo más aproximado son los archivos de
biblioteca (.h)
Java: un paquete es una entidad organizativa que permite agrupar clases,
interfaces y excepciones, así como que sus elementos dispongan de una
determinada visibilidad con respecto a elementos externos al paquete

Conversión implícita de tipos:
C y C++: existe (flexibilidad para el programador)
Java: no existe por considerarse un mecanismo objeto de errores
potenciales

Sobrecarga de funciones y operadores:
C++: existen ambos tipos de sobrecarga
Java: sólo existe la sobrecarga de funciones (métodos); Los
operadores que existen ya vienen sobrecargados por el compilador,
(p.e. + para sumar números o concatenar cadenas).

Herencia múltiple:
C++: existe
Java: no existe por considerarse poco eficiente (esto implicó algunas
críticas a Java desde ciertos sectores)

Interfaces:
C++: no existen este concepto
Java: existe el concepto de interfaz como conjunto de especificaciones
de métodos y de atributos constantes.

Estructuras dinámicas:
C++: Librería STL
Java: paquete java.util. Los nombres y el funcionamiento son distintos.

Compiladores:
C++: Muchos compiladores. Pueden ser bastante distintos.
Java: Un único compilador siempre igual.

Objetos:
C++: Ningún ancestro común.
Java: Todos los objetos heredan automáticamente de la clase Object.

Compartir impresora de Ubuntu Gutsy con Windows XP

Archivado en: Linux Ubuntu Administracion — Abelardo Jara @ 2:11 am

By following these steps, you will be able to share a printer from your Ubuntu computer so that Windows XP and Windows 2000 computers can print to it.
Gusty

NOTE: This was tested with the beta version of Gutsy.

1) Make sure your printer is installed.

2) Open the Printing window (System -> Administration -> Printing).

3) Click Server Settings in the list of printers.

4) To the right, under Basic Server Settings, check the box that reads, “Share published printers connected to this system”.

5) In the list of printers, click the printer you want to share.

6) Click in the Policies tab and make sure all three check boxes (Enabled, Accepting jobs, and Shared) are checked.

7) Click the Apply button in the lower-right corner of the window.

On the Windows machine:

1) Now add the printer to the Windows computer by using the Windows “Add Printer” Wizard. Select to connect a network printer and then select the option to connect a printer on the Internet or on a home or small office network. Type in the following for the printer URL:

http://:631/printers/

Replace “” with the hostname of the Ubuntu computer sharing the printer. Replace “” with the name (exactly as displayed including displayed casing) that was shown in the Printers window you opened earlier on the Ubuntu machine. It’s also possible to replace “” with the IP address of the computer sharing the printer.

2) Windows will ask you to select a driver for the printer. If you have the Windows print drivers, you should use them. Click the “Have Disk” button and select the .inf file that describes your print drivers.

If you do not have the drivers for the printer or cannot load the .inf file, you should select the “MS Publisher Color Printer” driver from the “Generic” manufacturer. This driver should be found on all Windows 2000 and XP installations by default and it gives all the printing functionality one should need.
Earlier Versions

NOTE: This document has been tested with Ubuntu versions 5.10, 6.06, 6.10, and 7.04.

1) Install the printer on the Ubuntu computer by using the printer wizard (System -> Administration -> Printers then double-click on “Add new printer” icon when the “Printers” window opens).

2) Press +.

3) Modify /etc/cups/cupsd.conf with your favourite editor, for example

gksudo gedit /etc/cups/cupsd.conf

or

gksudo gedit -w /etc/cups/cupsd.conf

NOTE: For Kubuntu users, you use kdesu instead of gksudo. An appropriate text editor would be kate instead of gedit.

4) Scroll down until you see the “Listen” configurations. There should be two and they are

Listen localhost:631
Listen /var/run/cups/cups.sock

Below those lines add another “Listen” configuration corresponding to the IP address of the computer sharing out the printer. For example, if the IP address is 192.168.1.2, add this line.

Listen 192.168.1.2:631

5) Save the file. Now restart the printing system with this command:

sudo /etc/init.d/cupsys restart

6) Now add the printer to the Windows computer by using the Windows “Add Printer” Wizard. Select to connect a network printer and then select the option to connect a printer on the Internet or on a home or small office network. Type in the following for the printer URL:

http://:631/printers/

Replace “” with the hostname of the Ubuntu computer sharing the printer. Replace “” with your printer’s name. It’s also possible to replace “” with the IP address of the computer sharing the printer.

NOTE: If using a hostname doesn’t work, you could add this entry to C:\WINDOWS\system32\drivers\etc\hosts. This should only be required for Ubuntu versions prior to Feisty.

192.168.0.100 printer-server

Replace “192.168.0.100″ with the IP address of the computer sharing the printer, then you can use a hostname instead.

http://printer-server:631/printers/Deskjet-940C

For a driver, you should select the “MS Publisher Color Printer” driver from the “Generic” manufacturer. This driver should be found on all Windows 2000 and XP installations by default and it gives all the printing functionality one can need.

It’s also possible to use a driver from the manufacturer of the printer. This is harder to setup as most driver installation software from the manufacturer require that the printer be detected first on the Windows machine before the driver can be installed.

Blog de WordPress.com.