]> git.llucax.com Git - z.facultad/75.31/presentacion.git/commitdiff
Prácticamente terminado, falta redondear detalles.
authorLeandro Lucarella <llucax@gmail.com>
Mon, 30 May 2005 01:33:09 +0000 (01:33 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Mon, 30 May 2005 01:33:09 +0000 (01:33 +0000)
ejemplos/invariante_repr.d [new file with mode: 0644]
ejemplos/modulo1.d [new file with mode: 0644]
ejemplos/modulo2.d [new file with mode: 0644]
ejemplos/modulos.d [new file with mode: 0644]
ejemplos/pre_post.d [new file with mode: 0644]
ejemplos/propiedades.d [new file with mode: 0644]
ejemplos/seguridad.d [new file with mode: 0644]
ejemplos/unit_test.d [new file with mode: 0644]
presentacion_d.lyx

diff --git a/ejemplos/invariante_repr.d b/ejemplos/invariante_repr.d
new file mode 100644 (file)
index 0000000..cca424c
--- /dev/null
@@ -0,0 +1,27 @@
+
+class Fecha
+{
+       int dia = 1;
+       int mes = 1;
+       invariant
+       {
+               assert(1 <= dia && dia <= 31);
+               assert(1 <= mes && mes <= 12);
+       }
+       void p()
+       {
+               int d = dia;
+               dia = 50;
+               dia = d;
+               printf("%02d-%02d\n", dia, mes);
+       }
+}
+
+int main()
+{
+       Fecha f = new Fecha;
+       f.p();
+       f.dia = 40;
+       f.p();
+       return 0;
+}
diff --git a/ejemplos/modulo1.d b/ejemplos/modulo1.d
new file mode 100644 (file)
index 0000000..70774f9
--- /dev/null
@@ -0,0 +1,10 @@
+
+import modulo2;
+
+class C { float i; }
+
+void func(modulo2.C c)
+{
+       printf("c.i = %d\n", c.i);
+}
+
diff --git a/ejemplos/modulo2.d b/ejemplos/modulo2.d
new file mode 100644 (file)
index 0000000..598d3b0
--- /dev/null
@@ -0,0 +1,3 @@
+
+class C { int i; }
+
diff --git a/ejemplos/modulos.d b/ejemplos/modulos.d
new file mode 100644 (file)
index 0000000..d551683
--- /dev/null
@@ -0,0 +1,8 @@
+import modulo1;
+import modulo2;
+
+int main()
+{
+       func(new modulo2.C);
+       return 0;
+}
diff --git a/ejemplos/pre_post.d b/ejemplos/pre_post.d
new file mode 100644 (file)
index 0000000..920cb60
--- /dev/null
@@ -0,0 +1,22 @@
+
+import std.math;
+
+long raiz(long x)
+       in
+       {
+               assert(x >= 0);
+       }
+       out (result)
+       {
+               assert((result * result) == x);
+       }
+       body
+       {
+               return cast(long) sqrt(cast(float) x);
+       }
+
+int main()
+{
+       raiz(8);
+       return 0;
+}
diff --git a/ejemplos/propiedades.d b/ejemplos/propiedades.d
new file mode 100644 (file)
index 0000000..473f413
--- /dev/null
@@ -0,0 +1,22 @@
+
+class C
+{
+       int _i;
+       int read() { return _i; }
+       int write(int i) { return _i = i; }
+       int rw() { return _i; }
+       int rw(int i) { return _i = i; }
+}
+
+int main()
+{
+       C c = new C;
+       // c.read = 1; NO COMPILA
+       c.write = 2;
+       printf("c.read = %d\n", c.read);
+       // printf("c.read = %d\n", c.write); NO COMPILA
+       c.rw = 3;
+       printf("c.rw = %d\n", c.rw);
+       return 0;
+}
+
diff --git a/ejemplos/seguridad.d b/ejemplos/seguridad.d
new file mode 100644 (file)
index 0000000..df984f1
--- /dev/null
@@ -0,0 +1,24 @@
+
+class C
+{
+       private int i;
+}
+
+struct S
+{
+       private int i;
+}
+
+int main()
+{
+       C c = new C;
+       printf("c.i = %d\n", c.i);
+       c.i = 1;
+       printf("c.i = %d\n", c.i);
+       S s;
+       printf("s.i = %d\n", s.i);
+       s.i = 1;
+       printf("s.i = %d\n", s.i);
+       return 0;
+}
+
diff --git a/ejemplos/unit_test.d b/ejemplos/unit_test.d
new file mode 100644 (file)
index 0000000..925e7c6
--- /dev/null
@@ -0,0 +1,14 @@
+
+class C
+{
+       unittest
+       {
+               assert(ok());
+       }
+       static bit ok() { return false; }
+}
+
+int main()
+{
+       return 0;
+}
index 28a50be33a47e1b1e58eb8daa5205ec7d6fe571c..4428aa198afa6b43ad39002da656b2ea7b20acc3 100644 (file)
@@ -35,6 +35,14 @@ Leandro Lucarella (77891)
 \layout Date
 
 30 de Mayo de 2005
 \layout Date
 
 30 de Mayo de 2005
+\layout Standard
+
+
+\begin_inset LatexCommand \tableofcontents{}
+
+\end_inset 
+
+
 \layout Section
 
 Introducción
 \layout Section
 
 Introducción
@@ -427,6 +435,11 @@ f.mes = 5;
 f.print();
 \layout Subsubsection
 
 f.print();
 \layout Subsubsection
 
+
+\begin_inset LatexCommand \label{sub:tipo-class}
+
+\end_inset 
+
 class
 \layout Standard
 
 class
 \layout Standard
 
@@ -435,6 +448,16 @@ Las clases son la forma en la que D implementa la orientaci
  Por ahora sólo adelantaremos que es muy similar a un struct, sólo que guarda
  algo más de información de control (como la tabla virtual) para poder implement
 ar polimorfismo y herencia.
  Por ahora sólo adelantaremos que es muy similar a un struct, sólo que guarda
  algo más de información de control (como la tabla virtual) para poder implement
 ar polimorfismo y herencia.
+\layout Subsubsection
+
+interface
+\layout Standard
+
+Las interfaces son un caso particular de clases, que no puede tener atributos,
+ sólo métodos.
+ Una clase puede implementar varias interfaces, por lo que esto no e es
+ más que una forma limitada de implementar herencia múltiple, eliminando
+ el problema de la representación en memoria de los datos.
 \layout Section
 
 Expresiones
 \layout Section
 
 Expresiones
@@ -974,12 +997,6 @@ tiene un comportamiento aleatorio.
  se puede usar memoria no administrada por el recolector.
 \layout Subsection
 
  se puede usar memoria no administrada por el recolector.
 \layout Subsection
 
-Instrucciones
-\layout Comment
-
-por ahora vuela porque no sé a qué se refiere
-\layout Subsection
-
 
 \begin_inset LatexCommand \label{sub:Rutinas}
 
 
 \begin_inset LatexCommand \label{sub:Rutinas}
 
@@ -1116,6 +1133,11 @@ call
  extra que no figuraban en la declaración de la función.
 \layout Subsubsection
 
  extra que no figuraban en la declaración de la función.
 \layout Subsubsection
 
+
+\begin_inset LatexCommand \label{sub:Sobrecarga-de-funciones}
+
+\end_inset 
+
 Sobrecarga de funciones
 \layout Standard
 
 Sobrecarga de funciones
 \layout Standard
 
@@ -1149,30 +1171,709 @@ name mangling
 \layout Section
 
 Estructura del programa
 \layout Section
 
 Estructura del programa
+\layout Standard
+
+La estructura general de un programa D es muy similar a la de uno en C++.
+ Simplemente se compone de funciones y tipos definidos por el usuario.
+ Existe una función especial llamada 
+\family typewriter 
+main()
+\family default 
+ que es el punto de partida del programa, indispensable a menos que estemos
+ construyendo una biblioteca.
+\layout Subsection
+
+Módulos
+\layout Standard
+
+D elimina el preprocesador e incorpora el concepto de módulo (a diferencia
+ de C++ que utiliza espacios de nombre).
+ El módulo tiene alcance de archivo y tiene correspondencia 1 a 1 con la
+ ruta y nombre del archivo.
+ Por ejemplo el módulo 
+\family typewriter 
+mi.primer.modulo
+\family default 
+ se busca en 
+\family typewriter 
+mi/primer/modulo.d
+\family default 
+.
+ A la ruta representada como módulo se la llama 
+\emph on 
+paquete
+\emph default 
+; es decir, el módulo 
+\family typewriter 
+modulo
+\family default 
+ pertenece al paquete 
+\family typewriter 
+mi.primer
+\family default 
+.
+ El módulo entonces provee un espacio de nombres, cuyos símbolos pueden
+ ser importados en otros módulos.
+ Por ejemplo:
+\layout Standard
+
+modulo1.d:
+\layout LyX-Code
+
+import modulo2;
+\layout LyX-Code
+
+class C
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        float i;
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+void func(modulo2.C c)
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        printf("c.i = %d
+\backslash 
+n", c.i);
+\layout LyX-Code
+
+}
+\layout Standard
+
+modulo2.d:
+\layout LyX-Code
+
+class C
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        int i;
+\layout LyX-Code
+
+}
+\layout Standard
+
+modulos.d
+\layout LyX-Code
+
+import modulo1;
+\layout LyX-Code
+
+import modulo2;
+\layout LyX-Code
+
+int main()
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        func(new modulo2.C);
+\layout LyX-Code
+
+        return 0;
+\layout LyX-Code
+
+}
+\layout Standard
+
+Como se puede observar, no es imperativo poner el modulo al que pertenece
+ un símbolo, a menos que se lo quiera desambiguar (si hay 2 símbolos con
+ el mismo nombre en 2 módulos distintos).
 \layout Subsection
 
 \layout Subsection
 
-Módulos, espacios de nombres, Interfaces
+Compilación condicional
 \layout Standard
 
 \layout Standard
 
+Al no proveer un precompilador, D provee un mecanismo de compilación condicional
+ directamente incluída en el lenguaje.
+ Simplemente se agregan bloques de código que se compilan sólamente si se
+ le pasa un cierto parámetro al compilador indicando que porción compilar.
+ Este concepto va un poco más allá, ya que hay compilación condicional incluso
+ de bloques no son puestos explícitamente como tales, como los bloques de
+ invariante de representación de una clase o de pre y post condiciones de
+ funciones.
+ Ejemplo:
+\layout LyX-Code
+
+version (OPTIMIZE)
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+    version (DEBUG) printf(
+\begin_inset Quotes eld
+\end_inset 
+
+entrando a optimización
+\begin_inset Quotes erd
+\end_inset 
+
+);
+\layout LyX-Code
+
+    optimizar();
+\layout LyX-Code
+
+}
+\layout Standard
+
+D además provee varios identificadores de versión predefinidos, como la
+ plataforma, 
+\emph on 
+endianess
+\emph default 
+, sistema operativo, etc.
+\layout Standard
+
+Además provee otros métodos, como 
+\family typewriter 
+static if
+\family default 
+, 
+\family typewriter 
+static assert
+\family default 
+, 
+\family typewriter 
+iftype
+\family default 
+ o 
+\family typewriter 
+debug
+\family default 
+, pero son todas vueltas de tuerca sobre el mismo concepto.
+\layout Subsection
+
+Assembly embebido
+\layout Standard
+
+D, al igual que C, permite embeber assembly en el lenguaje.
+ Esto es útil para hacer código de alta performance para fragmentos críticos,
+ ya que D está pensando como un lenguaje de alta performance y apto para
+ el desarrollo de aplicaciones de sistema (como controladores, etc).
 \layout Section
 
 Orientación a objetos
 \layout Section
 
 Orientación a objetos
+\layout Standard
+
+Como ya se ha mencionado, D provee orientación a objetos principalmente
+ a través de el tipo class (ver sección 
+\begin_inset LatexCommand \vref{sub:tipo-class}
+
+\end_inset 
+
+), pero provee algunos mecanismos también a través de los módulos o struct.
 \layout Subsection
 
 \layout Subsection
 
-TAD's
+Abstracción
+\layout Standard
+
+La abstracción de datos puede darse a nivel de class, struct o module.
+ Ambos proveen mecanismos para poder efectuar operaciones sobre un dato
+ sin conocerlo.
+ En el caso de struct y class es exactamente igual en cuanto a abstracción.
+ El módulo es un poco diferente ya que hay sólo una instancia del mismo
+ (es decir, todos sus datos son estáticos), pero también puede servir para
+ abstraer.
+ D provee sintaxis acoplada (
+\emph on 
+bundle
+\emph default 
+) a través del operador de 
+\emph on 
+scope
+\emph default 
+\begin_inset Quotes eld
+\end_inset 
+
+.
+\begin_inset Quotes erd
+\end_inset 
+
+, que se utiliza tanto para class como para struct y module.
+ El module, al no ser un tipo en sí, no soporta sintaxis desacoplada (
+\emph on 
+unbundle
+\emph default 
+).
+ Lo mismo pasa con los métodos estáticos de clase.
+\layout Standard
+
+Todos los objetos en D son con estado explícito, aunque pueden 
+\emph on 
+emularse
+\emph default 
+ objetos 
+\emph on 
+inmutables
+\emph default 
+ declarándolos 
+\family typewriter 
+const
+\family default 
+, pero esto no hace se se resuelvan en tiempo de compilación, en realidad
+ tienen estado sólo que el compilador no deja que se modifique.
+ Es decir, no hay forma de tener abstracción declarativa.
+\layout Subsubsection
+
+Propiedades
+\layout Standard
+
+D provee un mecanismo muy interesante y práctico, las propiedades.
+ Una clase (o estructura) puede tener métodos especiales que pueden ser
+ llamados como si fueran atributos de la clase.
+ No es más que azucar sintáctico pero es muy útil y está implementado de
+ una forma muy simple.
+ Cualquier método que tenga un sólo argumento y devuelva un valor del mismo
+ tipo se convierte en una propiedad de escritura y cualquier método que
+ no tome argumentos y devuelva un valor se convierte en una propiedad de
+ lectura.
+ Incluyendo ambos se pueden tener propiedades de lectura/escritura.
+ Veamos un ejemplo:
+\layout LyX-Code
+
+class C
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        int _i;
+\layout LyX-Code
+
+        int read() { return _i; }
+\layout LyX-Code
+
+        int write(int i) { return _i = i; }
+\layout LyX-Code
+
+        int rw() { return _i; }
+\layout LyX-Code
+
+        int rw(int i) { return _i = i; }
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+int main()
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        C c = new C;
+\layout LyX-Code
+
+        // c.read = 1; NO COMPILA
+\layout LyX-Code
+
+        c.write = 2;
+\layout LyX-Code
+
+        printf("c.read = %d
+\backslash 
+n", c.read);
+\layout LyX-Code
+
+        // printf("c.read = %d
+\backslash 
+n", c.write); NO COMPILA
+\layout LyX-Code
+
+        c.rw = 3;
+\layout LyX-Code
+
+        printf("c.rw = %d
+\backslash 
+n", c.rw);
+\layout LyX-Code
+
+        return 0;
+\layout LyX-Code
+
+}
+\layout Standard
+
+Además todos los tipos básicos poseen propiedades, algunas comunes a todos
+ (como 
+\family typewriter 
+sizeof
+\family default 
+, que devuelve su tamaño, en general estos son todos resueltos en tiempo
+ de compilación) y otros particulares de cada tipo (como 
+\family typewriter 
+length
+\family default 
+ para los array, que devuelve la cantidad de elementos que almacena).
+\layout Subsubsection
+
+Sobrecarga de operadores
+\layout Standard
+
+Otro mecanismo importante de abstracción que provee D es la sobrecarga de
+ operadores.
+ Se puede sobrecargar los operadores de clases y estructuras, de manera
+ tal de hacerlos ver sintácticamente como tipos nativos del lenguaje.
+ También es azucar sintáctico y un caso particular de sobrecarga de funciones
+ (ver página 
+\begin_inset LatexCommand \pageref{sub:Sobrecarga-de-funciones}
+
+\end_inset 
+
+).
+\layout Subsection
+
+Seguridad
+\layout Standard
+
+D provee mecanismos de seguridad, tanto a nivel de módulo como de clase
+ y estructuras, aunque se ha comprobado empíricamente que el compilador
+ no lo está chequeando por el momento.
+ Por ejemplo, el siguiente código compila y corre:
+\layout LyX-Code
+
+class C
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        private int i;
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+int main()
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        C c = new C;
+\layout LyX-Code
+
+        c.i = 1;
+\layout LyX-Code
+
+        return 0;
+\layout LyX-Code
+
+}
+\layout Subsection
+
+Herencia
+\layout Standard
+
+El único tipo que permite herencia es class (y su sub-tipo interface).
+ D permite herencia simple entre clases comunes y una herencia múltiple
+ limitada a través de las interfaces.
+ Es decir, una clase sólo puede heredar de una sola clase, pero puede implementa
+r muchas interfaces.
 \layout Subsection
 
 Polimorfismo
 \layout Subsection
 
 Polimorfismo
-\layout Comment
+\layout Standard
 
 
-Si hay orientación a objetos y describir cómo es.
+D implementa polimorfismo principalmente (pero no únicamente) a través de
+ las clases (e interfaces) y sus funciones virtuales, pero también a través
+ de la sobrecarga de funciones en general.
+\layout Subsubsection
+
+Polimorfismo estático
+\layout Standard
+
+D provee tipos genéricos, también conocidos en el mundo de los lenguajes
+ compilados como 
+\emph on 
+templates
+\emph default 
+ o polimorfismo estático, ya que permite que una función o clase se comporte
+ de distinta manera pero se resuelve en tiempo de compilación.
 \layout Section
 
 Paralelismo / Concurrencia
 \layout Section
 
 Paralelismo / Concurrencia
-\layout Section
+\layout Standard
+
+D provee algunas pocas primitivas para el soporte de concurrencia.
+ En la biblioteca estándar provee una clase para ejecutar múltiples hilos
+ y provee en el lenguaje la palabra reservada 
+\family typewriter 
+synchronized
+\family default 
+ para agregar bloqueo y desbloqueo de exclusión mutua (
+\emph on 
+mutex
+\emph default 
+) automáticamente antes y después (respectivamente) de bloque que encierra.
+ También puede usarse como clasificador de almacén (es decir, para proteger
+ una variable) o como modificador de una función (para proteger dicha función)
+ o de clase o de cualquier otra sentencia.
+\layout Standard
 
 
-¿Para qué no sirve este lenguaje?
+Es necesario utilizar la clase 
+\family typewriter 
+Thread
+\family default 
+ para ejecutar múltiples hilos ya que el recolector de basura tiene que
+ saber de todos los hilos que están corriendo para poder administrar su
+ memoria (y frenarlos ante un ciclo de recolección), aunque técnicamente
+ podría evitarse ya que se puede acceder a cualquier biblioteca de C (incluyendo
+ la de hilos).
 \layout Section
 
 \layout Section
 
-¿Para qué sí sirve este lenguaje? 
+Programación segura
+\layout Standard
+
+Uno de los objetivos principales de D es implementar técnicas de programación
+ segura, para tratar de evitar (o al menos detectar) la mayor cantidad de
+ errores de manera simple.
+ Veamos entonces algunos mecanismos que provee para satisfacer este objetivo.
+\layout Subsection
+
+Programación por contrato
+\layout Standard
+
+La programación por contrato consiste en imponer ciertas reglas que se cumplan
+ en distintos momentos del programa.
+ Básicamente provee 3 conceptos para verificar estos 
+\emph on 
+contratos
+\emph default 
+: 
+\emph on 
+assert
+\emph default 
+, invariantes de representación y pre y post condiciones.
+ Esto parece contradecir el objetivo de D de ser un lenguaje de alta performance
+, ya que si se hacen muchos chequeos, inevitablemente se sacrifica performance.
+ Pero esto no es necesariamente cierto, ya que todos estos mecanismos pueden
+ ser desactivados en tiempo de compilación, logrando tener un código para
+ depuración muy robusto y lleno de chequeos y un código para producción
+ muy eficiente y rápido.
+\layout Subsubsection
+
+assert
+\layout Standard
+
+Este es el tipo más básico de contrato, provisto también de una forma más
+ primitiva por C (a través del precompilador).
+ Simplemente evalua en tiempo de ejecución que una expresión evalue a 
+\emph on 
+true
+\emph default 
+.
+ Si no es así, simplemente el programa lanza una excepción.
+\layout Subsubsection
+
+Invariante de representación
+\layout Standard
+
+Las clases puede incluir un invariante de presentación.
+ Esto es un fragmento de código que se ejecuta cada vez que se cambia una
+ instancia de la clase (excepto cuando los cambios se realizan desde una
+ función miembro.
+ Esto permite asegurar que los objetos estén siempre en estado consistente,
+ mientras se ejecute código que no conoce su representación.
+ Por ejemplo:
+\layout LyX-Code
+
+class Fecha
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        int dia = 1;
+\layout LyX-Code
+
+        int mes = 1;
+\layout LyX-Code
+
+        invariant
+\layout LyX-Code
+
+        {
+\layout LyX-Code
+
+                assert(1 <= dia && dia <= 31);
+\layout LyX-Code
+
+                assert(1 <= mes && mes <= 12);
+\layout LyX-Code
+
+        }
+\layout LyX-Code
+
+        void p()
+\layout LyX-Code
+
+        {
+\layout LyX-Code
+
+                int d = dia;
+\layout LyX-Code
+
+                dia = 50; // ok, dentro de la clase no se chequea
+\layout LyX-Code
+
+                dia = d;
+\layout LyX-Code
+
+                printf("%02d-%02d
+\backslash 
+n", dia, mes);
+\layout LyX-Code
+
+        }
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+Fecha f = new Fecha;
+\layout LyX-Code
+
+f.p(); // ok
+\layout LyX-Code
+
+f.dia = 40; // error!
+\layout Subsubsection
+
+Pre y post condiciones
+\layout Standard
+
+Toda función puede tener, además de su cuerpo, un bloque de código de precondici
+ones y/o un bloque de código de postcondiciones, que será ejecutado antes
+ y/o después de ejecutar la función (respectivamente).
+ Veamos un ejemplo:
+\layout LyX-Code
+
+long raiz(long x)
+\layout LyX-Code
+
+    in
+\layout LyX-Code
+
+    {
+\layout LyX-Code
+
+        assert(x >= 0);
+\layout LyX-Code
+
+    }
+\layout LyX-Code
+
+    out (result)
+\layout LyX-Code
+
+    {
+\layout LyX-Code
+
+        assert((result * result) == x);
+\layout LyX-Code
+
+    }
+\layout LyX-Code
+
+    body
+\layout LyX-Code
+
+    {
+\layout LyX-Code
+
+        return cast(long) std.math.sqrt(cast(float) x);
+\layout LyX-Code
+
+    }
+\layout Standard
+
+El parámetro del bloque 
+\family typewriter 
+out
+\family default 
+ es el valor devuelto por el cuerpo de la función.
+ Entonces cuando se llame a 
+\family typewriter 
+raiz(8)
+\family default 
+, el compilador (a menos que esté en modo 
+\emph on 
+release
+\emph default 
+) lo traducirá a:
+\layout LyX-Code
+
+assert(8 >= 0); // ok
+\layout LyX-Code
+
+long tmp = raiz(8); // devuelve 2 por la conversión a long
+\layout LyX-Code
+
+assert((2 * 2) == 8); // error!
+\layout Subsection
+
+Casos de prueba
+\layout Standard
+
+D provee dentro del lenguaje herramientas para realizar casos de prueba
+ (
+\emph on 
+unit tests
+\emph default 
+) para asegurarse que una clase se comporte como debe.
+ Este código se ejecuta cuando se inicia el programa si se compila con la
+ opción de 
+\family typewriter 
+unittest
+\family default 
+.
+ Por ejemplo:
+\layout LyX-Code
+
+class C
+\layout LyX-Code
+
+{
+\layout LyX-Code
+
+        unittest
+\layout LyX-Code
+
+        {
+\layout LyX-Code
+
+                assert(ok());
+\layout LyX-Code
+
+        }
+\layout LyX-Code
+
+        static bit ok() { return false; }
+\layout LyX-Code
+
+}
+\layout Standard
+
+Un programa que use esta clase saldrá apenas se inicia con una excepción
+ por el 
+\family typewriter 
+assert
+\family default 
+.
 \the_end
 \the_end