Programación.
Índice general 1
Programación
1
1.1
Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.2
Léxico y programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.3
Programas y algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.4
Compilación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.5
Programación e ingeniería del software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.6
Referencias históricas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.7
Objetivos de la programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.8
Ciclo de vida del software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.9
Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
1.10 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
1.11 Enlaces externos
4
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Portal:Programación
5
3
&
6
4
5
6
3.1
Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
3.2
Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
3.3
Enlaces externos
7
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Acoplamiento secuencial
8
4.1
Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
4.2
Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
Adobe Director
9
5.1
Interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
5.2
Timeline
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
5.3
Director y Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
5.4
Shockwave / Shockwave 3D
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
5.5
Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
5.6
Enlaces externos
10
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Anidamiento (informática)
12
6.1
12
En las planillas de cálculo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
ii
7
8
9
ÍNDICE GENERAL 6.2
En programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
6.3
Véase también
12
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Antipatrón de diseño
13
7.1
Algunos antipatrones de desarrollo de software . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
7.1.1
Antipatrones de gestión
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
7.1.2
Antipatrones de gestión de proyectos . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
7.1.3
Antipatrones generales de diseño de software
. . . . . . . . . . . . . . . . . . . . . . . .
14
7.1.4
Antipatrones de programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
7.1.5
Antipatrones metodológicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
7.1.6
Antipatrones de gestión de la configuración
. . . . . . . . . . . . . . . . . . . . . . . . .
16
7.2
Algunos antipatrones organizacionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
7.3
Relación alfabética de otros antipatrones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
7.4
Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
7.5
Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
Archivo de cabecera
21
8.1
Motivación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
8.2
Alternativas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
8.3
Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
8.4
Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
Aserción (informática)
24
9.1
Uso de las aserciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
9.1.1
Aserciones en el diseño por contrato . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
9.1.2
Aserciones en tiempo de ejecución . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
9.1.3
Aserciones durante el ciclo de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
9.1.4
Aserciones estáticas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
9.2
Desactivación de las aserciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
9.3
Comparación con los manejadores de errores . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25
9.4
Enlaces externos
26
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10 Automatización de tareas
27
11 Base de código
28
11.1 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12 Bean
28 29
12.1 Bean en Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
12.2 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
13 Beta tester
30
13.1 Generalidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
13.2 Alfa tester . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
ÍNDICE GENERAL
iii
13.3 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
13.4 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
14 Bifurcación (sistema operativo)
31
14.1 UNIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
14.2 Véase también
31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15 Binding
32
15.1 Psicología y educación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
15.2 Informática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
15.3 Derecho mercantil
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
15.4 Enlaces externos 16 Bloqueo mutuo
33
16.1 Representación de Bloqueos Mutuos usando grafos . . . . . . . . . . . . . . . . . . . . . . . . . .
33
16.2 Condiciones necesarias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
16.3 Evitando bloqueos mutuos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
16.5 Livelock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
16.4 Prevención
17 Bodyshopping
35
17.1 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
18 BrookGPU
36
19 Caja blanca (sistemas)
37
19.1 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Caja negra (sistemas)
37 38
20.1 Justificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
20.2 Caja negra y programación modular
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
20.3 Pruebas de software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
20.4 Caja negra vs 'Cajanegrizar' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
20.5 Véase también
38
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21 CamelCase
40
21.1 Usos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
40
21.2 Enlaces externos
40
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22 Caml 22.1 Ejemplos
41 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22.1.1 Hola Mundo
41
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
22.1.2 Función factorial (recursividad y programación puramente funcional) . . . . . . . . . . . .
41
22.1.3 Derivación numérica (funciones de alto orden) . . . . . . . . . . . . . . . . . . . . . . . .
41
22.1.4 Transformada Wavelet discreta (concordancia de patrones) . . . . . . . . . . . . . . . . .
42
iv
ÍNDICE GENERAL 22.2 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
22.3 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
22.4 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
22.4.1 Libros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42
23 Cierre de exclusión mutua
43
23.1 Primitivas y uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
23.2 Bloqueos en bases de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43
24 Clase utilidad
44
24.1 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
25 Clear.gif
45
26 CMake
46
26.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
26.2 Documentación y tutoriales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
26.3 Principales funcionalidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46
26.4 CTest, CPack, CDash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
26.5 Aplicaciones que utilizan CMake . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
26.6 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
26.7 Enlaces externos 27 Codecademy
48
27.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
27.2 Code Year
48
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27.3 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
27.4 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48
27.5 Enlaces externos
49
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28 Código cerrado 28.1 Véase también
50 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
50
29 Código compilado
51
30 Código mutante
52
31 Código objeto
53
31.1 Código objeto en lenguajes de programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
31.2 Errores comunes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
31.3 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
31.4 Enlaces externos
53
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32 Ofuscación 32.1 Informática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54 54
ÍNDICE GENERAL
v
32.1.1 Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
32.2 Otros objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
32.3 Enlaces externos
55
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33 ColdFusion
56
33.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
33.2 Versiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
33.3 Ejemplos de código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
57
33.4 Enlaces externos
57
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34 Coloreado de sintaxis
58
34.1 Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
34.2 Programas con coloreado de sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
34.3 Véase también
58
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35 Comentario (informática)
59
35.1 Información general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
35.2 Usos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59
35.2.1 Planeación / Revisión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
35.2.2 Descripción de código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
35.2.3 Descripción algorítmica
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
35.2.4 Inclusión de recursos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
35.2.5 Depuración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
35.2.6 Generación de documentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
35.3 Estilos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
35.3.1 Etiquetas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
35.4 Curiosidades
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.1 Ensamblador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.2 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.3 C/C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.4 Delphi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.5 Lua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.6 Ruby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.7 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.8 Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.9 Javascript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.10 código HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.11 SQL
62
35.5 Ejemplos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35.5.12 Visual Basic
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.13 Pauscal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.5.14 PHP
62
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
vi
ÍNDICE GENERAL 35.5.15 Cobol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.6 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
35.7 Enlaces externos
63
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36 Compatibilidad (informática)
64
36.1 Problemas de compatibilidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
36.2 Emulación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
36.3 OpenSource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
36.4 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
65
36.5 Enlaces externos
37 Competición Internacional Universitaria ACM de Programación
66
37.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66
37.2 Reglas de la competición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66
37.3 Competiciones locales, regionales y final mundial
. . . . . . . . . . . . . . . . . . . . . . . . . .
67
37.4 Lista de competiciones regionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
37.5 Ganadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
37.6 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68
37.7 Enlaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68
37.7.1 Jueces en Línea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68
38 Computación parasitaria
69
38.1 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
38.2 Enlaces externos
69
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39 Conectiva lógica
70
39.1 Lenguajes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
39.1.1 Lenguaje natural . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
39.1.2 Lenguajes formales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
39.2 Lista de conectivos lógicos comunes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
39.2.1 Lista de conectivos lógicos comunes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
39.2.2 Historia de las notaciones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
71
39.4 Propiedades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
39.5 Ciencias de la computación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
39.6 Conectivas por el número de argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
39.6.1 Sin argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
39.6.2 Con un argumento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
39.6.3 Con dos argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
39.3 Redundancia
39.7 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
39.8 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
39.9 Enlaces externos
73
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ÍNDICE GENERAL
vii
40 Configuración regional
74
40.1 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
74
40.2 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
74
40.3 Enlaces externos
74
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41 Conteo de referencias 41.1 Véase también
75 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
42 Convención de Nombres (Programación)
75 76
42.1 Beneficios potenciales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
42.2 Desafíos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
42.3 El valor del negocio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76
42.4 Elementos comunes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
42.4.1 Longitud de identificadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
42.4.2 Mayúsculas, minúsculas y números
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
42.4.3 Identificadores de varias palabras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
77
42.5 Metadatos y convenciones híbridas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
42.5.1 Notación húngara . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
42.5.2 Notación posicional
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
42.5.3 Esquema de palabra compuesta (del lenguaje) . . . . . . . . . . . . . . . . . . . . . . . .
78
42.6 Convenciones específicas del lenguaje
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
42.6.2 Ada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
78
42.6.3 C y C++
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
42.6.4 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
42.6.5 JavaScript
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
42.6.6 Lisp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
42.6.7 .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
42.6.8 Objective-C
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
42.6.9 Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
42.6.10 Python y Ruby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
42.6.1 ActionScript
42.7 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
42.8 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
42.9 Enlaces externos
80
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43 Cracking (software) 43.1 Véase también
81 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
81
44 Cuaderno de carga
82
45 Currificación
83
45.1 Nomenclatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
45.2 Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
viii
ÍNDICE GENERAL 45.3 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
45.4 Enlaces externos
83
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46 Código enhebrado
84
46.1 Historia que llevó al código enhebrado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
46.2 Desarrollo del código enhebrado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
46.3 Modelos de enhebrado
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
46.3.1 Enhebrado directo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
85
46.3.2 Enhebrado indirecto
86
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
46.3.3 Enhebrado de subrutina
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
46.3.5 Enhebrado de Huffman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
46.3.6 Enhebrados menos usados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
46.4 Bifurcaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
46.5 Amenidades comunes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
46.6 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
46.7 Lectura adicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87
46.8 Véase también
88
46.3.4 Enhebrado de token
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47 Código inalcanzable 47.1 Causas
89
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
47.2 Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89
47.3 Análisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
47.3.1 Profiling
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
47.5 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
47.6 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90
47.7 Enlaces externos
90
47.4 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48 Código muerto
91
48.1 Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
48.2 Análisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
48.3 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
48.4 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
48.5 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
91
48.6 Enlaces externos
91
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
49 Código redundante 49.1 Ejemplos
93
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
49.2 Eliminación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
49.3 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
49.4 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
93
ÍNDICE GENERAL
ix
50 Dato
94
50.1 Véase también 50.2 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
51 Depuración de programas
95
51.1 Origen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
95
51.2 Aplicación
95
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51.3 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52 Desarrollador de software 52.1 Véase también
95 96
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53 Desarrollo en cascada
96 97
53.1 Fases del modelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
53.1.1 Análisis de requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
53.1.2 Diseño del Sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
97
53.1.3 Diseño del Programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.1.4 Codificación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.1.5 Pruebas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.1.6 Verificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.1.7 Mantenimiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.2 Variantes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.3 Ventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.4 Desventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.5 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
98
53.6 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
99
53.7 Enlaces externos
99
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54 Desarrollo en espiral 54.1 Introducción
100
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
54.2 Ciclos o Iteraciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 54.2.1 Tareas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
54.3 Mecanismos de control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 54.4 Variaciones del Modelo En Espiral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 54.5 Ventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 54.6 Desventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 54.7 Inconvenientes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
54.8 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
54.9 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 54.10Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
55 Desarrollo iterativo y creciente 55.1 Concepto de desarrollo iterativo y creciente
103 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
x
ÍNDICE GENERAL 55.2 Ciclo de vida
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
55.2.1 Consideraciones sobre el momento de aplicación
. . . . . . . . . . . . . . . . . . . . . . 103
55.2.2 Etapa de inicialización . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 55.2.3 Etapa de iteración
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
55.3 Caso práctico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 55.4 Características
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
55.5 Ventajas del desarrollo incremental . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 55.6 Ventajas del desarrollo iterativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 55.7 Debilidades de este modelo de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 55.8 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
55.9 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 56 Detección dinámica de invariantes
107
56.1 Implementaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 57 Diagrama de colaboración
108
57.1 Usos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 57.2 Tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 57.3 Mensajes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
57.4 Flujos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 57.5 Cambios en versiones recientes de UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 58 Diagrama de flujo
110
58.1 Normas de trabajo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
58.2 Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 58.3 Tipos de diagramas de flujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 58.4 Simbología y significado
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
58.5 Cursograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 58.5.1 Simbología y normas del cursograma
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
58.6 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 58.7 Ventajas de los diagramas de flujo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
58.8 Software para diseño de diagramas de flujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 58.9 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
58.10Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 58.11Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
59 Diagrama Nassi-Shneiderman
114
59.1 Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 59.2 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 59.3 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
59.3.1 Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 60 diff
115
ÍNDICE GENERAL
xi
60.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 60.2 Algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 60.3 Uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 60.4 Variantes
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
60.4.1 Edit script
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
60.5 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 60.6 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
60.7 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
61 Dirección de retorno
118
62 Diseño estructurado
119
62.1 Etapas del Diseño estructurado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 62.1.1 Descomposición
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
62.1.2 Jerarquía de módulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 62.1.3 Independencia
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
62.2 Evaluando el diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 62.2.1 Acoplamiento
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
62.2.2 Cohesión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 62.2.3 Fan-In y Fan-Out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 62.3 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
63 Distancia de Damerau-Levenshtein
122
63.1 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 63.2 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
63.3 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 64 Distancia de Levenshtein
123
64.1 El algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 64.2 Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 64.2.1 C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 64.2.2 C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 64.2.3 C#
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
64.2.4 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 64.2.5 Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 64.2.6 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 64.2.7 Ruby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 64.2.8 PHP 64.2.9 Delphi
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
64.2.10 VB.NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 64.2.11 ActionScript 3.0
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
64.2.12 ColdFusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 64.2.13 JavaScript (NodeJS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
xii
ÍNDICE GENERAL 64.3 Aplicaciones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
64.4 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
64.5 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 65 DLO
126
65.1 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 66 Driver Chain Manager
127
66.1 ¿Qué hace? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 66.1.1 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 66.1.2 Capacidades de DCM
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
66.1.3 Cuestiones fuera del alcance de DCM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 66.2 Sotrware que utiliza DCM
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
66.2.1 Aplicaciones que utilizan DCM 66.2.2 Empresas desarrolladoras
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
66.2.3 Sistemas operativos que soportan ʻDCM . . . . . . . . . . . . . . . . . . . . . . . . . . 128 66.3 Funcionamiento de la cadena de drivers 66.3.1 El problema
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
66.3.2 Forma de solucionarlo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 66.4 Otras aplicaciones que utilizan DCM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 66.5 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
66.6 Fuentes y referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 67 Dublin Core
129
67.1 Descripción general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 67.2 Clasificación y elementos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 67.3 Usos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 67.4 Ventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 67.5 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 68 eAthena 68.1 Enlaces externos
132 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
69 Efecto Hover
133
69.1 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 69.2 Enlaces de interés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 70 Emtp
134
70.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 70.2 ATP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 70.3 Método de solución . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 70.4 Distribución de EMTP-ATP 70.5 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
70.6 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
ÍNDICE GENERAL
xiii
71 Enlace dinámico
135
72 Enlace estático
136
73 Enlazado
137
74 Entrada chapuza
138
74.1 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
74.2 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
75 Error de software
139
75.1 Orígenes del término . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 75.2 Defectos de diseño de programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 75.3 Errores de programación comunes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 75.4 Defectos de instalación o programación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
75.5 Códigos de errores de lenguajes de programación 75.6 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . 140
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
75.7 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140 75.8 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
76 Estilo de programación
142
76.1 Características del estilo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
76.1.1 Nombres de variable apropiadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 76.1.2 Estilo de indentación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 76.1.3 Valores booleanos en estructuras de decisión . . . . . . . . . . . . . . . . . . . . . . . . . 142 76.1.4 Bucles y estructuras de control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 76.1.5 Espaciado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 76.2 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
76.3 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
76.3.1 Convenciones de código en castellano . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 76.3.2 Convenciones de código en inglés
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
76.3.3 Convenciones de código de proyectos 77 Eventos del ratón 77.1 Véase también
144 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
78 Exclusión mutua (informática) 78.1 Véase también 79 Expresión regular
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
145
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 146
79.1 Construcción de expresiones regulares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 79.2 Aplicaciones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
79.3 Las expresiones regulares en programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 79.4 Descripción de las expresiones regulares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
xiv
ÍNDICE GENERAL 79.4.1 El punto ".” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 79.4.2 La admiración "!"
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
79.4.3 La barra inversa o antibarra "\" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 79.4.4 Los corchetes "[ ]" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 79.4.5 La barra "|" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 79.4.6 El signo de dólar "$" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 79.4.7 El acento circunflejo "^" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 79.4.8 Los paréntesis "()" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 79.4.9 El signo de interrogación "?" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 79.4.10 Las llaves "{}" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 79.4.11 El asterisco "*" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 79.4.12 El signo de suma "+" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 79.4.13 Grupos anónimos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 79.5 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
80 Flag
153
80.1 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
81 Front-end y back-end
154
81.1 Informática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 81.2 Tecnología
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
81.3 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 81.4 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 82 Fuga de memoria 82.1 RAII
156
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
82.2 Fugas de memoria en lenguajes con recolector de basura . . . . . . . . . . . . . . . . . . . . . . . 156 82.3 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 83 Generación de código
158
83.1 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
84 Generador de números aleatorios 84.1 Algoritmos
159
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
84.2 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 84.3 Enlaces externos 85 Gledplay
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 161
85.1 Dispositivos Soportados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 85.2 GledDraw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 85.3 GledVideo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
85.4 GledSave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 85.5 GledApplication
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
85.6 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
ÍNDICE GENERAL
xv
86 GPGPU
163
86.1 Modelo de programación GPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 86.2 Herramientas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 86.3 Críticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 86.4 Otros
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
86.5 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
86.6 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
87 Hackathon
165
87.1 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 87.2 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
88 Hacker
166
88.1 Otros significados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 88.2 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 88.2.1 ARPANET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 88.2.2 UNIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 88.2.3 GNU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 88.2.4 LINUX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 88.3 Ética hacker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 88.4 Controversia
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
88.4.1 Ambigüedad y debate
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
88.5 Activismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 88.6 Terminología . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 88.6.1 OverHat
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
88.6.2 White hat y black hat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 88.6.3 Samurái
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
88.6.4 Phreaker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 88.6.5 Lamer o script-kiddie
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
88.6.6 Newbie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 88.7 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
88.8 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 88.9 Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 88.10Enlaces externos 89 Heisenbug
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 172
89.1 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 89.2 Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 90 Hoja de estilo 90.1 Véase también 90.2 Enlaces externos
173 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
90.3 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
xvi
ÍNDICE GENERAL
91 Hola mundo 91.1 Véase también
174 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
91.2 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
91.3 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 92 Homebrew
175
92.1 Generalidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 92.2 Homebrew en diferentes consolas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 92.2.1 Sega Dreamcast
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
92.2.2 Nintendo Entertainment System (NES) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 92.2.3 Super Nintendo Entertainment System (SNES) . . . . . . . . . . . . . . . . . . . . . . . . 176 92.2.4 Nintendo DS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 92.2.5 Sony PSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 92.2.6 Microsoft Xbox
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
92.2.7 Microsoft Xbox 360 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 92.2.8 Nintendo Wii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 92.2.9 PlayStation 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 92.3 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
92.4 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 93 ICONIX 93.1 Ventajas de Iconix
179 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
93.2 Tareas de la metodología Iconix
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
93.2.1 Fase 1: Análisis de requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 93.2.2 Fase 2: Análisis y diseño preliminar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 93.2.3 Fase 3: Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 93.2.4 Fase 4: Implementación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
93.3 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 93.4 Conceptos Relacionados 93.5 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
93.5.1 Fase 2: Análisis y diseño preliminar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 93.5.2 Fase 3: Diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 93.5.3 Fase 4: Implementación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
93.6 Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 93.7 Conceptos Relacionados 93.8 Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
94 Anexo:Implementaciones de Smalltalk
181
95 Anexo:Implementaciones para algoritmo de rut
182
95.1 Objective-C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 95.2 C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 95.3 Visual Basic MS Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
ÍNDICE GENERAL
xvii
95.4 C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 95.5 Perl 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 95.6 Javascript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 95.7 PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 95.8 Transact-SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 95.9 MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 95.10PSeInt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 95.11Python 95.12Ruby
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
95.13Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 95.14Pl/pgsql de PostgreSql
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
96 Inanición (informática)
185
97 Indirección
186
98 Infraestructura de lenguaje común
187
98.1 Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
99 Ingeniería de software
189
99.1 Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 99.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 99.3 Recursos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
99.3.1 Recurso humano . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 99.3.2 Recursos de software reutilizables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 99.3.3 Recursos de entorno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 99.4 Implicaciones socioeconómicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 99.4.1 Económicamente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 99.4.2 Socialmente 99.5 Notaciones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
99.5.1 LUM (lenguaje unificado de modelado) o UML . . . . . . . . . . . . . . . . . . . . . . . 191 99.5.2 BPMN (notación para el modelado de procesos de negocios)
. . . . . . . . . . . . . . . . 191
99.5.3 Diagrama de flujo de datos (DFD) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 99.6 Herramienta CASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 99.7 Metodología
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
99.7.1 Etapas del proceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 99.7.2 Ventajas* [22] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 99.8 Modelos y Ciclos de Vida del Desarrollo de Software
. . . . . . . . . . . . . . . . . . . . . . . . 195
99.8.1 Modelo en cascada o clásico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 99.8.2 Modelo de prototipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 99.8.3 Modelo en espiral
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
99.8.4 Modelo de desarrollo por etapas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 99.8.5 Modelo Incremental o Iterativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
xviii
ÍNDICE GENERAL 99.8.6 Modelo RAD (rapid application development) . . . . . . . . . . . . . . . . . . . . . . . . 197 99.8.7 Modelo de desarrollo concurrente
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
99.8.8 Proceso unificado del desarrollo de software . . . . . . . . . . . . . . . . . . . . . . . . . 197 99.9 Producto
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
99.10Naturaleza de la Ingeniería de Software
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
99.11Participantes y papeles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 99.11.1 Cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 99.11.2 Desarrolladores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 99.11.3 Gestores
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
99.11.4 Usuarios finales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 99.11.5 Código ético de un ingeniero de software
. . . . . . . . . . . . . . . . . . . . . . . . . . 199
99.12Educación ética . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 99.12.1 Organizaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 99.13Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
99.14Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 99.15Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 99.16Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
100Instancia (informática) 100.1Etimología
202
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
100.2Programación basada en clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 100.2.1 Clases como objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 100.3Programación basada en prototipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 100.4Notas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 100.5Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 101Instrucción (informática)
204
101.1Campos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 101.2Tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 101.3Repertorio
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
101.4Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
102Interfaz binaria de aplicaciones
206
102.1Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 102.2EABI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 102.3Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
102.4Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 102.5Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 103Interfaz fluida
208
103.1Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 103.2Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
ÍNDICE GENERAL
xix
104Invariante (informática)
210
104.1Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
105Jframe 105.1Herencia
211 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
105.2Constructores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 105.3Métodos propios de la clase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 105.4Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
106Usuario discusión:Juliasocorro
213
107Kanban (desarrollo)
215
107.1El método Kanban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 107.2Los principios del método Kanban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 107.3Cinco prácticas centrales del método Kanban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 107.4Comportamiento emergente con Kanban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 107.5La implementación del método Kanban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 107.6Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 107.7Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
108Kit de desarrollo de software
218
108.1Incompatibilidad de licencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 108.2SDK para añadidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 108.3Términos más específicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 108.4Ejemplos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
108.5Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 108.6Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
108.7Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
109Kommander
220
109.1El editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 109.2El ejecutor
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
109.3Direcciones de Kommander 110Last Error (informática) 110.1Errores personalizados
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 221
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
110.2En DELPHI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 110.3Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
111Línea de código fuente 111.1El uso de medidas de LCF
222 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
111.2Programas para contar líneas de código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 111.2.1 Software Libre/Open Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 111.2.2 Freeware (software no libre) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
xx
ÍNDICE GENERAL 111.2.3 Comerciales
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
111.2.4 Basados en web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 111.3Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
111.4Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223 111.5Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
112Macintosh Toolbox
225
113Macro
226
113.1Macros de aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 113.2Macros en programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 113.3Macros ocultas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
113.4Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
114Malla de triángulos 3D
227
114.1Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 114.2Obtención de las mallas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 114.3Compresión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 115Mapeo objeto-relacional
229
115.1El problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 115.2Implementaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 115.3Bases de datos distintas a SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 115.4Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
115.5Enlaces relacionados
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
116Máquina de estados
231
117Máquina desnuda
232
118MCML
233
118.1Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
119Metaprogramación
234
119.1Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 120Microformatos Dublin Core
235
121Modelo de prototipos
236
121.1Etapas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 121.2Ventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 121.3Inconvenientes 121.4Conclusiones 121.5Véase también 122Modificador
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 238
ÍNDICE GENERAL
xxi
122.1Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
123Modularidad
239
123.1Modularidad en Ciencias de la Computación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 123.2Modularidad en Biología . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 123.3Modularidad en Economía y en la Empresa
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
123.4Modularidad en el diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 123.5Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 123.6Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
124Módulo (informática)
241
124.1Características de un módulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 124.2Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
125Monitor (concurrencia)
242
125.1Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 125.2Exclusión mutua en un monitor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 125.3Tipos de monitores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 125.3.1 Tipo Hoare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 125.3.2 Tipo Mesa
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
125.4Verificación de monitores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 125.4.1 Inicialización de las variables del monitor
. . . . . . . . . . . . . . . . . . . . . . . . . . 244
125.4.2 Monitores tipo Hoare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 125.4.3 Monitores tipo Mesa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 125.5Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
125.6Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 126Anexo:Motores de persistencia
245
126.0.1 ColdFusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 126.0.2 Common Lisp
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
126.0.3 Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 126.0.4 JavaScript
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
126.0.5 .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 126.0.6 Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 126.0.7 PHP
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
126.0.8 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 126.0.9 Ruby . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 126.0.10Smalltalk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 126.0.11C++
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
127Método de depuración del patito de goma 127.1Véase también
248
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
127.2Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
xxii
ÍNDICE GENERAL
127.3Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
128Net Yaroze
249
128.1Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
128.2Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
128.3Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 129Nodo (informática)
251
129.1Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 129.2Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
130Notación Reddick
252
130.1Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 130.2Notación para objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 130.3Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
131Notación húngara 131.1Ejemplos
253
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
131.2Situación actual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 131.2.1 Ejemplo notaciones de 1 carácter 131.3Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
132Null
254
133NWNScript
255
133.1Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
134Objeto todopoderoso
256
134.1Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 134.2Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 134.3Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
135Oday
257
136Offset (informática)
258
136.1Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
136.2Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 137OGNL
259
137.1Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 137.2Cadenas (chains) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 137.3Proyectos que usan OGNL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 137.4Enlaces externos 138OpenACS 138.1Arquitectura
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 260
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
ÍNDICE GENERAL
xxiii
138.2Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 138.3Véase también 138.4Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
139Operaciones con archivos (informática) 139.1Véase también
261
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
140Operador
262
140.1Operadores en un espacio vectorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 140.2Operadores bilineales o bivariantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 140.3Tipos generales de operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 140.3.1 Operadores de condición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 140.3.2 Operadores de orden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 140.3.3 Operadores lógicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 140.3.4 Operaciones aritméticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 140.4Otros operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 140.5Temas relacionados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 140.6Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 141Operando
265
141.1En informática
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
141.2Conexiones externas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
141.2.1 Matemática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 141.2.2 Informática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 142Paquetes en PL/SQL
266
142.1Especificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 142.2Cuerpo
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
143Pascal Casing
268
143.1Enlaces externos 144Patch (Unix)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 269
144.1Contexto de uso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 144.2Enlaces externos 145Phrogram
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 270
145.1Detalles técnicos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
145.2¡Hola, Mundo! en KPL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 145.3Filosofía
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
145.4Otra información . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 145.5The Phrogram Company . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 145.6Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
xxiv
ÍNDICE GENERAL
146Plataforma de desarrollo 146.1Véase también
272
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
147Plataforma virtual didáctica
273
147.1Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 147.2Herramientas que las componen
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
147.3Para que sirven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 147.4Autores y contribuyentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 147.5Ventajas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 147.6Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 147.7Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 147.8Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
148Polling
275
148.1Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 148.2Polling del registro de Windows
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
148.3Soluciones para el polling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 148.4Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 148.5Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
149Poltergeist (informática) 149.1Consecuencias
277
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
149.2Solución . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 149.3Véase también 149.4Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
150Portabilidad 150.1Véase también
278 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
150.2Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 151Postcondición
279
151.1Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 152Pragma
280
152.1Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 152.2Véase también 152.3Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
153Precondición
281
153.1Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 154Primitiva de sincronización rendezvous
282
154.1Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 154.2Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
ÍNDICE GENERAL
xxv
155Proceso (informática)
283
155.1Creación de un proceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 155.2Terminación de un proceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 155.3Estados de un proceso
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
155.4Tipos de procesos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 155.5Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
155.6Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 155.7Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 156Proceso para el desarrollo de software
286
156.1Generalidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 156.2Actividades del desarrollo de software
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
156.2.1 Planificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 156.2.2 Implementación, pruebas y documentación
. . . . . . . . . . . . . . . . . . . . . . . . . 286
156.2.3 Despliegue y mantenimiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 156.3Modelos de Desarrollo de Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 156.3.1 Modelo de cascada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 156.3.2 Modelo de espiral
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
156.3.3 Desarrollo iterativo e incremental
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
156.3.4 Desarrollo ágil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288 156.3.5 Codificación y corrección 156.3.6 Orientado a la Reutilización
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
156.4Modelos de mejora de procesos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 156.5Métodos formales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 156.6Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
156.7Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 156.8Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
157Programa informático
291
157.1Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 157.1.1 Paradigmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 157.1.2 Compilado o interpretando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 157.1.3 Programas que se auto-modifican
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
157.2Ejecución y almacenamiento de los programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 157.2.1 Programas empotrados en hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 157.2.2 Programas cargados manualmente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 157.2.3 Programas generados automáticamente
. . . . . . . . . . . . . . . . . . . . . . . . . . . 293
157.2.4 Ejecución simultánea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293 157.3Categorías funcionales 157.4Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
157.5Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 157.6Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
xxvi
ÍNDICE GENERAL
157.7Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
158Programa interactivo
296
158.1Frente a Procesamiento por lotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 158.1.1 Ventajas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
158.1.2 Inconvenientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 158.2Ejemplos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
158.2.1 Cajero automático
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
158.2.2 Compresor de archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 159Programación lineal paramétrica
297
159.1Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 160Programación visual
298
160.1Programación orientada a objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 160.2Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
161Programador
299
161.1Reseña histórica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 161.2Funciones del programador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 161.3Especialidades
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
161.4Notas y referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 161.5Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
162Pseudocódigo 162.1Aplicaciones
301 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
162.2Sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 162.3Definición de datos del pseudocódigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 162.4Funciones y operaciones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
162.5Estructuras de control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 162.5.1 Estructuras secuenciales
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
162.5.2 Estructuras selectivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 162.5.3 Estructuras iterativas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 162.5.4 El anidamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 162.6Desarrollo de algoritmos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
162.7Funciones y procedimientos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
162.8Ventajas del pseudocódigo sobre los diagramas de flujo 162.9Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . 304
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
162.10Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 162.11Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 162.12Véase también 163Puente de aplicación
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 305
ÍNDICE GENERAL
xxvii
164Puntero inteligente
306
164.1Punteros inteligentes en Boost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 164.1.1 Scoped pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 164.1.2 Shared pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 164.2Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 165Pure data
308
165.1Tipos de objetos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
165.2Objetos más importantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 165.3Instalación en GNU posibles problemas y soluciones . . . . . . . . . . . . . . . . . . . . . . . . . 310 165.4Introducción rápida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 165.5Bibliotecas pdp, pidip y opencv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 165.6Patch patrones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
165.7Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
165.8Material en español . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 165.9Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
166QuadTIN
313
167Query string
314
167.1Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
168Quest3D
315
168.1Entorno de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 168.1.1 Lógica de las aplicaciones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
168.1.2 Orientación a objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 168.1.3 Editores
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
168.1.4 Publicación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 168.2Requerimientos del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 168.3Licencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 168.4Aplicaciones
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
168.5Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 168.6Enlaces externos 169Quine (programa)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 317
169.1Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 169.1.1 C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 169.1.2 C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 169.1.3 Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 169.1.4 Common Lisp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 169.1.5 Ocaml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 169.1.6 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 169.1.7 JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
xxviii
ÍNDICE GENERAL 169.1.8 Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 169.1.9 BASIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 169.1.10Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 169.1.11Brainfuck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 169.1.12HQ9+ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 169.1.13DOS Batch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 169.1.14PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 169.1.15PL/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 169.1.16PostScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 169.1.17Visual FoxPro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
169.2Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 170Rebanamiento estático
320
170.1Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 170.2Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
170.3Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 170.4Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 171Recolector de basura
321
171.1Breve reseña histórica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 171.2Contexto
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
171.3Cómo funciona . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 171.4Ventajas y desventajas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
171.5Cómo se implementa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 171.6Ejemplos de lenguajes con recolector de basura 171.7Véase también 171.8Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . 322
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
172Recursión
323
172.1Recursión en matemáticas
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
172.1.1 Conjuntos definidos de forma recurrente . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 172.1.2 Funciones definidas de forma recurrente . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 172.1.3 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 172.1.4 Resolución de problemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 172.2Recursión en informática . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324 172.3Humor recursivo 172.4Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
172.5Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 172.6Enlaces externos 173Refactorización
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 326
173.1Refactorización de código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 173.2Refactorización de otros textos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
ÍNDICE GENERAL 173.3Etimología
xxix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
173.4Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327 173.5Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
174Reflexión (informática)
328
174.1Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 174.2Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 174.2.1 Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 174.2.2 C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 174.3Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
175Relación de compresión (informática)
329
175.0.1 Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 176Resolución de problemas de programación
330
176.1Análisis del problema informático . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 176.2Diseño del algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 176.2.1 Acciones elementales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 176.2.2 Secuencia de acciones elementales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 176.2.3 Composición condicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 176.2.4 Composición condicional doble (alternativa) . . . . . . . . . . . . . . . . . . . . . . . . . 331 176.2.5 Composición condicional múltiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 176.2.6 Composición iterativa o bucle 176.3Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
177Instancia (programación)
333
177.1Programación basada en clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 177.1.1 Clases como objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 177.2Programación basada en prototipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 177.3Notas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 177.4Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 178Anexo:Scan code
335
179scanf
336 179.0.1 Modificantes de longitud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
179.1Sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 179.2Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 179.3Funciones derivadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 179.3.1 fscanf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 179.3.2 sscanf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 179.4Véase también 179.5Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
xxx
ÍNDICE GENERAL
180SCons 180.1Véase también
340 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
180.2Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
181Screen scraping 181.1Véase también
341 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
182Sección crítica 182.1Véase también
342 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
183Serialización
343
183.1Usos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 183.2Soporte en los lenguajes de programación 183.3Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
184Sigil
344
185Signatura (informática)
345
186Signum Framework
346
186.1Características
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
186.1.1 Elementos de Signum Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 186.1.2 Entidades primero
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
186.1.3 Generación del esquema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 186.1.4 Herencia de entidades
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
186.1.5 Interfaz de usuario y WCF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 186.1.6 LINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 186.2Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 186.3Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
187Simple Network Library 187.1Origen del nombre
348 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
187.2Desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 187.3Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
187.4Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 187.5Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 187.5.1 Documentación de SNL 187.6Enlaces externos 188Smarty 188.1Características
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 349 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
188.2Críticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 188.3Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 188.4Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
ÍNDICE GENERAL
xxxi
188.5Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
189Snippet
351
189.1Rich snippets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351 189.2Enlaces externos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351 190Stack Overflow
352
190.1Funcionamiento de Stack Overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 190.2Reputación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 190.3Moderación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 190.4Estadísticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 191StarBasic
354
191.1Primer virus para OpenOffice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 191.2Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
192Stub
355
192.1Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 192.2Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
193Subalgoritmo
356
193.1Tipos de subalgoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 193.2Ámbito de las variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 193.3Paso de argumentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 193.4Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
194Tabla de saltos
357
194.1Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 194.2Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 194.3Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
195Tabla de verdad
359
195.1Definiciones en el cálculo lógico
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
195.2Número de combinaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 195.2.1 Para cero variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 195.2.2 Para una variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 195.2.3 Para dos variables 195.3Tablas de verdad
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
195.3.1 Verdad Indeterminada o Contingencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 195.3.2 Contradicción
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
195.3.3 Tautologías . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 195.4Tablas de verdad, proposiciones lógicas y argumentos deductivos 195.5Aplicaciones
. . . . . . . . . . . . . . . . . . 362
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
195.5.1 Cálculo lógico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
xxxii
ÍNDICE GENERAL 195.5.2 Lógica de circuitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 195.5.3 Desarrollo del algoritmo fundamental en lógica de circuitos . . . . . . . . . . . . . . . . . 363
195.6Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
195.7Notas y referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 195.8Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
196Thunk
366
196.1Invocación por «gestionada» a «no gestionada»
. . . . . . . . . . . . . . . . . . . . . . . . . . . 366
196.2Invocación por «no gestionada» a «gestionada»
. . . . . . . . . . . . . . . . . . . . . . . . . . . 366
196.3Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366 197Tipo de dato elemental
367
198Triángulo de Floyd
368
198.1Algoritmo computacional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368 198.2Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
198.3Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368 199Tubería (informática)
369
199.1Véase también . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 200Violación de acceso
371
200.1Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
201Waf
372
201.1Funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 201.2Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 201.3Ejemplo Waf archivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373 201.4Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
201.5Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373 201.6Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
202Win32 Thread Information Block 202.1Contenido del TIB
374
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
202.2Acceso al TIB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 202.3Enlaces externos 203Wrapper
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 375
203.1Computación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 203.2Véase también
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
203.3Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 204XAML 204.1Tecnología 204.2Ejemplos
376 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
ÍNDICE GENERAL 204.3Véase también
xxxiii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
204.4Referencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 204.5Enlaces externos
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
205Zenphp 205.1¿Qué es zenphp?
378 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
205.2¿Qué ventajas ofrece zenphp?
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
205.3Origen del texto y las imágenes, colaboradores y licencias . . . . . . . . . . . . . . . . . . . . . . 379 205.3.1 Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 205.3.2 Imágenes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391 205.3.3 Licencia del contenido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396
Capítulo 1
Programación La programación informática, acortada como programación, es el proceso de diseñar, codificar, depurar y mantener el código fuente de programas computacionales. El código fuente es escrito en un lenguaje de programación. El propósito de la programación es crear programas que exhiban un comportamiento deseado. El proceso de escribir código requiere frecuentemente conocimientos en varias áreas distintas, además del dominio del lenguaje a utilizar, algoritmos especializados y lógica formal. Programar no involucra necesariamente otras tareas tales como el análisis y diseño de la aplicación (pero sí el diseño del código), aunque sí suelen estar fusionadas en el desarrollo de pequeñas aplicaciones.
trivial como multiplicar dos números puede necesitar un conjunto de instrucciones en lenguaje ensamblador, en un lenguaje de alto nivel bastará con solo una. Una vez que se termina de escribir un programa, sea en ensamblador o en algunos lenguajes de alto nivel, es necesario compilarlo, es decir, traducirlo completo a lenguaje máquina.* [1] Eventualmente será necesaria otra fase denominada comúnmente link o enlace, durante la cual se anexan al código, generado durante la compilación, los recursos necesarios de alguna biblioteca. En algunos lenguajes de programación, puede no ser requerido el proceso de compilación y enlace, ya que pueden trabajar en modo intérprete. Esta modalidad de trabajo es equivalente pero se realiza instrucción por instrucción, a medida Del proceso de programación surge lo que comúnmente que es ejecutado el programa. se conoce como software (conjunto de programas), aunque estrictamente este último abarca mucho más que solo la programación.
1.2 Léxico y programación 1.1 Historia
La programación se rige por reglas y un conjunto más o menos reducido de órdenes, expresiones, instrucciones y comandos que tienden a asemejarse a una lengua natural acotada (en inglés); y que además tienen la particularidad de una reducida ambigüedad. Cuanto menos ambiguo es un lenguaje de programación, se dice, es más potente. Bajo esta premisa, y en el extremo, el lenguaje más potente existente es el binario, con ambigüedad nula (lo cual lleva a pensar así del lenguaje ensamblador).
Para crear un programa, y que la computadora lo interprete y ejecute las instrucciones escritas en él, debe escribirse en un lenguaje de programación. En sus inicios las computadoras interpretaban solo instrucciones en un lenguaje específico, del más bajo nivel, conocido como código máquina, siendo éste excesivamente complicado para programar. De hecho solo consiste en cadenas de números 1 y 0 (sistema binario). Para facilitar el trabajo de programación, los primeros científicos, que trabajaban en el área, decidieron reemplazar las instrucciones, secuencias de unos y ceros, por palabras o abreviaturas provenientes del inglés; las codificaron y crearon así un lenguaje de mayor nivel, que se conoce como Asembly o lenguaje ensamblador. Por ejemplo, para sumar se podría usar la letra A de la palabra inglesa add (sumar). En realidad escribir en lenguaje ensamblador es básicamente lo mismo que hacerlo en lenguaje máquina, pero las letras y palabras son bastante más fáciles de recordar y entender que secuencias de números binarios. A medida que la complejidad de las tareas que realizaban las computadoras aumentaba, se hizo necesario disponer de un método sencillo para programar. Entonces, se crearon los lenguajes de alto nivel. Mientras que una tarea tan
En los lenguajes de programación de alto nivel se distinguen diversos elementos entre los que se incluyen el léxico propio del lenguaje y las reglas semánticas y sintácticas.
1.3 Programas y algoritmos Un algoritmo es una secuencia no ambigua, finita y ordenada de instrucciones que han de seguirse para resolver un problema. Un programa normalmente implementa (traduce a un lenguaje de programación concreto) uno o más algoritmos. Un algoritmo puede expresarse de distintas maneras: en forma gráfica, como un diagrama de flujo, en forma de código como en pseudocódigo o un 1
2
CAPÍTULO 1. PROGRAMACIÓN
lenguaje de programación, en forma explicativa, etc. Los programas suelen subdividirse en partes menores, llamadas módulos, de modo que la complejidad algorítmica de cada una de las partes sea menor que la del programa completo, lo cual ayuda al desarrollo del programa. Esta es una práctica muy utilizada y se conoce como “refino progresivo”. Según Niklaus Wirth, un programa está formado por los algoritmos y la estructura de datos.
puede almacenarse solo de forma temporal. Un programa podría tener partes escritas en varios lenguajes, por ejemplo, Java, C, C++ y ensamblador, que se podrían compilar de forma independiente y luego enlazar juntas para formar un único módulo ejecutable.
1.5 Programación e ingeniería del software
Se han propuesto diversas técnicas de programación cuyo objetivo es mejorar tanto el proceso de creación de Existe una tendencia a identificar el proceso de creación software como su mantenimiento. Entre ellas, se pueden de un programa informático con la programación, que es mencionar las siguientes: cierta cuando se trata de programas pequeños para uso personal, y que dista de la realidad cuando se trata de grandes proyectos. • Programación declarativa • Programación estructurada • Programación modular • Programación orientada a objetos
1.4 Compilación El programa escrito en un lenguaje de programación de alto nivel (fácilmente comprensible por el programador) es llamado programa fuente y no se puede ejecutar directamente en una computadora. La opción más común es compilar el programa obteniendo un módulo objeto, aunque también puede ejecutarse en forma más directa a través de un intérprete informático. El código fuente del programa se debe someter a un proceso de traducción para convertirlo a lenguaje máquina o bien a un código intermedio, generando así un módulo denominado “objeto”. A este proceso se le llama compilación.
El proceso de creación de software, desde el punto de vista de la ingeniería, incluye mínimamente los siguientes pasos: 1. Reconocer la necesidad de un programa para solucionar un problema o identificar la posibilidad de automatización de una tarea. 2. Recoger los requisitos del programa. Debe quedar claro qué es lo que debe hacer el programa y para qué se necesita. 3. Realizar el análisis de los requisitos del programa. Debe quedar claro qué tareas debe realizar el programa. Las pruebas que comprueben la validez del programa se pueden especificar en esta fase. 4. Diseñar la arquitectura del programa. Se debe descomponer el programa en partes de complejidad abordable.
5. Implementar el programa. Consiste en realizar un Habitualmente la creación de un programa ejecutable (un diseño detallado, especificando completamente totípico.exe para Microsoft Windows o DOS) conlleva dos do el funcionamiento del programa, tras lo cual la pasos. El primer paso se llama compilación (propiamente codificación (programación propiamente dicha) dedicho) y traduce el código fuente escrito en un lenguaje bería resultar inmediata. de programación almacenado en un archivo de texto a 6. Probar el programa. Comprobar que pasan pruebas código en bajo nivel (normalmente en código objeto, no que se han definido en el análisis de requisitos directamente a lenguaje máquina). El segundo paso se llama enlazado en el cual se enlaza el código de bajo ni7. Implantar (instalar) el programa. Consiste en poner vel generado de todos los ficheros y subprogramas que se el programa en funcionamiento junto con los comhan mandado compilar y se añade el código de las funcioponentes que pueda necesitar (bases de datos, redes nes que hay en las bibliotecas del compilador para que el de comunicaciones, etc.). ejecutable pueda comunicarse directamente con el sistema operativo, traduciendo así finalmente el código objeto a código máquina, y generando un módulo ejecutable. La ingeniería del software se centra en los pasos de plaEstos dos pasos se pueden hacer por separado, almace- nificación y diseño del programa, mientras que antiguanando el resultado de la fase de compilación en archivos mente (programación artesanal) la realización de un proobjetos (un típico .o para Unix, .obj para MS-Windows, grama consistía casi únicamente en escribir el código, baDOS); para enlazarlos en fases posteriores, o crear direc- jo solo el conocimiento de los requisitos y con una motamente el ejecutable; con lo que la fase de compilación desta fase de análisis y diseño.
1.8. CICLO DE VIDA DEL SOFTWARE
1.6 Referencias históricas El trabajo de Ada Lovelace, hija de Anabella Milbanke Byron y Lord Byron, realizó para la máquina de Babbage le hizo ganarse el título de primera programadora de computadoras del mundo, aunque Babbage nunca completó la construcción de la máquina. El nombre del lenguaje de programación Ada fue escogido como homenaje a esta programadora.
1.7 Objetivos de la programación
3 • Portabilidad. Un programa es portable cuando tiene la capacidad de poder ejecutarse en una plataforma, ya sea hardware o software, diferente a aquélla en la que se desarrolló. La portabilidad es una característica muy deseable para un programa, ya que permite, por ejemplo, a un programa que se ha elaborado para el sistema GNU/Linux ejecutarse también en la familia de sistemas operativos Windows. Esto permite que el programa pueda llegar a más usuarios más fácilmente.
1.8 Ciclo de vida del software
La programación debe perseguir la obtención de programas de calidad. Para ello se establece una serie de factores El término ciclo de vida del software describe el desaque determinan la calidad de un programa. Algunos de los rrollo de software, desde la fase inicial hasta la fase final, incluyendo su estado funcional. El propósito es definir las factores de calidad más importantes son los siguientes: distintas fases intermedias que se requieren para validar • Correctitud. Un programa es correcto si hace lo que el desarrollo de la aplicación, es decir, para garantizar que debe hacer tal y como se estableció en las fases pre- el software cumpla los requisitos para la aplicación y vevias a su desarrollo. Para determinar si un progra- rificación de los procedimientos de desarrollo: se asegura ma hace lo que debe, es muy importante especifi- que los métodos utilizados son apropiados. Estos métodos car claramente qué debe hacer el programa antes de se originan en el hecho de que es muy costoso rectificar su desarrollo y, una vez acabado, compararlo con lo los errores que se detectan tarde dentro de la fase de implementación (programación propiamente dicha), o peor que realmente hace. aun, durante la fase funcional. El modelo de ciclo de vida • Claridad. Es muy importante que el programa sea permite que los errores se detecten lo antes posible y por lo más claro y legible posible, para facilitar tanto su lo tanto, permite a los desarrolladores concentrarse en la desarrollo como su posterior mantenimiento. Al ela- calidad del software, en los plazos de implementación y borar un programa se debe intentar que su estructu- en los costos asociados. El ciclo de vida básico de un softra sea sencilla y coherente, así como cuidar el es- ware consta de, al menos, los siguientes procedimientos: tilo de programación. De esta forma se ve facilita• Definición de objetivos: definir el resultado del prodo el trabajo del programador, tanto en la fase de yecto y su papel en la estrategia global. creación como en las fases posteriores de corrección de errores, ampliaciones, modificaciones, etc. Fases • Análisis de los requisitos y su viabilidad: recopilar, que pueden ser realizadas incluso por otro prograexaminar y formular los requisitos del cliente y examador, con lo cual la claridad es aún más necesaria minar cualquier restricción que se pueda aplicar. para que otros puedan continuar el trabajo fácilmente. Algunos programadores llegan incluso a utilizar • Diseño general: requisitos generales de la arquitecArte ASCII para delimitar secciones de código; una tura de la aplicación. práctica común es realizar aclaraciones en el código • Diseño en detalle: definición precisa de cada subfuente utilizando líneas de comentarios. Contrariaconjunto de la aplicación. mente, algunos por diversión o para impedirle un análisis cómodo a otros programadores, recurren al • Programación (programación e implementación): es uso de código ofuscado. la implementación en un lenguaje de programación para crear las funciones definidas durante la etapa de • Eficiencia. Se trata de que el programa, además de diseño. realizar aquello para lo que fue creado (es decir, que • Prueba de unidad: prueba individual de cada subsea correcto), lo haga gestionando de la mejor forconjunto de la aplicación para garantizar que se imma posible los recursos que utiliza. Normalmente, plementaron de acuerdo con las especificaciones. al hablar de eficiencia de un programa, se suele hacer referencia al tiempo que tarda en realizar la ta• Integración: para garantizar que los diferentes rea para la que ha sido creado y a la cantidad de módulos y subprogramas se integren con la aplicamemoria que necesita, pero hay otros recursos que ción. Éste es el propósito de la prueba de integración también pueden ser de consideración para mejorar que debe estar cuidadosamente documentada. la eficiencia de un programa, dependiendo de su na• Prueba beta (o validación), para garantizar que el turaleza (espacio en disco que utiliza, tráfico en la software cumple con las especificaciones originales. red que genera, etc.).
4
CAPÍTULO 1. PROGRAMACIÓN • Documentación: se documenta con toda la información necesaria, sea funcional final para los usuarios del software (manual del usuario), y de desarrollo para futuras adaptaciones, ampliaciones y correcciones. • Mantenimiento: para todos los procedimientos correctivos (mantenimiento correctivo) y las actualizaciones secundarias del software (mantenimiento continuo).
1.11 Enlaces externos •
Wikimedia Commons alberga contenido multimedia sobre Programación. Commons
•
Wikcionario tiene definiciones y otra información sobre programación.Wikcionario
• Wikiquote alberga frases célebres de o sobre El orden y la presencia de cada uno de estos procedimienProgramación. Wikiquote tos en el ciclo de vida de una aplicación dependen del tipo de modelo de ciclo de vida acordado entre el cliente y el Wikilibros equipo de desarrolladores. •
1.9 Véase también • •
Portal:Programación. Contenido relacionado con Programación.
• Wikiproyecto:Informática/Programación • error de software • filosofías del desarrollo de software • historia de la ingeniería del software • ingeniería en computación • Desarrollo De Software • ingeniería en informática • línea de código fuente • lenguaje de programación • programación automática • programación dirigida por eventos • programación estructurada • programación extrema • programación en pareja • programación dinámica • programación orientada a objetos • pruebas de software • software
1.10 Referencias [1] Laboda, Xavier; Josep Galimany, Rosa María Pena, Antoni Gual (1985). «Software». Biblioteca práctica de la computación. Barcelona: Ediciones Océano-Éxito, S.A.
Wikilibros alberga un libro o manual sobre Fundamentos de programación.
Capítulo 2
Portal:Programación
5
Capítulo 3
& El signo en sí es una ligadura ̶combinación de diseño de dos letras en un único grafema, usado primero para aumentar la velocidad de la escritura manual̶desarrollada por Marco Tulio Tirón, secretario del gran orador romano Cicerón. Para poder registrar los discursos y la correspondencia dictada por este último, Tiro, que era un esclavo liberto, inventó varias formas de acelerar la escritura, siendo por ello considerado el padre de la taquigrafía. En la Edad Media o en los primeros tiempos de la imprenta el uso de ligaduras era muy común, en este caso por la economía de espacio, cuando la materia prima ̶pergamino o papel̶añadía mucho al precio de los libros.
«Et» redirige aquí. Para otras acepciones, véase E. T.
Evolución de la ligadura &: 1-3, cursivas romanas de los siglos ii-iv 4-5, minúsculas medievales de los siglos vi-vii 6, minúscula carolingia, s. ix.
También se le conoce como signo tironiano.
El signo &, cuyo nombre en español es et,* [1] es una alternativa gráfica de la conjunción copulativa latina et, que significa y de la que deriva la española «y».
3.1 Historia
Es conocido también por su nombre en inglés ampersand, proveniente a su vez de la expresión and per se and, es decir, «y por sí mismo, y», antiguamente usada como parte de la retahíla para la memorización del alfabeto. Deriva del latín de donde el signo pasó a diversos idiomas, incluido el español. Su uso en nuestra lengua es superfluo, pues no resulta económico (a diferencia de otros idiomas) ya que la conjunción copulativa y tiene una grafía más breve y sencilla. En textos españoles antiguos es frecuente encontrarlo empleado en la expresión latina adoptada et El et latino a la izquierda se encuentra estilizado, pero la forma cetera, en las formas &c. o &cetera. itálica a la derecha revela sus orígenes de la palabra del latín et.
Un uso extendido es el que persiste en la bibliografía académica en inglés, en la enumeración de los autores, in- El símbolo fue usado en el antiguo Imperio romano, y su cluidas la expresión como & al. (del latín et alii, plural uso data del primer siglo d.C. Se adjudica su invención a masculino, o et alia, plural neutro) que se traduce como Marco Tulio Tirón.* [2] «y otros». Para el siglo viii, la caligrafía occidental estaba bien desarrollada, particularmente en la forma uncial, escritura insular y minúscula carolingia. Los calígrafos hicieron un extensivo uso del et, ya que la condensación de una palabra en una sola letra hacía su trabajo más fácil. Durante aquel tiempo, se desarrolló una versión mucho más comprimida del et. Normalmente se le llama ampersand“RoEn la tipografía de la derecha es evidente el origen de la ligadura mana”. et.
En HTML se usa al comienzo de los códigos de entidad Como se observa en la lista de letras de Byrhtferð (año con que se designan los caracteres especiales: los ejem1011), este signo «&» fue considerado a menudo como plos más típicos son > <, y & (>, < y &, una letra más al final del alfabeto latino. respectivamente). 6
3.3. ENLACES EXTERNOS En Internet y direcciones web, & simboliza la separación de variables pasadas mediante GET. En Excel, se usa para concatenar celdas. En la línea de comando (CLI) de Bash (Bourne Again Shell) Zbash, etc. usadas en Unix, GNU/Linux y *BSD se usa & al final de una orden para ejecutarla en segundo plano.
3.2 Referencias [1] Real Academia Española (2001). «Apéndice 4: Lista de símbolos o signos no alfabetizables». Diccionario de la lengua española. Consultado el 25 de septiembre de 2012. [2] «The History of Court Reporting». National Court Reporters Association.
3.3 Enlaces externos •
Wikimedia Commons alberga contenido multimedia sobre &Commons.
•
Wikcionario tiene definiciones y otra información sobre &.Wikcionario
•
Wikcionario tiene definiciones y otra información sobre ampersand.Wikcionario
• Apéndice 4: Lista de símbolos o signos no alfabetizables en la página de la Real Academia Española.
7
Capítulo 4
Acoplamiento secuencial En Programación orientada a objetos el antipatrón de diseño acoplamiento secuencial se refiere a una clase que requiere que sus métodos sean llamados en un orden secuencial particular. Los métodos cuyo nombre comienza por Init, Begin, en Inicio, etc puede indicar la existencia de acoplamiento secuencial. Usando el ejemplo de un coche a modo de analogía, si el usuario sigue los pasos de acelerar sin antes arrancar el motor, el coche no se mueve y envía una Excepción. Las excepciones son aceptables en algunas ocasiones porque los programas (en particular los grandes) necesitan la información para determinar por qué en un objeto no se está realizando el comportamiento esperado cuando uno de sus métodos es llamado. La inicialización de objetos no siempre es posible en el constructor y puede ser necesario retrasarla a un momento posterior. El acoplamiento secuencial puede ser reprogramado con el Template Method (patrón de diseño)* [1] para superar los problemas planteados por el uso de este antipatrón.
4.1 Véase también • Antipatrón de diseño • Patrón de diseño
4.2 Referencias [1] Andriy, Buday. «Refactor: Acoplamiento secuencial => Template Method». The Code Project. Consultado el 23 de abril de 2011.
8
Capítulo 5
Adobe Director Adobe Director Es una aplicación de Desarrollo de Software (o Autoría de Software) Multimedia (que inspiró a Adobe Flash® ) destinado para la producción de programas ejecutables ricos en contenido multimedia. Es considerada una de las herramientas más poderosas de integración y programación de medios digitales, debido a su versatilidad de poder incorporar imágenes, audio, vídeo digital, películas flash, y un engine 3D, en una sola aplicación, y manipularlas a través de un lenguaje de programación (Lingo; Javascript).
Con el lanzamiento de Director 11 y su evolución a la versión 11.5, de la mano de Adobe, se incorporó soporte para DirectX y se extendieron las capacidades en 3D basadas en el engine PhysX de NVIDIA, importación de 3D desde Google SketchUp, así como también filtros de bitmaps, canales de audio 5.1, vídeo en alta definición, soporte para H.264, e integración de Adobe Flash CS3 y Shockwave Player 11. Director 12, lanzado en febrero de 2013, incorporó la posibilidad de publicación para dispositivos iOS, además de otras utilidades como esteDesarrollado a fines de los años 80 por la empresa reoscopía, nuevos efectos, y nuevas potencialidades del Macromedia, es distribuido desde el año 2008 por Adobe engine 3D. Systems Incorporated. Adobe Director, permite crear y publicar juegos interactivos, prototipos, simulaciones y cursos eLearning para la Web, dispositivos iOS, sistemas de escritorio Windows® y Mac, DVDs y CDs. Con Director también es posible programar una amplia gama de aplicaciones basadas en redes, lo que ha permitido crear innumerables sistemas y juegos multiusuario online.
5.1
Interfaz
A lo largo de todas sus versiones, la interfaz de Director ha sido fiel a su concepción inicial, y a su nombre: entregarle al desarrollador un escenario (Stage), para el armado de su Aplicación. Cada uno de los múltiples medios que pueden ser utilizados en Director son considerados“actores”(casts), cuyas características pueden ser manipuladas a través de guiones (o Scripts) escritos en lenguaje Lingo o Javascript. En síntesis, el desarrollador es el director de su propia película, controlando todos sus aspectos.
Director también permite la manipulación de modelos en 3D, gracias a Shockwave 3D. Es así como diversos programas de modelamiento, como 3D Studio MAX (de la empresa Autodesk), permiten exportar sus modelos (incluyendo las animaciones) en formato Shockwave 3D, el que puede ser importado a Director, y manipulado a través de instrucciones. A través de variados Xtras (como Havok), Director también puede manipular propiedades físicas de modelos 3D (como por ejemplo, gravedad, coeficientes de roce, restitución, etc) que permiten lograr simulaciones más realistas, tanto para software de ingeniería avanzada, como para juegos.
5.2 Timeline • 1985: VideoWorks (Disponible para Apple Macintosh) • 1988: Director 1.0
Además del potente lenguaje incorporado (Lingo), una de sus principales ventajas radica en el uso de los llamados xtras. Se trata de “pequeños programas”(plugins) desarrollados en lenguaje C++ por otros usuarios o terceras empresas, que proporcionan al usuario infinidad de utilidades.
• 1993: Macromind Director se convierte en Macromedia Director (v 3.1.3) • 1994: Macromedia Director 4 (Plataformas Windows y Powermac)
Se pueden generar varios tipos de archivos, sin embargo lo más normal es crear un archivo ejecutable para Windows (.exe) o Macintosh (.app). De esta forma puede verse la presentación en cualquier ordenador, sin tener instalado Adobe Director.
• 1996: Macromedia Director 5 (Aparición de Shockwave) • 1997: Macromedia Director 6 (Implementación de Behaviors & y soporte mp3) 9
10 • 1997: Macromedia Director 6.5 (integración de Xtras)
CAPÍTULO 5. ADOBE DIRECTOR
5.4 Shockwave / Shockwave 3D
Desde la aparición de Director 5, Shockwave es el for• 1998: Macromedia Director 7 (Se re-escribió el en- mato exclusivo de publicación para web de Director. El gine) plugin de shockwave permite ejecutar aplicaciones realizadas en Director (archivos DCR), a través de Internet, • 2000: Macromedia Director 8 sin que estas pierdan su calidad ni características, además de aprovechar al máximo las potencialidades de aquellas • 2001: Macromedia Director 8.5 (Aparición de que poseen engine multiusuario. Con la aparición de Director 8.5, Shockwave tuvo un nuevo impulso, al incorShockwave3D) porar capacidades de manipulación de elementos en 3D • 2002: Macromedia Director MX (También conoci- (Shockwave 3D). Esto abrió las puertas a los desarrolladores de Director a un nuevo mundo, a partir del cual fue do como Director 9) posible crear ambientes modelados en 3D (generados en • 2004: Macromedia Director MX 2004 (También Director, o importados como archivos W3D desde aplicaciones externas) y utilizar toda la riqueza del código linconocido como Director 10) go / javascript, para manipular dichos modelos en tiempo real. • 2008: Adobe Director 11 El motor 3D de Shockwave es todavía el líder indiscutible en su mercado, y hace que este plugin sea muy popular entre un gran número de desarrolladores de juegos en línea y de jugadores. Los archivos Flash (swf) pueden ser • 2010: Adobe Director 11.5.8 incorporados a Director y ser ejecutados en Shockwave, • 2013: Adobe Director 12. (Publicación a dispositi- pero no a la inversa. vos iOS, estereoscopía, mejora de Engine 3D) Otras características no incorporadas por Flash incluyen un motor de render mucho más rápido, junto con aceleración 3D por medio de hardware, acceso directo al píxel en imágenes bitmap, diferentes modos de filtrado 5.3 Director y Flash para composiciones en capas de los gráficos y compatibilidad con diversos protocolos de red, incluido Internet Históricamente, la comunidad más cercana a Flash y Relay Chat. Además, a través de los Xtras, los desarrodesconocedora de Director, tiende a preguntarse sobre lladores pueden ampliar la funcionalidad de Shockwave las comparaciones entre ambos programas. Literalmen- con aplicaciones hechas a medida. te, Director y Flash no son competidores. Flash nació en 1996, orientado al desarrollo de aplicaciones multimedia • Macromedia Shockwave Player, instalado en un en Web, y en poco tiempo evolucionó poderosamente de 50% de los navegadores. Ficheros con extensión la mano del lenguaje ActionScript. Director nació varios ".dcr”desarrollados con Adobe Director años antes (1985), y evolucionó como una poderosa herramienta de integración de medios digitales de alta cali• Macromedia Flash Player, instalado en un 98% dad para plataformas de escritorio, y que también generó de los navegadores. Utiliza ficheros con extensión una arista para su incorporación a Web (Shockwave). ".swf”desarrollados con Macromedia Flash, Macro• 2009: Adobe Director 11.5
La evolución de la popularidad de Flash sobre Shockwave tiene varias explicaciones; no solo el plugin de Shockwave fue históricamente más pesado y menos amigable de instalar que Flash, sino también la autoría de Director siempre ha requerido la mano de un desarrollador de software, con conocimientos en programación; en cambio Flash se posicionó rápidamente en el universo de diseñadores Web (sin necesidad de poseer conocimientos de programación), y de hecho ha incentivado con los años el aprendizaje de programación ActionScript a varios “no programadores”, generando una importante sinergia en el mundo del diseño y la programación -antes estrictamente lejanos-. Por otro lado, Macromedia logró acuerdos con empresas como DELL y Apple, para que Flash sea preinstalado en sus sistemas, evitando que los usuarios deban instalar software adicional.
media FreeHand, Generator y otras aplicaciones.
5.5 Referencias 5.6 Enlaces externos • Sitio oficial de Adobe Director • Adobe Director Forum • Director-Online.com Foro temático sobre el programa (en inglés). • Foro de usuarios de Adobe Director (en inglés).
5.6. ENLACES EXTERNOS • Dean's Director Tutorials, sitio web con tutoriales del programa (en inglés). • IEEE History Center: John Thompson, inventor of Lingo Programming Language Biografía de John Thompson, inventor del lenguaje de programación “Lingo”(en inglés).
11
Capítulo 6
Anidamiento (informática) El anidamiento (llamado nesting en inglés) es la práctica de incorporar llamadas (calls) a funciones o procedimientos (unas) dentro de otras, mediante la inclusión de diversos niveles de paréntesis.
linea, ruta as string dim valor_a_devolver as integer ruta="C:\Probar.csv”if FileExists(ruta) then open “C:\Probar.csv”for input as #1 do while not EOF(1) line input #1, linea if left(linea, 3)=cod then 'Realizar Debido a que la potencial acumulación de éstos últimos una acción o varias acciones End if loop close #1 suele hacer que la edición y la detección de errores se BuscarCodigo=valor_a_devolver end function vuelva un proceso engorroso, los entornos de programación modernos -así como los programas de planilla de En este simple ejemplo, la estructura condicional if... cálculo- resaltan en negrita el par correspondiente a la po- then... end if (“si... entonces... fin si”) está anidada sición que está editando el programador o usuario en cada dentro de otra que la contiene, el ciclo do while... loop momento. El control (automático) del balance o equili- (“repetir... mientras”, literalmente “hacer mientras... brio entre los paréntesis de apertura y de cierre se suele bucle”). conocer como brace match checking en inglés. Naturalmente, para la resolución matemática de estas complejas formulas encadenadas, las expresiones deben ser evaluadas desde adentro hacia afuera, ya que los resultados de las más internas sirven, temporalmente, de datos de entrada de las exteriores.
6.3 Véase también • Bucle (programación) • Estructuras de control • Función (programación)
6.1 En las planillas de cálculo
• Procedimiento (programación)
En las hojas de cálculo, se suelen anidar o agrupar funciones unas dentro de otras, derivando en fórmulas relativamente complejas. El programa OpenOffice.org Calc permite, mediante su asistente de funciones (function wizard), navegar a través de los varios o múltiples niveles de anidamiento, permitiendo editar (y eventualmente corregir) cada una de ellas por separado. Tal vez de manera sorprendente, su rival Microsoft Excel no posee esa característica, eventualmente deseable cuando se trabaja en algunas grandes planillas.
6.2 En programación En los lenguajes de programación estructurada, el anidamiento está relacionado a la inclusión de estructuras de control dentro de otras, usualmente indicado mediante la inclusión de distintos niveles de sangría (llamada indentation en inglés) dentro del código fuente, como se muestra en el sencillo código BASIC siguiente: function BuscarCodigo(cod as string) as integer dim 12
• Programación estructurada • Pseudocódigo
Capítulo 7
Antipatrón de diseño Un antipatrón de diseño es un patrón de diseño que invariablemente conduce a una mala solución para un problema. Al documentarse los antipatrones, además de los patrones de diseño, se dan argumentos a los diseñadores de sistemas para no escoger malos caminos, partiendo de documentación disponible en lugar de simplemente la intuición. El término se origina inspirado en el libro Design Patterns, escrito por un grupo de autores conocido como Gang of Four, y que aglutina un conjunto de buenas soluciones de programación. Los autores bautizaron dichas soluciones con el nombre de “patrones de diseño”por analogía con el mismo término, usado en arquitectura. El libro Anti-Patterns (de William Brown, Raphael Malveau, Skip McCormick y Tom Mowbray, junto con la más reciente incorporación de Scott Thomas) describe los antipatrones como la contrapartida natural al estudio de los patrones de diseño. El estudio formal de errores que se repiten permite reconocer y reconducir los elementos involucrados hacia una mejor solución. Los antipatrones no se mencionan en el libro original de Design Patterns, puesto que éste es anterior. Los antipatrones se consideran una parte importante de una buena práctica de programación. Es decir, un buen programador procurará evitar los antipatrones siempre que sea posible, lo que requiere su reconocimiento e identificación tan pronto como sea posible, dentro del ciclo de vida del software. El concepto de antipatrón se puede aplicar a la ingeniería en general, e incluso a cualquier tarea realizada por el hombre. Aunque no se escucha con frecuencia fuera del campo ingenieril, la noción está ampliamente extendida.
7.1 Algunos antipatrones desarrollo de software 7.1.1
de
Antipatrones de gestión
• Productividad a toda costa: La empresa busca la productividad a costa de la calidad del software y de la 13
calidad de vida de sus empleados, intenta homogeneizar los puestos de trabajo quitando en la medida de lo posible los permisos a los programadores para que no dañen los sistemas operativos, monitoriza a los equipos de trabajo y actúa cortando la visibilidad de ciertas páginas o las reuniones de programadores, al final se consigue que se vaya la gente de la empresa cuando la situación es insostenible, esto suele ocurrir en ciclos de uno o dos años. • Responsable ausente (absentee manager): Situación en la que el principal responsable o coordinador se ausenta o permanece en paradero desconocido o no localizable durante importantes períodos de tiempo. • Todo lo que tienes es un martillo (all you have is a hammer): Gestión gris y plana, incapaz de tratar a los subordinados de manera personalizada y acorde con sus necesidades particulares. • Negociador de jaula de acero (cage match negotiator): Se aplica cuando un coordinador, gestor o responsable aplica una filosofía de "éxito a cualquier precio”. • Dos caras (doppelganger): Coordinador o compañero que en un determinado momento puede ser agradable y de trato fácil, pero igualmente puede volverse irracional y despiadado de modo inesperado. • Rodeos improductivos (fruitless hoops): Gestor o coordinador que solicita grandes cantidades de datos (en ocasiones sin relevancia alguna) antes de tomar una decisión. • Niñito de oro (golden child): Situación en la que ciertas responsabilidades, oportunidades, reconocimientos o recompensas van a parar a un determinado miembro del equipo como consecuencia de una relación personal o en clara contradicción con su rendimiento real. • Pollo sin cabeza (headless chicken): Se aplica al gestor, coordinador o responsable que vive en una permanente situación de pánico y medidas desesperadas.
14
CAPÍTULO 7. ANTIPATRÓN DE DISEÑO
• Líder pero no gestor (leader not manager): Un buen líder no tiene por qué ser necesariamente un buen gestor, coordinador o responsable.
• Mala gestión (bad management): Gestionar un proyecto sin tener suficientes conocimientos sobre la materia.
• Gestión clonada (managerial cloning): Situación en la que los coordinadores o gestores son contratados e instruidos para actuar y trabajar todos del mismo modo, a imagen y semejanza de sus propios jefes.
• Software inflado (software bloat): Permitir que las sucesivas versiones de un sistema exijan cada vez más recursos.
• Gestor pero no líder (manager not leader): Un coor- 7.1.3 Antipatrones generales de diseño de dinador brillante en sus deberes administrativos y de software gestión, pero que carece de habilidades de liderazgo. • Base de datos como comunicador de procesos (data• Abuso de la métrica (metric abuse): Utilización mabase as an IPC): Usar una base de datos para comunipuladora o incompetente de las medidas y las ménicar procesos en uno o varios ordenadores, cuando tricas. la comunicación entre procesos directa es más adecuada. • Sr. Amigo de todos (Mr. Nice Guy): Se aplica al gestor que pretende convertirse en amigo de todos. • Blob: Véase Objeto todopoderoso. • Héroe del proletariado (proletariat hero): El “empleado para todo”que siempre es puesto como ejemplo ante sus compañeros, pero que realmente es la excusa perfecta para demandas crecientes y constantes incrementos de expectativas. • Estrellas nacientes (rising upstart): Se aplica a quienes, teniendo potencial, no son capaces de respetar la progresión profesional establecida, y pretenden sortear los plazos y requisitos de aprendizaje y madurez. • Ejecutivo sin carácter (spineless executive): Gestor, coordinador o responsable que no tiene el coraje de enfrentarse a las situaciones, asumir las responsabilidades de los errores, o dar la cara por sus subordinados.
• BOMQ (Batch Over MQ): Abuso en el empleo de integración basada en mensajes en tiempo real para transferencias esporádicas de gran tamaño en segundo plano. • Clase Gorda: Dotar a una clase con demasiados atributos y/o métodos, haciéndola responsable de la mayoría de la lógica de negocio. • Botón mágico (magic pushbutton): Tender, desarrollando interfaces, a programar la lógica de negocio en los métodos de interacción, implementando los resultados de las acciones del usuario en términos no suficientemente abstractos. • Carrera de obstáculos (race hazard): Incapacidad de prever las consecuencias de diferentes sucesiones de eventos.
• Caballero de tres cabezas (three-headed knight): Gestor indeciso, poco firme, dubitativo.
• Entrada chapuza (input kludge): No especificar e implementar el manejo de entradas inválidas.
• Arma definitiva (ultimate weapon): Individuos altamente competentes en los que la organización o sus compañeros confían tanto que se convierten en el canal por el que todo pasa.
• Fábrica de combustible (gas factory): Diseñar de manera innecesariamente compleja.
• Recién llegado (warm body): Trabajador que apenas cubre las expectativas mínimas y por tanto circula de proyecto en proyecto o de equipo en equipo. • Arquitecto a obrero (super builder): Creencia por la que se asigna a un buen diseñador de software al desarrollo de código pensando en que tardara mucho menos en teclearlo.
7.1.2
Antipatrones de gestión de proyectos
• Humo y espejos (smoke and mirrors): Mostrar cómo será una funcionalidad antes de que esté implementada.
• Gran bola de lodo (big ball of mud): Construir un sistema sin estructura definida. • Interfaz inflada (interface bloat): Pretender que una interfaz sea tan potente que resulta extremadamente difícil de implementar. • Inversión de abstracción (abstraction inversion): No exponer las funcionalidades implementadas que los usuarios necesitan, forzando a que se reimplementen a más alto nivel. • Punto de vista ambiguo (ambiguous viewpoint): Presentar un modelo sin concretar ciertos aspectos, postergando así decisiones conflictivas. • Re-dependencia (re-coupling): Introducir dependencias innecesarias entre objetos.
7.1. ALGUNOS ANTIPATRONES DE DESARROLLO DE SOFTWARE
15
• Sistema de cañerías de calefacción (stovepipe sys- 7.1.4 Antipatrones de programación tem): Construir un sistema difícilmente mantenible, • Nomenclatura heroica (heroic naming): Identificar ensamblando componentes poco relacionados. los miembros de un programa (interfaces, clases, propiedades, métodos...) con nombres que provocan que el conjunto aparente estandarización con la inAntipatrones de diseño orientado a objetos geniería del software pero que en realidad oculta una implementación anárquica. • Acoplamiento secuencial (sequential coupling): Construir una clase que necesita que sus métodos se invoquen en un orden determinado. • BaseBean: Heredar funcionalidad de una clase utilidad en lugar de delegar en ella. • Fallo de clase vacía (empty subclass failure): Crear una clase que no supera el test de la subclase vacía, es decir, que se comporta de manera diferente cuando se invoca desde una subclase que no añade modificación alguna. • Llamar a super (callsuper): Obligar a las subclases a llamar a un método de la superclase que ha sido sobrescrito. • Modelo de dominio anémico (anemic domain model): Usar un modelo del dominio sin ninguna lógica de negocio. Esto no es un enfoque orientado a objetos porque cada objeto debería tener tanto propiedades como comportamiento asociado. • Objeto sumidero (object cesspool): Reutilizar objetos no adecuados realmente para el fin que se persigue. • Objeto todopoderoso (god object): Concentrar demasiada funcionalidad en una única parte del diseño (clase). • Poltergeist (informática): Emplear objetos cuyo único propósito es pasar la información a terceros objetos. • Problema del círculo-elipse (circle-ellipse problem): Crear variables de tipo pensando en los valores de posibles subtipos. • Problema del yoyó (yo-yo problem): Construir estructuras (por ejemplo, de herencia) que son difíciles de comprender debido a su excesiva fragmentación. • Singletonitis: Abuso de la utilización del patrón singleton. • YAFL (yet another fucking layer, y otra maldita capa más) o 'Código Lasagna': Añadir capas innecesarias a un programa, biblioteca o framework. Esta tendencia se extendió bastante después de que se publicase el primer libro sobre patrones.
• Acción a distancia (action at a distance): Provocar la interacción no prevista de componentes muy distantes de un sistema. • Acumular y disparar (accumulate and fire): Establecer una colección de variables globales para ser usadas por un conjunto de subrutinas. • Ancla del barco (boat anchor): Retener partes del sistema que ya no tienen utilidad. • Bucle activo (busy spin): Utilizar espera activa cuando existen alternativas. • Código duro (hard code): Hacer supuestos sobre el entorno del sistema en demasiados lugares de la implementación. • Complejidad no indispensable (accidental complexity): Dotar de complejidad innecesaria a una solución. • Código espagueti (spaghetti code): Construir sistemas cuya estructura es difícilmente comprensible, especialmente debido a la escasa utilización de estructuras de programación. • Código ravioli (ravioli code): Construir sistemas con multitud de objetos muy débilmente conectados. • Comprobación de tipos en lugar de interfaz (checking type instead of interface): Comprobar que un objeto es de un tipo concreto cuando lo único que se necesita es verificar si cumple un contrato determinado. • Confianza ciega (blind faith): Descuidar la comprobación de los resultados que produce una subrutina, o bien de la efectividad de un parche o solución a un problema. • Doble comprobación de bloqueo (double-checked locking): Comprobar, antes de modificar un objeto, si es necesario hacer esa modificación, pero sin bloquear para comprobarlo, de manera que dicha comprobación puede fallar. • Fallo de caché (caching failure): Olvidar restablecer una marca de error cuando éste ya ha sido tratado. • Lava seca (lava flow): Código muerto e información de diseño olvidada permanecen congelados en un diseño cambiante. Esto es análogo a un flujo de lava en el que se van endureciendo pedazos de roca. La
16
CAPÍTULO 7. ANTIPATRÓN DE DISEÑO solución incluye un proceso de gestión de la configuración que elimina el código muerto y permite evolucionar o rehacer el diseño para acrecentar la calidad.
• Lógica super-booleana (superboolean logic): Emplear comparaciones o abstracciones de la lógica booleana innecesarias. • Manejo de excepciones (exception handling): Emplear el mecanismo de manejo de excepciones del lenguaje para implementar la lógica general del programa. • Manejo de excepciones inútil (useless exception handling): Introducir condiciones para evitar que se produzcan excepciones en tiempo de ejecución, pero lanzar manualmente una excepción si dicha condición falla. • Momento del código (code momentum) : Establecer demasiadas restricciones sobre una parte del sistema debido a la asunción de muchas de sus propiedades desde otros lugares del propio sistema. • Números mágicos (magic numbers): Incluir en los algoritmos números concretos sin explicación aparente.
• Desfactorización (de-factoring): Eliminar funcionalidad y reemplazarla con documentación. • Factor de improbabilidad (improbability factor): Asumir que es improbable que un error conocido cause verdaderos problemas. • Martillo de oro (golden hammer): Asumir que nuestra solución favorita es universalmente aplicable, haciendo bueno el refrán a un martillo, todo son clavos. • Optimización prematura (premature optimization): Realizar optimizaciones sin disponer de la información suficiente para hacerlo con garantías, sacrificando decisiones de diseño. • Programación de copiar y pegar (copy and paste programming): Programar copiando y modificando código existente en lugar de crear soluciones genéricas. • Programación por permutación (programming by permutation): Tratar de aproximarse a una solución modificando el código una y otra vez para ver si acaba por funcionar.
• Ocultación de errores (error hiding): Capturar un error antes de que se muestre al usuario, y reemplazarlo por un mensaje sin importancia o ningún mensaje en absoluto.
• Reinventar la rueda (reinventing the wheel): Enfrentarse a las situaciones buscando soluciones desde cero, sin tener en cuenta otras que puedan existir ya para afrontar los mismos problemas.
• Packratting: Consumir memoria en exceso debido a no liberar objetos reservados dinámicamente una vez ya han dejado de ser necesarios.
• Reinventar la rueda cuadrada (reinventing the square wheel): Crear una solución pobre cuando ya existe una buena.
• Programación por excepción (coding by exception): Añadir trozos de código para tratar casos especiales 7.1.6 a medida que se identifican. • Secuencia de bucle por casos (Loop-switch sequence): Programar un conjunto de pasos secuenciales usando un bucle en combinación con una estructura de control por casos. • Cadenas mágicas (magic strings): Incluir cadenas de caracteres determinadas en el código fuente para hacer comparaciones, como tipos de eventos, etc.
7.1.5
Antipatrones metodológicos
Antipatrones de gestión de la configuración
• Conflicto de extensiones (extension conflict): Problemas con diferentes extensiones que tratan de gestionar las mismas partes del sistema (específico de Mac OS). • Infierno de dependencias (dependency hell): Escenario de problemas producidos por las versiones de otros productos que se necesitan para hacer funcionar un tercero.
• Bala de plata (silver bullet): Asumir que nuestra solución técnica favorita puede resolver un problema mucho mayor.
• Infierno DLL (DLL hell): Problemas con las versiones, disponibilidad o proliferación de DLLs (específico de Microsoft Windows)
• Desarrollo conducido por quien prueba (tester driven development): Permitir que un proyecto software avance a base de extraer sus nuevos requisitos de los informes de errores.
• Infierno JAR (JAR hell): Problemas con diferentes versiones o ubicaciones de ficheros JAR (Java), típicamente causados por la falta de comprensión del modelo de carga de clases.
7.3. RELACIÓN ALFABÉTICA DE OTROS ANTIPATRONES
7.2 Algunos antipatrones organizacionales • Alcance incremental (scope creep): Permitir que el alcance de un proyecto crezca sin el control adecuado. • Dependencia de proveedor (vendor lock-in): Construir un sistema que dependa en exceso de un componente proporcionado por un tercero. • Diseño en comité (design by committee): Contar con muchas opiniones sobre un diseño, pero adolecer de falta de una visión unificada. • Escalada de compromiso (escalation of commitment): No ser capaz de revocar una decisión a la vista de que no ha sido acertada. • Funcionalitis creciente (creeping featuritis): Añadir nuevas funcionalidades al sistema en detrimento de su calidad. • Gestión basada en números (management by numbers): Prestar demasiada atención a criterios de gestión cuantitativos, cuando no son esenciales o difíciles de cumplir. • Gestión de champiñones (mushroom management): Tratar a los empleados sin miramientos, sin informarles de las decisiones que les afectan (manteniéndolos cubiertos y en la oscuridad, como los champiñones). • Gestión porque lo digo yo (management by perkele): Aplicar una gestión autoritaria con tolerancia nula ante las disensiones. • Migración de costes (cost migration): Trasladar los gastos de un proyecto a un departamento o socio de negocio vulnerable. • Obsolescencia continua (continuous obsolescence): Destinar desproporcionados esfuerzos a adaptar un sistema a nuevos entornos. • Organización de cuerda de violín (violin string organization): Mantener una organización afinada y en buen estado, pero sin ninguna flexibilidad. • Parálisis por análisis (analysis paralysis): Dedicar esfuerzos desproporcionados a la fase de análisis de un proyecto, eternizando el proceso de diseño iterando sobre la búsqueda de mejores soluciones o variantes. • Peligro moral (moral hazard): Aislar a quien ha tomado una decisión a raíz de las consecuencias de la misma.
17 • Sistema de cañerías (stovepipe): Tener una organización estructurada de manera que favorece el flujo de información vertical, pero inhibe la comunicación horizontal. • Te lo dije (I told you so): Permitir que la atención se centre en que la desoída advertencia de un experto se ha demostrado justificada. • Gallina de los huevos de oro (cash cow): Pecar de autocomplacencia frente a nuevos productos por disponer de un producto legacy muy lucrativo.
7.3 Relación alfabética de otros antipatrones • Arrojar al otro lado del muro (thrown over the wall): Cuando un proyecto involucra a varios grupos de trabajo y va pasando secuencialmente de uno a otro, con escasa o nula comunicación entre ellos. • Billete lobo (wolf ticket): Declarar compatibilidad con un estándar cuando ésta no existe, o bien cuando el estándar solo incluye recomendaciones no obligatorias que, de hecho, no se siguen. • Fiesta de los bocazas (Blowhard Jamboree): Cuando se intenta que las decisiones técnicas del proyecto sean las basadas en opiniones de expertos publicadas en prensa. • Cadena sin longitud (string without length). • Cajas de diálogos en cascada (cascading dialog boxes). • Callejón sin salida (dead end): Encontrar un problema que impide continuar trabajando, pero la dirección no permite corregir el problema. El equipo queda estancado. • Caminar por un campo de minas (walking through a mine field): Trabajar con un componente pobremente probado (usualmente inestable), y por tanto poco confiable. • Chivo expiatorio (scape goat): Ante circunstancias de crisis en un proyecto se toma la decisión de dirigir las culpas a una persona o a un conjunto de personas concretas sin analizar si verdaderamente la naturaleza del problema se encuentra en las mismas. • Codificación brutal: Presionar a los programadores a trabajar sobre una arquitectura sin diseñar y sin requisitos evidentes. • Comité designado (appointed team): Crear un comité o grupo de trabajo para resolver un problema y no ocuparse de lograr que el grupo funcione.
18
CAPÍTULO 7. ANTIPATRÓN DE DISEÑO
• Compensación equitativa (egalitarian compensation): Compensar al personal por el trabajo individual hecho.
• El correo electrónico es peligroso (email is dangerous): Peligro de olvidar que detrás de los emails recibidos hay personas de carne y hueso.
• Contenedor mágico (magic container): La implementación de métodos que intentan ser tan flexibles como para adaptar su comportamiento a multitud de circunstancias, sobrepasando el umbral de una mantenibilidad adecuada del mismo.
• El gestor controla el proceso (manager controls process).
• Cuerpos tibios (warm bodies). • Culto al carguero (cargo cult): Consiste en copiar ciertas prácticas que podrían ser consideradas (no siempre) buenas prácticas sin saber muy bien los beneficios o ventajas que proporcionan, provocando esfuerzo innecesario en el proyecto para incorporarlas o problemas. • Cultura del miedo (fear culture)): Ambiente en el que cada empleado tiene miedo de mostrar el resultado de su trabajo por miedo a ser despedido por tener errores. • Cultura del héroe (hero culture): Se produce cuando una o pocas personas toman la responsabilidad del éxito de todo el equipo o proyecto, a menudo trabajando sobretiempo. • Decisión aritmética (decision by arithmetic): En lugar de intentar tomar una decisión con los datos disponibles y basado en el conocimiento y experiencia de nuestros colaboradores y el nuestro, se trata de justificar la misma sobre la base de unos factores presuntamente objetivos. • Desarrollo distribuido geográficamente (geographically distributed development). • Desarrollo marcado por las herramientas (autogenerated stovepipe): Preferir una solución generada automáticamente sobre la mejor solución. • Descomposición funcional (functional decomposition): Traducir un programa de un lenguaje estructurado a uno OO usando una sola clase y muchos métodos privados. • Diseñar por diseñar (design for the sake of design): Realizar un diseño excesivamente complejo sin necesidad real. • Diseño con arquitectura impuesta (architecture as requirement): Imponer que el diseño considere, obligatoriamente, el uso de herramientas o métodos no necesariamente idóneos. • Diseño de fregadero (kitchen sink design). • Diseñadores empíricos (architects don't code): Incapacidad del grupo de diseño para evaluar la complejidad del objeto diseñado.
• El traje nuevo del emperador (emperor's new clothes): Temor a señalar los defectos de un producto o proceso que un gerente o manager cree que funciona bien. • El viejo gran duque de York (the grand old Duke of York): Cuando los arquitectos o analistas no intervienen (uno o los dos), dejando a los programadores (especialistas en la implementación) prácticamente todas las decisiones a nivel e ejecución de las especificaciones del usuario. • Ellos me entendieron (they understood me): Explicar a programadores o diseñadores junior lo que se espera de ellos muy brevemente, y asumir que entendieron lo que se les pidió. • Embudo de excepciones (exception funnel): Atrapar una excepción e ignorarla, sin reportarlo. • Entrenar al entrenador (train the trainer): Contratar una formación sin haber precisado con cierta exactitud la materia sobre la que se desea la misma. Esto puede provocar que la formación no se enfoque de manera adecuada, tratando aspectos que no son necesarios en el proyecto o dejando fuera aspectos fundamentales. Contratar una formación sin tener referencias del formador, ya que lo mismo su nivel de conocimiento no es el adecuado a la naturaleza de la formación a impartir. • Es un problema de operadores (it is an operator problem). • Esconder las armas (cover your assets). • Falsa economía (false economy): Permitir que los recortes de presupuesto afecten la eficiencia de los trabajadores (las pérdidas terminan siendo mayores que lo ahorrado). • Falso punto final subrogado (false surrogate endpoint). • Fechas en punto flotante (floating point times). • Haz tu propia base de datos (roll your own database): Ante la necesidad de persistencia de datos se utiliza una solución que no se basa en un estándar. • Ingenieros compatibles e intercambiables (plug compatible interchangeable engineers). • Introducción de dificultad por analogía (analogy breakdown): Diseñar por analogía con problemas resueltos, posiblemente introduciendo dificultades no inherentes al problema, o descuidando dificultades propias del nuevo caso que se maneja.
7.3. RELACIÓN ALFABÉTICA DE OTROS ANTIPATRONES • Invocar a constructores con nulos (passing nulls to constructors).
19 contingencias del proceso de desarrollo, o cuando no se es flexible ante una planificación inicial, conservándose a lo largo del proyecto pese a que se pueda apreciar que resulta absolutamente irreal.
• La disputa familiar (the feud): Cuando existiendo un conflicto entre gestores de proyectos no se le busca una solución definitiva al mismo.
• Nacionalismo (national ism).
• La experiencia mata el diseño (architecture by implication): Descuidar el diseño por confiar excesivamente en la experiencia previa.
• Navaja suiza (swiss army knife): Intentar crear un producto que solucione varios problemas poco relacionados entre sí.
• Los clientes son tontos (customers are idiots): Pensar que uno sabe más que el cliente, y por tanto no es necesaria una investigación con el cliente.
• No es mi trabajo (Not my job): No solucionar algún problema evidente argumentando que es problema o fallo de otro.
• Maníaco del control (control freak): El deseo de control lleva a la microgestión y ésta a su vez a una pérdida importante de la capacidad de autogestión del equipo, ya que todos los pasos se miden milimétricamente.
• No especificar (specify nothing).
• Máquina de Rube Goldberg (Rube Goldberg machine): Realizar implementaciones muy complejas para tareas sencillas.
• Otra reunión más lo resolverá (yet another meeting will solve it): Ante un problema en la planificación del proyecto, se convocan reuniones para intentar dar una solución al problema. En éstas reuniones participan los miembros del equipo de proyecto que tendrán que dejar su trabajo habitual, produciéndose nuevos retrasos.
• Matar al mensajero (shoot the messenger). • Matar dos pájaros de un tiro (kill two birds with one stone). • Matrimonio sumarísimo (sumo marriage): Suele ocurrir en cualquier situación en la que exista una dependencia de un elemento o de una serie de factores que dificultan el mantenimiento o evolución del sistema. • Mazorca de maíz (corn cob): Mantener personas en el proyecto que resultan difíciles, conflictivas o que funcionan de manera absolutamente al margen de lo que es cualquier trabajo en equipo o de un comportamiento solidario y que rompen con la armonía del grupo. • Mecanismos de recompensa discordantes (discordant reward mechanisms): Un equipo recibe reconocimiento por ser el que más trabajo ejecuta sobre la base de criterios objetivos que no son válidos para medir el nivel de productividad o calidad. • Mezclador de software (software merger).
• No inventado aquí (not invented here): Cuando la organización o uno se niega a utilizar soluciones, metodologías, prácticas, herramientas, etc. externas sólo porque no se nos ocurrió previamente.
• Otro programador más (yet another programmer). • Presunto heredero (heir apparent): Cuando vemos que los posibles huecos que podrían quedar para seguir progresando en nuestra organización tienen ya nombres y apellidos (cuando además sus méritos son más que discutibles), provocará la salida de la organización en busca de otras alternativas o se producirá una pérdida de motivación que impactará directamente en la productividad. • Proceso a prueba de idiotas (idiot proof process). • Programador discordante (net negative producing programmer): Hay proyectos donde el rendimiento de uno o más miembros del equipo es muy inferior al esperado, hasta el punto de ser su productividad neta en el proyecto negativa (el proyecto mejoraría con el simple hecho de prescindir de estas personas, sin necesidad de sustituirlas por otra)
• Miedo al éxito (fear of success): Permitir que las únicas razones de que los trabajos no se completen sean de índole social.
• Proyecto del día de la marmota (ground hog day project): Discutir los mismos temas en todas las reuniones, sólo para llegar a la conclusión de que “algo debe hacerse”.
• Moneda en punto flotante (floating point currency): Utilizar una representación en punto flotante para valores que representan dinero, lo que puede provocar pérdida de precisión.
• Prueba incompleta (asynchronous unit testing): Descuidar en la etapa de pruebas, algunas unidades en todos los casos, o todas las unidades en algunos casos.
• Morir planificando (death by planning): Invertir más esfuerzo (y tiempo) del necesario para establecer un plan que después puede ser destruido por las propias
• Quiero estimaciones ahora (give me estimates now): Dar estimaciones sin tener suficientes datos para hacerlas.
20 • Requisitos esparcidos por la pared (requirements tossed over the wall): Existe un desorden general en los requisitos: se encuentran en distinto grado de terminación, no hay priorización de los mismos o es muy general como para poder hacer una ordenación adecuada por ese criterio, etc. Esto normalmente es provocado por una colaboración inadecuada por parte del área usuaria. • Requisitos ocultos (Hidden requirements): El equipo de proyecto conocedor de la dificultad de implementar un determinado requisito lo obvia dentro del catálogo de requisitos, le asigna una prioridad muy baja o lo engloba dentro de un requisito de mayor nivel quedando difuminado en el mismo. El área usuaria no especifica un requisito o no lo especifica de manera adecuada, solicitando explicaciones a posteriori por la no implementación de ese requisito o por su comportamiento incorrecto. • Si funciona, no lo toques (if it is working don't change):. • Somos tontos (we are idiots): Pensar que el conocimiento interno del problema es peligroso (por riesgo de que sea pobre o equivocado), y pedir validación del cliente para cada característica o decisión mayor. • Tarjetas CRCI (CRCI cards): Cuando se usa la técnica de tarjetas CRC, se aprovecha e incluye en la misma la implementación de la clase, convirtiéndose automáticamente la tarjeta CRC (Class-Responsibility-Collaboration) en CRCI (Class-Responsibility-CollaborationImplementation). • Tormenta de reproches (blame storming): En un equipo de proyecto se llega a la conclusión de que la mejor forma de analizar las causas de la no consecución de los objetivos es que se discuta quiénes internamente han tenido la culpa. • Torre de vudú (tower of voodoo):Se tiene un código que se sabe que funciona (aunque generalmente no se sabe muy bien cómo) y se pretende añadir algún tipo de funcionalidad adicional, en ocasiones no muy cohesionada con la ya implementada y se le coloca un envoltorio (wrapper) proporcionando una nueva interfaz de acceso a ese nuevo componente. • Trampa para osos (bear trap): Invertir mucho en una herramienta poco adaptada o factible, de manera que después es imposible deshacerse de ella. • Único punto de salida de función (single function exit point). • Valor por defecto indefinido (zero means null): Escoger un valor arbitrario para representar la indefinición, sin garantizar que ese valor no puede realmente ocurrir.
CAPÍTULO 7. ANTIPATRÓN DE DISEÑO • Violencia intelectual (intellectual violence): De manera interna en un equipo de trabajo o en una reunión con el cliente y/o con usuarios se utilizan términos, generalmente técnicos, que no son comprendidos o conocidos por la mayoría de los interlocutores.
7.4 Véase también • Patrón de diseño • Crisis del software • Hediondez del código • No hay balas de plata
7.5 Enlaces externos • C2.com (antipatrones) Portland Pattern Repository's Wiki
Capítulo 8
Archivo de cabecera Se denomina header file, al español fichero/archivo (de) cabecera, o include file, al español fichero de inclusión, en ciencias de computación, especialmente en el ámbito de los lenguajes de programación C y C++, al archivo, normalmente en forma de código fuente, que el compilador incluye de forma automática al procesar algún otro archivo fuente. Típicamente los programadores especifican la inclusión de los header files por medio de pragmas al comienzo (head o cabecera) de otro archivo fuente. Un header file contiene, normalmente, una declaración directa de clases, subrutinas, variables, u otros identificadores. Aquellos programadores que desean declarar identificadores estándares en más de un archivo fuente pueden colocar esos identificadores en un único header file, que se incluirá cuando el código que contiene sea requerido por otros archivos. La biblioteca estándar de C y la biblioteca estándar de C++ tradicionalmente declaran sus funciones estándar en header files.
8.1 Motivación En la mayoría de lenguajes de programación modernos, los programadores pueden dividir los programas en componentes de menor tamaño (como pueden ser clases y subrutinas) y distribuir esos componentes entre muchas unidades por traducir (típicamente en forma de archivos), que el sistema puede compilar de forma autónoma. Si una subrutina se tiene que usar al margen de la unidad por traducir donde ha sido definida, se tiene que introducir el concepto de declaración directa o prototipos de funciones. Por ejemplo, una función definida así en un archivo fuente:
Sin embargo en esta simple ilustración se requiere que el programador mantenga la declaración de la función de add en dos sitios ̶en el archivo que contiene su implementación y en el archivo que usa la funcionalidad. Si la definición de la función llega a alterarse, entonces el programador debe actualizar todos los prototipos repartidos a lo largo del programa. Esto es necesario porque la implementación de ambos, C y C++ han de diagnosticar todas las violaciones de lo que en C++ se llama "one definition rule" (ODR), al español “regla de una única definición”. De hecho, la mayoría de ellos se sirven de un enlazador para realizar esta labor. El enlazador, sin embargo, suele conocer, de forma muy limitada los tipos usados en los programas. Por ello, algunas de las violaciones de ODR no se detectan a la hora de implementar el lenguaje. Como resultado, es responsabilidad del programador el mantener la coherencia de todas las declaraciones que cruzan las fronteras de una unidad por traducir. Buscar todas estas declaraciones de una entidad externa y verficar que son compatibles de forma manual es una tarea ardua. (Nótese que C no define el término “one definition rule”̶es específico del lenguaje C++. Si declaraciones de la misma entidad en muchos archivos fuentes de C son diferentes, la función no funcionará de forma adecuada y puede llegarse a un comportamiento impredecible, independientemente de la regla que se esté violando.) Para entender una violación ODR, considérese el siguiente código (correcto): /* File print-heading.c */ #include
void print_heading(void) { printf(“standard heading\n”); } /* File main.c */ void print_heading(void); int main(void) { print_heading(); return 0; }
La unidad por traducir representada por el archivo fuente main.c referencia a la función print_heading() que está definida en otra unidad por traducir (print-heading.c). De int add(int a, int b) { return a + b; } acuerdo con las reglas de C99, los programadores deben declarar una función externa antes del primer uso. Para puede declararse (con un prototipo de función) y ser re- cumplir con este requisito el archivo main.c declara la ferida desde un segundo archivo fuente como sigue: función en la primera línea. Esta versión del código funint add(int, int); int triple(int x) { return add(x, add(x, ciona de forma correcta. x)); } Posteriormente, el programador que mantiene el archivo
21
22
CAPÍTULO 8. ARCHIVO DE CABECERA
fuente print-heading.c puede decidir hacer la función más /* File add.c */ #include “add.h”int add(int a, int b) { flexible y dar soporte a cabeceras a gusto del usuario. Una return a + b; } posible implementación podría ser la siguiente: /* File print-heading.c */ #include void Normalmente, los programadores sólo utilizan los heaprint_heading(const char *heading) { printf("%s\n”, der files para especificar los interfaces, y suelen aportar al heading); } menos, una pequeña cantidad de información explicando cómo usar los componentes declarados en el archivo. Al Si el programador olvida actualizar la declaración en igual que en este ejemplo, las implementaciones de sumain.c, se pueden dar resultados devastadores. La fun- brutinas permanecen en un archivo fuente separado, que ción print_heading() espera un argumento y hace uso del continua siendo compilado de forma independiente. (Una valor del mismo, sin embargo la función main() no pro- excepción común entre C y C++ son las "funciones inlivee ningún valor. Al ejecutar este programa se produce un ne", que suelen incluirse en header files porque la mayoría comportamiento impredecible: la aplicación puede im- de implementaciones no pueden expendir funciones inliprimir basura, terminar de forma inesperada o dar pie a ne de forma adecuada sin ver sus definiciones durante el resultados impredecibles en la plataforma en la que es eje- tiempo de compilación.) cutado. ¿Por qué se puede compilar y enlazar este código sin problema alguno? El motivo es que el compilador se guía por la declaración en main.c a la hora de compilar la unidad por traducir main.c. Y esa declaración se ajusta con la forma de la función. Más tarde, cuando el enlazador combina las unidades de traducción ya compiladas main.c y printheading.c (en la mayoría de implementaciones representadas como archivos main.o o main.obj), probablmente podría detectar la inconsistencia ̶pero no en C. Las implementaciones en C referencian las funciones por el nombre al nivel de archivo objeto y archivo binario, esto no incluye el valor de retorno o la lista de argumentos. El enlazador encuentra una referencia a print_heading() en main.o y una función adecuada en print-heading.o. Llegado este punto, toda la información relativa a tipos de argumentos de funciones se pierde. ¿Cómo es entonces posible llevar a cabo declaraciones múltiples sin problema alguno? La solución se llama header file. El header file de un módulo declara cada función, objeto y tipo de dato que forma parte del interfaz público del módulo ̶por ejemplo, en este caso el header file incluiría sólo la delcaración de add. Todo aquel archivo fuente que se refiera a add usa la directiva #include en el header file:
8.2 Alternativas Los header files no son la única solución al problema de acceder identificadores declarados en diferentes archivos. Tienen la desventaja de que los programadores siguen teniendo que realizar cambios en dos sitios diferentes (en el archivo fuente y en el header file) cuando se realiza un cambio en una definición. Algunos lenguajes más jóvenes (como Java) prescienden de los header files y usan, en su lugar, una esquema de nombres que permite al compilador localizar los archivos fuente asociados con implementaciones de clases e interfaces (pero, al hacerlo, se restringe la libertad a la hora de nombrar archivos). En estos lenguajes, el problema de ODR se suele resolver por medio de dos técnicas: la primera, el compilador pone toda la información necesaria sobre los tipos en el código compilado y esta información es accesisble incluso cuando el programa se ejecuta.; la segunda, Java y otros lenguajes modernos tienen la posiblidad de verificar el número y tipo de los argumentos como método de invocación. Todo esto tiene su precio: un exceso en espacio y tiempo de ejecución que no es aceptable para algunas aplicaciones donde el tiempo de respuesta es crítica.
/* File add.h */ #ifndef ADD_H #define ADD_H int COBOL y RPG IV tienen una forma de incluir archivos llamada copybooks. Los programadores“incluyen”éstos add(int, int); #endif /* ADD_H */ en la fuente del programa de forma similar a como se hace con los header files, permitiendo también reemplazar (Nótese que el header file utiliza un "Include guard".) ciertas partes del texto. La palabra clave de COBOL para /* File triple.c */ #include “add.h”int triple(int x) { la inclusión es copy, y el reemplazo se realiza por medio de la cláusula replacing...by. return add(x, add(x, x)); } Esto reduce la carga del mantenimiento: cuando una definición cambia, solo se tiene que actualizar una única copia de la declaración (la del fichero de cabecera). El fichero de cabecera también se puede incluir en el fichero fuente que contiene las correspondientes definiciones, dándole al compilador la oportunidad de comprobar si la declaración y la definición son consistentes.
8.3 Véase también • Application Programming Interface • Interface description language • #pragma once
8.4. ENLACES EXTERNOS
8.4 Enlaces externos • Esta obra deriva de la traducción de Header file de Wikipedia en inglés, publicada por sus editores bajo la Licencia de documentación libre de GNU y la Licencia Creative Commons AtribuciónCompartirIgual 3.0 Unported. • Organizing Code Files (the potential pitfalls and guidelines for using header files in C++) • C++ header file inclusion rules
23
Capítulo 9
Aserción (informática) En programación, una aserción es un predicado (i.e., una 9.1 Uso de las aserciones sentencia verdadero-falso) incluido en un programa como indicación de que el programador piensa que dicho En lenguajes como Eiffel, las aserciones son parte del propredicado siempre se cumple en ese punto del flujo de ceso de diseño, mientras que en otros, como C o Java, programa. solamente son utilizadas para comprobar suposiciones en Por ejemplo, el siguiente código contiene dos aserciones: tiempo de ejecución. x := 5; {x > 0} x := x + 1 {x > 1}
9.1.1 Aserciones en el diseño por contrato x > 0 y x > 1, y las dos son ciertas en dichos puntos de la Las aserciones pueden ser una forma de documentación: ejecución. pueden describir el estado en que el código empieza su Las aserciones suelen ser útiles para especificar prograejecución (precondición), y el estado que el código espera mas y para razonar la corrección de los mismos. Por alcanzar cuando finalice (postcondición); asimismo pueejemplo, una precondición ̶una aserción al comienzo den servir de especificación para los invariantes de clase. de una sección de código ̶determina que se espera que En Eiffel, tales aserciones se integran en el código y son el conjunto de sentencias que la siguen sean ejecutadas. automáticamente extraídas para documentar la clase. EsUna postcondición ̶colocada al final ̶describe el estato supone una parte importante del método de diseño por do que se espera alcanzar al final de la ejecución. contrato. El ejemplo anterior utiliza la notación introducida por C. Esta aproximación también resulta útil en lenguajes que A. R. Hoare en su artículo de 1969 "An axiomatic bano las soportan explícitamente: la ventaja de usar sentensis for computer programming" ("Una base axiomácias de aserción en lugar de aserciones en comentarios es tica para la programación de ordenadores"). Como esta que las primeras pueden ser comprobadas en cada ejecunotación normalmente no es aceptada por los compiladoción; si la aserción no se cumple, puede informarse del res de los lenguajes actuales, los programadores suelen error. Esto previene que el código y las aserciones se desincluir aserciones mediante comentarios. A continuación fasen (un problema que puede ocurrir con las aserciones se incluye un ejemplo en C: comentadas). x = 5; /* {x > 0} */ x = x + 1; /* {x > 1} */ Se han incluido las llaves para distinguir este uso de los comentarios de su uso habitual. Varios lenguajes de programación modernos incluyen una sentencia de aserción, que no es más que una aserción que se comprueba en tiempo de ejecución. Si su evaluación resulta falsa, se produce un “error de aserción”. La intención de estas sentencias de aserción es facilitar la depuración del programa, evitando que dicho fallo quede sin comprobar.
9.1.2 Aserciones en tiempo de ejecución Una aserción puede ser utilizada para verificar que una suposición hecha por el programador durante la implementación del programa sigue siendo válida durante la ejecución del programa. Por ejemplo, considérese el siguiente código en Java: int total = contarUsuarios(); if (total % 2 == 0) { // total es par } else { // total es impar assert(total % 2 == 1); }
El uso de aserciones ayuda al programador en las tareas En Java, % es el operador resto (no módulo) ̶si el pride diseño, desarrollo y razonamiento de un programa. mer operando es negativo, el resultado puede ser también negativo, Aquí, el programador ha asumido que la variable total no es negativa, así que el resto de una división entre 2 siempre será 0 o 1. La aserción explicita esta su24
9.2. DESACTIVACIÓN DE LAS ASERCIONES
25
posición ̶si contarUsuarios devuelve un valor negativo, es probable que haya un fallo en el programa.
9.2 Desactivación de las aserciones
Una gran ventaja de esta técnica es que cuando se produce algún error éste es inmediata y directamente detectado, evitando posibles daños colaterales ocultos. Puesto que un error de aserción normalmente informa de la línea de código donde se produce, se puede localizar el error sin necesidad de una depuración más exhaustiva.
Las aserciones suelen ser implementadas de modo que puedan ser activadas o desactivadas, normalmente en el conjunto del programa. Sin embargo, los lenguajes que distinguen entre distintos tipos de aserciones – p.ej. pre y postcondiciones – suelen permitir activarlas o desactivarlas de forma independiente. Si las aserciones son desactivadas, no se comprueban en tiempo de ejecución. De esta forma el programador puede colocar aserciones en lugares donde en otro caso no tendría sentido ponerlas (p.ej., comprobar que no se accede a un array mediante índices fuera de rango). Puesto que las aserciones son en principio una herramienta de desarrollo, normalmente son desactivadas cuando el programa en cuestión es publicado. Por otra parte, como algunas versiones del programa pueden incluir aserciones y otras no, es primordial que su desactivación no modifique el comportamiento del programa. En otras palabras, las aserciones deben ser libres de efectos colaterales. Una alternativa en el caso de C o C++ es redefinir la macro assert para evaluar la expresión incluso cuando las aserciones están desactivadas.
Las aserciones también suelen colocarse en puntos que se supone que no se alcanzan durante la ejecución. Por ejemplo, las aserciones pueden ser colocadas en la cláusula default de una estructura switch en lenguajes como C, C++ y Java. Los casos que intencionadamente no se manejan pueden provocar errores que aborten el programa.
En Java, las aserciones han sido parte del lenguaje desde la versión 1.4. Los errores de aserción resultan en AssertionError cuando el prorgama es ejecutado con los parámetros correctos, sin los cuales las sentencias de aserción son ignoradas. En C y C++, son añadidas por el fichero de cabeceras estándar assert.h definiendo assert (aserción) como una macro que devuelve un error en caso de fallo y La eliminación de las aserciones del código de producfinaliza el programa. ción es un proceso que se realiza de forma casi automáLas inclusión en los lenguajes de construcciones de aser- tica. Normalmente se realiza mediante compilación conción facilitan el desarrollo guiado por pruebas (Test- dicional, por ejemplo utilizando el preprocesador de C driven Development - TDD) al no necesitar de una libre- o C++ o pasando un parámetro de ejecución, como en ría independiente que implemente dichas aserciones. Java. Algunas personas, sin embargo, se oponen a la eliminación de las aserciones basándose en una analogía que compara la ejecución con aserciones y sin ellas en la fase de desarrollo con la práctica de la natación en una piscina 9.1.3 Aserciones durante el ciclo de desa- con la vigilancia de un socorrista para después nadar solo rrollo en el mar. Asimismo añaden que las aserciones también ayudan a desarrollar un programa a prueba de fallos. Durante el ciclo de desarrollo, el programador normalmente ejecuta su programa con las aserciones activadas. Cuando una aserción resulta falsa y se produce el correspondiente error, el programador automáticamente recibe 9.3 Comparación con los manejaun aviso. Muchas implementaciones además detienen la dores de errores ejecución del programa ̶esto resulta útil ya que si el programa sigue ejecutándose tras la violación de una aserEs importante establecer las semejanzas y diferencias ención, éste entra en un estado corrupto que puede hacer tre las aserciones y las rutinas de control de errores. Las más difícil la localización del problema. Gracias a la inaserciones deberían ser utilizadas para documentar situaformación proporcionada por el error de aserción (punto ciones lógicamente imposibles y descubrir posibles errodel código que ha provocado el fallo, quizás el stack trace res de programación̶si ese“imposible”ocurre, es que o incluso todo el contexto de la aserción violada), el proalgo fundamental está claramente equivocado. Esto difiegramador puede corregir el problema. De este modo, las re del control de errores: la mayoría de las condiciones de aserciones sirven como potente herramienta de depuraerror son posibles, aunque deberían ser muy poco probación. bles en la práctica. El uso de aserciones como mecanismo general de control de errores suele ser algo desacertado: las aserciones no permiten al programa recuperarse de los errores, y un fallo de aserción suele suponer una ter9.1.4 Aserciones estáticas minación abrupta del programa. Asimismo las aserciones Las aserciones que son comprobadas en tiempo de com- no suelen mostrar mensajes de error comprensibles por el pilación reciben el nombre de aserciones estáticas. Este usuario. tipo de aserciones resultan particularmente útiles en la Considérese el siguiente ejemplo de uso de aserciones pametaprogramación de plantillas. ra manejar un error:
26 int *ptr = malloc(sizeof(int) * 10); assert(ptr != NULL); // usar ptr Aquí, el programador advierte que malloc puede devolver un puntero a NULL si no resulta posible realizar la asignación de memoria. Esto es posible: el sistema operativo no garantiza que cada llamada a malloc termine con éxito, y el programa debe estar preparado para manejar el error. Una aserción quizás no es la mejor elección en este caso, ya que un error causado por malloc no es lógicamente imposible ̶es una posibildad legítima, aunque no es muy común que suceda. En este ejemplo, es cierto que la aserción resulta útil, aclarando que el programador ha decidido de forma deliberada no construir una rutina robusta de control de errores de asignación de memoria. El programador también puede decidirse por una utilización mixta de aserciones y rutinas estándar de control de errores para un mismo problema. Esto es útil en situaciones donde el programador quiere recibir aviso inmediato del error, pero con la seguridad de que será manejado de forma correcta en situaciones reales de explotación del programa. En el ejemplo anterior, esto supondría añadir una rutina de control de errores, pero también habría que mantener la aserción para que el programador supiese del fallo de memoria durante el proceso de depuración. Esto permite al programador localizar errores de forma más sencilla, lo que a su vez hará que el usuario final pueda ejecutar el programa sin recibir mensajes de error innecesarios. Esta táctica solamente resulta útil cuando el error especificado no supone la terminación abrupta del programa o afecte a los datos que éste maneja, sino que hará que el programa siga funcionando aunque sea más lentamente o de forma menos eficiente.
9.4 Enlaces externos • Hoare, C. A. R. (2001). «Assertions: a personal perspective». research.microsoft.com. Archivado desde el original el 02 de diciembre de 2015. • «Programming With Assertions in Java». java.sun.com. Archivado desde el original el 02 de diciembre de 2015. • «Using Assertions». java.sun.com. Artículo técnico.
CAPÍTULO 9. ASERCIÓN (INFORMÁTICA)
Capítulo 10
Automatización de tareas La automatización de tareas es, en informática, el conjunto de métodos que sirven para realizar tareas repetitivas en un ordenador. Algunos métodos para la automatización de tareas son la programación simple, los macros, los intérpretes y las bombas lógicas. También hay algunos programas específicos que automatizan tareas. Incluso los virus informáticos utilizados de forma benéfica podrían considerarse otro método para la automatización de tareas para el usuario.
27
Capítulo 11
Base de código El término codebase, o base de código, es usado en el desarrollo de software con el significado de la colección completa de código fuente usada para construir una aplicación o componente particular. Típicamente, el codebase incluye solamente los archivos del código fuente escritos por humanos y no los archivos del código fuente generados por otras herramientas o archivos de biblioteca binaria. Sin embargo, incluye generalmente archivos de configuración y de propiedades. El codebase para un proyecto es típicamente almacenado en un repositorio de control de fuentes. Un repositorio del código fuente es un lugar en donde son guardadas grandes cantidades de código fuente, tanto públicamente como privadamente. Son frecuentemente usados por proyectos de multi-desarrolladores para manejar, de una manera organizada, varias versiones y los conflictos que se presentan con los desarrolladores sometiendo modificaciones conflictivas. Subversion y Mercurial son herramientas populares usadas para manejar este flujo de trabajo, y son comunes en proyectos de fuente abierta. Refiriéndose a múltiples codebases como “distintos”se declara que hay implementaciones independientes sin código fuente compartido y que históricamente, estas implementaciones no evolucionaron de un proyecto común. En el caso de estándares, esto puede ser una manera de demostrar interoperabilidad mostrando dos piezas independientes de software que implementan un estándar dado.
11.1 Véase también • Apache Software Foundation • Bonsai (software) • Codase • Forja (software) • Programas para control de versiones • Control de versiones • SourceForge • Subversion (software)
28
Capítulo 12
Bean Un Bean es un componente software que tiene la particularidad de ser reutilizable y así evitar la tediosa tarea de programar los distintos componentes uno a uno. Se puede decir que existen con la finalidad de ahorrarnos tiempo al programar. Es el caso de la mayoría de componentes que manejan los editores visuales más comunes. Los que hayan utilizado Visual Studio, Eclipse o Delphi por ejemplo, ya estarán familiarizados con ellos. Un Bean puede representar desde un botón, un grid de resultados, un panel contenedor o un simple campo de texto, hasta otras soluciones mucho más complejas como conexiones a bases de datos, etc. Son bastante conocidas las EJB (Enterprise JavaBeans) que ofrecen numerosos Beans para Java.
12.1 Bean en Java Debe cumplir los siguientes criterios: - implementación serializable. - tener todos sus atributos privados (private). - tener métodos set() y get() públicos de los atributos privados. - tener un constructor público por defecto
12.2 Enlaces externos • JavaBeans de Sun
29
Capítulo 13
Beta tester Un Beta tester es un usuario de programas cuyos ejecutables están pendientes de terminar su fase de desarrollo, o alcanzar un alto nivel de funcionamiento, pero que aún no son completamente estables.* [1]
13.1 Generalidades Los beta testers usan sus conocimientos informáticos y su tiempo para detectar errores en la versión beta del software y así poder informar de éstos para que los desarrolladores los corrijan, o corregirlos ellos mismos. Algunas compañías los contratan para asegurarse de que sus programas van a funcionar lo mejor posible en el mercado. Otro tipo de beta testers son los que trabajan desinteresadamente ofreciendo soporte y ayuda a la comunidad GNU. Generalmente el“betatester”comparte una cierta afinidad con la herramienta puesta a prueba en cuestión, de ahí el entusiasmo por probarla, verificar nuevas funcionalidades y detectar anomalías en pos de mejorar el desarrollo de la herramienta en cuestión.
13.2 Alfa tester Es el mismo concepto, pero aplicado a la versión alfa del software, es decir, al software que se encuentra en la fase alfa del desarrollo.
13.3 Véase también • Fases del desarrollo de software
13.4 Referencias [1] S.E. Smith (2003). «What is a Beta Tester?» (en inglés). Consultado el 20 de octubre de 2010.
30
Capítulo 14
Bifurcación (sistema operativo) Este artículo se refiere a la bifurcación de procesos en sistemas operativos, consulta Bifurcación (informática) para otros usos.
Soy el padre con id 1 id proceso original 1 Soy el hijo con id 2 id proceso original 1
Una bifurcación o fork, cuando se aplica en el contexto de un lenguaje de programación o un sistema operativo, hace referencia a la creación de una copia de sí mismo por parte de un programa, que entonces actúa como un "proceso hijo" del proceso originario, ahora llamado "padre". Los procesos resultantes son idénticos, salvo que tienen distinto número de proceso (PID). Más generalmente, una bifurcación en un entorno multihilo significa que un hilo de ejecución se bifurca.
El orden de la salida será determinada por diversos parámetros del núcleo del sistema operativo. Como se puede observar, el valor contenido en la variable idPropio es compartido por proceso padre e hijo; sin embargo, la referencia a la variable no es la misma y su posterior modificación en cada código, ya sea del padre o del hijo, no se verá reflejada en ambos procesos.
14.2 Véase también • Bomba fork • Tubería
14.1 UNIX En el caso de los sistemas operativos derivados de UNIX, la llamada al sistema fork permite realizar una bifurcación del proceso. Esta llamada devuelve el identificador de proceso del proceso hijo al padre y un 0 al proceso hijo. Aquí hay un ejemplo escrito en lenguaje de programación C que muestra el uso de esta llamada. El código que se ejecute depende de si el proceso es padre o hijo. #include #include #include int main(void) { pid_t idHijo; pid_t idPropio; idPropio = getpid(); //Se obtiene el id del proceso actual idHijo = fork(); //Se crea un proceso 'hijo' if (idHijo == −1) { //Si hay un código menor que cero, hubo un error perror(“Error al realizar la bifurcación” ); //Se notifica al usuario return 1; //Se interrumpe la ejecución del proceso con una salida distinta a cero } if (idHijo == 0) //la ejecución de la llamada al sistema fork devuelve un cero al proceso 'hijo' printf(“Soy el hijo con id %ld id proceso original %ld\n”, (long)getpid(), (long)idPropio); else //la ejecución de la llamada al sistema fork devuelve el identificador al proceso 'padre' printf(“Soy el padre con id %ld id proceso original %ld\n”, (long)getpid(), (long)idPropio); return 0; } Este código imprimirá: 31
Capítulo 15
Binding 15.4 Enlaces externos
15.1 Psicología y educación En Psicología, el término binding se refiere a una metodología innovadora (Proyecto Binding) para enseñar a leer que nace de aplicar la evidencia científica en el ámbito del aprendizaje, desarrollada por la Universidad de Barcelona. Saber cómo trabaja nuestro cerebro para realizar una tarea tan complicada como la lectura es esencial para poder crear las mejores técnicas de aprendizaje lector (http://www.binding.es). Aunque todavía queda mucho camino por recorrer en este sentido, hoy en día se sabe que leer (y comprender) es el resultado de una gran cantidad de procesos cognitivos: la memoria de trabajo, el bucle fonológico, la capacidad de inferencia y deducción, entre otros. Así pues, Binding parte de la idea de que la mejor manera de enseñar a leer es entrenar lo que se ha comprobado científicamente que es importante a la hora de adquirir la lectura - decodificación, memoria de trabajo, morfología, léxico −. Los resultados extraídos los últimos años de la aplicación del Binding así lo avalan.
15.2 Informática En informática, un binding es una “ligadura”o referencia a otro símbolo más largo y complicado, y que se usa frecuentemente. Este otro símbolo puede ser un valor de cualquier tipo, numérico, de cadena, etc o el nombre de una variable que contiene un valor o un conjunto de valores. En el campo de la programación, un binding es una adaptación de una biblioteca para ser usada en un lenguaje de programación distinto de aquél en el que ha sido escrita.
15.3 Derecho mercantil En Derecho mercantil, cuando un contrato es “binding” indica que el mismo es vinculante, debiendo estar firmado y no forzar ninguna norma superior. 32
• http://www.binding.es - Información sobre el programa 'Binding'
Capítulo 16
Bloqueo mutuo En sistemas operativos, el bloqueo mutuo (también conocido como interbloqueo, traba mortal, deadlock, abrazo mortal) es el bloqueo permanente de un conjunto de procesos o hilos de ejecución en un sistema concurrente que compiten por recursos del sistema o bien se comunican entre ellos. A diferencia de otros problemas de concurrencia de procesos, no existe una solución general para los interbloqueos.
A
R1
Todos los interbloqueos surgen de necesidades que no pueden ser satisfechas, por parte de dos o más procesos. En la vida real, un ejemplo puede ser el de dos niños que intentan jugar al arco y flecha, uno toma el arco, el otro la flecha. Ninguno puede jugar hasta que alguno libere lo que tomó. En el siguiente ejemplo, dos procesos compiten por dos recursos que necesitan para funcionar, que sólo pueden ser utilizados por un proceso a la vez. El primer proceso obtiene el permiso de utilizar uno de los recursos (adquiere el lock sobre ese recurso). El segundo proceso toma el lock del otro recurso, y luego intenta utilizar el recurso ya utilizado por el primer proceso, por lo tanto queda en espera. Cuando el primer proceso a su vez intenta utilizar el otro recurso, se produce un interbloqueo, donde los dos procesos esperan la liberación del recurso que utiliza el otro proceso.
16.1 Representación de Bloqueos Mutuos usando grafos
R2 B
Ejemplo de representación de Bloqueo Mutuo en grafos de alocación de recursos con dos procesos A y B, y dos recursos R1 y R2.
16.2 Condiciones necesarias También conocidas como condiciones de Coffman por su primera descripción en 1971 en un artículo escrito por E. G. Coffman. Estas condiciones deben cumplirse simultáneamente y no son totalmente independientes entre ellas. Sean los procesos P0 , P1 , ..., Pn y los recursos R0 , R1 , ..., Rm :
El Bloqueo mutuo también puede ser representado usando grafos dirigidos, donde el proceso es representado por un cuadrado y el recurso, por un círculo. Cuando un proceso solicita un recurso, una flecha es dirigida del círculo al cuadrado. Cuando un recurso es asignado a un proceso, una flecha es dirigida del cuadrado al círculo. En la figura del ejemplo, se pueden ver dos procesos diferentes (A y B), cada uno con un recurso diferente asignado (R1 y R2). En este ejemplo clásico de bloqueo mutuo, es fácilmente visible la condición de espera circular en la que los procesos se encuentran, donde cada uno solicita un recurso que está asignado a otro proceso. 33
• Condición de exclusión mutua: existencia de al menos de un recurso compartido por los procesos, al cual sólo puede acceder uno simultáneamente. • Condición de retención y espera: al menos un proceso Pi ha adquirido un recurso Ri , y lo retiene mientras espera al menos un recurso Rj que ya ha sido asignado a otro proceso. • Condición de no expropiación: los recursos no pueden ser expropiados por los procesos, es decir, los recursos sólo podrán ser liberados voluntariamente por sus propietarios.
34 • Condición de espera circular: dado el conjunto de procesos P0 ...Pm (subconjunto del total de procesos original),P0 está esperando un recurso adquirido por P1 , que está esperando un recurso adquirido por P2 ,... ,que está esperando un recurso adquirido por Pm , que está esperando un recurso adquirido por P0 . Esta condición implica la condición de retención y espera.
CAPÍTULO 16. BLOQUEO MUTUO • La condición de espera circular es la más fácil de atacar. Se le permite a un proceso poseer sólo un recurso en un determinado momento, o una jerarquía puede ser impuesta de modo tal que los ciclos de espera no sean posibles.
16.5 Livelock
Un livelock es similar a un deadlock, excepto que el estado de los dos procesos envueltos en el livelock constantemente cambia con respecto al otro. Livelock es una forma de Los bloqueos mutuos pueden ser evitados si se sabe cier- inanición y la definición general sólo dice que un proceso ta información sobre los procesos antes de la asignación específico no está procesando. de recursos. Para cada petición de recursos, el sistema En un ejemplo del mundo real, un livelock ocurre por controla si satisfaciendo el pedido entra en un estado inejemplo cuando dos personas, al encontrarse en un paseguro, donde puede producirse un bloqueo mutuo. De sillo angosto avanzando en sentidos opuestos, y cada una esta forma, el sistema satisface los pedidos de recursos trata de ser amable moviéndose a un lado para dejar a solamente si se asegura que quedará en un estado seguro. la otra persona pasar, pero terminan moviéndose de lado Para que el sistema sea capaz de decidir si el siguiente a lado sin tener ningún progreso, pues ambos se mueven estado será seguro o inseguro, debe saber por adelantahacia el mismo lado, al mismo tiempo. do y en cualquier momento el número y tipo de todos los recursos en existencia, disponibles y requeridos. Existen Livelock es un riesgo con algunos algoritmos que detectan y recuperan los interbloqueos, pues si más de uno tovarios algoritmos para evitar bloqueos mutuos: ma cartas en el asunto, la detección del interbloqueo puede ser disparada continuamente; pudiendo ser arreglado • Algoritmo del banquero, introducido por Dijkstra. asegurándose que sólo un proceso (escogido al azar o por • Algoritmo de grafo de asignación de recursos. prioridad) tome acción. • Algoritmo de Seguridad.
16.3 Evitando bloqueos mutuos
• Algoritmo de solicitud de recursos.
16.4 Prevención Los bloqueos mutuos pueden prevenirse asegurando que no suceda alguna de las condiciones necesarias vistas anteriormente. • Eliminando la exclusión mutua: ningún proceso puede tener acceso exclusivo a un recurso. Esto es imposible para procesos que no pueden ser encolados (puestos en un spool), e incluso con colas también pueden ocurrir interbloqueos. • La condición de posesión y espera puede ser eliminada haciendo que los procesos pidan todos los recursos que van a necesitar antes de empezar. Este conocimiento por adelantado muchas veces es imposible nuevamente. Otra forma es requerir a los procesos liberar todos sus recursos antes de pedir todos los recursos que necesitan. Esto también es poco práctico en general. • La condición de no expropiación puede ser también imposible de eliminar dado que un proceso debe poder tener un recurso por un cierto tiempo o el procesamiento puede quedar inconsistente.
Capítulo 17
Bodyshopping Bodyshopping es un término ligado al mundo empresarial informático o tecnológico que hace referencia a la venta de capital humano. Conlleva la cesión de personal de este tipo a terceras empresas con ánimo de lucro. Término que proviene del inglés que podríamos definir como anglicismo o extranjerismo y que en su traducción literal hace referencia a la compra de cuerpos. Una forma castiza de denominar estas empresas es charcuteras o cárnicas. Esta práctica es muy habitual en el mundo de la consultoría informática y existen multitud de empresas que basan su negocio en esta "venta" de personal actuando prácticamente como empresas de trabajo temporal orientadas a la tecnología. En ocasiones ciertas compañías que tienen esta práctica como núcleo de su negocio, fundamentan sus ingresos en la contratación de este personal, normalmente con poca experiencia y bajo salario, con contratos temporales o por obra, quienes posteriormente son revendidos a terceras empresas como profesionales altamente cualificados y con una gran experiencia, siendo ésta única y exclusivamente la base de su negocio y de su Retorno de la inversión, ya que a menos experiencia y salario del personal, mayor beneficio por las altas tarifas cobradas. La legislación española expone claramente en su Estatuto de los Trabajadores (Artículo 43. Cesión de trabajadores.) que el bodyshopping es ilegal.
17.1 Enlaces externos • Trabajo Basura Directorio con estas empresas y experiencias personales de gente que ha trabajado en ellas. • Trabajungla Experiencias personales y salarios sobre estas empresas revelados de forma anónima. • El Informático Impasible: Outsourcing: OnShore y OffShore • El Sector de la Consultoría Informática en España « Peccata Minuta • Entendiendo el Bodyshopping « Peccata Minuta 35
• Las consultoras informáticas :: LinuxAdicto.org • Podcast monográfico sobre consultoría
Capítulo 18
BrookGPU BrookGPU fue desarrollado por la Universidad de Stanford, es un grupo de compiladores y aplicaciones basadas en el lenguaje Brook para utilizar con unidades de procesamiento gráfico (GPU). la programación con unidades GPU es continuamente abreviada con el nombre de General-purpose computing on graphics processing units (GPGPU). Para usar este programa es necesario una unidad de procesamiento gráfico (GPU) tipo ATI, NVIDIA o Gráficos integrados Intel, capaces de soportar gran paralelismo. BrookGPU compila programas escritos en Brook, una extensión de ANSI C diseñado para incorporar computación de datos paralelos y aritméticos con un eficaz y familiar lenguaje. respecto al modelo general de programación, por flujo de datos tipo por Stream, ofrece 2 grandes ventajas respecto a estos: • Paralelismo de datos: permite al programador especificar cómo realizar las mismas operaciones en paralelo sobre diferentes datos. • Intensidad aritmética: le da a los programadores el poder para minimizar la comunicación global de las operaciones y maximizar la comunicación local de las mismas Muchos de los progresos en este lenguaje se han visto en el proyecto de computación distributiva Folding@home, además con el fin de expandir las nuevas técnicas GPGPU, viene bajo licencia GPL, y así abrir las puertas a nuevos programadores de Direct3D, OpenGL o hasta Close to Metal sin dejar los detalles implementados en estos dichos lenguajes.* [cita requerida]
36
Capítulo 19
Caja blanca (sistemas) En programación, se denomina cajas blancas a un tipo de pruebas de software que se realiza sobre las funciones internas de un módulo. Así como las pruebas de caja negra ejercitan los requisitos funcionales desde el exterior del módulo, las de caja blanca están dirigidas a las funciones internas. Entre las técnicas usadas se encuentran; la cobertura de caminos (pruebas que hagan que se recorran todos los posibles caminos de ejecución), pruebas sobre las expresiones lógico-aritméticas, pruebas de camino de datos (definición-uso de variables), comprobación de bucles (se verifican los bucles para 0,1 e interacciones, y luego para las interacciones máximas, máximas menos uno y más uno). Las pruebas de caja blanca se llevan a cabo en primer lugar, sobre un módulo concreto, para luego realizar las de caja negra sobre varios subsistemas (integración). En los sistemas orientados a objetos, las pruebas de caja blanca pueden aplicarse a los métodos de la clase, pero según varias opiniones, ese esfuerzo debería dedicarse a otro tipo de pruebas más especializadas (un argumento podría ser que los métodos de una clase suelen ser menos complejos que los de una función de programación estructurada). Dentro de las Pruebas de Caja Blanca encontramos las llamadas coberturas (sentencia, decisión, condición y múltiple además de los mencionados caminos ciclomáticos propuestos por McCabe) Este concepto también es utilizado de manera análoga en la teoría general de sistemas.
19.1 Véase también • Pruebas de software • Pruebas de caja blanca • Pruebas de caja negra •
37
Capítulo 20
Caja negra (sistemas) deberá conocer como es la comunicación con los otros módulos (la interfaz), pero no necesitará conocer como trabajan esos otros módulos internamente; en otras palabras, para el desarrollador de un módulo, idealmente, el resto de módulos serán cajas negras. Esquema de una caja negra
En teoría de sistemas y física, se denomina Caja Negra a aquel elemento que es estudiado desde el punto de vista de las entradas que recibe y las salidas o respuestas que produce, sin tener en cuenta su funcionamiento interno. En otras palabras, de una caja negra nos interesará su forma de interactuar con el medio que le rodea (en ocasiones, otros elementos que también podrían ser cajas negras) entendiendo qué es lo que hace, pero sin dar importancia a cómo lo hace. Por tanto, de una caja negra deben estar muy bien definidas sus entradas y salidas, es decir, su interfaz; en cambio, no se precisa definir ni conocer los detalles internos de su funcionamiento.
20.1 Justificación Un sistema formado por módulos que cumplan las características de caja negra será más fácil de entender ya que permitirá dar una visión más clara del conjunto. El sistema también será más robusto y fácil de mantener, en caso de ocurrir un fallo, éste podrá ser aislado y abordado más ágilmente.
20.2 Caja negra y programación modular
20.3 Pruebas de software En pruebas de software, conociendo una función específica para la que fue diseñado el producto, se pueden diseñar pruebas que demuestren que dicha función está bien realizada. Dichas pruebas son llevadas a cabo sobre la interfaz del software, es decir, de la función, actuando sobre ella como una caja negra, proporcionando unas entradas y estudiando las salidas para ver si concuerdan con las esperadas.
20.4 Caja negra vs 'Cajanegrizar' Este concepto de caja negra utilizado en física, informática y disciplinas técnicas o tecnológicas en general, aunque está relacionado, no debe confundirse con el 'Cajanegrismo'; éste es un concepto más vinculado a la sociología que hace referencia al hecho de que las personas solemos olvidarnos del funcionamiento interno de las cosas (generalmente nuevos dispositivos tecnológicos) a medida que nos familiarizamos con ellos y terminamos por asimilarlos como de uso cotidiano. A este proceso de olvidar el funcionamiento interno de las cosas se le conoce con el nombre de 'cajanegrizar'.
Se podría decir que la principal diferencia entre ambos conceptos es que mientras el primero, el estudio de un sistema como una caja negra, es un proceso de abstracción, En programación modular, donde un programa (o un el segundo, el 'cajanegrismo', es más bien un proceso de algoritmo) es dividido en módulos, en la fase de diseño se olvido. buscará que cada módulo sea una caja negra dentro del sistema global que es el programa que se pretende desarrollar, de esta manera se consigue una independencia en- 20.5 Véase también tre los módulos que facilita su implementación separada por un equipo de trabajo donde cada miembro va a en• Teoría de sistemas cargarse de implementar una parte (un módulo) del pro• Modularidad grama global; el implementador de un módulo concreto 38
20.5. VÉASE TAMBIÉN • Interfaz • Interfaz de usuario • Diseño estructurado • Caja blanca (sistemas) • Abstracto y Abstracción • Cajanegrizar
39
Capítulo 21
CamelCase • En nombres de empresas tales como • BellSouth • CompuServe • LinuxCabal • Microsoft, antiguamente MicroSoft
Ejemplo de CamelCase en un indicador.
• PriceWaterhouseCoopers
CamelCase es un estilo de escritura que se aplica a frases o palabras compuestas. El nombre se debe a que las mayúsculas a lo largo de una palabra en CamelCase se asemejan a las jorobas de un camello. El nombre CamelCase se podría traducir como Mayúsculas/Minúsculas Camello. El término case se traduce como“caja tipográfica”, que a su vez implica si una letra es mayúscula o minúscula y tiene su origen en la disposición de los tipos móviles en casilleros o cajas. Existen dos tipos de CamelCase:
• OmegaSoft • VaxaSoftware • La Sexta • eDreams • En algunos hashtag
21.2 Enlaces externos
• UpperCamelCase, cuando la primera letra de cada una de las palabras es mayúscula. Ejemplo: EjemploDeUpperCamelCase. • lowerCamelCase, igual que la anterior con la excepción de que la primera letra es minúscula. Ejemplo: ejemploDeLowerCamelCase.
21.1 Usos • En varios lenguajes de programación • Java • .NET • C • C++ • Python • C# • Objective-C • ActionScript • PHP • En las primeras herramientas wiki 40
• Primer wiki, creado por Ward Cunningham • Caja alta y baja en el DRAE.
Capítulo 22
Caml Caml (Originalmente un acrónimo para Categorical let rec fact = function | 0 -> 1 | n -> n * fact(n - 1);; Abstract Machine Language, en español Lenguaje Máquina Abstracto Categórico) es un dialecto de lafamilia de Esta última forma es la definición matemática de factorial losmeta lenguajes, desarrollado en INRIA y anteriormen- como una relación de recurrencia. te en ENS. Note que el compilador infirió el tipo de esta función para Como muchos descendientes delML, Caml es un len- ser int -> int, significa que esta función mapea enteros a guaje de tipado estático, evaluación estricta, y utiliza enteros. Por ejemplo, 12! Es: administración de memoria automática. # fact 12;; - : int = 479001600 La primera implementación de Caml en Lisp fue apodada “CAML pesado”debido a los requisitos de memoria y CPU relativos a su sucesor “Caml Light”, aquello fue implementado en C por Xavier Leroy y Damien Doligez. Además de una reescritura completa, “CAML Special 22.1.3 Derivación numérica (funciones de Light”añadió un potente sistema de módulos al núcleo alto orden) del lenguaje. Actualmente, la implementación principal de Caml es Desde que OCaml es un lenguaje de programación funOCaml, el cual añade muchas características nuevas al cional, es fácil crear y repasar funciones en programas de lenguaje, entre ellas una capa de objeto. OCaml. Esta capacidad tiene un número enorme de aplicaciones. Calcular la derivada numérica de una función es una de ellas. La funciónd en Caml computa la derivada 22.1 Ejemplos numérica de una función dada f en un punto dado x: Lo siguiente, # representa el prompt de OCaml.
22.1.1
Hola Mundo
print_endline “Hello World!";;
let d delta f x = (f (x +. delta) −. f (x −. delta)) /. (2. *. delta);; Esta función requiere un valor infinitesimal delta. Una buena elección para delta es la raíz cúbica del épsilon de la máquina.
El tipo de la función d indica que ésta mapea un tipo de dato flotante a otra función del mismo tipo (float -> float) -> float -> float. Esto nos permite aplicar argumen22.1.2 Función factorial (recursividad y tos parcialmente. Este estilo funcional es conocido como programación puramente funcio- currificación. En este caso, es útil al aplicar parcialmente el primer argumento delta a d, para obtener una función nal) más especializada: Muchas funciones matemáticas, como el factorial, son re- # let d = d (sqrt epsilon_float);; val d : (float -> float) -> presentadas más naturalmente en una forma puramente float -> float = funcional. La siguiente función recursiva, puramente funcional implementa la operación factorial en Caml: Note que el tipo inferido indica que la sustitución d espelet rec fact n = if n=0 then 1 else n * fact(n - 1);; ra una función del tipo flotante float -> float como primer argumento. Podemos computar una aproximación numéLa función puede ser escrita equivalentemente utilizando rica a la derivada de la función x3 − x − 1 en el punto patrones de emparejamiento: x = 3 con: 41
42
CAPÍTULO 22. CAML
# d (fun x -> x *. x *. x −. x −. 1.) 3.;; - : float = 26.
ciation of Computer Machinery.
La respuesta correcta es: f ′ (x) = 3x2 − 1 → f ′ (3) = 27 − 1 = 26
22.4 Enlaces externos
La función d se denomina “función de alto orden”ya que acepta otra función (f) como argumento.
• [Repositorio de Caml en Github]
• [Sitio oficial de Caml] Los conceptos de funciones currificadas y de alto orden son útiles evidentemente en programas matemáticos. De • [Tutoriales de caml (inglés)] hecho, estos conceptos son igualmente aplicables a otras formas de programación y pueden ser empleados en código de factor mucho más agresivamente, resultando epro- 22.4.1 Libros gramas más cortos y con menos errores. • The Functional Approach to Programming with Caml by Guy Cousineau and Michel Mauny.
22.1.4
Transformada Wavelet discreta (concordancia de patrones)
La transformada Wavelet de Haarde de una lista de números enteros de potencia en base dos puede ser implementada muy sucintamente en Caml y es un ejemplo excelente del uso de la concordancia de patrones sobre listas, tomando pares de elementos (h1 y h2) del frente y almacenando sus sumas y diferencias en las listas s y d, respectivamente: # let haar l = let rec aux l s d = match l, s, d with [s], [], d -> s :: d | [], s, d -> aux s [] d | h1 :: h2 :: t, s, d -> aux t (h1 + h2 :: s) (h1 - h2 :: d) | _ -> invalid_arg “haar”in aux l [] [];; val haar : int list -> int list = Por ejemplo: # haar [1; 2; 3; 4; −4; −3; −2; −1];; - : int list = [0; 20; 4; 4; −1; −1; −1; −1] El patrón de emparejamiento permite transformaciones complicadas para ser representadas claramente y sucintamente (brevemente). Además, el compilador de OCaml realiza concordancia de patrones en un código muy eficaz, el tiempo en el que los programas arrojan resultados es más corto y más rápido que el código equivalente escrito con una estructura "switch-case" (Cardelli 1984, p. 210.).
22.2 Véase también • OCaml • ML • F#
22.3 Referencias Cardelli, Luca (1984). Compiling a functional language ACM simposio en LISP y programación funcional, Asso-
Capítulo 23
Cierre de exclusión mutua En ciencias de la computación, los cierres de exclusión Estas son: mutua o candados son un mecanismo de sincronización que limita el acceso a un recurso compartido por varios • Sólo el dueño de un cerrojo puede desbloquearlo procesos o hilos en un ambiente de ejecución concurrente, • La readquisición de un cerrojo no está permitida permitiendo así la exclusión mutua. Cuando un elemento es compartido por más de un hilo, pueden ocurrir condiciones de carrera si el mismo no es protegido adecuadamente. El mecanismo más simple para la protección es el cierre o cerrojo. En general cuando debe protegerse un conjunto de elementos, se le asocia un cerrojo. Cada proceso/hilo para tener acceso a un elemento del conjunto, deberá bloquear, con lo que se convierte en su dueño. Esa es la única forma de ganar acceso. Al terminar de usarlo, el dueño debe desbloquear, para permitir que otro proceso/hilo pueda tomarlo a su vez. Es posible que mientras un proceso/hilo esté accediendo a un recurso (siendo por lo tanto dueño del cerrojo), otro proceso/hilo intente acceder. Esta acción debe esperar hasta que el cerrojo se encuentre libre, para garantizar la exclusión mutua. El proceso/hilo solicitante queda entonces en espera o pasa a estado de bloqueo según el algoritmo implementado. Cuando el dueño del cerrojo lo desbloquea puede tomarlo alguno de los procesos/hilos que esperaban. Este mecanismo se puede ver en un ejemplo de la vida real. Supongamos un baño público, donde sólo puede entrar una persona a la vez. Una vez dentro, se emplea un cierre para evitar que entren otras personas. Si otra persona pretende usar el baño cuando está ocupado, deberá quedar esperando a que la persona que entró anteriormente termine. Si más personas llegaran, formarían una cola (del tipo FIFO) y esperarían su turno. En informática, el programador no debe asumir este tipo de comportamiento en la cola de espera.
Algo muy importante es que todos los procesos/hilos deben utilizar el mismo protocolo para bloquear y desbloquear los cerrojos en el acceso a los recursos, ya que si mientras dos procesos/hilos utilizan el cerrojo de forma correcta, existe otro que simplemente accede a los datos protegidos, no se garantiza la exclusión mutua y pueden darse condiciones de carrera y errores en los resultados.
23.1 Primitivas y uso Las funciones de los cerrojos en general son tres: init(), lock() y unlock(). El cerrojo se inicializa con la función init(). Luego cada proceso/hilo debe llamar a la función lock() antes de acceder a los datos protegidos por el cierre. Al finalizar su sección crítica, el dueño del cerrojo debe desbloquearlo mediante la función unlock().
23.2 Bloqueos en bases de datos Los sistemas gestores de bases de datos suelen utilizar bloqueos para evitar problemas de concurrencia y, en ocasiones, garantizar la serializabilidad de las transacciones. Para hacerlo adecuadamente, los mecanismos de bloqueo suelen implementar protocolos como el bloqueo de dos fases y utilizar registros transaccionales (logs) como apoyo.
El cerrojo, usado de esta manera, forma una sección crítica en cada proceso/hilo, desde que es tomado hasta que se libera. En el ejemplo del baño, dentro de la sección crítica se encuentran las funciones que se realizan generalmente dentro de este tipo de instalaciones sanitarias. Como garantizan la exclusión mutua, muchas veces se los denomina mutex (por mutual exclusion). En general hay un número de restricciones sobre los cerrojos, aunque no son las mismas en todos los sistemas.
43
Capítulo 24
Clase utilidad En programación, una clase utilidad es una clase que define un conjunto de métodos que realizan funciones, normalmente muy reutilizadas. La mayoría de las clases utilidad definen estos métodos comunes con alcance estático. Ejemplos de clases utilidad incluyen java.util.Collections que proveen muchos métodos estáticos (tales como ordenar) en objetos que implementan una Collection (java.util.collection ).
24.1 Enlaces externos • Utility Pattern: Para una clase utilidad, que no requiere instanciación y sólo tiene métodos estáticos, se debe usar un constructor privado.
44
Capítulo 25
Clear.gif El lenguaje HTML para desarrollar páginas web no permite el alineamiento arbitrario de los objetos dentro del documento. Cuando Internet no se encontraba tan desarrollado, y prácticamente el HTML era lo único con lo que se contaba para mostrar contenidos, un truco que los desarrolladores utilizaban para poder alinear los textos a la altura y anchura que se desearan dentro de la página, era crear un archivo transparente de un píxel de tamaño y en formato gráfico GIF, que en aquel entonces era el único que permitía manejar transparencia en las imágenes. El archivo era manipulado dentro del código de la página web para que apareciera con cierta alineación, ya que las imágenes si permitían la alineación, pero no el texto. La transparencia era importante, pues permitía que la imagen no apareciera dentro de la visualización de la página web. El archivo era usualmente llamado clear.gif, aunque cualquier desarrollador que hiciera la imagen podía crearla con el nombre que quisiera. El nombre de dicho archivo dio lugar al de la técnica. La manera sencilla en la que se hace trabajar este truco en el código HTML es la siguiente: 
vspace=y
Donde x y y son las coordenadas de espaciado horizontal y vertical que se desean, y el atributo SRC señala la ruta hacia el archivo clear.gif. El texto que se escriba a continuación de ese fragmento de código, se alineará a la altura y anchura indicada en la etiqueta.
45
Capítulo 26
CMake CMake es una herramienta multiplataforma de generación o automatización de código. El nombre es una abreviatura para“cross platform make”(make multiplataforma); más allá del uso de “make”en el nombre, CMake es una suite separada y de más alto nivel que el sistema make común de Unix, siendo similar a las autotools. CMake es una familia de herramientas diseñada para construir, probar y empaquetar software. CMake se utiliza para controlar el proceso de compilación del software usando ficheros de configuración sencillos e independientes de la plataforma. Cmake genera makefiles nativos y espacios de trabajo que pueden usarse en el entorno de desarrollo deseado. Es comparable al GNU build system de Unix en que el proceso es controlado por ficheros de configuración, en el caso de CMake llamados CMakeLists.txt. Al contrario que el GNU build system, que está restringido a plataformas Unix, CMake soporta la generación de ficheros para varios sistemas operativos, lo que facilita el mantenimiento y elimina la necesidad de tener varios conjuntos de ficheros para cada plataforma.
el Visualization Toolkit (VTK), un sistema para gráficos 3D y visualización libres. Para crear CMake, Bill Hoffman en Kitware incorporó algunas ideas de pcmaker, y añadió más cosas propias, con el pensamiento de adoptar algunas de las funcionalidades del GNU build system. La implementación inicial de CMake tuvo lugar a mediados del 2000, con un desarrollo acelerado a comienzos del 2001. Muchas mejoras se debieron a influencias de otros desarrolladores a la hora de incorporar CMake a sus propios sistemas. Por ejemplo, la comunidad de VXL adoptó CMake, contribuyendo con muchas características esenciales. Brad King añadió varias características para dar soporte a CABLE y GCC-XML, un juego de herramientas de envoltura automáticas; y GE Corporate R&D necesitaba soporte para su infraestructura de pruebas (DART). Otras funcionalidades se añadieron para soportar la transición de VTK's a CMake, y soportar ParaView, un sistema de visualización paralela para el Advanced Computing Lab en Los Alamos National Laboratory.
El proceso de construcción se controla creando uno o más ficheros CMakeLists.txt en cada directorio (incluyendo subdirectorios). Cada CMakeLists.txt consiste en uno o 26.2 Documentación y tutoriales más comandos. Cada comando tiene la forma COMANDO (argumentos...) donde COMANDO es el nombre del Aparte de la documentación oficial de CMake, existe un comando, y argumentos es una lista de argumentos sepa- libro titulado Mastering CMake, publicado por Kitware. rados por espacios. CMake provee comandos predefinidos y definidos por el usuario. Existen generadores makefile para Unix, Borland make, Watcom make, MinGW, MSYS y Microsoft NMake. También es posible generar 26.3 Principales funcionalidades ficheros de proyecto para Code::Blocks, Eclipse CDT, Microsoft Visual Studio de la 6 a la 10 incluyendo ver• Ficheros de configuración escritos en un lenguaje de siones de 64 bits y KDevelop. scripting específico para CMake • Análisis automático de dependencias para C, C++, Fortran, y Java
26.1 Historia CMake se creó en respuesta a la necesidad de disponer de un entorno multiplataforma apropiado de construcción para el Insight Segmentation and Registration Toolkit (ITK) creado por la United States National Library of Medicine como parte del Visible Human Project. Fue influenciado por un sistema anterior llamado pcmaker creado por Ken Martin y otros desarrolladores para soportar 46
• Soporte para SWIG, Qt, FLTK, a través del lenguaje de scripting de CMake • Soporte para varias versiones de Microsoft Visual Studio, incluyendo la 6, 7, 7.1, 8.0, 9.0 y 10.0 • Genera ficheros para Eclipse CDT (C/C++ Development Tools)
26.6. VÉASE TAMBIÉN
47
• Detección de cambios en ficheros usando timestamps tradicionales
26.6 Véase también
• Soporte para builds paralelos
• Automake
• Compilador cruzado
• Autoconf
• Vista global de todas las dependencias, usando CMake para generar un diagrama graphviz
• premake
• Soporte para builds multiplataforma • Linux y otros sistemas POSIX (incluyendo AIX, *BSD, HP-UX, IRIX/SGI, y Solaris) • Mac OS X • Windows 95/98/NT/2000/XP, Windows Vista, Windows 7 y MinGW/MSYS • Integrado con DART (software), CDash, CTest y CPack, una colección de herramientas para prueba y liberación de software
• SCons • VTK • Waf
26.7 Enlaces externos • CMake • CMake Wiki • Documentación
26.4 CTest, CPack, CDash
• Listas de correo
Kitware desarrolló estas herramientas en colaboración con muchos otros. Incluyen CMake, CTest, CPack y CDash. CPack es una utilidad de empaquetamiento y despliegue. CTest es un cliente de pruebas libre.
26.5 Aplicaciones CMake • Avidemux • Compiz • Kicad • KVIrc • LMMS • MiKTeX • MuseScore • MySQL • OpenCV • Poppler • PvPGN • Quantum GIS • Scribus • Second Life • SuperTux • OGRE 3D • Ryzom
que
utilizan
Capítulo 27
Codecademy Codecademy es una plataforma interactiva en línea que ofrece clases gratuitas de codificación en lenguajes de programación como Python, PHP, JavaScript, y Ruby, así como lenguajes de marcado incluyendo HTML y CSS* [2]* [3] y también uso de API's. A partir de septiembre del 2011, el sitio ha tenido más de 550,000 usuarios que han completado más de seis millones de ejercicios.* [4]* [5] El sitio ha recibido críticas positivas de varios blogs y sitios web, incluyendo el New York Times* [6] y TechCrunch.* [7]
para aprender como programar, mediante la introducción de un nuevo curso cada semana en el 2012.* [12] Más de 450,000 personas tomaron el curso en el 2012,* [13]* [14] y Codecademy continua ofertando el programa en el 2013.
27.3 Véase también • Academic Earth
Para motivar a los usuarios a participar el sitio cuenta con un sistema de gamificación por el que ofrece insignias o medallas al completar ejercicios, cuenta con foros de discusión y un glosario por curso, y mantiene un registro de la puntuación total del usuario y la muestra a los demás. El sitio también permite que cualquier persona pueda crear y publicar un nuevo curso usando la herramienta de creación de cursos.
• Coursera • Dev Bootcamp • edX • Gilles Babinet • Khan Academy • lynda.com
27.1 Historia
• Marginal Revolution University Codecademy fue fundada en 2011 por Zach Sims y Ryan Bubinski.* [8] Sims dejó la universidad Columbia University para centrarse en el lanzamiento de una empresa, mientras que Bubinski se graduó en Columbia con una licenciatura en ciencias de la computación y biofísica.* [9] La compañía actualmente se encuentra en Nueva York. Obtuvo 2,5 millones de dólares en su primera ronda de financiación en octubre de 2011 y 10 millones en la segunda serie en junio de 2012.* [8]* [10] La última ronda de financiación fue llevada a cabo por Index Ventures.* [11]
• Udacity • Udemy
27.4 Referencias
Finalmente en el año 2014, la empresa Codecademy decide vender publicidad, comenzando con brindar un banner al gobierno de la ciudad de buenos aires.
27.2 Code Year Code Year es un programa gratuito de Codecademy para cualquiera que este interesado en aprender como programar. El programa tiene la intención de ayudar a las personas a seguir a través de un New Year's Resolution 48
[1] «Codecademy.com Site Info». Alexa Internet. Consultado el 18 de Septiembre de 2015. [2] «Codecademy». Codecademy. Consultado el 4 de agosto de 2012. [3] Indvik, Lauren. «Codeacademy Releases Free Ruby Development Courses». Mashable. Mashable. Consultado el 30 de diciembre de 2012. [4] Frier, Sarah. «Codecademy Raises $10M, Sees Job Service as Part of Its Future». Consultado el 19 de junio de 2012. [5] Kafka, Peter. «Codecademy Rounds Up $10 Million for Web Lessons». Consultado el 19 de junio de 2012.
27.5. ENLACES EXTERNOS
[6] Wortham, Jenna. «Codecademy Offers Free Coding Classes for Aspiring Entrepreneurs». The New York Times. Consultado el 26 de julio de 2012. [7] Cincaid, Jason. «Codecademy Surges To 200,000 Users, 2.1 Million Lessons Completed In 72 Hours». TechCrunch. Consultado el 26 de julio de 2012. [8] «30 Under 30: Zach Sims and Ryan Bubinski, Codecademy». Inc.com. 2 de julio de 2012. Consultado el 13 de agosto de 2012. [9] Segall, Laurie (29 de noviembre de 2011). «Codecademy says it can turn anyone into a Web programmer - Nov. 29, 2011». Money.cnn.com. Consultado el 13 de agosto de 2012. [10] Wortham, Jenna (27 de octubre de 2011). «Codecademy Lands $2.5 Million From Investors - NYTimes.com». Bits.blogs.nytimes.com. Consultado el 13 de agosto de 2012. [11] Colao, JJ (19 de junio de 2012). «Codecademy Raises $10 Million To Conquer The World». Forbes.com. [12] Segall, Laurie (6 de enero de 2012). «Code Year draws 200,000 aspiring programmers - Jan. 6, 2012». Money.cnn.com. Consultado el 16 de febrero de 2013. [13] «Learning JavaScript With Code Year " Feld Thoughts Feld Thoughts». Feld.com. Consultado el 16 de febrero de 2013. [14] Codecademy. «Code Year». Code Year. Consultado el 16 de febrero de 2013.
27.5 Enlaces externos • Sitio Web de Codecademy
49
Capítulo 28
Código cerrado En informática un programa es de código cerrado cuando el código fuente no se encuentra disponible para cualquier usuario, es decir no se hace público. Se le llama así en contraposición al código abierto. El software no libre generalmente utiliza un código cerrado. Por su calidad de secreto industrial, su divulgación podría ser constituyente de delito en algunos países.
28.1 Véase también • Software privativo
50
Capítulo 29
Código compilado Un código compilado es un código que previamente fue un código simbólico interpretable por un compilador, y luego ese compilador lo convirtió en un código directamente interpretable por un controlador (Código máquina).
51
Capítulo 30
Código mutante En informática, el término código mutante o código ambiguo se emplea para referirse a un código cuya integridad es modificada por sí mismo durante su ejecución, generalmente este código trata de un malware por el hecho de que si como algoritmo (cuando es ejecutado) se automodifica como información (donde está almacenado) fácilmente puede engañar a un programa del tipo antivirus o similar. Aunque de todas maneras, ciertos programas Antivirus son capaces de detectar este tipo de modificaciones.
52
Capítulo 31
Código objeto En programación, se llama código objeto al código que con parámetros incorrectos o inexistentes puede generar resulta de la compilación del código fuente.* [1] un error que generalmente el compilador no detecta ya Consiste en lenguaje máquina o bytecode y se distribuye que el código objeto no es verificado, únicamente unien varios archivos que corresponden a cada código fuente do. Este tipo de error se puede solucionar reescribiendo compilado. Para obtener un programa ejecutable se han el código de manera correcta y re compilarlo a código objeto. de enlazar todos los archivos de código objeto con un programa llamado enlazador (linker).
31.3 Referencias [1] http://www.alegsa.com.ar/Dic/codigo%20objeto.php
31.4 Enlaces externos • Fases en la realizazión de software
31.1 Código objeto en lenguajes de programación Un claro ejemplo de lenguaje de programación que usa código objeto en sus librerías es Pauscal. Esto le permite aumentar la velocidad de compilación de los programas y reducir su tamaño (ya que cada librería objeto puede ser comprimida), también permite a programadores compartir sus librerías/funciones sin tener la necesidad de liberar sus códigos fuentes originales. Incluso puede permitir a distintos lenguajes de programación compartir funciones sin necesidad de tener que reescribir el código plano a sus respectivas sintaxis.
Wikcionario tiene definiciones y otra información sobre código objeto.Wikcionario
el código objeto es el resultado de la compilación del código fuente. Puede ser en lenguaje máquina o bytecode, y puede distribuirse en varios archivos que corresponden a cada código fuente compilado. Luego un enlazador (linker) se encarga de juntar todos los archivos de código objeto para obtener el programa ejecutable. - See more at: http://www.alegsa.com.ar/Dic/codigo%20objeto. php#sthash.ktzQpZxJ.dpuf Código objeto: Conjunto de instrucciones y datos escritos en un lenguaje que entiende el ordenador directamente: binario o código máquina. Provienen de la traducción de cierto código fuente, es un fragmento del programa final y es específico de la plataforma de ejecución.
31.2 Errores comunes Los código objeto pueden ser muy útiles en muchas situaciones sin embargo consigo traen problemas que pueden generar errores muy difíciles de corregir, por ejemplo cuando un objeto importa funciones de otro código objeto que ha sido modificado, el intento de la librería o el programa que importó la librería de ejecutar el código 53
Capítulo 32
Ofuscación La ofuscación se refiere a encubrir el significado de una 32.1.1 Ejemplos comunicación haciéndola más confusa y complicada de interpretar. Un ejemplo simple de ofuscación es llamar a las variables o funciones con palabras reservadas del lenguaje añadiendo algún símbolo int int_;
32.1 Informática
Con esta línea se define una variable de tipo entero. En computación, la ofuscación se refiere al acto delibe- long int _int(int int_){return int_-int_}; rado de realizar un cambio no destructivo, ya sea en el código fuente de un programa informático o código máquina cuando el programa está en forma compilada o bi- Con esta línea definimos una función con un parámetro entero que devuelve un valor long int, que por otra parte naria, con el fin de que no sea fácil de entender o leer. siempre será 0. En Internet, la ofuscación refiere a crear una publicación _int-_int; o formar parte del grupo los Ofuscados. El código ofuscado es aquél código que, aunque se tiene el código fuente, ha sido enrevesado específicamente para Esto equivale a poner 0. ocultar su funcionalidad (hacerlo ininteligible). (_int-_int)!; La ofuscación binaria se realiza habitualmente para impedir o hacer más difícil los intentos de ingeniería inversa Esto equivale a poner 1. y desensamblado que tienen la intención de obtener una (((!(int_-int_)<
32.2 Otros objetivos
Aparte de los lenguajes más conocidos, existen lenguajes de programación esotéricos. Además, también se puede buscar que el código fuente resulte una obra de ascii art. Existen otros programas ofuscados llamados quine que al ejecutarse la salida debe ser el código fuente del programa.
La ofuscación puede servir para otros propósitos. Los médicos han sido acusados de usar una jerga para encubrir hechos desagradables de un paciente. El autor y doctor Michael Crichton ha afirmado que la escritura médica es un “intento altamente capacitado y calculado de confundir al lector”. De forma similar, el lenguaje basado También hay programas ofuscadores que pueden actuar en texto, como gyaru-moji y algunas formas de leet speak sobre el código fuente, código objeto o ambos para difi- es ofuscado para hacerlo incomprensible a terceras percultar la ingeniería inversa. sonas. lomelo 54
32.3. ENLACES EXTERNOS
32.3 Enlaces externos • Competición de código ofuscado en C • Protección online de librerías javascript • The International Obfuscated C Code Contest (Concurso internacional de código en C ofuscado) • Cómo proteger código en Java por medio de la ofuscación de código • - Ofuscador de Codigo PHP online • FOPO - Free Online PHP Obfuscator • Análisis de ofuscación de código en Javscript
55
Capítulo 33
ColdFusion Coldfusion (Adobe ColdFusion) es una plataforma de desarrollo rápido de aplicaciones web que usa el lenguaje de programación CFML. En este aspecto, es un producto similar a ASP, JSP o PHP.
Es un lenguaje que se ejecuta en el servidor. A diferencia de JavaScript y Applets Java, que se ejecuta en el cliente, ColdFusion se ejecuta en el servidor web. Esto significa que los guiones escritos en ColdFusion correrán de la ColdFusion es una herramienta que corre en forma misma manera en cualquier navegador web. concurrente con la mayoría de los servidores web de Windows, Mac OS X, Linux y Solaris (también en servidores web personales en Windows 98 y puede ser usado 33.1 Historia para intranets). El servidor de aplicaciones web de ColdFusion trabaja con el servidor HTTP para procesar peti- ColdFusion fue desarrollado inicialmente por J. J. Allaiciones de páginas web. Cada vez que se solicita una pági- re, y su primera versión apareció en julio de 1995. En na de ColdFusion, el servidor de aplicaciones ColdFusion 2001, estando en el mercado la versión 5, Allaire fue ejecuta el guion o programa contenido en la página. adquirido por Macromedia, que en junio de 2002 lanzó El lenguaje de programación CFML, propio de Coldfu- ColdFusion MX (6.0), llamado de esta manera para sesion, puede crear y modificar variables igual que en otros guir la nomenclatura de sus otros productos. Esta versión lenguajes de programación que nos son familiares. Posee fue completamente reescrita en Java desde cero, y fue dicontrol de flujo de programas, como IF, Case, ciclo, etc. señada, entre otros aspectos, para integrarse de manera Tiene muchas funciones built-in para realizar tareas más sencilla con Macromedia Flash, el producto estrella de la complicadas, por ejemplo: para averiguar qué día de la compañía. semana será el 3 de agosto del 2027 ColdFusion MX 7 fue lanzado en febrero de 2005, meses antes de la adquisición de Macromedia por Adobe SysDayOfWeekAsString(DayOfWeek('2027/08/03')) tems. En la actualidad está disponible la versión 11. No es un lenguaje de bases de datos, pero interacciona de manera simple con bases de datos (Sybase, Oracle, MySQL, SQL Server, o Access). Usando SQL estándar, las páginas y aplicaciones web pueden fácilmente recuperar, guardar, formatear y presentar información dinámicamente.
33.2 Versiones
Muchas de las funciones poderosas de ColdFusion, como leer desde y escribir en discos duros del servidor, son basadas en tags. Así como el tag puede tener argumentos como 'width' o 'align', el tag tiene argumentos que especifican 'action=read/write/copy/delete', path=' etc. El tag construye automáticamente todo el código JavaScript para verificar los campos requeridos antes de hacer el formulario. ColdFusion también tiene tags para COM, Corba y Applets y Servlets de Java. ColdFusion fue diseñado para desarrollar sitios complejos y de alto tráfico. ColdFusion está diseñado para correr en máquinas multi-procesador, y permite construir sitios que pueden correr en clusters de servidores. 56
• 1995: Allaire Cold and Fusion, versión 1.0 • 1996: Allaire Cold and Fusion, versión 1.5 • 1996: Allaire Cold and Fusion, versión 2.0 • Junio 1997: Allaire Cold and Fusion, versión 3.0 • Enero 1998: Allaire Cold and Fusion, versión 3.1 • Noviembre 1998: Allaire ColdFusion, versión 4.0 (a partir de esta versión se le conoce como ColdFusion, ya que antes era “Cold and Fusion”) • Noviembre 1999: Allaire ColdFusion, versión 4.5 • Junio 2001: Macromedia ColdFusion, versión 5.0 • Mayo 2002: Macromedia ColdFusion MX, version 6.0, Updater 1, Updater 2, Updater 3
33.3. EJEMPLOS DE CÓDIGO
57
• Julio 2003: Macromedia ColdFusion MX, version 6.1, hot fix, Updater 1
33.3 Ejemplos de código
• 2005: Macromedia ColdFusion MX 7, 7.0.1, 7.0.2
Consulta a una base de datos:
• 30 de julio, 2007: Adobe ColdFusion 8 • 4 de abril, 2009: Adobe ColdFusion 8.0.1
SELECT * FROM table WHERE campo = 'hola'
• 5 de octubre, 2009: Adobe ColdFusion 9
Mostrar la respuesta de la consulta:
• 13 de julio, 2010: Adobe ColdFusion 9.0.1
#nombredelaconsulta.campo#
• 15 de mayo, 2012: Adobe ColdFusion 10 • 31 de mayo, 2012: Adobe ColdFusion 9.0.2
Dar valores y mostrar variables:
Contenido de la va• 31 de agosto, 2012: Adobe ColdFusion 10 Update riable: #sCadena# 1 Usar servicios web: • 11 de septiembre, 2012: Adobe ColdFusion 10 Up • 16 de octubre, 2012: Adobe ColdFusion 10 Update 3 • 2 de noviembre, 2012: Adobe ColdFusion 10 Update 4 • 19 de noviembre, 2012: Adobe ColdFusion 10 Update 5 • 11 de diciembre, 2012: Adobe ColdFusion 10 Update 6 • 15 de enero, 2013: Adobe ColdFusion 10 Update 7 • 27 de febrero, 2013: Adobe ColdFusion 10 Update 8 • 10 de abril, 2013: Adobe ColdFusion 10 Update 9 • 14 de mayo, 2013: Adobe ColdFusion 10 Update 10 • 9 de julio, 2013: Adobe ColdFusion 10 Update 11 • 12 de noviembre, 2013: Adobe ColdFusion 10 Update 12 • 10 de enero, 2014: Adobe ColdFusion 10 Update 13 • 14 de octubre, 2014: Adobe ColdFusion 10 Update 14 • 9 de diciembre, 2014: Adobe ColdFusion 10 Update 15 • 29 de abril, 2014: Adobe ColdFusion 11 • 22 de septiembre: Adobe ColdFusion 11 Update 1 • 14 de octubre, 2014: Adobe ColdFusion 11 Update 2 • 9 de diciembre, 2014: Adobe ColdFusion 11 Update 3
33.4 Enlaces externos
• Web oficial de ColdFusion en Adobe • Adobe ColdFusion community • Introducción a Adobe ColdFusion
Capítulo 34
Coloreado de sintaxis 34.1 Ejemplo Abajo se muestra un trozo de código en C++: // Bucle for normal for (int i=0; i
El resaltado de sintaxis, a veces llamado coloreado de sintaxis, es una capacidad de algunas aplicaciones para tratamiento de textos (como los editores de texto), para diferenciar elementos de texto (especialmente el llamado código fuente) mediante diversos colores o estilos tipográficos, dependiendo de las categorías sintácticas de sus términos, conforme a las reglas de algún lenguaje formal concreto.
34.2 Programas con coloreado de sintaxis • Scintilla • Notepad++ • Notepad2 • SciTE
Este resaltado se utiliza a modo de notación secundaria, habitualmente para mejorar la legibilidad del código fuente de programas o de textos escritos en algún lenguaje de marcado, permitiendo aumentar la productividad de los programadores. Los estilos aplicados por defecto dependen de cada programa informático, alguno de los cuales permiten configurar los estilos e incluso reconocer diversos lenguajes.
• Geany • Vim • Emacs • gedit • El visor de código fuente de la mayoría de los navegadores web.
Presentación independiente del significado La interpretación del texto no varía en absoluto al resaltar sus elementos. Los cambios en la representación del texto cumplen una función visual identificativa y no semántica, sólo se usan para transmitir información al lector humano. Por tanto, en el caso del código fuente de un programa, los intérpretes y los compiladores lo ignoran. No forman parte ni del lenguaje formal en sí, ni del texto, por lo que tampoco se guardan en el fichero, sino que se analiza cada vez que se carga.
34.3 Véase también
58
• Editor de páginas web • Editor de texto • WYSIWYG • WYSIWYM
Capítulo 35
Comentario (informática) /** * Simple HelloButton() method. * @version 1.0 * @author john doe */ HelloButton() { JButton hello = new JButton( "Hello, wor hello.addActionListener( new HelloBtnList
}
// use the JFrame type until support for t // new component is finished JFrame frame = new JFrame( "Hello Button" Container pane = frame.getContentPane(); pane.add( hello ); frame.pack(); // display the fra frame.show();
a un amplio abanico de formas de uso distintas y a la inclusión de información inútil dentro del código fuente. Para evitar este inconveniente, muchos programadores y analistas de software adoptan alguna de las “filosofías” o metodologías para la correcta utilización de los comentarios.
35.1 Información general Los comentarios adoptan por norma general un formato o bien de“bloque”(también denominado de“prólogo” ) o bien de“fin de línea”(también denominado“inline” ).* [5]
Un comentario de bloque delimita una zona del código fuente en la cual es permitido expandirse a varias líneas Un ejemplo de código fuente de Java, con comentarios de prólogo de texto. Esta región se reconoce por un delimitador de en rojo, comentarios entre líneas en verde. Código del prograinicio y un delimitador de final del comentario. Algunos ma en azul. lenguajes de programación admiten que los comentarios se aniden recursivamente (e.g., MATLAB), pero otros En la programación de computadoras, un comentario lenguajes no lo admiten (e.g., Java).* [6]* [7]* [8] es una construcción del lenguaje de programación* [1] Un comentario de fin de línea comienza con un delimitadestinada a incrustar anotaciones legibles al programa- dor y continúa hasta el final de la línea de texto (es decir, dor en el código fuente de un Programa informático.* [2] no es necesario un segundo delimitador). En otros casos, Estas anotaciones son potencialmente significativas pa- el comentario de fin de línea comienza en una cierta cora los programadores, pero usualmente ignorados por los lumna dentro del código fuente no siendo necesario un compiladores e intérpretes.* [3]* [4] Los comentarios son delimitador.* [8] añadidos usualmente con el propósito de hacer el código fuente más fácil de entender con vistas a su mantenimien- Los delimitadores son una secuencia conocida de caracteto o reutilización. La sintaxis y reglas para los comenta- res y suelen ser distintos para los comentarios de bloque rios varían y usualmente son definidas en la especificación que para los de fin de línea. Por ejemplo, el lenguaje C++ usa, para los comentarios de bloque, los delimitadores /* del lenguaje de programación. y */ mientras que los comentarios de fin de línea utiliza Se ha de tener en cuenta que los comentarios necesitan el delimitador //. Otros lenguajes solamente admiten un mantenimiento igual que el código y, por tanto, que un tipo de comentario. Por ejemplo, ADA solamente dispocomentario preciso y conciso es más fácil de mantener ne de comentarios de fin de línea mediante el delimitador que uno largo, repetitivo y complicado. -−.* [8] Los comentarios tienen una amplia gama de posibles usos: desde la mejora del código fuente con descripciones básicas hasta la generación de documentación exter- 35.2 Usos na. También se utilizan para la integración con sistemas de control de versiones y otros tipos de herramientas de La mejor manera de dar uso a los comentarios es obprogramación externas. jeto de controversia con posiciones a menudo enfrentaLa flexibilidad proporcionada por los comentarios da pie das.* [9]* [10] Hay una gran variedad de formas de escri59
60
CAPÍTULO 35. COMENTARIO (INFORMÁTICA)
bir comentarios y muchos comentaristas que ofrecen, en 35.2.3 ocasiones, consejos contradictorios.* [10]
35.2.1
Planeación / Revisión
Los comentarios se pueden utilizar como una forma de pseudocódigo para describir la intención antes de escribir el código real. En este caso se debe explicar la lógica detrás del código en lugar del código en sí mismo.
Descripción algorítmica
A veces, el código fuente contiene una solución nueva o digna de mencionarse a un problema específico. En tales casos, los comentarios pueden contener una explicación de la metodología. Estas explicaciones pueden incluir diagramas y pruebas matemáticas formales. Esto puede ser la explicación del código, en lugar de una clarificación de sus intenciones, pero otros encargados del mantenimiento del código pueden encontrar como fundamental esta explicación. Esto puede ser especialmente cierto en el caso de problemas de dominios de alta especialización; así como en optimizaciones, construcciones o llamadas a funciones de uso no cotidiano.* [13]
/* itera hacia atrás por todos los elementos retornados por el servidor (estos deben ser procesados cronológicamente)*/ for (i = (numElementsReturned - 1); i >= 0; i--){ /* procesa los datos de cada elemento */ Por ejemplo, un programador puede agregar un comentaupdatePattern(i, returnedElements[i]); } rio para explicar por qué se eligió un Ordenamiento por inserción en lugar de quicksort, pues el primero es, en Si se deja este tipo de comentario luego de escribir el có- teoría, más lento que el segundo. Esto podría escribirse digo, se simplifica el proceso de revisión al permitir la de la siguiente manera: comparación directa del código con los resultados previstos. Una falacia lógica común es que el código fácil de list = [f (b), f (b), f (c), f (d), f (a), ...]; // Se requiere un ordenamiento estable, mientras el desempeño realmente entender hace lo que tiene que hacer. no importa. insertion_sort (list);
35.2.2
Descripción de código
Los comentarios pueden ser utilizados para resumir el código o para explicar la intención del programador. Se- 35.2.4 Inclusión de recursos gún esta escuela de pensamiento, re-explicar el código en lenguaje natural se considera superfluo y la necesidad de volver a explicar el código puede ser un signo de que es Logotipos, diagramas y diagramas de flujo consistentes en construcciones de arte ASCII pueden ser insertados en demasiado complejo y debe ser reescrito. el código fuente en forma de comentario.* [14] Además, puede incrustarse como comentarios avisos de derechos de autor, fecha de creación, versión del producto, contac“No documentes mal código – re-escríbelo.” * to con el propietario y/o creador, etc.. [11] El fragmento de código que sigue es un simple diagrama ASCII que representa el flujo de proceso para un script “Los buenos comentarios no repiten el código, de administración de sistemas contenido en un Fichero ni lo explican. Estos aclaran su intención. Los Windows Script que se ejecuta en Windows Script Host comentarios deben explicar, a un nivel de absA pesar de que la sección que marca el código aparece cotracción más alto que el propio código, lo que mo un comentario, el diagrama de hecho aparece en una * se intenta conseguir” [12] sección XML CDATA sección, que técnicamente se considera distinta de los comentarios, pero que puede servir * Los comentarios también pueden ser utilizados para ex- para propósitos similares. [15] plicar por qué un bloque de código no se ajusta a las con- relacionado con proyectos de escaso tiempo de desarro- (Main_process) | V script.wsf (app_cmd) --> ClientApp (async_run, batch_process) | | V mru.ini (mru_history) llo, o en la corrección de errores. Por ejemplo: ' Se asigna una segunda variable debido a que se pro- ]]> ducen errores ' en el servidor cuando se reutilizan los datos del formulario. No se encontró documentación ' sobre el comportamiento extraño del servidor, así que simplemente se codificó para resolverlo. vtx = server.mappath(“local settings”)
Aún cuando este diagrama fácilmente podría haber sido incluido como un comentario, el ejemplo ilustra un caso en que el programador puede optar por no utilizar los comentarios, como una forma de incluir recursos en el código fuente.* [15]
35.3. ESTILOS
35.2.5
Depuración
61
35.3 Estilos
Una práctica común entre programadores es comentar un fragmento de código, es decir, agregar delimitadores de modo que un bloque de código se convierta en un comentario, y por tanto no se ejecutará en el programa final. Esto podría hacerse para excluir algunas piezas del código del programa o, de manera más común, para encontrar la causa de un error. Comentando sistemáticamente y ejecutando partes del programa, la causa del error puede ser determinada, permitiendo su corrección. A continuación un ejemplo de cómo comentar código con el propósito de excluirlo:
Hay muchas alternativas cuando se considera como los comentarios deben aparecer en el código fuente. Para grandes proyectos, los estilos de los comentarios se agregan apenas comienzan el proyecto. Normalmente los programadores prefieren estilos que son consistentes, no obstructivos, fáciles de modificar, y difíciles de romper.
El fragmento de código de arriba sugiere que el programador optó por desactivar la opción de depuración por alguna razón. Este estilo específico de comentario es más adecuado para la depuración. Un carácter de barra simple delante del delimitador de apertura es el que permite habilitar o deshabilitar el comentarios de bloque completo.
Factores tales como la preferencia personal, la flexibilidad de las herramientas de programación, y otras consideraciones tienden a influir en las variantes de estilo utilizado en el código fuente.
Los siguientes fragmentos de código en C son solo un ejemplo de como los comentarios pueden variar de estilo, mientras todos contienen la misma información básica:
/* Este es el cuerpo del comentario. Variante 1 */ if (opt.equals “ ( e”)) opt_enabled = true; /* if (opt.equals /***********************************\ * * * (“d”)) opt_debug = true; // */ //* if (opt.equals (“v” Este es el cuerpo del comentario. * * Variante 2. * * * \************************************/ )) opt_verbose = true; // */
Muchos EIDs permiten agregar o remover rápidamente este tipo de comentarios con opciones del menú singulares o atajos del teclado. El programador solamente debe marcar la parte de texto que desea comentar o descomentar y elegir la opción apropiada. Esto es particularmente útil con fragmentos grandes de código.
35.2.6
Generación de documentación
Las herramientas de programación en ocasiones incorporan documentación y metadatos en los comentarios.* [16] Estas pueden incluir las posiciones de inserción para la inclusión automática de archivos de cabecera, comandos para configurar el modo de resaltado de sintaxis* [17] o el número de revisión del archivo.* [18] Estos comentarios de control funcional son también conocidos comúnmente como anotaciones. Mantener la documentación dentro de comentarios en el código fuente es considerado como una forma de simplificar el proceso de documentación, así como un aumento en las posibilidades de que la documentación se mantendrá al día con los cambios en el código.* [19] Habitualmente este tipos de comentarios requiere utilizar una sintaxis básica para que puedan ser interpretados por el generador de documentación a diferencia de los comentarios anteriores donde no necesariamente se debe de utilizar una sintaxis predefinida.
35.3.1 Etiquetas Algunas etiquetas se utilizan en los comentarios para ayudar en la indexación de los problemas comunes. Tales etiquetas son comúnmente resaltado de sintaxis y permite búsquedas con herramientas de programación común, como la utilidad grep de UNIX. Ejemplos de convenios etiqueta son: • FIXME: para marcar código problemático potencial que requiere una atención especial y/o revisión. • NOTE: peligros potenciales para documentar el funcionamiento interno del código y de indicar. • TODO: para indicar las mejoras planificadas. • XXX: para advertir a otros programadores de código problemático o equivoco. Existe el riesgo de que las etiquetas se acumulan con el tiempo, es conveniente incluir la fecha y el propietario de etiqueta en el comentario de etiquetas para facilitar el seguimiento.
35.4 Curiosidades
Ddoc para el [[lenguaje de programacinet D]] y doxygen, para ser usado con C/C++, Java IDL y PHPDoc para Whitespace es un lenguaje de programación esotérico en PHP. el cual la sintaxis consiste únicamente en espacios en C#, F# e implementan una característica similar llamada blanco, tabulador y líneas nuevas, cualquier otro carácter comentarios XML, que son leídos por IntelliSense para es ignorado, por lo que en este lenguaje cualquier escrito los ensamblados compilados del entorno.NET.* [20] es un comentario.
62
CAPÍTULO 35. COMENTARIO (INFORMÁTICA)
35.5 Ejemplos
35.5.10 código HTML
35.5.1
En las páginas webs .html se introduce el comentario entre
Ensamblador
;comentario
35.5.2
Java
35.5.11 SQL
//comentario de línea /*comentario de bloque*/ /** co//esto es un comentario --este también /* y este en bloque mentario que será usado por javadoc */ */
35.5.3
C/C++
35.5.12 Visual Basic
//comentario en línea /* comentario en bloque*/ #if 0 Comentario de bloque aunque el bloque contenga /* este tipo 'comentario '''comentario XML de comentarios */ #endif
35.5.13 Pauscal 35.5.4
Delphi
' Soy un sensual comentario.
//comentario en línea { comentario en bloque }
35.5.14 PHP
(* comentario en bloque *)
//comentario en línea #este también /* comentario en bloEn delphi se pueden anidar comentarios de bloque siem- que */ pre que no usen el mismo delimitador, e.g. (* comentario en bloque { que contiene otros comentarios en bloque } // o de fin de línea y que es perfectamente 35.5.15 Cobol válido *) * Comentario
35.5.5
Lua
-- Un comentario de línea --[[ Un comentario de bloque ]]--
35.5.6
Ruby
#comentario =begin comentario de bloque =end
35.5.7
Python
#comentario
35.5.8
Perl
#comentario
35.5.9
Javascript
En archivo.js pueden darse las siguientes formas: //comentario en línea /* comentario en bloque */
35.6 Referencias [1] Para los propósitos de este artículo, los comentarios de un lenguaje de programación son tratados indistintamente de comentarios que aparecen en lenguajes de marcas, archivos de configuración u otros contextos similares. Más aún, los lenguajes de marcas con frecuencia se relacionan de manera cercana con código de lenguajes de programación, especialmente en el contexto de generación de código. Ver por ejemplo Ganguli, Madhushree (2002). Making Use of Jsp (en inglés). Nueva York: Wiley. ISBN 0471219746., Hewitt, Eben (2003). Java for Coldfusion Developers (en inglés). Upper Saddle River: Pearson Education. ISBN 0130461806. [2] Source code can be divided into program code (which consists of machine-translatable instructions); and comments (which include human-readable notes and other kinds of annotations in support of the program code).Penny Grubb, Armstrong Takang (2003). Software Maintenance: Concepts and Practice (en inglés). World Scientific. pp. 7, 120–121. ISBN 981238426X. [3] Algunos entornos de programación incluyen los comentarios como uno de los elementos de la sintaxis del lenguaje que son retenidos para procesamiento posterior, en lugar
35.7. ENLACES EXTERNOS
de ser descartados una vez han sido reconocidos por el procesador de lenguaje. [4] Los comentarios deben ser indicados de tal manera que sea posible para el procesador de código fuente reconocerlos como tal. Esto es usualmente simplificado al decir que los comentarios son “ignorados”(luego de ser reconocidos y desechados) por el procesador. [5] Dixit, J.B. (2003). Computer Fundamentals and Programming in C (en inglés). Laxmi Publications. ISBN 8170088828. [6] Desmond, Higham (2005). MATLAB Guide (en inglés). SIAM. ISBN 0898715784. [7] Vermeulen, Al (2000). The Elements of Java Style (en inglés). Cambridge University Press. ISBN 0521777682. [8] «Using the right comment in Java» (en inglés). Consultado el 24 de julio. Parámetro desconocido |añoacce3so= ignorado (ayuda) [9] W. R., Dietrich (2003). Applied Pattern Recognition: Algorithms and Implementation in C++ (en inglés). Springer. p. 66. ISBN 3528355581. ofrece puntos de vista sobre el uso adecuado de comentarios en el código fuente [10] Keyes, Jessica (2003). Software Engineering Handbook (en inglés). CRC Press. p. 256. ISBN 0849314798. discute los comentarios y la ciencia de la documentación [11] The Elements of Programming Style, Kernighan & Plauger [12] Code Complete, McConnell [13] Spinellis, Diomidis (2003). Code reading: The Open Source Perspective (en inglés). Addison-Wesley. ISBN 0201799405. [14] «CodePlotter 1.6 - Add and edit diagrams in your code with this 'Visio-like' tool». Consultado el 24 de julio de 2007. [15] Niederst, Jennifer (2006). Web Design in a Nutshell: A Desktop Quick Reference (en inglés). O'Reilly. ISBN 0596009879.En ocasiones la diferencia entre un“comentario”y otros elementos de la sintaxis de un lenguaje de programación o de marcas implica matices sutiles. Niederst indica una situación tal al decir: “Unfortunately, XML software thinks of comments as unimportant information and may simply remove the comments from a document before processing it. To avoid this problem, use an XML CDATA section instead.” [16] Vease e.g., Wynne-Powell, Rod (2008). Mac Os X for Photographers: Optimized Image Workflow for the Mac User (en inglés). Oxford: Focal Press. p. 243. ISBN 0240520270. [17] Lamb, Linda (1998). Learning the VI Editor (en inglés). Sebastopol: O'Reilly & Associates. ISBN 1565924266. describe el uso de sintaxis modeline en los archivos de configuración de Vim [18] Ver e.g., Berlin, Daniel (2006). Practical Subversion, Second Edition (en inglés). Berkeley: APress. p. 168. ISBN 1590597532.
63
[19] Ambler, Scott (2004). The Object Primer: Agile ModelDriven Development with UML 2.0 (en inglés). Cambridge University Press. ISBN 1397805218. [20] Murach. C# 2005. p. 56.
35.7 Enlaces externos • 13 consejos para comentar tu código • Como escribir comentarios (en inglés)
Capítulo 36
Compatibilidad (informática) La compatibilidad es la condición que hace que un programa y un sistema, arquitectura o aplicación logren comprenderse correctamente tanto directamente o indirectamente (mediante un algoritmo). A este algoritmo que hace que un programa logre ser comprendido por un sistema, arquitectura o aplicación se lo denomina emulador por el hecho de que es un intérprete entre el programa y el sistema, arquitectura o aplicación.
Un ejemplo: Ejecución de orden del programa: programa_orden_decir=(“huta”) Ejecución del emulador: emul transformar ma_realizar_*
programa_orden_*
en
siste-
Ejecución de orden del programa emulada en memoria: sistema_realizar_decir=(“Hola”)
36.1 Problemas de compatibilidad
Resultado en el sistema:
Un problema de compatibilidad (incompatibilidad) surge sistema> Hola a partir de la falta o mala interpretación de un programa por un algoritmo, esto conlleva a una mala ejecución de dicho programa o a la imposibilidad de ser ejecutado. 36.3 OpenSource Un ejemplo práctico: Hoy en día los programas OpenSource (código abierto), generalmente en los sistemas basados en unix lograron programa_orden_decir=(“Hola”) sistema> Hola solucionar bastante el tema de la compatibilidad, por el El programa le indica una orden al sistema y el sistema la hecho de que el sistema que compilará el programa, podrá antes adaptar el código a su kernel modificando opciones interpreta y la ejecuta sin problemas. de compilación, generalmente ingresando en la consola el Incompatibilidad Caso A (Mala ejecución): siguiente comando: programa_orden_decir=(“Hola”) sistema> Chau ./configure Compatibilidad:
El programa le indica una orden al sistema y el sistema la Luego compila el código con el siguiente comando: interpreta pero de forma errónea, devolviendo un resulmake tado no esperado. Y por último instala los ejecutables compilados con: Incompatibilidad Caso B (Imposibilidad de ejecución): make-install
programa_orden_da31s4s232sd2453ce sistema> Error
El programa le indica una orden al sistema que para él es Logrando así obtener un programa genérico completamente adaptado al sistema operativo que lo ha compilado. arbitraria y por ende no logra interpretarla.
36.4 Véase también
36.2 Emulación La emulación consiste en utilizar un algoritmo de por medio, denominado emulador que simula ser el sistema, arquitectura o aplicación para el cual el programa está preparado, el emulador modifica los comandos del programa en memoria para que el sistema pueda interpretarlo como si estuviera especialmente diseñado para él.
64
• Compatibilismo e incompatibilismo • Emulador • Software • Wine
36.5. ENLACES EXTERNOS • Compatibilidad hacia atrás
36.5 Enlaces externos • Emulación de windows para unix • Emuladores • Más emuladores
65
Capítulo 37
Competición Internacional Universitaria ACM de Programación La Competición Internacional Universitaria ACM de Programación (en inglés ACM International Collegiate Programming Contest, abreviado ACM-ICPC o simplemente ICPC) es una competición anual de programación y algorítmica entre universidades de todo el mundo patrocinada por IBM. En la competición prima el trabajo en equipo, el análisis de problemas y el desarrollo rápido de software. ICPC es un evento organizado por la Association for Computing Machinery (ACM).
37.1 Historia La ACM ICPC es una competición que hubo en la Universidad A&M de Texas en 1970. Pasó a ser una competición con varias rondas clasificatorias en 1977 y la final mundial se organizó en colaboración con la ACM Computer Science Conference. De 1977 a 1989, compitieron principalmente equipos de Estados Unidos y Canadá. La sede central está ubicada en la Universidad de Baylor desde 1989 y las competiciones regionales se ubican en universidades de todo el mundo, bajo el auspicio de la ACM y la colaboración de grandes empresas de la industria informática. La ACM ICPC ha ido aumentando en número de participantes y países por lo que ahora es una competición mundial con equipos de 84 países (en 2005).
universidad antes del concurso. Los estudiantes que hayan competido en dos finales mundiales (World Finals) o cinco competiciones regionales no pueden participar otra vez. Durante la competición, los equipos tienen 5 horas para resolver entre 8 y 10 problemas (lo normal es 8 para las competiciones regionales y 10 para la final). Se deben programar las soluciones con C, C++ o Java. Los programas enviados por los equipos se compilan y ejecutan con unos ciertos datos de entrada, si el programa falla al calcular la solución, el equipo es notificado del error y pueden enviar nuevamente el programa o probar con otros problemas. El ganador es el equipo que resuelve más problemas. Si hay equipos empatadas con el mismo número de problemas resueltos, el orden de clasificación se calcula a partir de los que han tardado menos en resolver los problemas. Ejemplo: si un equipo A ha enviado sus soluciones para 2 problemas los 60 y 120 minutos desde el inicio del concurso, y otro equipo B lo ha hecho a los 80 y 90 minutos. El desempate entre ambos equipos se haría mirando los tiempos, para el equipo A: 60+120 = 180 minutos. Para el equipo B: 80+90 = 170 minutos. El equipo B ganaría.
El tiempo que se toma para los desempates es el tiempo que ha pasado desde el inicio del concurso más 20 minutos por cada solución incorrecta enviada. En el ejemplo anterior, si el equipo A hubiera enviado 2 soluciones inDesde 1997 el principal patrocinador es IBM y la parti- correctas para su primer problema, su tiempo final sería: cipación en la competición ha aumentado enormemente. 20+20+60+120 = 220. En 1997 participaron 840 equipos de 560 universidades. El ICPC se diferencia de otras competiciones de prograEn 2005, 5606 equipos de 1737 universidades. El núme- mación (por ejemplo la IOI) en que suele tener un gran ro de equipos aumenta en un 10 y un 20% cada año. número de problemas (8 o más para resolver en 5 horas) y que es una competición por equipos con un sólo ordenador. Es necesario un buen entendimiento entre los miembros de un equipo para conseguir la victoria.
37.2 Reglas de la competición El ICPC es una competición por equipos. Las reglas actuales estipulan que cada equipo ha de tener como máximo 3 miembros. Los miembros han de ser estudiantes universitarios, que hayan estudiado menos de 5 años en la
66
37.5. GANADORES
37.3 Competiciones locales, regionales y final mundial
67 - Manila - Seul - Teerán
La competición tiene distintas fases clasificatorias. Algunas universidades tienen competiciones locales para elegir a los componentes de los equipos. Cada universidad puede mandar un máximo de 2 equipos de 3 personas a la fase regional, si desean participar con un tercer equipo deben solicitarlo a la organización que determinará si les conceden permiso o no. Las competiciones locales son opcionales y las organiza cada universidad como estime conveniente. Algunas universidades optan por seleccionar a los alumnos con notas más altas o a los que muestran más interés.
- Xian
Los equipos de cada universidad participan en la fase regional, con otros equipos de universidades próximas geográficamente. Hay más de 30 regiones en todo el mundo. Algunas regiones agrupan distintos países (por ejemplo la SWERC incluye a España, Portugal, Francia y otros países Europeos), otras son un sólo país (la región de Brasil) y otras son sólo parte un país (Estados Unidos está dividido en varias regiones). Los mejor clasificados en cada competición regional participarán en la final mundial. Cada región envía a la final un cierto número de equipos, no puedo haber más de un equipo de una misma universidad.
- Caribe
- Shanghai - Yokohama - Hanoi Regiones de Oceanía: - Pacífico sur (SPacific) Regiones de América Latina: - México y Centroamérica (CAmerica) - Brasil - Suramérica Norte - Suramérica Sur Regiones de Norteamérica: - Pacific Northwest (PacNW) - North Central (NCNA) - East Central (ECNA)
La final mundial se celebra cada año en un lugar distinto, - Northeastern (NENA) normalmente hoteles de lujo, y congrega a los equipos - Rocky Mountain (RM) ganadores de todas las competiciones regionales. - Mid-Central (MCUSA) - Greater New York (GNY)
37.4 Lista de competiciones regionales
- Southern California (Scal) - South Central (SCUSA) - Southeast USA (SEUSA)
Regiones de Europa y Rusia: - Suroeste (SWERC): esta región comprende España, Portugal, Francia, Italia, Suiza y el oeste de Austria.* [1] - Noroeste (NWERC) - Central (CERC) - Sureste (SEERC) - Noreste (NEERC) Regiones de África: - África y Arabia (AARPC) - Sudáfrica (SAfrica) Regiones de Asia: - Beijing
- Mid-Atlantic (MAUSA)
37.5 Ganadores • 2015 - Instituto de Óptica y Mecánica Fina de San Petersburgo, Rusia • 2014 - Universidad Estatal de San Petersburgo, Rusia • 2013 - Instituto de Óptica y Mecánica Fina de San Petersburgo, Rusia • 2012 - Instituto de Óptica y Mecánica Fina de San Petersburgo, Rusia
- Coimbatore (Coim)
• 2011 - Universidad de Zhejiang, China
- Kanpur (Kolkata)
• 2010 - Universidad de Shanghai Jiaotong, China
- Dhaka
• 2009 - Instituto de Óptica y Mecánica Fina de San Petersburgo, Rusia
- Kaohsiun
68
CAPÍTULO 37. COMPETICIÓN INTERNACIONAL UNIVERSITARIA ACM DE PROGRAMACIÓN
• 2008 - Instituto de Óptica y Mecánica Fina de San Petersburgo, Rusia
• 1979 - Universidad Washington en San Luis, Estados Unidos
• 2007 - Universidad de Varsovia, Polonia
• 1978 - Instituto Tecnológico de Massachusetts, Estados Unidos
• 2006 - Universidad Estatal de Saratov, Rusia • 2005 - Universidad de Shanghai Jiaotong, China • 2004 - Instituto de Óptica y Mecánica Fina de San Petersburgo, Rusia • 2003 - Universidad de Varsovia, Polonia • 2002 - Universidad de Shanghai Jiaotong, China • 2001 - Universidad Estatal de San Petersburgo, Rusia • 2000 - Universidad Estatal de San Petersburgo, Rusia • 1999 - Universidad de Waterloo, Canadá • 1998 - Universidad Carlos, República checa
• 1977 - Universidad Estatal de Míchigan, Estados Unidos
37.6 Véase también • Olimpiada Internacional de Informática
37.7 Enlaces • Sitio oficial
37.7.1 Jueces en Línea
• 1997 - Harvey Mudd College, Estados Unidos
• ACM-ICPC Live Archive Around the World
• 1996 - Universidad de California, Berkeley, Estados Unidos
• Universidad de Valladolid Online Judge
• 1995 - Universidad Albert-Ludwigs, Friburgo, Alemania
• Ural State University Online Judge
• 1994 - Universidad de Waterloo, Canadá • 1993 - Universidad de Harvard, Estados Unidos • 1992 - Universidad de Melbourne, Australia • 1991 - Universidad de Stanford, Estados Unidos • 1990 - Universidad de Otago, Nueva Zelanda • 1989 - Universidad de California, Los Ángeles, Estados Unidos • 1988 - Instituto Tecnológico de California, Estados Unidos • 1987 - Universidad de Stanford, Estados Unidos • 1986 - Instituto Tecnológico de California, Estados Unidos
• Caribbean Online Judge
• Tianjin University Online Judge • Saratov State University Online Judge • Sphere Online Judge • A2 Online Judge • Codeforces • MIPT Online Judge • Peking University Online Judge • Jilin University Online Judge • Zhejiang University Online Judge • Harbin Institute of Technology Online Judge • Tianjin University Online Judge
• 1985 - Universidad de Stanford, Estados Unidos
• Fuzhou University Online Judge
• 1984 - Universidad Johns Hopkins, Estados Unidos
• Online Problems Solving System
• 1983 - Universidad de Nebraska, Estados Unidos
• University of Dhaka Online Judge & Contest Training
• 1982 - universidad Baylor, Estados Unidos • 1981 - Universidad de Missouri-Rolla, Estados Unidos • 1980 - Universidad Washington en San Luis, Estados Unidos
• Moscow State University Virtual Contest System [1] http://pc.fdi.ucm.es/swerc/
Capítulo 38
Computación parasitaria Computación parasitaria es un paradigma de programación por el cual una aplicación consigue realizar cálculos complejos utilizando interacciones autorizadas sobre otras aplicaciones. Surge a partir de un trabajo publicado en Nature en el año 2000. En el trabajo original se utilizan dos ordenadores comunicándose a través de internet y protocolo TCP/IP, en una sesión de comunicación estándar. Uno de los ordenadores intenta solucionar un complicado problema, el de la satisfactibilidad de la lógica booleana, o 3-SAT; Lo hace descomponiendo el problema original en un número considerable de problemas más pequeños. Cada uno de estos problemas más pequeños se codifica como una relación entre un checksum (suma de control) y un paquete de red, de manera que la comprobación de si el checksum es correcto o no es la solución del problema más pequeño. El ordenador envía estos paquetes al ordenador que pretende realice la computación, el ordenador de destino comprueba el checksum del paquete recibido, si es correcto solicita mas paquetes, si es incorrecto, solicita la retransmisión.
38.1 Referencias 1. Parasitic computing, Barabasi et al., Nature, 412: 894-897 (2000).
38.2 Enlaces externos
De esta manera, el ordenador que recibe los paquetes y comprueba checksums, está realizando computaciones en beneficio del ordenador que las solicita, sin ser consciente de elllo, y sin hacer nada más que mantener una sesión TCP/IP normal. La prueba de concepto en el trabajo original es extremadamente ineficiente, ya que la cantidad de recursos computacionales necesarios para generar y enviar los paquetes fácilmente exceden los recursos computacionales solicitados al otro extremo; El problema 3-SAT se podría haber solucionado mucho antes si se analizase únicamente en local. Además, en la práctica, los paquetes probablemente y ocasionalmente deberán ser retransmitidos realmente cuando ocurran errores de transmisión y/o red reales. De todas maneras, la computación parasitaria a nivel de checksums simplemente es una prueba de concepto. Los autores del trabajo original sugieren que a medida que se mueva la computación a lo largo de la pila de protocolo, se puede llegar a un punto en el cual la computación solicitada al/los ordenadores huésped favorezca al parásito.
69
• http://www.nd.edu/~{}parasite • http://www.szene.ch/parasit/
Capítulo 39
Conectiva lógica En lógica, una conectiva lógica, o simplemente conectiva, (también llamado operador lógico o conectores lógicos) es un símbolo o palabra que se utiliza para conectar dos fórmulas bien formadas o sentencias (atómicas o moleculares), de modo que el valor de verdad de la fórmula compuesta depende del valor de verdad de las fórmulas componentes.
ya que da el valor de verdad de (C) está completamente determinado por el valor de (A) y (B) no tiene sentido para el estado (A) y (B) y negar (C). Sin embargo, entonces en (D) no es un conector lógico, ya que sería bastante razonable para afirmar (A) y (B) y negar (D): tal vez Pedro subió a la montaña para ir a buscar un balde de agua, y no porque Juan subió la montaña.
Los conectivos lógicos más comunes son los conectivos binarios (también llamados conectivos diádicos) que 39.1.2 Lenguajes formales unen dos frases, que pueden ser consideradas los operandos de la función. También es común considerar a la neEn los lenguajes formales, las funciones de verdad son gación como un conectivo monádico. representadas por símbolos inequívocos. Estos símbolos Las conectivas lógicas son, junto con los cuantificadores, se llaman “conectivos lógicos”, “operadores lógicos” las principales constantes lógicas de muchos sistemas ló- , “operadores proposicionales”, o, en la lógica clásica, gicos, principalmente la lógica proposicional y la lógica la “de funciones conectivos de verdad.”Véase fórmude predicados. las bien formadas para saber las reglas que permiten las En programación se utilizan para combinar valores de nuevas fórmulas bien formadas sean construidas al junverdad y obtener nuevos valores que determinen el flu- tar otras fórmulas bien formadas utilizando conectivos de funciones de verdad. jo de control de un algoritmo o programa.
39.1 Lenguajes 39.1.1
Lenguaje natural
Los conectivos lógicos pueden ser utilizados para conectar más de dos afirmaciones, entonces es común hablar de “conector lógico n-ario”.
39.2 Lista de conectivos lógicos comunes
La gramática de los lenguajes naturales, dos frases pueden unirse mediante una conjunción gramatical para formar una oración gramaticalmente compuesta. Algunas de estas conjunciones gramaticales, pero no todas, son fun- 39.2.1 Lista de conectivos lógicos comunes ciones de verdad. Por ejemplo, considere las siguientes Conectivos lógicos comúnmente usados: frases: A: Juan subió la montaña.
• Negación (no): ¬, ~
B: Pedro subió a la montaña.
• Conjunción (y): ∧, y, ∙
C: Juan subió a la montaña y Pedro se subió a la montaña.
• Disyunción (o) ∨
D: Juan subió la montaña, por lo tanto Pedro subió la montaña.
• Implicación material (Si.. entonces): →, ⇒, ⊃ • Bicondicional (si y solo si): ↔, ≡, =
Las palabras y y entonces son conjunciones gramaticales que unen las oraciones (A) y (B) para formar las oracio- Nombres alternativos para bicondicional son “sii”, nes compuestas (C) y (D). O y (C) es un conector lógico, “xnor”y “bi-implicación.” 70
39.3. REDUNDANCIA
71
Por ejemplo, el significado de los estados está lloviendo y estoy en el interior se transforma cuando los dos se combinan con conectivos lógicos: • No está lloviendo • Está lloviendo y estoy dentro de casa (P ∧ Q) • Está lloviendo o estoy dentro de casa (P ∨ Q) • Si está lloviendo, entonces estoy en casa. (P → Q) • Si estoy en casa, entonces está lloviendo. (P → Q) • Estoy dentro si y solo si está lloviendo (P ↔ Q) • No está lloviendo (¬ P)
• Bicondicional: el símbolo fue utilizado ≡ al menos por Russell en 1908;* [3] se utilizó ↔ al menos por Tarski in 1940;* [9] ⇔ fue utilizado en Vax; otros símbolos aparecieron puntualmente en la historia como ⊃ ⊂ en Gentzen,* [10] ~ en Schönfinkel* [5] o ⊂ ⊃ en Chazal.* [11] • Verdadero: el símbolo 1 vino de la interpretación de Boole de la lógica como un álgebra elemental de booleana como la álbegra dos elementos; otras ano∧ taciones incluyendo fueron encontrados en Peano. • Falso: el símbolo 0 también proviene de la interpretación de Boole de la lógica ∨ como un anillo [?]; otras anotaciones inclusive fueron encontradas en Peano.
Algunos autores utilizan letras para conectivos en algún Por declaración P = Q = Está lloviendo Estoy dentro de momento de la historia: u. para conjunción (del Alemán casa. “und”, significa“y”) y el. para la disyunción (del Alemán “oder”, significa “o”) en los primeros trabajos de HilTambién es común considerar la fórmula siempre verdabert (1904); N para la negación, K para la conjunción, A dera y la fórmula siempre falsa como conectivos para la disyunción, C para bicondicional en Łukasiewicz (1929).* [12] • Verdadero (⊤, 1 o T) • Falso (⊥, 0 o F)
39.2.2
39.3 Redundancia
Historia de las notaciones
• Negación: el símbolo ¬ apareció en Heyting en
A
1929.* [1]* [2] (comparar con en símbolo de Frege en Begriffsschrift); el símbolo ~ apareció en Russell en 1908;* [3] una notación alternativa es añadir una línea horizontal encima de la fórmula, como en P ; otra notación alternativa es utilizar una comilla simple como en P'.
El conectivo lógico de la implicación recíproca ← es en realidad el mismo que el condicional material con las premisas cambiadas, luego el símbolo de implicación es recripoca es redundante. En algunos cálculos lógicos (en particular, en la lógica clásica, ciertas afirmaciones compuestas esencialmente diferentes son lógicamente equivalentes. Un ejemplo menos trivial es una redundancia de la equivalencia clásica entre ¬ P ∨ Q → P y Q. Por lo tanto, un sistema lógico de base clásica no necesita del operador condicional "→" si "¬" (no) y "∨" (o) operador condicional que ya se utilizan, o se puede utilizar el "→" solo con un azúcar sintáctico para una composición que tiene una negación y una disyunción.
• Conjunción: el símbolo ∧ apareció en Heyting en 1929* [1] (comparar el uso de la notación de Peano de notación de intersección ∩ en teoría de conjuntos)* [4]); & apareció al menos en Schönfinkel en Hay 16 funciones booleanas que asocian los valores ver1924;* [5] ∙ vino la interpretación de Boole de la ló- dad de entrada de P y Q con salidas binarias 4 dígitos. gica como un álgebra elemental. Estos corresponden a las posibles opciones conectivos lógicos binarios para la lógica clásica. Una implementación • Disyunción: el símbolo ∨ apareció en Russell en diferente de la lógica clásica puede elegir diferentes sub1908 (comparar el uso de Peano de la notación de conjuntos de funcionalmente completos de conectivos. unión ∪ en teoría de conjuntos); también se utiliza el símbolo +, a pesar de la ambigüedad surgida de la Un método consiste en elegir un mínimo establecido y fiálgebra elemental ordinaria al ser el + considerado jado por cualquier otra manera lógicas como en el ejemun o exclusivo lógicamente interpretado como una plo con el condicional material anteriormente. Los sialianza de dos elementos; puntualmente en la histo- guientes son conjuntos mínimos funcionalmente compleria, un + junto con un punto en la esquina inferior tos de conectivos de los operadores en la lógica clásica, cuyo aridades no excedan 2: derecha fue usado por Peirce,* [6] • Implicación: el símbolo → se puede ver en Hilbert Un elemento {↑}, {↓}. en 1917;* [7] ⊃ fue utilizado por Russell en 1908* [3] (comparar con la notación de la C invertida de Dos elementos { ∨ , ¬}, { ∧ , ¬}, {→, ¬}, {←, ¬}, {→, Peano); ⇒ se utilizó en Vax.* [8] ⊥ }, {←, ⊥ }, {→, ̸↔ }, {←, ̸↔ }, {→, ̸→ }, {→,
72
CAPÍTULO 39. CONECTIVA LÓGICA ̸← }, {←, ̸→ }, {←, ̸← }, { ̸→ , ¬}, { ̸← , ¬}, { ̸→ , ⊤ }, { ̸← , ⊤ }, { ̸→ , ↔ }, { ̸← , ↔ }.
Tres elementos { ∨ , ↔ , ⊥ }, { ∨ , ↔ , ̸↔ }, { ∨ , ̸↔ , ⊤ }, { ∧ , ↔ , ⊥ }, { ∧ , ↔ , ̸↔ }, { ∧ , ̸↔ , ⊤ }. Vea más detalles sobre integridad funcional. Otro enfoque es utilizar en igualdad de derechos, de un cierto conjunto conveniente y funcionalmente completo, pero no mínimo. Este enfoque requiere más axiomas proposicionales y cada equivalencia entre las formas lógicas debe ser o bien un axioma o comprobada como un teorema. Pero la lógica intuicionista tiene una situación más complicada. De sus cinco conectivos {∧, ∨, →, ¬, ⊥} solamente la negación ¬ tiene que ser reducida a otros conectivos (¬p ≡ (p → ⊥)). Ni la conjunción, disyunción y condicional material tiene una forma equivalente construida de los otros cuatro conectivos lógicos.
• Dualidad: Para leer las asignaciones de valores de verdad para la operación desde arriba hacia abajo en su tabla de verdad es lo mismo que tomar el complemento de lectura de la tabla de la misma u otra conectiva desde abajo hacia arriba. Sin recurrir a tablas de verdad esto se puede formular como g̃ (¬a1 , ..., ¬an ) = ¬g(a1 , ..., an ). E.j., ¬ . • Preservación de la verdad: El compuesto todos los argumentos son tautologías es una tautología en sí. E.j., ∨ , ∧ , ⊤ , → , ↔ , ⊂. (ver validez) • Falsedad de preservación: El compuesto de todos los argumentos son contradicciones es una contradicción en sí. Por ejemplo, ∨ , ∧ , ̸↔ , ⊥ , ⊄, ⊅. (ver validez) • Involutividad (para conectivos unarios): f(f(a)) = a. Por ejemplo negación en la lógica clásica.
En la lógica clásica, tanto la conjunción y la disyunción son asociativas, conmutativas y idempotentes, en la mayoría de las variedades de lógica multi-valuada y la lógica Algunos conectivos lógicos tienen propiedades que se intuicionista. Lo mismo es cierto sobre distributiva de la pueden expresar en teoremas que contienen el conectivo. conjunción y la disyunción sobre más de conjunción, así Algunas de estas propiedades que una conectiva lógica como para la ley de absorción. puede tener son: En lógica clásica y algunas variedades de lógica multi-
39.4 Propiedades
valuada, la conjunción y la disyunción son duales, y la • Asociatividad: En una expresión que contiene dos negación es auto-dual, en la lógica intuicionista, esta úlo más del mismo conectivo asociativo en una línea, tima también es auto-dual. el orden de las operaciones, no importa, siempre y cuando la secuencia de los operandos no cambia. • Conmutatividad: Los operandos del conectivo 39.5 Ciencias de la computación pueden ser intercambiados (uno por el otro), mientras que la preservación de equivalencia lógica de la El planteamiento funcional a la verdad a los operadores expresión original. lógicos se implementa como puertas lógicas en circuitos • Distributividad: Un conectivo denotado por • dis- digitales. Prácticamente todos los circuitos digitales (la tribuye sobre otra que conecta denotado por el signo principal excepción es DRAM) se construye a partir de +, • si a • (b + c) = (a • b) + (a • c) para todos los NAND, NOR, NOT y puertas de transmisión; ver más detalles en función de verdad en informática. Los operaoperandos a, b, c. dores lógicos más de vectores de bits (correspondientes a • Idempotencia: Cuando los operandos de una opera- finita álgebra de boole) son operaciones bit a bit. ción son iguales, el compuesto es lógicamente equi- Pero no todo uso de un conector lógico en programación valente al operando. informática tiene una semántica de Boole. Por ejemplo, a veces se implementa evaluación perezosa para P ∧ Q • Absorción: Un par de conectivos ∧ , ∨ satisface la y P ∨ Q, de modo que estos conectores no son conmuley de absorción si a ∧ (a ∨ b) = a para todos los tativo si algunas de las expresiones P, Q tiene efecto seoperandos a, b. cundario. También, un condicional, que en cierto sentido • Monotonicidad: Si f(a1 ,..., an ) ≤ f(b1 ,..., bn ) para corresponde al conectivo condicional material, es esentodo a1 ,..., an , b1 ,..., bn ∈ {0,1} tal que a1 ≤ b1 , a2 cialmente no-booleano porque para si (P) entonces Q; la consiguiente Q no se ejecuta si el antecedente P es falso ≤ b2 ,..., an ≤ bn . Ej., ∨ , ∧ , ⊤ , ⊥ . (aunque un compuesto como un todo es exitosa ≈“verda• Afinidad: Cada variable siempre hace una diferen- dera”en tal caso). Esto se acerca más a las ópticas intuicia en el valor de verdad de la operación o nunca cionistas y constructivistas sobre el condicional material, más que a las de la lógica clásica. hace una diferencia. Ej., ¬ , ↔ , ̸↔ , ⊤ , ⊥ .
39.9. ENLACES EXTERNOS
39.6 Conectivas por el número de argumentos
73
[9] Tarski (1940) Introduction to logic and to the methodology of deductive sciences. [10] Gentzen (1934) Untersuchungen über das logische Schließen.
Si vemos las distintas conectivas por su número de argumentos podemos distinguir: [11] Chazal (1996): Éléments de logique formelle. [12] Véase Roegel
39.6.1
Sin argumentos
Las conectivas lógicas sin argumentos son:
39.6.2
Con un argumento
Las conectivas con solo un argumento son:
39.6.3
Con dos argumentos
Las conectivas que necesitan dos argumentos son:
39.9 Enlaces externos • Hazewinkel, Michiel, ed. (2001), «Propositional connective» (en inglés), Encyclopaedia of Mathematics, Springer, ISBN 978-1556080104 • Lloyd Humberstone (2011). The Connectives. MIT Press. ISBN 978-0-262-01654-4. • Bocheński, Józef Maria (1959). A Précis of Mathematical Logic. traducido al inglés de las ediciones francesa y alemana por Otto Bird. Dordrecht, South Holland. • Enderton, Herbert (2001). A Mathematical Introduction to Logic (2da edición). Boston, MA: Academic Press. ISBN 978-0-12-238452-3. • Gamut, L.T.F (1991). «Chapter 2». En University of Chicago Press. Logic, Language and Meaning 1. pp. 54–64. OCLC 21372380.
39.7 Véase también 39.8 Referencias [1] Heyting (1929) Die formalen Regeln der intuitionistischen Logik. [2] Denis Roegel (2002), Petit panorama des notations logiques du 20e siècle (véase chart en página 2). [3] Russell (1908) Mathematical logic as based on the theory of types (American Journal of Mathematics 30, p222– 262, también en From Frege to Gödel edited by van Heijenoort). [4] Peano (1889) Arithmetices principia, nova methodo exposita. [5] Schönfinkel (1924) Über die Bausteine der mathematischen Logik, translated as On the building blocks of mathematical logic in From Frege to Gödel edited by van Heijenoort. [6] Peirce (1867) On an improvement in Boole's calculus of logic. [7] Hilbert (1917/1918) Prinzipien der Mathematik (Bernays' course notes). [8] Vax (1982) Lexique logique, Presses Universitaires de France.
• Humberstone, Lloyd (2010), «Sentence Connectives in Formal Logic», Stanford Encyclopedia of Philosophy, http://plato.stanford.edu/entries/ connectives-logic/ • MacFarlane, John (2005), «Logical constants», Stanford Encyclopedia of Philosophy, http://plato. stanford.edu/entries/logical-constants/ • Esta obra deriva de la traducción total de Logical connective de Wikipedia en inglés, concretamente de esta versión, publicada por sus editores bajo la Licencia de documentación libre de GNU y la Licencia Creative Commons AtribuciónCompartirIgual 3.0 Unported.
Capítulo 40
Configuración regional En informática, la configuración regional* [1] ̶conocida como locale en inglés̶es un conjunto de parámetros que define el idioma, país y cualquier otra preferencia especial que el usuario desee ver en su interfaz de usuario. Generalmente, un identificador de configuración regional consiste como mínimo de un identificador de idioma y un identificador de región. Este concepto es de fundamental importancia en el campo de la localización de idiomas.
40.1 Véase también • Internacionalización y localización
40.2 Referencias [1] Microsoft Corporation. «Traducción del término en el Portal de idiomas de Microsoft». Consultado el 1 de noviembre de 2014.
40.3 Enlaces externos • Esta obra deriva de la traducción de Locale de Wikipedia en inglés, publicada por sus editores bajo la Licencia de documentación libre de GNU y la Licencia Creative Commons AtribuciónCompartirIgual 3.0 Unported. • Unicode Common Locale Data Repository • Language Subtag Registry
74
Capítulo 41
Conteo de referencias Conteo de referencias, en inglés Reference counting, es una técnica para contabilizar las veces que un determinado recurso está siendo referido. Por lo general ese recurso son bloques de memoria y la técnica permite establecer cuando no existe ninguna referencia a ese bloque y éste puede ser liberado. Es una técnica de muy fácil implementación, pero tiene una importante desventaja: Si las referencias forman un ciclo los objetos involucrados no se liberarán nunca. Otra técnica más efectiva es el uso de un recolector de basura.
41.1 Véase también • Recolector de basura • Fuga de memoria
75
Capítulo 42
Convención de Nombres (Programación) • para mejorar la apariencia estética y profesional de producto de trabajo (por ejemplo, al no permitir nombres excesivamente largos nombres “lindo”, cómico o, o las abreviaturas);
En Programación, una convención de nombres es un conjunto de reglas para la elección de la secuencia de caracteres que se utilizará para un identificador s que denotan variables, tipos, funciones y otras entidades en el código fuente y la documentación.
• para ayudar a evitar “conflictos de nombres”que podrían ocurrir cuando se combina el producto del trabajo de diferentes organizaciones (véase también: espacios de nombres);
Razones para utilizar una convención de nombres (en lugar de permitir a los programadores elegir cualquier secuencia de caracteres) incluyen los siguientes:
• para proporcionar datos significativos que se utilizarán en los traspasos de proyectos que requieren la presentación de código fuente del programa y toda la documentación pertinente
• para reducir el esfuerzo necesario para leer y entender el código fuente;* [1] • para mejorar la apariencia del código fuente (por ejemplo, al no permitir nombres excesivamente largos o abreviaturas poco claras).
• para proporcionar una mejor comprensión en el caso de la reutilización de código después de un largo intervalo de tiempo.
La elección de las convenciones de nombres puede ser un problema de enorme polémica, con los partidarios considerar su tendencia mejor y las demás inferiores. Coloquialmente, este se dice que es una cuestión de 42.2 Desafíos dogma.* [2] Muchas empresas también han establecido su propio conjunto de convenciones para satisfacer mejor La elección de las convenciones de nombres (y la medida sus intereses. en que se hacen cumplir) es a menudo un tema polémico, con partidarios considerando su punto de vista para ser el mejor y los demás como inferiores. Además, incluso con las convenciones de nombres conocidos y bien definidos 42.1 Beneficios potenciales en el lugar, algunas organizaciones pueden no adherirse constantemente a ellos, haciendo que la incoherencia y Algunos de los beneficios potenciales que se pueden obteconfusión. Estos retos pueden ser exacerbadas si las reglas ner mediante la adopción de una convención de nombres de la convención de nomenclatura no tienen coherencia incluyen los siguientes: interna, arbitraria, difíciles de recordar, o percibida de otra manera como más gravosas de lo beneficioso. • para proporcionar información adicional (es decir, los metadatos) sobre el uso que se hace de un identificador;
42.3 El valor del negocio
• para ayudar a formalizar las expectativas y promover la coherencia dentro de un equipo de desarrollo; Aunque en gran parte oculto a la vista de la mayoría de los usuarios de negocios, identificadores bien escogidos • para permitir el uso de refactorización automatizado hacen que sea mucho más fácil para las siguientes generao buscar y reemplazar herramientas con un potencial ciones de analistas y desarrolladores para entender lo que mínimo para el error; hace el sistema y cómo solucionarlo o ampliar el código • para mejorar la claridad en los casos de ambigüedad fuente para las nuevas necesidades del negocio. potencial;
Por ejemplo, aunque la siguiente: 76
42.4. ELEMENTOS COMUNES a = b * c; es sintácticamente correcta, su propósito no es evidente. Contraste esto con: WEEKLY_PAY = hours_worked * pay_rate; lo que implica la intención y el significado del código fuente, por lo menos para aquellos que están familiarizados con el contexto subyacente de la aplicación.
42.4 Elementos comunes Las reglas exactas de una convención de nombres dependen del contexto en que se emplean. Sin embargo, hay varios elementos comunes que más influyen en si no todos los convenios de denominación de uso común hoy en día.
42.4.1
Longitud de identificadores
Un elemento fundamental de todas las convenciones de nomenclatura son las reglas relacionadas con identificadora longitud (es decir, el número finito de caracteres individuales permitidos en un identificador). Algunas reglas dictan un numérico fijo atado, mientras que otros especifican heurística o directrices menos precisos.
77 • primeros enlazadores que requerían nombres de variables que se limitan a 6 caracteres para ahorrar memoria. Un “avance”más adelante permitió que los nombres de variables ya que se utilizarán para la comprensión humana, pero donde sólo los primeros caracteres fueron significativas. En algunas versiones de BASIC como TRS-80 Nivel Básico 2, los nombres largos se les permitió, pero sólo las dos primeras letras fueron significativas. Esta característica permitirá el comportamiento erróneo de que podría ser difícil de depurar, por ejemplo, cuando fueron utilizados y destinados a ser distinto nombres como “VALOR”y “VAI”. • editor de código fuente temprana s autocompletar careciendo • monitores tempranas de baja resolución con longitud de línea limitada (por ejemplo, sólo 80 caracteres) • gran parte de la informática procedentes de las matemáticas, donde los nombres de variables son, tradicionalmente, sólo una sola letra
42.4.2 Mayúsculas, minúsculas y números
Algunas convenciones de nomenclatura si limitan letras pueden aparecer en mayúsculas o minúsculas. Otro convenios no restrinjan caso carta, pero conceden una interpretación bien definido basado en mayúsculas y minúscuReglas de longitud de identificador son impugnadas de las. Algunas convenciones de nombres especifican si alfaforma rutinaria en la práctica, y sujeto a mucho debate béticos, numéricos o alfanuméricos caracteres se pueden académico. usar, y si es así, en qué secuencia. Algunas consideraciones: • identificadores más cortos pueden ser preferidos co- 42.4.3 Identificadores de varias palabras mo más conveniente, ya que son más fáciles de escribir Una recomendación común es “Utilizar identificadores significativos.”Una sola palabra puede no ser tan signi• extremadamente identificadores cortos (por ejemficativa, o específicas, como varias palabras. En conseplo, 'i' o 'j') son muy difíciles de distinguir de forma cuencia, algunas convenciones de nombres especifican las única mediante la búsqueda automática y reemplareglas para el tratamiento de identificadores “compueszar herramientas tos”que contienen más de una palabra. • identificadores más largos pueden ser preferidos Como en la mayoría de los lenguajes de programación no porque identificadores cortos no pueden codificar la están permitidos los espacios en blanco en los identifiinformación suficiente o parecer demasiado críptico cadores, se necesita un método de delimitación de cada • identificadores más largos pueden ser desfavorecido palabra (para que sea más fácil para los lectores posteriores para interpretar personajes que pertenecen a cada debido a la confusión visual palabra). Es un tema de investigación abierto si algunos programadores prefieren identificadores más cortos porque son más fáciles de escribir, o inventan, de los identificadores más largos, o porque en muchas situaciones un identificador ya simplemente estorba el código visible y proporciona no perciben beneficio adicional.
Palabras delimitadores separados
Un enfoque consiste en delimitar palabras separadas con un carácter no alfanumérico. Los dos caracteres más usados para este fin son el guión ("-") y el guión bajo ("_”); La brevedad en la programación podría ser en parte atri- por ejemplo, el nombre de dos palabras “two words”se representaría como “two-words”o “two_words”. El buido a:
78
CAPÍTULO 42. CONVENCIÓN DE NOMBRES (PROGRAMACIÓN)
guión es usado por casi todos los programadores que es- ve en los 8,3 (máximo 8 caracteres con periodo separador criben COBOL, Forth, y Lisp; también es común que los seguido de 3 caracteres tipo de archivo) estilo MS-DOS. nombres de selector en Cascading Style Sheets. La mayoría de los otros idiomas (por ejemplo, las lenguas en las familias C y Pascal) se reservan el guión para su uso como el operador infijo resta, por lo que no está disponible 42.5.3 Esquema de palabra compuesta (del lenguaje) para su uso en los identificadores y por lo tanto se utilizan en lugar de subrayado. Véase el caso de serpientes. Uno de los sistemas de convenciones publicadas primeros fue de IBM “del lenguaje”documentada en un IMS Carta de los casos separados palabras (Information Management System) 1980 Manual * [cita requerida]. Otro enfoque consiste en indicar los límites de palabra utilizando capitalización medial (también llamado Se detalla el esquema de palabra PRIME-MODIFIER"CamelCase" y muchos otros nombres), haciendo así CLASS, que consistía en nombres como “MEM-ACT“two words”ya sea como“twoWords”o“TwoWords” NO”para indicar “número de cuenta del cliente.” . Esta convención se utiliza comúnmente en Java, C# y PRIME palabras estaban destinadas a indicar las princiVisual Basic. Tratamiento de las siglas en identificadores pales “entidades”de interés para un sistema. (por ejemplo, el“XML”y“HTTP”en XMLHttpRequest ) varía. Algunos dictan que sean en minúsculas (por Palabras MODIFIER fueron utilizados para el refinaejemplo XmlHttpRequest ) para facilitar la mecanogra- miento adicional, la cualificación y la legibilidad. fía y la lectura, mientras que otros los dejan upperca- Palabras CLASS ideal sería una lista muy corta de los sed (por ejemplo XMLHTTPRequest ) para la exacti- tipos de datos relevantes para una aplicación particular. tud. Una opción menos popular es ampliar siempre las Clase de palabras comunes pueden ser: NO (número), siglas (por ejemplo ExtensibleMarkupLanguageHyper- ID (identificador), TXT (texto), AMT (cantidad), CANT TextTransferProtocolRequest ). (cantidad), FL (bandera), CD (código), W (trabajo) y así sucesivamente. En la práctica, la clase de palabras disponibles sería una lista de menos de dos docenas de térmi42.5 Metadatos y convenciones hí- nos.
bridas Algunas convenciones de nombres representan normas o requisitos que van más allá de los requisitos de un proyecto específico o dominio del problema, y en lugar de reflejar una mayor conjunto general de principios definidos por la arquitectura de software, lenguaje de programación subyacente u otro tipo de metodología entre proyectos.
42.5.1
Notación húngara
Palabras CLASS, normalmente situados a la derecha (sufijo), sirven el mismo propósito como prefijos de notación húngara. El propósito de la clase de palabras, además de la consistencia, era especificar al programador el tipo de datos de un campo de datos particular. Antes de la aceptación de BOOLEAN (dos valores únicos) Campos, FL (bandera) indicarían un campo con sólo dos valores posibles.
42.6 Convenciones específicas del lenguaje
Tal vez la más conocida es la notación húngara, que codifica ya sea el propósito (“Aplicaciones de Hungría”) o el tipo (“Sistemas de Hungría”) de una variable en su 42.6.1 ActionScript nombre.* [3] Por ejemplo, el prefijo“sz”para el szName variable indica que la variable es una cadena de cero (es Las convenciones y las mejores prácticas de codificadecir null-) terminado. ción de Adobe sugieren estándares de nomenclatura para ActionScript que en su mayoría son consistentes con los de ECMAScript. * [cita requerida] El estilo de identifica42.5.2 Notación posicional dores es similar a la de Java. Un estilo utilizado para muy cortas (8 caracteres y menos) podría ser: LCCIIL01, donde LC sería la aplicación (cartas de crédito), C para COBOL, IIL para el subconjunto 42.6.2 proceso en particular, y el 01 un número de secuencia.
Ada
Este tipo de convenciones se encuentra todavía en uso En Ada, el único estilo recomendado de identificadores activo en mainframes que dependen de JCL y también se es Mixed_Case_With_Underscores.* [4]
42.6. CONVENCIONES ESPECÍFICAS DEL LENGUAJE
42.6.3
79
C y C++
lugar de parseDBMXMLFromIPAddress ). También se puede establecer el límite en dos o más letras (por ejemEn C y C++, las palabras clave e identificadores de la bi- plo parseDbmXmlFromIpAddress ). blioteca estándar son en su mayoría en minúsculas. En la biblioteca estándar de C, los nombres abreviados son los más comunes (por ejemplo isalnum para una prueba 42.6.5 JavaScript de la función si un carácter es alfanumérico), mientras que la biblioteca estándar C++ menudo utiliza un guión Las bibliotecas incorporadas de JavaScript utilizan las como separador de palabra (por ejemplo out_of_range ). mismas convenciones de nomenclatura como Java. Las Identificadores representan macros son, por convención, clases utilizan camel case superior (RegExp, TypeError, escrito usando sólo letras mayúsculas y guiones bajos (es- XMLHttpRequest, DOMObject) y métodos utilizar loto está relacionado con la convención en muchos lengua- wer camel case (getElementById, getElementsByTagNajes de programación de la utilización de todo mayúscu- meNS, createCDATASection). Con el fin de ser consislas identificadores de constantes). Nombres que contie- tentes desarrolladores más de JavaScript siguen estas con* nen doble guión o que comienzan con un guión bajo y venciones. [cita requerida] Ver también: convenciones una letra mayúscula se reservan para la implementación de Douglas Crockford (compilador, biblioteca estándar) y no deben ser usados (por ejemplo reserved__ o _Reserved ).* [5]* [6] Esto es superficialmente similar a afilar, pero la semántica difie- 42.6.6 Lisp re: los subrayados son parte del valor del identificador, en lugar de ser carácter delimitador (como se afila): el valor La práctica común en la mayoría de los dialectos de Lisp de __foo es __foo (que está reservado), no foo (pero en es utilizar guiones para separar las palabras en los identificadores, como en with-open-file y make-hash-table. un espacio de nombres diferente). Nombres de variables globales convencionalmente comienzan y terminan con asteriscos: *map-walls*. Nombres Constantes están marcadas por signos de suma: 42.6.4 Java +map-size+.* [10] En Java, las convenciones de nombres para los identificadores se han establecido y propuesto por varias comunidades de Java como Sun Microsystems,* [7] Netscape,* [8] AmbySoft,* [9] etc Una muestra de las convenciones de nomenclatura establecidas por Sun Microsystems se enumeran a continuación, donde un nombre en "CamelCase" es un compuesto de un número de palabras unidas sin espacios, con letra inicial de cada palabra en mayúsculas - por ejemplo “CamelCase”.
42.6.7 .NET
Microsoft NET recomienda UpperCamelCase para la mayoría de los identificadores. (LowerCamelCase se recomienda para los parámetros y variables) y es una convención común para los lenguajes.NET.* [11] Microsoft recomienda también que no se utilicen pistas de tipo prefijo (también conocido como notación húngara).* [12] En Compiladores Java no hacen cumplir estas reglas, pe- lugar de utilizar la notación húngara se recomienda terro no seguir las mismas pueden dar lugar a confusión minar el identificador con el nombre de la clase base; Lo* y código erróneo. Por ejemplo, widget.expand() y Wid- ginButton en lugar de BtnLogin. [13] get.expand() implica significativamente diferentes comportamientos: widget.expand() implica una invocación al método expand() en una instancia con nombre widget, 42.6.8 Objective-C mientras que Widget.expand() implica una invocación al Objective-C tiene un estilo común de codificación que método estático expand() en la clase Widget. tiene sus raíces en Apple ejemplo de código. Un estilo de programación Java ampliamente utilizado dicta que UpperCamelCase ser utilizado para Entidades de primer nivel, incluyendo clases, protocolos, clases y lowerCamelCase utilizarse para instancias y categorías, así como construcciones de C que se utilizan métodos.* [7] Reconociendo este uso, algunos IDE como en los programas de Objective-C como variables y funEclipse, implementar atajos basados en CamelCase. Por ciones globales, están en UpperCamelCase con una breve ejemplo, en el contenido de Eclipse función de asisten- mayúsculas-espacio de nombres que denota prefijo, como cia, escribiendo únicamente las letras mayúsculas de una NSString, UIAppDelegate, NSApp o CGRectMake. Las palabra CamelCase sugerirá ningún nombre de la clase constantes pueden ser opcionalmente precedidos por una a juego o método (por ejemplo, al escribir “NPE”y letra minúscula “k”como kCFBooleanTrue. activando ayuda de contenido podría sugerir NullPointe- variables de instancia de un uso objeto lowerCamelCase rException ). precedidos por un guión, como _delegate y _tableView. Siglas de tres o más letras se camelCase en lugar de Nombres de los métodos utilizan múltiples partes lowermayúsculas (por ejemplo, parseDbmXmlFromIPAddress CamelCase separados por dos puntos que delimitan argu-
80
CAPÍTULO 42. CONVENCIÓN DE NOMBRES (PROGRAMACIÓN)
mentos, como: aplicación: didFinishLaunchingWithOp- [11] Microsoft NET Framework Estilos de Capitalización tions:, stringWithFormat: y IsRunning.
[12] Guía de NET Framework Developer - Convenciones de nomenclatura general
42.6.9
Perl
[13] [Framework Instrucciones de diseño, Krzysztof Cwalina, Brad Abrams Página 62]
Perl toma algunas señales de su patrimonio C para convenciones. A nivel local ambito de variables y nombres [14] «Perl style guide». de subrutinas son minúsculas con guiones bajos infijos. [15] «perlmodlib - constructing new Perl modules and finding Subrutinas y variables con la intención de ser tratado coexisting ones». mo privado están prefijadas con un guión bajo. Las variables del paquete son título entubado. Constantes de- [16] [Guía de Estilo https://www.python.org/dev/peps/ pep-0008/ de código Python PEP8] claradas son mayúsculas. Los nombres de paquetes son camel case-exceptuando prágmata por ejemplo, strict y mro -que son minúsculas. * [14] * [15]
42.9 Enlaces externos
42.6.10
Python y Ruby
Python y Ruby tanto recomiendan UpperCamelCase para nombres de clases, CAPITALIZED_WITH_UNDERSCORES para las constantes y lowercase_separated_by_underscores para otros nombres. En Python, si un nombre está destinado a ser “privado”, que está precedido de un guión bajo.* [16]
42.7 Véase también 42.8 Referencias [1] Derek M. Jones“nombres operando la influencia del operador decisiones de precedencia”Un experimento que investiga el efecto de los nombres de variables de selección de prioridad de operador [2] Raymond, Eric S. (1 de octubre de 2004), «religious issues», The Jargon File (version 4.4.8 edición), http:// www.catb.org/jargon/html/R/religious-issues.html, consultado el 7 de noviembre de 2011 [3] http://www.joelonsoftware.com/articles/Wrong.html [4] http://www.adaic.org/resources/add_content/docs/ 95style/html/sec_3/3-2-1.html [5] «ISO/IEC 9899:1999 Programming languages -- C». ISO. [6] «ISO/IEC 14882:2011 Information technology -- Programming languages -- C++». ISO. [7]“Convenciones de código para el lenguaje de programación Java”, Sección 9:“Convenciones de nomenclatura” [8]“SOFTWARE DE NETSCAPE Normas de codificación GUÍA PARA JAVA”, Collab Software Codificación Guía de Normas para Java [9] “AmbySoft Inc. Estándares de Codificación para v17.01d Java” [10] http://www.gigamonkeys.com/book/variables.html
• Americana Name Society - Promueve la onomástica, el estudio de los nombres y las prácticas de asignación de nombres, tanto en Estados Unidos como en el extranjero. • Codificación-guidelines.com tiene una de 100 páginas pdf que usa la lingüística y la psicología para intentar un análisis de costo / beneficio de las cuestiones de nomenclatura de identificadores • Convenciones de nomenclatura de Ontología La aplicación de etiquetado o las convenciones de nomenclatura unificadas en la ingeniería de la ontología ayudarán a armonizar la apariencia y aumentar la robustez de las unidades de representación ontológica, como nombres de clases y relaciones dentro del conjunto ortogonal de ontologías OBO Foundry.
Capítulo 43
Cracking (software) El cracking es la modificación del software con la intención de eliminar los métodos de protección de los cuales este disponga: protección de copias, versiones de prueba, números de serie, claves de hardware, verificación de fechas, verificación de CD o publicidad y adware. La distribución y uso de copias modificadas es ilegal en casi todos los países desarrollados. Muchos juicios se han llevado a cabo debido al cracking de software; sin embargo, la mayoría de estos han tenido que ver con la distribución de copias duplicadas en vez de con el proceso de quebrantar la protección, debido a la dificultdad de construir pruebas válidas de culpabilidad individual en el segundo caso. En Estados Unidos, la aprobación de la Digital Millennium Copyright Act (DMCA) declaró a la modificación de software, así como a la distribución de información que habilita el cracking de software, ilegal. Sin embargo, la ley ha sido apenas probada en el poder judicial de EE. UU. en casos de ingeniería inversa para único uso personal. La Unión Europea aprobó la Directiva de la Unión Europea sobre derecho de autor en mayo de 2001, haciendo la infracción de los derechos de autor de software ilegal en los estados miembros, una vez que la legislación nacional fuera promulgada en favor de la directiva.
43.1 Véase también • Crack informático • Cracker • Password cracking • Razor 1911
81
Capítulo 44
Cuaderno de carga El cuaderno de carga es, dentro de la terminología informática, el modo de comunicación más frecuente entre el analista y el programador de un proyecto. En él el analista detalla las especificaciones que el programador debe seguir para desarrollar un programa informático.
82
Capítulo 45
Currificación En la ciencia de la computación, currificar es la técnica inventada por Moses Schönfinkel y Gottlob Frege que consiste en transformar una función que utiliza múltiples argumentos (o más específicamente una n-tupla como argumento) en una función que utiliza un único argumento.
45.4 Enlaces externos •
Wikcionario tiene definiciones y otra información sobre currificar.Wikcionario
• Currying in Python • Implicit currying in Scheme
45.1 Nomenclatura
• Currying in Ruby
El nombre “currificar”, acuñado por Christopher Strachey en 1967, es una referencia al lógico Haskell Curry. Un nombre alternativo, Schönfinkelisation, ha sido propuesto.* [1]
• Currying in Smalltalk • Currying in Algol68G • Currying != Generalized Partial Application! - post at Lambda-the-Ultimate.org • Currying in Scala
45.2 Definición
• Currying in Perl
Dada una función f del tipo f : (X × Y ) → Z , currificándola sería una función del tipo curry(f ) : X → (Y → Z) . En otras palabras, curry(f ) toma un argumento del tipo X y retorna una función del tipo Y → Z . Descurrificar es la transformación inversa. Intuitivamente, la currificación expone que“Si fijas algunos argumentos, tendrás una función de los argumentos restantes”. Por ejemplo, si la función div significa la versión currificada de la operación x / y, entonces div con el parámetro x fijado en 1 es otra función: igual que la función inv que devuelve la inversa multiplicativa de sus argumentos, definida por inv(y) = 1 / y. La motivación práctica para currificar es que en ocasiones, muy seguidas, las funciones obtenidas al utilizar algunos, pero no todos, los argumentos en una función currificada pueden resultar útiles; por ejemplo, muchos lenguajes tienen una función o un operador similar a plus_one. Currificar hace fácil definir dichas funciones.
45.3 Referencias [1] I. Heim and A. Kratzer (1998). Semantics in Generative Grammar. Blackwell.
83
Capítulo 46
Código enhebrado En ciencias de la computación, el término código enhebrado se refiere a una técnica de implementación del compilador donde el código generado tiene una forma que esencialmente consiste enteramente en llamadas a subrutinas. El código puede ser procesado por un intérprete, o simplemente puede ser una secuencia de instrucciones de llamadas a código de máquina. Una de las principales ventajas del código enhebrado es que es muy compacto, comparado al código generado por técnicas alternativas de generación del código y de convención de llamadas. Esta ventaja usualmente viene a expensas de una velocidad de ejecución ligeramente más lenta (usualmente apenas una sola instrucción de máquina). Sin embargo, a veces hay un efecto sinergético - a veces un código más compacto es más pequeño y significativamente más rápido que el código no enhebrado.* [1] Un programa suficientemente pequeño para caber enteramente en la memoria de acceso aleatorio puede correr más rápido que un programa menos compacto en el espacio de intercambio que requiere un constante acceso mecánico de la unidad de disco, aunque sufra de la sobrecarga en la interpretación del código enhebrado. Similarmente, un programa lo suficientemente pequeño para caber enteramente en el caché del procesador de la computadora puede correr más rápido que un programa menos compacto que sufra fallas de caché constantes.
plataforma de hardware específica. Un acercamiento diferente usa un conjunto de instrucciones de una máquina virtual - que no tiene un destino particular de hardware. Un intérprete lo ejecuta en cada nuevo hardware de destino. Los computadores tempranos tenían relativamente poca memoria. Por ejemplo, la mayoría de los Data General Nova, IBM 1130, y muchas computadores Apple II tenían solamente 4 k palabras de memoria RAM instalada. Consecuentemente se pasaba mucho tiempo intentando encontrar formas de reducir el tamaño de los programas de tal manera que pudieran caber en la memoria disponible. Al mismo tiempo, los computadores eran relativamente lentos, así que la interpretación simple era perceptiblemente mucho más lenta que ejecutar el código de máquina. En vez de escribir cada paso de una operación en cada parte del programa donde era necesaria, los programadores ahorraban memoria escribiendo cada paso de tales operaciones una sola vez y poniéndolo en una subrutina (ver "no te repitas").
Este proceso - la refactorización de código - es usado hoy, aunque por diversas razones. En estos programas, la aplicación del nivel superior puede consistir de nada más que llamadas a subrutinas. A su vez, muchas de estas subrutinas, también no consisten nada más que llamadas a suEl código enhebrado es bien conocido como la técnica brutinas de nivel inferior. de implementación comúnmente usada en el lenguaje de programación Forth. También fue usado en las versiones Los mainframes y algunos microprocesadores tempranos tempranas del lenguaje de programación B, así como en tales como el RCA 1802 requerían varias instrucciones muchas implementaciones de BASIC, y algunas imple- para llamar a una subrutina. En la aplicación de nivel sumentaciones de COBOL y de otros lenguajes para pe- perior y en muchas subrutinas, esa secuencia es constantemente repetida, sólo cambiando la dirección de la suqueños microcomputadores. brutina desde una llamada a la siguiente. Usando la memoria para almacenar las mismas instrucciones repetidamente era un desperdicio.
46.1 Historia que llevó al código enhebrado
La manera común de hacer programas de computadora es usando un compilador para“traducir”un programa escrito en una cierto lenguaje simbólico al código de máquina. El código es típicamente rápido pero no es portable puesto que el código binario ejecutable es diseñado para una
La respuesta simple fue una tabla de saltos (es decir una tabla consistiendo solo en las direcciones contiguas de las subrutinas - usualmente extraídas usando un índice, un registro de propósitos generales o un puntero). Las direcciones pueden ser directas o indirectas, contiguas o no contiguas (encadenadas por punteros), relativas o absolutas, resueltas en de tiempo de compilación o construidas dinámicamente - pero el programa se convierte en una
84
46.3. MODELOS DE ENHEBRADO lista de puntos de entrada al código real a ser ejecutado. Esta técnica “se ha reinventado”con los nombres de “código enhebrado”, “tabla de despacho”o “tabla de método virtual”- todas estas técnicas llenan propósitos similares.
46.2 Desarrollo del código enhebrado
85 *tp++ Esto se llama código enhebrado directo (DTC). Aunque la técnica sea más vieja, el primer uso extensamente circulado del término“código enhebrado”es probablemente el artículo “código enhebrado”de Bell de 1973.* [2] En 1970, Charles H. Moore inventó una notación más compacta para su máquina virtual Forth: el código enhebrado indirecto (ITC). Originalmente, Moore inventó esto porque era fácil y rápido en los minicomputadores de NOVA, que tenían un bit de indirección en cada dirección. Moore dijo (en comentarios publicados en la edición de la revista Byte sobre Forth) que él encontró esto tan conveniente que lo propagó en todos los diseños Forth posteriores.
Para ahorrar espacio, los programadores exprimieron las listas códigos de llamadas a subrutinas y las convirtieron en simples listas con solo las direcciones de las subrutinas, y usaron un pequeño loop para llamar a cada subrutina una por una. Por ejemplo: Algunos compiladores Forth compilan los programas start: thread: pushA: *sp++ = A tp = &thread &pushA Forth en código enhebrado directo, mientras que otros jump top top: &pushB pushB: *sp++ = B jump *tp++ hacen código enhebrado indirecto. Los programas actúan &add jump top ... add: *sp++ = *--sp + *--sp jump top igual de cualquier manera. En este caso, la decodificación de los bytecodes se realiza una sola vez, durante la compilación o la carga de programa, así que no es repetida cada vez que una instrucción es ejecutada. Esto puede ahorrar mucho tiempo y espacio cuando la sobrecarga por la decodificación (decode) y el enviar (dispath) es grande comparado al costo de la ejecución. Observe, sin embargo, que las direcciones en thread para &pushA, &pushB, etc., tienen dos o más bytes, comparados a típicamente un byte, para el intérprete de decodificar (decode) y enviar (dispath) descrito arriba. En general las instrucciones para un intérprete de decodificar y enviar pueden ser de cualquier tamaño. Como ejemplo, un intérprete de decodificar y enviar para simular un Intel Pentium decodifica las instrucciones con un rango de 1 a 16 bytes. Sin embargo, los sistemas de bytecode eligen típicamente códigos de 1 byte para las operaciones más comunes. Así, el enhebrado a menudo tiene un costo de espacio más alto que los bytecodes. En la mayoría de los usos, la reducción en costo de decodificar compensa el aumento en costo de espacio.
46.3 Modelos de enhebrado Prácticamente todo el código enhebrado ejecutable usa uno u otro de estos métodos para invocar subrutinas (cada método es llamado un “modelo de enhebrado”).
46.3.1 Enhebrado directo
Las direcciones en el enhebrado son las direcciones del lenguaje de máquina. Esta forma es simple, pero puede tener sobrecargas porque el enhebrado consiste solo de direcciones de máquina, así que todos los otros parámetros deben ser cargados indirectamente desde la memoria. Algunos sistemas Forth producen código enhebrado Observe también que mientras que los bytecodes son no- directo. En muchas máquinas el enhebrado directo es más minalmente independientes de la máquina, el formato y rápido que el enhebrado de subrutina (ver la referencia el valor de los punteros en el enhebrado generalmente abajo). dependen de la máquina destino que está ejecutando al intérprete. Así, un intérprete puede cargar un programa Como ejemplo, una máquina de pila puede ejecutar la secuencia“push A, push B, add”. Eso puede ser traducido bytecode portable, decodificar los bytecodes para generar código enhebrado independiente de la plataforma, luego al enhebrado y rutinas siguientes, donde el tp es inicializado apuntando hacia la dirección de &thread. ejecutar el código enhebrado sin referencia adicional a los thread: pushA: *sp++ = A pushB: *sp++ = B add: *sp++ bytecodes. El loop es simple, así que está duplicado en cada hand- = *--sp + *--sp &pushA jump *tp++ jump *tp++ jump ler, removiendo jump top de la lista de instrucciones de *tp++ &pushB &add ... máquina necesarias para ejecutar cada instrucción del in- Alternativamente, los operandos pueden estar incluidos térprete. Como ejemplo: en el enhebrado. Esto puede remover alguna indirección start: thread: pushA: *sp++ = A tp = thread &pushA necesaria arriba, pero hace el enhebrado más grande: jump *tp++ jump *tp++ &pushB pushB: *sp++ = B thread: push: *sp++ = *tp++ add: *sp++ = *--sp + *--sp &add jump *tp++ ... add: *sp++ = *--sp + *--sp jump &push jump *tp++ jump *tp++ &A &push &B &add
86
46.3.2
CAPÍTULO 46. CÓDIGO ENHEBRADO
Enhebrado indirecto
El enhebrado indirecto usa punteros que apuntan hacia localizaciones que a su vez apuntan al código de máquina. El puntero indirecto puede ser seguido por los operandos que son almacenados en el“bloque”indirecto en vez de estar almacenados repetidamente en el enhebrado. Así, el código indirecto es a menudo más compacto que el código enhebrado directo, pero la indirección típicamente también lo hace más lenta, aunque usualmente todavía más rápida que los intérpretes de bytecode. Donde los operandos del handler incluyen tanto valores como tipos, los ahorros de espacio sobre el código enhebrado directo pueden ser significativos. Los sistemas Forth más antiguos producían típicamente código enhebrado indirecto.
thread: pushA: pushB: add: call pushA *sp++ = A *sp++ = B *sp++ = *--sp + *--sp call pushB ret ret ret call add
46.3.4 Enhebrado de token
El código enhebrado de token usa listas de índices de 8 ó 12 bits a una tabla de punteros. El código enhebrado de token es notablemente compacto, sin mucho esfuerzo especial por un programador. Tiene usualmente entre la mitad y tres cuartas partes el tamaño de otros códigos enhebrados, los cuales a su vez tienen entre la cuarta y la octava parte del tamaño del código compilado. Los punteros de la tabla pueden ser tanto indirectos como directos. Algunos compiladores Forth producen código enhebrado de token. Algunos programadores consideran al “p-code”generado por algunos compiladores de Pascal, Como ejemplo, si la meta es ejecutar el“psuh A, push B, al igual que los bytecodes usados por .NET, Java, BASIC, add”, lo siguiente puede ser usado. Aquí, el tp es iniciay algunos compiladores C, como enhebrado de token. lizado apuntando a la dirección &thread, cada fragmento del código (push, add) es encontrado por doble indirec- Históricamente, un acercamiento común es el bytecode, ción por medio del tp; y los operandos para cada frag- que utiliza opcodes de 8 bits y, a menudo, una máquina mento de código son encontrados en el primer nivel de virtual basada en pila. Un interpretador típico es conocido como "decode and dispatch interpreter" y sigue la forma: indirección siguiendo la dirección del fragmento. thread: i_pushA: push: add: &i_pushA &push *sp++ = *(*tp + 1) *sp++ = *--sp + *--sp &i_pushB &A jump *(*tp++) jump *(*tp++) &i_add i_pushB: &push &B i_add: &add
46.3.3
Enhebrado de subrutina
El “código enhebrado de subrutina”(también llamado “código enhebrado de llamada”) consiste en una serie de instrucciones “call”en lenguaje de máquina (o solo las direcciones de las funciones “call”, en oposición el enhebrado directo el cual usa“jump”). Los compiladores tempranos para el ALGOL, FORTRAN, COBOL y algunos sistemas Forth produjeron a menudo código enhebrado de subrutina. El código en muchos de estos sistemas operaba una pila de operandos LIFO (last-in-firsout), que tenía una bien desarrollada teoría del compilador. La mayoría de los procesadores modernos tienen soporte especial del hardware para las subrutinas con las instrucciones “call”y “return”, así que la sobrecarga de una instrucción de máquina adicional por envío es disminuida; pero según mediciones de Antón Ertl, “en contraste con los mitos populares, el enhebrado de subrutina es usualmente más lento que el enhebrado directo”. [3] Pruebas más recientes de Ertl demuestran que el enhebrado directo es el modelo de enhebrado más rápido en los procesadores Xeon, Opteron, y Athlon, mientras que el enhebrado indirecto es el modelo de enhebrado más rápido en procesadores Pentium M, y el enhebrado de subrutina es el modelo de enhebrado más rápido en el Pentium 4, el Pentium III, y procesadores PPC. Como un ejemplo de enhebrado de llamada, el“push A, push B, add":
bytecode: top: pushA: pushB: add: 0 /*pushA*/ i = decode(vpc++) *sp++ = A *sp++ = B *sp++ = *--sp + *--sp 1 /*pushB*/ addr = table[i] jump top jump top jump top 2 /*add*/ jump *addr Si la máquina virtual usa solamente instrucciones del tamaño de un byte, el decode() es simplemente un ferch desde el bytecode, pero a menudo hay instrucciones comunes de 1 byte más instrucciones menos comunes de múltiples bytes (ver CISC), en este caso, decode() es más complejo. La decodificación de opcodes de un solo byte puede ser muy simple y eficientemente manejado por una tabla de saltos usando el opcode directamente como un índice. Para, en las instrucciones donde las operaciones individuales son simples, por ejemplo “push”y “add”, la sobrecarga implicada en decidir lo que se debe ejecutar es más grande que el costo real de la ejecución, tales intérpretes son a menudo mucho más lentos que el código de máquina. Sin embargo para instrucciones (“compuestas” ) más complejas, el porcentaje de sobrecarga es proporcionalmente menos significativo.
46.3.5 Enhebrado de Huffman El código enhebrado de Huffman consiste en listas de códigos Huffman. Un código de Huffman es una cadena de bits de longitud variable usada para identificar un elemento único. Un intérprete de enhebrado de Huffman localiza las subrutinas usando una tabla de índice o un árbol de punteros que pueden ser navagados por el código Huffman. El código enhebrado de Huffman es una de las más compactas representaciones conocidas para un programa de computadora. Básicamente el índice y los códi-
46.6. REFERENCIAS gos están organizados midiendo la frecuencia en que cada subrutina ocurre en el código. A las llamadas frecuentes se le dan los códigos más cortos. Las operaciones con frecuencias aproximadamente iguales se le dan códigos con longitudes de bits casi iguales. La mayoría de los sistemas enhebrados de Huffman han sido implementados como sistemas Forth de enhebrado directo, y son usados para grandes cantidades de paquetes de código corriendo lentamente dentro de pequeños y baratos [[microcontrolador}}es. La mayoría de las aplicaciones publicadas han estado en juguetes, calculadoras o relojes.
87 • SP o s (puntero de pila de parámetros, usado para pasar parámetros entre las palabras) A menudo, las máquinas virtuales enhebradas tales como las implementaciones de Forth tienen una máquina virtual simple en su corazón, consistiendo en tres primitivas. Ésas son: • nest, también llamado docol • unnest, o semi_s (; s)
46.3.6
Enhebrados menos usados
• Enhebrado de cadena, donde las operaciones son identificadas por cadenas, usualmente buscados en una tabla hash. Esto fue usado por Charles H. Moore en las implementaciones más tempranas de Forth y en el lenguaje de computadora experimental interpretado por hardware de la Universidad Illinois. También se utiliza en Bashforth.
46.4 Bifurcaciones Los ejemplos de arriba no muestran bifurcaciones. Para todos los intérpretes, una bifurcación cambia el puntero del enhebrado (arriba indicado como tp). Como ejemplo, una bifurcación condicional cuando el valor tope de la pila es cero puede ser codificada como sigue. Observe que el &thread[123] es la localización a saltar (jump), no la dirección de un handler, y así que debe ser saltada (tp++) independientemente de si la bifurcación es tomada. thread: brz: ... tmp = *tp++ &brz if (*sp++ == 0) &thread[123] tp = tmp ... jump *tp++
46.5 Amenidades comunes En una máquina, la separación de las pilas de datos y de retorno elimina mucho del código para el manejo de la pila, reduciendo substancialmente el tamaño del código enhebrado. El principio de la doble pila fue originado tres veces independientemente: para los grandes sistemas de Burroughs, el Forth y el PostScript, y es usado en algunas máquinas virtuales de Java. Tres registros están a menudo presentes en una máquina virtual enhebrada. Otro existe para pasar datos entre las subrutinas (“palabras”). Éstos son: • IP o i (puntero de instrucción); llamado tp en los ejemplos de arriba
• next En una máquina virtual de enhebrado indirecto, la que está dada aquí, las operaciones es: next: (ip)+ -> w ; jmp (w)+ nest: ip -> -(rp) ; w -> ip ; next unnest: (rp)+ -> ip ; next Éste es quizás el intérprete más simple y más rápido o máquina virtual.
46.6 Referencias [1] Speed of various interpreter dispatch techniques V2 [2] James R. Bell, “Threaded Code”, CACM, 1973, 16, 6, pp 370–372
46.7 Lectura adicional • Anton Ertl's explanatory page What is Threaded Code? describes different threading techniques and provides further references. • The Development of the C Language by Dennis M. Ritchie describes B (a precursor of C) as implemented using “threaded code”. • Thinking Forth Project includes the seminal (but out of print) book Thinking Forth by Leo Brodie published in 1984. • Starting FORTH online version of the book Starting FORTH by Leo Brodie published in 1981. • Brad Rodriguez's Moving FORTH: Part 1: Design Decisions in the Forth Kernel covers threading techniques in depth.
• w (puntero de trabajo)
• Historia de los CPU de propósito general
• rp o r (puntero de pila de retorno)
• GCC extensions. Labels as Values
88
46.8 Véase también • Compilación en tiempo de ejecución • Tabla de saltos • Forth
CAPÍTULO 46. CÓDIGO ENHEBRADO
Capítulo 47
Código inalcanzable En programación, el código inalcanzable es una parte del código fuente que nunca podrá ser ejecutado porque no existe ningún camino dentro de las estructuras de control en el resto del programa para llegar a este código.* [1]
• Código complejo obsoleto que se retuvo intencionalmente, pero se dejó inalcanzable para que pueda ser utilizado más adelante en el desarrollo si es necesario.
Suele referirse a este tipo de código como código muerto, aunque entre ellos hay una diferencia (el código muerto se ejecuta pero no produce cambios en la salida del programa).* [2]
• Construcciones de depuración y vestigios de código durante el desarrollo que aún no se han retirado del programa.
El código inalcanzable generalmente se considera indeEn los últimos cinco casos, el código que es inalcanzaseable por las siguiente razones: ble, a menudo existe como parte de un legado, es decir, código que una vez fue útil, pero ya no se utiliza o no 1. Ocupa memoria innecesaria. se requiere. Sin embargo, el código inalcanzable también 2. Genera almacenamiento innecesario en la caché de puede ser parte de un componente complejo (biblioteca, instrucciones de la CPU - lo que también disminuye módulo o rutina), donde el código sigue siendo útil en la localidad de datos. conjunción con diferentes datos de entrada (nunca gene3. Desde la perspectiva de mantenimiento de soft- rada por la aplicación actual) o en condiciones que no se ware, se pierde tiempo y esfuerzo en mantener y cumplen en el entorno de ejecución actual, haciendo el documentar una pieza de código que nunca se eje- código correspondiente inalcanzable, pero puede ocurrir en otros entornos de ejecución, para que el componente cuta. no ha sido desarrollado. Un ejemplo de tal código condicionalmente inalcanzable puede ser la implementación de una función printf() en la biblioteca de tiempo de ejecución de un compilador, el La existencia de código inalcanzable puede ser debido a cual contiene el código complejo para procesar todos los argumentos de cadenas posibles, de los que en realidad varios factores, tales como: es sólo un pequeño subconjunto utilizados en el progra• Errores de programación en situaciones complejas ma. Sin tener que recompilar la biblioteca de ejecución, los compiladores normalmente no serán capaces de elide saltos condicionales. minar las secciones de código no utilizadas en tiempo de • Consecuencia de las transformaciones internas rea- compilación. lizadas por un compilador optimizador.
47.1 Causas
• Pruebas de software incompletas que no se pudo detectar código inalcanzable.
47.2 Ejemplo
• Código obsoleto que un programador se haya olvidado de borrar. Considerando el siguiente código en C: • Código no utilizado que un programador haya deci- int foo (int X, int Y) { return X + Y; int Z = X*Y; } dido no suprimir, ya que estaba entremezclado con el código funcional. La definición de Z = X*Y nunca es alcanzada debido a • Código condicionalmente útil que nunca será alcan- que la función retorna el flujo del programa a la parte que zado, dado que los datos de entrada nunca causará la llamo antes, de esta manera dicha definición puede ser que el código va a ser ejecutado. descartada. 89
90
CAPÍTULO 47. CÓDIGO INALCANZABLE
47.3 Análisis La detección de código inalcanzable es una forma de análisis estático y consiste en realizar un análisis de control de flujo para encontrar el código que nunca se ejecutará independientemente de los valores de las variables y otras condiciones en tiempo de ejecución. En algunos lenguajes (como Java* [3]) algunas formas de código inalcanzable no están permitidas y no es posible compilar el programa con este tipo de código. Se conoce a la optimización que remueve código inalcanzable como eliminación de código muerto (que es la misma para el código muerto y código redundante). A veces el código puede volverse inalcanzable por alguna optimización introducida por el compilador como por ejemplo: eliminación de subexpresiones comunes. En la práctica la sofisticación del análisis realizado tiene un impacto significativo en la cantidad de código inalcanzable que se detecta. Por ejemplo, el plegamiento de constantes y un simple análisis de control de flujo muestra que la declaración a = 2 en el siguiente código no se puede alcanzar: int N = 2 + 1; if (N == 4) { a = 2; } Sin embargo se necesita mas sofisticación para determinar si esta declaración a = 2 es o no inalcanzable debido que con un método tradicional habría que calcular la raíz cuadrada en tiempo de compilación: double d = sqrt(2); if (d > 5) { a = 2; }
47.3.1
Profiling
A veces se pueden utilizar profilers para detectar código inalcanzable, un profiler no prueba nada acerca de si el código realmente es o no inalcanzable pero es una buena heurística para buscar código potencialmente inalcanzable. Una vez detectado las partes potenciales se puede llevar a cabo en las mismas un análisis más profundo.
47.4 Véase también • Código muerto • Código redundante • Cobertura de código
47.5 Referencias [1] Debray, S. K.; Evans, W., Muth, R., and De Sutter, B. (2000-03). «Compiler techniques for code compaction.» (PDF). Volume 22, issue 2 (en inglés). New York, USA:
ACM Transactions on Programming Languages & Systems (TOPLAS). Bibcode:378-415. |autor= y |apellido= redundantes (ayuda) [2] «Eliminación de Código Inalcanzable y Código Muerto». [3] «Java Language Specification».
47.6 Bibliografía • Muchnick S. S. 1997 Advanced Compiler Design and Implementation. Morgan Kaufmann. • Appel, A. W. 1998 Modern Compiler Implementation in Java. Cambridge University Press.
47.7 Enlaces externos • Código inalcanzable java
Capítulo 48
Código muerto En programación, se conoce como código muerto a una parte del código fuente que se ejecuta pero sus resultados nunca se usan.* [1]* [2] La ejecución de este tipo de código consume tiempo de computo en algo que jamás se utiliza. Es frecuente confundirlo con el código inalcanzable aunque conservan una diferencia (este jamás se ejecuta, y si bien los dos son indeseables el código muerto es más grave que el inalcanzable). Además de consumir tiempo de computo el código muerto puede arrojar excepciones o afectar un estado global del programa. por lo tanto si bien los resultados jamás se utilizan remover este código puede cambiar la salida del programa y evitar bugs innecesarios. Esta es una razón por la cual el código muerto es menos deseado que el código inalcanzable.
mente cuando algún módulo entero quede muerto.* [3] Algunos IDE (como Visual Studio 2010* [4] y Eclipse* [5]) poseen la habilidad de detectar código muerto durante tiempo de compilación.
48.3 Véase también • Código inalcanzable • Código redundante
48.4 Referencias
48.1 Ejemplo
[1] Debray, S. K., Evans, W., Muth, R., and De Sutter, B. 2000. Compiler techniques for code compaction. ACM Trans. Program. Lang. Syst. 22, 2 (Mar. 2000), 378-415.
int foo (int X, int Y) { int Z = X/Y; return X*Y; }
[2] Appel, A. W. 1998 Modern Compiler Implementation in Java. Cambridge University Press. [3] Douglas W. Jones Dead Code Maintenance, Risks 8.19 (Feb. 1, 1989)
En el código anterior la división entre X e Y se calcula pero jamás se utiliza, además, en el caso que Y sea 0 el programa arrojaría una excepción con posibilidad de abortar la ejecución, por lo tanto la salida del programa se ve afectada por esta línea.
[4] Habib Heydarian, Microsoft Corp. [5] Eclipse Developer Guide
48.5 Bibliografía
48.2 Análisis Se puede utilizar una optimización de compilador llamada eliminación de código muerto para eliminar este código. Este análisis se puede llevar a cabo mediante el análisis de variable viva, que es una forma de análisis estático de software y análisis de flujo de datos. Esta también es una diferencia con respecto al código inalcanzable que se descubre mediante un análisis de control del flujo.
• Muchnick S. S. 1997 Advanced Compiler Design and Implementation. Morgan Kaufmann. • Appel, A. W. 1998 Modern Compiler Implementation in Java. Cambridge University Press.
48.6 Enlaces externos
La eliminación de código en general es la misma técnica que se usa para eliminar el código inalcanzable y el código redundante. En los proyectos de programación grandes, a veces es difícil de reconocer y eliminar código muerto, especial91
• Optimización de código • Dead Code Detector (DCD) Java/JEE • Comparación de DCD para Java
92 • UCDetector Plugin Eclipse para encontrar código muerto Java
CAPÍTULO 48. CÓDIGO MUERTO
Capítulo 49
Código redundante En programación, se conoce como código redundante 49.2 Eliminación a cualquier parte del código fuente que tenga algún tipo de redundancia tales como recalcular un valor que ha sido Existen técnicas de optimización de software comúnmencalculado previamente y todavía esta disponible.* [1] te llevadas a cabo por un compilador optimizador para Una instrucción NOP podría ser considerado como códi- eliminar el código redundante del código fuente. La más go redundante que ha sido explícitamente insertado para común es la eliminación de código muerto. rellenar el flujo de instrucciones o introducir un retardo de tiempo, por ejemplo para crear un bucle de temporización para“perder el tiempo”. Los identificadores que se 49.3 Véase también declaran, pero nunca se les hace referencia, se denominan declaraciones redundantes. • Código muerto • Código inalcanzable
49.4 Referencias
49.1 Ejemplos
[1] Debray, S. K., Evans, W., Muth, R., and De Sutter, B. 2000. Compiler techniques for code compaction. ACM Trans. Program. Lang. Syst. 22, 2 (Mar. 2000), 378–415.
int foo(int X) { int Y = X*2; return X*2; } En este ejemplo la instrucción int Y = X*2; puede ser removida para evitar calcular el valor dos veces, o también se puede retornar el valor de la variable Y (aunque particularmente este método consume mas memoria). Considerando: #define min(A,B) ((A)<(B)?(A):(B)) int magnitud_mas_corta(int u1, int v1, int u2, int v2) { /* retorna la magnitud mas corta entre (u1,v1) y (u2,v2) */ return sqrt(min(u1*u1 + v1*v1, u2*u2 + v2*v2)); } Como consecuencia de usar el preprocesador de C el compilador escribirá la forma expandida: int magnitud_mas_corta(int u1, int v1, int u2, int v2) { int temp; if (u1*u1 + v1*v1 < u2*u2 + v2*v2) temp = u1*u1 + v1*v1; /* Redundante */ else temp = u2*u2 + v2*v2; /* Redundante */ return sqrt(temp); } Provocando un código totalmente redundante e ineficiente, sin embargo debido a que los macros de máximo y mínimo son muy utilizados los compiladores modernos detectan estas situaciones y corrigen el código generado. 93
Capítulo 50
Dato Un dato es una representación simbólica (numérica, alfabética, algorítmica, espacial, etc.) de un atributo o variable cuantitativa o cualitativa. Los datos describen hechos empíricos, sucesos y entidades. Es un valor o referente que recibe el computador por diferentes medios, los datos representan la información que el programador manipula en la construcción de una solución o en el desarrollo de un algoritmo.
• Dato experimental
50.2 Enlaces externos
Los datos aisladamente pueden no contener información humanamente relevante. Sólo cuando un conjunto de datos se examina conjuntamente a la luz de un enfoque, hipótesis o teoría se puede apreciar la información contenida en dichos datos. Los datos pueden consistir en números, estadísticas o proposiciones descriptivas. Los datos convenientemente agrupados, estructurados e interpretados se consideran que son la base de la información humanamente relevante que se pueden utilizar en la toma de decisiones, la reducción de la incertidumbre o la realización de cálculos. Es de empleo muy común en el ámbito informático y, en general, prácticamente en cualquier investigación científica. En programación, un dato es la expresión general que describe las características de las entidades sobre las cuales opera un algoritmo. En estructura de datos, es la parte mínima de la información. Datos
Procesamiento
Información
Un dato por sí mismo no constituye información, es el procesamiento de los datos lo que nos proporciona información.
50.1 Véase también • Información • Conocimiento • Sabiduría • Metadato • Estadística 94
•
Wikcionario tiene definiciones y otra información sobre dato.Wikcionario
• Datos Gráficos: Web que permite generar gráficos a partir de datos del Instituto Nacional de Estadística. • GraficandoDatos.com: Tienda on-line de gráficas para uso digital e impreso. Servicio de producción de gráficas a la medida para empresas y particulares. • Stat4You: En stat4you tienes todas las estadísticas del INE y del ISTAC para que crees tus gráficos fácilmente. • Centro de datos - Lanzarote: La mayor colección de datos y estadísticas de la Isla de Lanzarote en Internet.
Capítulo 51
Depuración de programas 51.1 Origen
Una fotografía del supuestamente primer “bug”(bicho) real, el cual fue depurado (“debugged”) en 1947.
Existe una controversia acerca del origen del término depuración o “debugging”en inglés. Los términos “bug” y “debugging”son atribuidos popularmente a la almirante Grace Murray Hopper por los años 1940. Mientras trabajaba con un Mark II en la Universidad de Harvard, ella encontró una polilla atrapada en un relé impidiendo las operaciones de dicha computadora, por lo cual ella comentó que cuando se sacó aquella polilla le habían hecho “debugging”al sistema. Sin embargo el término “bug” cómo significado de error técnico data cerca de 1878, y el término “debugging”o depuración ha sido usado en aeronáutica antes de entrar al mundo de las computadoras.
51.2 Aplicación Como el software y los sistemas electrónicos se vuelven generalmente más complejos, se han desarrollado varias técnicas comunes de depuración para detectar anomalías, corregir funcionalidades y optimizar código fuente. ExisDepuración de programas es el proceso de identificar y ten algunos aficionados que consideran la depuración cocorregir errores de programación. En inglés se le conoce mo una forma de arte. como debugging, es que se asemeja a la eliminación de bichos (bugs), manera en que se conoce informalmente a los errores de programación. Se dice que el término bug proviene de la época de los ordenadores de válvula ter- 51.3 Véase también moiónica, en los cuales los problemas se generaban por • Depurador los insectos que eran atraídos por las luces y estropeaban el equipo. Si bien existen técnicas para la revisión siste• Error de software mática del código fuente y se cuenta con medios computacionales para la detección de errores (depuradores) y fa• Emulador BOCHS cilidades integradas en los sistemas lower CASE y en los ambientes de desarrollo integrado, sigue siendo en buena medida una actividad manual, que desafía la paciencia, la imaginación y la intuición del programador. Muchas veces se requiere incluir en el código fuente instrucciones auxiliares que permitan el seguimiento de la ejecución del programa, presentando los valores de variables y direcciones de memoria y ralentizando la salida de datos (modo de depuración). Dentro de un proceso formal de aseguramiento de la calidad, puede ser asimilado al concepto de prueba unitaria. 95
Capítulo 52
Desarrollador de software El desarrollador de software es una persona programadora que se dedica a uno o más aspectos del proceso de desarrollo de software. Se trata de un ámbito más amplio de la programación. El desarrollador puede contribuir a la visión general del proyecto más a nivel de aplicación que a nivel de componentes o en las tareas de programación individuales. Conforme pasa el tiempo, las diferencias entre el diseño de sistemas informáticos, el desarrollo de software y la programación se van haciendo más claras. En el nicho de mercado puede encontrarse una separación entre programadores y desarrolladores, siendo estos últimos los que diseñan la estructura o jerarquía de clases. Incluso esos desarrolladores se convierten en arquitectos de sistemas informáticos, aquellos que diseñan la arquitectura a varios niveles o las interacciones entre componentes de un proyecto de software grande. El concepto de desarrollo de software incluye: • trabajo en equipo: los proyectos son en general una colaboración entre varios desarrolladores, que tratan cada uno una parte del programa, y también de otros colaboradores como los comerciales, que definen con el cliente la finalidad del producto, diseñadores gráficos que definen el aspecto y la ergonomía, entre otros temas. • concepción o diseño: a partir de un pliego de condiciones (user requirement specifications), definir las especificaciones técnicas (estructura de los datos, comunicación entre los módulos, etcétera). • pruebas: que sirven para detectar las disconformidades y los errores • mantenimiento: la corrección de los errores después de la salida del programa informático, y la mejora para hacer evolucionar el producto.
52.1 Véase también • Ambiente de desarrollo integrado • Desarrollador de videojuegos 96
• Ingeniería del software • Interfaz de programación de aplicaciones • Programación • Software
Capítulo 53
Desarrollo en cascada En Ingeniería de software el desarrollo en cascada, también llamado modelo en cascada (denominado así por la posición de las fases en el desarrollo de esta, que parecen caer en cascada “por gravedad” hacia las siguientes fases), es el enfoque metodológico que ordena rigurosamente las etapas del proceso para el desarrollo de software, de tal forma que el inicio de cada etapa debe esperar al término de la etapa anterior.* [1] Al final de cada etapa, el modelo está diseñado para llevar a cabo una revisión final, que se encarga de determinar si el proyecto está listo para avanzar a la siguiente fase. Este modelo fue el primero en originarse y es la base de todos los demás modelos de ciclo de vida.
Requisitos Diseño
Implementación Verificación
Maintenimiento
Un ejemplo de una metodología de desarrollo en cascada El “modelo cascada”sin modificar. El progreso fluye de arriba es: hacía abajo, como una cascada.
1. Análisis de requisitos. qué objetivos debe cubrir. De esta fase surge una memoria llamada SRD (documento de especificación de requisitos), que contiene la especificación completa de lo que debe hacer el sistema sin entrar en detalles internos.
2. Diseño del Sistema. 3. Segregación del programa. 4. Diversificación. 5. Verificación integral.
Es importante señalar que en esta etapa se debe consensuar todo lo que se requiere del sistema y será aquello lo que seguirá en las siguientes etapas, no pudiéndose requerir nuevos resultados a mitad del proceso de elaboración del software de una manera.
6. Ordeñado del programa.
De esta forma, cualquier error de diseño detectado en la etapa de prueba conduce necesariamente al rediseño y nueva programación del código afectado, aumentando los costos del desarrollo. La palabra cascada sugiere, mediante la metáfora de la fuerza de la gravedad, el esfuerzo necesario para introducir un cambio en las fases más 53.1.2 Diseño del Sistema avanzadas de un proyecto. Descompone y organiza el sistema en elemenSi bien ha sido ampliamente criticado desde el ámbito tos que puedan elaborarse por separado, aproacadémico y la industria* [cita requerida], sigue siendo el vechando las ventajas del desarrollo en equipo. paradigma más seguido al día de hoy* [cita requerida]. Como resultado surge el SDD (Documento de Diseño del Software), que contiene la descripción de la estructura relacional global del sis53.1 Fases del modelo tema y la especificación de lo que debe hacer cada una de sus partes, así como la manera en que se combinan unas con otras. 53.1.1 Análisis de requisitos En esta fase se analizan las necesidades de los usuarios finales del software para determinar
Es conveniente distinguir entre diseño de alto nivel o arquitectónico y diseño detallado. El 97
98
CAPÍTULO 53. DESARROLLO EN CASCADA primero de ellos tiene como objetivo definir la estructura de la solución (una vez que la fase de análisis ha descrito el problema) identificando grandes módulos (conjuntos de funciones que van a estar asociadas) y sus relaciones. Con ello se define la arquitectura de la solución elegida. El segundo define los algoritmos empleados y la organización del código para comenzar la implementación.
53.1.3
Diseño del Programa
Es la fase en donde se realizan los algoritmos necesarios para el cumplimiento de los requerimientos del usuario así como también los análisis necesarios para saber qué herramientas usar en la etapa de Codificación
53.1.4
Codificación
Es la fase en donde se implementa el código fuente, haciendo uso de prototipos así como de pruebas y ensayos para corregir errores. Dependiendo del lenguaje de programación y su versión se crean las bibliotecas y componentes reutilizables dentro del mismo proyecto para hacer que la programación sea un proceso mucho más rápido.
53.2 Variantes Existen variantes de este modelo; especialmente destacamos la que hace uso de prototipos y en la que se establece un ciclo antes de llegar a la fase de mantenimiento, verificando que el sistema final este libre de fallos. Otros ejemplos de variantes del modelo en cascada son el modelo en cascada con fases solapadas, cascada con subproyectos, y cascada con reducción de riesgos.* [2]
53.3 Ventajas Realiza un buen funcionamiento en equipos débiles y productos maduros, por lo que se requiere de menos capital y herramientas para hacerlo funcionar de manera óptima. Es un modelo fácil de implementar y entender. Está orientado a documentos. Es un modelo conocido y utilizado con frecuencia. Promueve una metodología de trabajo efectiva: Definir antes que diseñar, diseñar antes que codificar.* [3]
53.4 Desventajas 53.1.5
Pruebas
Los elementos, ya programados, se ensamblan para componer el sistema y se comprueba que funciona correctamente y que cumple con los requisitos, antes de ser entregado al usuario final.
53.1.6
Verificación
En la vida real, un proyecto rara vez sigue una secuencia lineal, esto crea una mala implementación del modelo, lo cual hace que lo lleve al fracaso. El proceso de creación del software tarda mucho tiempo ya que debe pasar por el proceso de prueba y hasta que el software no esté completo no se opera. Esto es la base para que funcione bien.
Es la fase en donde el usuario final ejecuta el sistema, para ello el o los programadores ya realizaron exhaustivas pruebas para comprobar que el sistema no falle.
Cualquier error de diseño detectado en la etapa de prueba conduce necesariamente al rediseño y nueva programación del código afectado, aumentando los costos del desarrollo.
En la creación de desarrollo de cascada se implementa los códigos de investigación y pruebas del mismo.
Una etapa determinada del proyecto no se puede llevar a cabo a menos de que se haya culminado la etapa anterior.
53.1.7
Mantenimiento
Una de las etapas más críticas, ya que se destina un 75 % de los recursos, es el mantenimiento del Software ya que al utilizarlo como usuario final puede ser que no cumpla con todas nuestras expectativas.
53.5 Véase también • Ingeniería de software • Desarrollo en espiral • Modelos de desarrollo de software: Cascada vs V
53.7. ENLACES EXTERNOS
53.6 Referencias [1] S. Pressman, Roger. Ingeniería del Software: Un enfoque práctico, 3.ª Edición, Pag. 26-30. [2] , Patricia Arieta Melgarejo, Modelos del ciclo de vida de software. [3] , Ruby Casallas, Andrés Yie, Ingeniería de Software: Ciclos de Vida y Metodologías.
53.7 Enlaces externos • Ciclo de vida del software
99
Capítulo 54
Desarrollo en espiral El desarrollo en espiral es un modelo de ciclo de vida del software definido por primera vez por Barry Boehm en 1986,* [1] utilizado generalmente en la Ingeniería de software. Las actividades de este modelo se conforman en una espiral, en la que cada bucle o iteración representa un conjunto de actividades. Las actividades no están fijadas a ninguna prioridad, sino que las siguientes se eligen en función del análisis de riesgo, comenzando por el bucle interior.
54.1 Introducción
Enhancement”.* [1] En 1988, Boehm publicó un artículo similar* [2] destinado a una audiencia más amplía. Básicamente consiste en una serie de ciclos que se repiten en forma de espiral, comenzando desde el centro. Se suele interpretar como que dentro de cada ciclo de la espiral se sigue un Modelo Cascada, pero no necesariamente debe ser así. El Espiral puede verse como un modelo evolutivo que conjuga la naturaleza iterativa del modelo MCP con los aspectos controlados y sistemáticos del Modelo Cascada, con el agregado de gestión de riesgo.
54.2 Ciclos o Iteraciones
La Ingeniería de software, se vale y establece a partir de En cada vuelta o iteración hay que tener en cuenta: una serie de modelos que establecen y muestran las distintas etapas y estados por los que pasa un producto soft• Los Objetivos: qué necesidad debe cubrir el proware, desde su concepción inicial, pasando por su desaducto. rrollo, puesta en marcha y posterior mantenimiento, hasta la retirada del producto. A estos modelos se les denomina • Alternativas: las diferentes formas de conseguir los «modelos de ciclo de vida del software». El primer modeobjetivos de forma exitosa, desde diferentes puntos lo concebido fue el de Royce, más comúnmente conocido de vista como pueden ser: como desarrollo en cascada o desarrollo lineal secuencial. Este modelo establece que las diversas actividades que se 1. Características: experiencia del personal, requisivan realizando al desarrollar un producto software sucetos a cumplir, etc. den de forma lineal. Boehm, autor de diversos artículos de ingeniería del soft2. Formas de gestión del sistema. ware; modelos de estimación de esfuerzo y tiempo que se consume en hacer productos software; y Modelos de 3. Riesgo asumido con cada alternativa. Ciclo de Vida; ideó y promulgó un modelo desde un enfoque distinto al tradicional en Cascada: El Modelo Evo• Desarrollar y Verificar: Programar y probar el lutivo Espiral. Su Modelo de Ciclo de Vida en Espiral tiesoftware. ne en cuenta fuertemente el riesgo que aparece a la hora de desarrollar software. Para ello, se comienza mirando las posibles alternativas de desarrollo, se opta por la de Si el resultado no es el adecuado o se necesita implemenriesgo más asumible y se hace un ciclo de la espiral. Si el tar mejoras o funcionalidades: cliente quiere seguir haciendo mejoras en el software, se vuelve a evaluar las distintas nuevas alternativas y riesgos • Se planificaran los siguientes pasos y se comienza un y se realiza otra vuelta de la espiral, así hasta que llegue nuevo ciclo de la espiral. La espiral tiene una forma un momento en el que el producto software desarrollado de caracola y se dice que mantiene dos dimensiones, sea aceptado y no necesite seguir mejorándose con otro la radial y la angular: nuevo ciclo. Este modelo fue propuesto por Boehm en 1986 en su artículo “A Spiral Model of Software Development and 100
1. Angular: Indica el avance del proyecto del software dentro de un ciclo.
54.3. MECANISMOS DE CONTROL 2. Radial: Indica el aumento del coste del proyecto, ya que con cada nueva iteración se pasa más tiempo desarrollando. Este sistema es muy utilizado en proyectos grandes y complejos como puede ser, por ejemplo, la creación de un Sistema Operativo.
101 • Dependiendo del resultado de la evaluación de los riesgos, se elige un modelo para el desarrollo, el que puede ser cualquiera de los otros existentes, como formal, evolutivo, cascada, etc. Así si por ejemplo si los riesgos en la interfaz de usuario son dominantes, un modelo de desarrollo apropiado podría ser la construcción de prototipos evolutivos. Si lo riesgos de protección son la principal consideración, un desarrollo basado en transformaciones formales podría ser el más apropiado.
Al ser un modelo de Ciclo de Vida orientado a la gestión de riesgo se dice que uno de los aspectos fundamentales de su éxito radica en que el equipo que lo aplique tenga la necesaria experiencia y habilidad para detectar y cataAnálisis del riesgo logar correctamente los riesgos.
54.2.1
Tareas
Para cada ciclo habrá cuatro actividades:
• Se lleva a cabo el estudio de las causas de las posibles amenazas y probables eventos no deseados y los daños y consecuencias que éstas puedan producir. Se evalúan alternativas. Se debe tener un prototipo antes de comenzar a desarrollar y probar.
1. Determinar Objetivos. En resumen, es para tener en cuenta los riesgos de cada uno de los ambitos
2. Análisis del riesgo. 3. Desarrollar y probar.
54.3 Mecanismos de control
4. 'Planificación.'
• La dimensión radial mide el coste. Determinar objetivos
Análisis del riesgo
• La dimensión angular mide el grado de avance del proyecto.
54.4 Variaciones del Modelo En Espiral Planificación
Desarrollar y probar
Modelo en Espiral Típico de seis regiones Modelo en espiral(Boehm, 1986).
Determinar o fijar objetivos
El modelo en espiral puede adaptarse y aplicarse a lo largo de la vida del software de computadora, a diferencia del modelo de proceso clásico que termina cuando se entrega el software.
• Fijar también los productos definidos a obtener: re- Las 6 regiones que componen este modelo son las siguienquisitos, especificación, manual de usuario. tes: • Fijar las restricciones. • Identificación de riesgos del proyecto y estrategias alternativas para evitarlos. • Hay una cosa que solo se hace una vez: planificación inicial.
• Comunicación con el cliente - Tareas necesarias para plantear la comunicación entre el desarrollador y el cliente. • Planificación - Tareas inherentes a la definición de recursos, el tiempo y otras informaciones relacionadas con el proyecto. Son todos los requerimientos.
• Tareas de la actividad propia y de prueba.
• Análisis de riesgos – Tareas para evaluar riesgos técnicos y otras informaciones relacionadas con el proyecto.
• Análisis de alternativas e identificación resolución de riesgos.
• Ingeniería - Tareas para construir una o más representaciones de la aplicación.
Desarrollar, verificar y validar(probar)
102 • Construcción y adaptación - Tareas requeridas para construir, probar, instalar y proporcionar soporte a los usuarios.
CAPÍTULO 54. DESARROLLO EN ESPIRAL
54.7 Inconvenientes
Planificar un proyecto con esta metodología es a menudo imposible, debido a la incertidumbre en el número de ite• Evaluación del cliente - Tareas requeridas para ob- raciones que serán necesarias. En este contexto la evaluatener la reacción del cliente según la evaluación de ción de riesgos es de la mayor importancia y, para granlas representaciones del software creadas durante la des proyectos, dicha evaluación requiere la intervención etapa de ingeniería e implementación durante la eta- de profesionales de gran experiencia. pa de instalación.* [3] El IEEE clasifica al desarrollo en espiral como modelo no operativo en sus clasificaciones de MCV.* [5] Modelo en espiral WIN WIN El modelo Win-Win es una adaptación del modelo espiral que se enfatiza en la participación del cliente en el proceso de desarrollo de un producto de software. En un caso ideal, el desarrollador simplemente pregunta al cliente lo que se requiere y el cliente proporciona suficiente información y detalles para proceder. Sin embargo esto no suele ocurrir en la mayoría de los casos y es necesario que se establezcan negociaciones significativas entre ambas partes para equilibrar la funcionalidad y rendimiento con los costos y tiempo de salida al mercado del producto. El modelo Win-Win deriva su nombre del objetivo de estas negociaciones, es decir, “ganar-ganar”. El cliente recibe el producto que satisface la mayoría de sus necesidades, y el desarrollador trabaja para alcanzar presupuestos y fechas de entrega. Para lograr este objetivo, se realizan varias actividades de negociación al principio de cada paso alrededor de la espiral.* [4]
54.5 Ventajas El análisis del riesgo se hace de forma explícita y clara. Une los mejores elementos de los restantes modelos. • Reduce riesgos del proyecto • Incorpora objetivos de calidad • Integra el desarrollo con el mantenimiento, etc. Además es posible tener en cuenta mejoras y nuevos requerimientos sin romper con la metodología, ya que este ciclo de vida no es rígido ni estático.
54.6 Desventajas • Genera mucho tiempo en el desarrollo del sistema • Modelo costoso • Requiere experiencia en la identificación de riesgos
54.8 Véase también • Ingeniería de Software • Desarrollo de Software • Modelo en Cascada o Secuencial • Modelo Iterativo Incremental • Modelo por Prototipos • Modelo de Desarrollo Rápido
54.9 Referencias [1] Boehm B, A Spiral Model of Software Development and Enhancement, ACM SIGSOFT Software Engineering Notes, ACM, 11(4):14-24, Agosto 1986. [2] Boehm B, “A Spiral Model of Software Development and Enhancement", IEEE Computer, IEEE, 21(5):61-72, May 1988 [3] http://modeloespiral.blogspot.com/2009/08/ modelo-tipico-de-seis-regiones.html [4] http://www.hanantek.com/win-win [5] Developing a Software Project Life Cycle Process (IEEE 1074), 30 de marzo de 2006.
54.10 Enlaces externos • A Spiral Model of Software Development and Enhancement. artículo original de Barry Boehm en el que proponía el modelo de desarrollo en espiral (en inglés)
Capítulo 55
Desarrollo iterativo y creciente Desarrollo iterativo y creciente (o incremental) es un fied Process y el Dynamic Systems Development Metproceso de desarrollo de software creado en respuesta a hod. El desarrollo incremental e iterativo es también una las debilidades del modelo tradicional de cascada. parte esencial de un tipo de programación conocido coBásicamente este modelo de desarrollo, que no es más mo Extreme Programming y los demás frameworks de desarrollo rápido de software. que un conjunto de tareas agrupadas en pequeñas etapas * repetitivas (iteraciones), [1] es uno de los más utilizados en los últimos tiempos ya que, como se relaciona con novedosas estrategias de desarrollo de software y una pro- 55.2 Ciclo de vida gramación extrema, es empleado en metodologías diversas. La idea principal detrás de mejoramiento iterativo es El modelo consta de diversas etapas de desarrollo en cada desarrollar un sistema de programas de manera increincremento, las cuales inician con el análisis y finalizan mental, permitiéndole al desarrollador sacar ventaja de lo que se ha aprendido a lo largo del desarrollo anterior, incon la instauración y aprobación del sistema.* [2] crementando, versiones entregables del sistema. El aprendizaje viene de dos vertientes: el desarrollo del sistema, y su uso (mientras sea posible). Los pasos claves en el 55.1 Concepto de desarrollo itera- proceso son comenzar con una implementación simple de los requerimientos del sistema, e iterativamente mejorar tivo y creciente la secuencia evolutiva de versiones hasta que el sistema completo esté implementado. En cada iteración, se realiSe planifica un proyecto en distintos bloques temporales zan cambios en el diseño y se agregan nuevas funcionalique se le denominan iteración. En una iteración se repite dades y capacidades al sistema. un determinado proceso de trabajo que brinda un resul- Básicamente este modelo se basa en dos premisas: tado más completo para un producto final, de forma que quien lo utilice reciba beneficios de este proyecto de ma• Los usuarios nunca saben bien que es lo que necesinera creciente. tan para satisfacer sus necesidades. Para llegar a lograr esto, cada requerimiento debe tener • En el desarrollo, los procesos tienden a cambiar.* [4] un completo desarrollo en una única iteración que debe de incluir pruebas y una documentación para que el equipo pueda cumplir con todos los objetivos que sean necesa- El proceso en sí mismo consiste de: rios y esté listo para ser dado al cliente. Así se evita tener arriesgadas actividades en el proyecto finalizado. • Etapa de inicialización Lo que se busca es que en cada iteración los componentes logren evolucionar el producto dependiendo de los completados de las iteraciones antecesoras, agregando más opciones de requisitos y logrando así un mejoramiento mucho más completo.
• Etapa de iteración • Lista de control de proyecto
55.2.1 Consideraciones sobre el momento
Una manera muy primordial para dirigir al proceso iterade aplicación tivo incremental es la de priorizar los objetivos y requerimientos en función del valor que ofrece el cliente.* [3] Para integrar la usabilidad en un proceso de desarrollo, Para apoyar el desarrollo de proyectos por medio de este no es suficiente con asignar técnicas de usabilidad a acmodelo se han creado frameworks (entornos de trabajo), tividades de desarrollo, puesto que no todas las técnicas de los cuales los dos más famosos son el Rational Uni- de usabilidad son aplicables en cualquier momento de un 103
104
CAPÍTULO 55. DESARROLLO ITERATIVO Y CRECIENTE
desarrollo iterativo. Por ejemplo, las técnicas para desarrollar el concepto del producto están concebidas para su aplicación en los primeros esfuerzos del desarrollo, cuando las necesidades se identifican y el esquema general del sistema se establece. Aunque es aconsejable aplicarlas también más tarde, para refinar el concepto, su principal esfuerzo de aplicación esta en las tareas iniciales de desarrollo.* [5]
55.2.2
Etapa de inicialización
Se crea una versión del sistema. La meta de esta etapa es crear un producto con el que el usuario pueda interactuar, y por ende retroalimentar el proceso. Debe ofrecer una muestra de los aspectos claves del problema y proveer una solución lo suficientemente simple para ser comprendida e implementada fácilmente. Para guiar el proceso de iteración se crea una lista de control de proyecto, que contiene un historial de todas las tareas que necesitan ser realizadas. Incluye cosas como nuevas funcionalidades para ser implementadas, y areas de rediseño de la solución ya existente. Esta lista de control se revisa periódica y constantemente como resultado de la fase de análisis.
55.2.3
Etapa de iteración
Esta etapa involucra el rediseño e implementación de una tarea de la lista de control de proyecto, y el análisis de la versión más reciente del sistema. La meta del diseño e implementación de cualquier iteración es ser simple, directa y modular, para poder soportar el rediseño de la etapa o como una tarea añadida a la lista de control de proyecto. El código puede, en ciertos casos, representar la mayor fuente de documentación del sistema. El análisis de una iteración se basa en la retroalimentación del usuario y en el análisis de las funcionalidades disponibles del programa. Involucra el análisis de la estructura, modularidad, usabilidad, confiabilidad, eficiencia y eficacia (alcanzar las metas). La lista de control del proyecto se modifica bajo la luz de los resultados del análisis. Las guías primarias que guían la implementación y el análisis incluyen: • Cualquier dificultad en el diseño, codificación y prueba de una modificación debería apuntar a la necesidad de rediseñar o recodificar.
• Las modificaciones deben ser más fáciles de hacer conforme avanzan las iteraciones. Si no es así, hay un problema primordial usualmente encontrado en un diseño débil o en la proliferación excesiva de parches al sistema. • Los parches normalmente deben permanecer solo por una o dos iteraciones. Se hacen necesarios para evitar el rediseño durante una fase de implementación. • La implementación existente debe ser analizada frecuentemente para determinar qué tal se ajusta a las metas del proyecto. • Las facilidades para analizar el programa deben ser utilizadas cada vez para ayudar en el análisis de implementaciones parciales. • La opinión del usuario debe ser solicitada y analizada para indicar deficiencias en la implementación referida por él.
55.3 Caso práctico La mejora iterativa fue exitosamente aplicada al desarrollo de una familia extensa de compiladores para una familia de lenguajes de programación en una gama de arquitecturas de hardware. Un conjunto de 17 versiones del sistema se desarrollaron en un lugar, generando 17 mil líneas de código fuente de lenguaje de alto nivel (6500 de código ejecutable). El sistema posteriormente fue desarrollado en dos sitios diferentes, llegando a dos versiones diferentes del lenguaje base: una versión esencialmente se enfocaba en aplicaciones matemáticas, añadiendo números reales y varias funciones matemáticas, y la otra se centró en añadir capacidades para escribir del compilador. Cada iteración fue analizada del punto de vista de los usuarios (las capacidades del lenguaje fueron determinadas en parte por las necesidades del usuario) y el punto de vista del desarrollador (el diseño del compilador evolucionó para ser más fácilmente modificable, por ejemplo, para añadir nuevos tipos de datos). Mediciones tales como acoplamiento y modularización fueron seguidas sobre múltiples versiones.
55.4 Características
• Las modificaciones deben ajustarse fácilmente a los Usando análisis y mediciones como guías para el procemódulos fáciles de encontrar y a los aislados. Si no so de mejora es una diferencia mayor entre las mejoras es así, entonces se requiere algún grado de rediseño. iterativas y el desarrollo rápido de aplicaciones, princi• Las modificaciones a las tablas deben ser especial- palmente por dos razones: mente fáciles de realizar. Si dicha modificación no ocurre rápidamente, se debe aplicar algo de rediseño.
• Provee de soporte para determinar la efectividad de los procesos y de la calidad del producto.
55.7. DEBILIDADES DE ESTE MODELO DE DESARROLLO • Permite estudiar y después mejorar y ajustar el proceso para el ambiente en particular. Estas mediciones y actividades de análisis pueden ser añadidas a los métodos de desarrollo rápido existentes. De hecho, el contexto de iteraciones múltiples conlleva ventajas en el uso de mediciones. Las medidas a veces son difíciles de comprender en lo absoluto, aunque en los cambios relativos en las medidas a través de la evolución del sistema puede ser muy informativo porque proveen una base de comparación. Por ejemplo, un vector de medidas m1, m2,..., mn puede ser definido para caracterizar varios aspectos del producto en cierto punto, como pueden ser el esfuerzo total realizado, los cambios, los defectos, los atributos lógico, físico y dinámico, consideraciones del entorno, etcétera. Así el observador puede decir como las características del producto como el tamaño, la complejidad, el acoplamiento y la cohesión incrementan o disminuyen en el tiempo. También puede monitorearse el cambio relativo de varios aspectos de un producto o pueden proveer los límites de las medidas para apuntar a problemas potenciales y anomalías.
55.5 Ventajas del desarrollo incremental • En este modelo los usuarios no tienen que esperar hasta que el sistema completo se entregue para hacer uso de él. El primer incremento cumple los requerimientos más importantes de tal forma que pueden utilizar el software al instante. • Los usuarios pueden utilizar los incrementos iniciales como prototipos y obtener experiencia sobre los requerimientos de los incrementos posteriores del sistema. • Existe muy pocas probabilidades de riesgo en el sistema. Aunque se pueden encontrar problemas en algunos incrementos, lo normal es que el sistema se entregue sin inconvenientes al usuario. • Ya que los sistemas de más alta prioridad se entregan primero, y los incrementos posteriores se integran entre ellos, es muy poco probable que los sistemas más importantes sean a los que se les hagan más pruebas. Esto quiere decir que es menos probable que los usuarios encuentren fallas de funcionamiento del software en las partes más importantes del sistema.* [6]
55.6 Ventajas del desarrollo iterativo • En el desarrollo de este modelo se da la retroalimentación muy temprano a los usuarios.
105
• Permite separar la complejidad del proyecto, gracias a su desarrollo por parte de cada iteración o bloque. • El producto es consistente y puntual en el desarrollo. • Los productos desarrollados con este modelo tienen una menor probabilidad de fallar. • Se obtiene un aprendizaje en cada iteración que es aplicado en el desarrollo del producto y aumenta las experiencias para próximos proyectos.* [7]
55.7 Debilidades de este modelo de desarrollo • La entrega temprana de los proyectos produce la creación de sistemas demasiados simples que a veces se ven un poco monótonos a los ojos del personal que lo recibe.* [6] • La mayoría de los incrementos se harán en base de las necesidades de los usuarios. Los incrementos en si ya son estipulados desde antes de la entrega del proyecto, sin embargo hay que ver cómo se maneja el producto para ver si necesita otros cambios además de los estipulados antes de la entrega del proyecto. Este problema no se ve frecuentemente ya que la mayoría de las veces los incrementos estipulados suplen satisfactoriamente al usuario.* [6] • Los incrementos no deben constar de muchas líneas de código ya que la idea de los incrementos es agregar accesorios al programa principal (o funcional), para que este tenga una y mil formas de desenvolverse en su tarea; llenar los incrementos de muchas líneas de código provocaría que se perdiera la objetividad o base de lo que se trata el desarrollo incremental.* [6] • Requiere de un cliente involucrado durante todo el curso del proyecto. Hay clientes que simplemente no estarán dispuestos a invertir el tiempo necesario. • El trato con el cliente debe basarse en principios éticos y colaboración mutua, más que trabajar cada parte independientemente, defendiendo sólo su propio beneficio.* [8] • La entrega de un programa que es parcial pero funcional puede hacer vulnerable al programa debido a la falta de robustez en su sistema, provocando que agentes ajenos puedan interferir con el correcto funcionamiento del programa en sí.* [6] • Infunde responsabilidad en el equipo de desarrollo al trabajar directamente con el cliente, requiriendo de profesionales sobre el promedio.
106
CAPÍTULO 55. DESARROLLO ITERATIVO Y CRECIENTE
• Sufre fuertes penalizaciones en proyectos en los cuales los requerimientos están previamente definidos, o para proyectos“todo/nada”en los cuales se requiere que se completen en un 100% el producto para ser implementado (por ejemplo, licitaciones) otro punto muy importante es asegurarnos de que el trabajo se pueda cumplir tomando en cuenta los costos que podamos usar en nuestros propios recursos.
55.8 Véase también • Scrum • Iteración • Desarrollo en cascada • Ingeniería de software • Desarrollo de software
55.9 Referencias [1] |Proceso de Desarrollo Iterativo| http://fernandosoriano. com.ar/?p=13 [2] |Desarrollo de software. Ciclo de vida iterativo incremental| https://jummp.wordpress.com/2011/03/31/ desarrollo-de-software-ciclo-de-vida-iterativo-incremental/ [3] |Desarrollo iterativo e incremental| http://www. proyectosagiles.org/desarrollo-iterativo-incremental [4] |Modelo Iterativo| http://procesosoftware.wikispaces. com/Modelo+Iterativo [5] Constantine, L. L., Lockwood, L. A. D.: Software for Use: A Practical Guide to the Models and Methods of Usage Centred Design. Addison - Wesley ( 1999) [6] Ian Sommerville (2005). «Entrega Incremental». Ingeniería del Software, Séptima edición edición... España: Pearson. [7] |Proceso de Desarrollo Iterativo| http://fernandosoriano. com.ar/?p=13 [8] |Desarrollo iterativo e incremental| http://www. proyectosagiles.org/desarrollo-iterativo-incremental
Capítulo 56
Detección dinámica de invariantes La “generación dinámica de invariantes”es una técnica dinámica para el análisis informático, normalmente orientado a la prueba y monitorización de software
56.1 Implementaciones La implementación más famosa es Daikon
107
Capítulo 57
Diagrama de colaboración Un diagrama de colaboración en las versiones de UML 1.x es esencialmente un diagrama que muestra interacciones organizadas alrededor de los roles. A diferencia de los diagramas de secuencia, los diagramas de colaboración, también llamados diagramas de comunicación, muestran explícitamente las relaciones de los roles. Por otra parte, un diagrama de comunicación no muestra el tiempo como una dimensión aparte, por lo que resulta necesario etiquetar con números de secuencia tanto la secuencia de mensajes como los hilos concurrentes.
implícitas. Un diagrama de comunicación muestra relaciones entre roles geométricamente y relaciona los mensajes con las relaciones, pero las secuencias temporales están menos claras.
57.2 Tipos
Es útil marcar los objetos en cuatro grupos: los que exis• Muestra cómo las instancias específicas de las clases ten con la interacción entera; los creados durante la intrabajan juntas para conseguir un objetivo común. teracción (restricción {new}); los destruidos durante la • Implementa las asociaciones del diagrama de clases interacción (restricción {destroyed}); y los que se crean mediante el paso de mensajes de un objeto a otro. y se destruyen durante la interacción (restricción {transient}). Dicha implementación es llamada “enlace”. Un diagrama de comunicación es también un diagrama de clases que contiene roles de clasificador y roles de asociación en lugar de sólo clasificadores y asociaciones. Los roles de clasificador y los de asociación describen la configuración de los objetos y de los enlaces que pueden ocurrir cuando se ejecuta una instancia de la comunicación. Cuando se instancia una comunicación, los objetos están ligados a los roles de clasificador y los enlaces a los roles de asociación. El rol de asociación puede ser desempeñado por varios tipos de enlaces temporales, tales como argumentos de procedimiento o variables locales del procedimiento. Los símbolos de enlace pueden llevar estereotipos para indicar enlaces temporales.
Aunque las comunicaciones muestran directamente la implementación de una operación, pueden también mostrar la realización de una clase entera. En este uso, muestran el contexto necesario para implementar todas las operaciones de una clase. Esto permite que el modelador vea los roles múltiples que los objetos pueden desempeñar en varias operaciones. No hay ejemplos de los diagramas, diferentes casos o sistemas, ya que con UML se modelan áreas de un negocio así como los sistemas que estos requieren
57.3 Mensajes 57.1 Usos Un uso de un diagrama de colaboración es mostrar la implementación de una operación. La comunicación muestra los parámetros y las variables locales de la operación, así como asociaciones más permanentes. Cuando se implementa el comportamiento, la secuencia de los mensajes corresponde a la estructura de llamadas anidadas y el paso de señales del programa. Un diagrama de secuencia muestra secuencias en el tiempo como dimensión geométrica, pero las relaciones son
Los mensajes se muestran como flechas etiquetadas unidas a los enlaces. Cada mensaje tiene un número de secuencia, una lista opcional de mensajes precedentes, una condición opcional de guarda, un nombre, una lista de argumentos y un nombre de valor de retorno opcional. El nombre de serie incluye el nombre (opcional) de un hilo. Todos los mensajes del mismo hilo se ordenan secuencialmente. Los mensajes de diversos hilos son concurrentes a menos que haya una dependencia secuencial explícita. En conclusión en un diagrama muy sencillo de hacer.
108
57.5. CAMBIOS EN VERSIONES RECIENTES DE UML
57.4 Flujos Generalmente, un diagrama de comunicación contiene un símbolo para un objeto durante una operación completa. Sin embargo, a veces, un objeto contiene diferentes estados que se deban hacer explícitos. Por ejemplo, un objeto pudo cambiar de localización o sus asociaciones pudieron diferenciarse. Los diferentes símbolos de objeto que representan un objeto se pueden conectar usando flujos“become”o“conversión”. Un flujo“become”es una transición, a partir de un estado de un objeto a otro. Se dibuja como una flecha de línea discontinua con el estereotipo “become”o “conversión”y puede ser etiquetado con un número de serie para mostrar cuando ocurre. Un flujo de conversión también se utiliza para mostrar la migración de un objeto a partir de una localización a otra distinta para otro lugar también se deben marcar con el número en secuencias.
57.5 Cambios en versiones recientes de UML En versiones recientes de UML este diagrama ha sido reemplazado por el diagrama de comunicación.
109
Capítulo 58
Diagrama de flujo La lámpara no funciona
¿Está enchufada la lámpara?
No
Enchufar la lámpara
Sí
¿Está quemada la ampolleta?
Sí
Cambiar la ampolleta
No Comprar nueva lámpara Diagrama de flujo sencillo con los pasos a seguir si una lámpara no funciona.
El diagrama de flujo o diagrama de actividades es la representación gráfica del algoritmo o proceso. Se utiliza en disciplinas como programación, economía, procesos industriales y psicología cognitiva. En Lenguaje Unificado de Modelado (UML), un diagrama de actividades representa los flujos de trabajo paso a paso de negocio y operacionales de los componentes en un sistema. Un diagrama de actividades muestra el flujo de control general. En SysML el diagrama ha sido extendido para indicar flujos entre pasos que mueven elementos físicos (p. ej., ga- Diagrama de actividades para un loop a(bucle solina) o energía (p. ej., presión). Los cambios adicionales permiten al diagrama soportar mejor flujos de comportamiento y datos continuos. Estos diagramas utilizan símbolos con significados defini- tan el flujo de ejecución mediante flechas que conectan dos que representan los pasos del algoritmo, y represen- los puntos de inicio y de fin del proceso. 110
58.3. TIPOS DE DIAGRAMAS DE FLUJO
111
58.1 Normas de trabajo
es una forma especial de diagrama de estado usado para modelar una secuencia de acciones y condiciones tomaUn diagrama de flujo presenta generalmente un único das dentro de un proceso. punto de inicio y un único punto de cierre, aunque puede La especificación del Lenguaje de Notificación Unificado tener más, siempre que cumpla con la lógica requerida. (UNL) define un diagrama de actividad como: Las siguientes son acciones previas a la realización del “…una variación de los estados de una máquina, los cuales diagrama de flujo: representan el rendimiento de las acciones o subactividades y las transiciones se provocan por la realización de las * • Identificar las ideas principales al ser incluidas en el acciones o subactividades.” [1] diagrama de flujo. Deben estar presentes el autor o El propósito del diagrama de actividad es modelar un proresponsable del proceso, los autores o responsables ceso de flujo de trabajo (workflow) y/o modelar operaciodel proceso anterior y posterior y de otros proce- nes. sos interrelacionados, así como las terceras partes Una Operación es un servicio proporcionado por un obinteresadas. jeto, que está disponible a través de una interfaz. • Definir qué se espera obtener del diagrama de flujo. Una Interfaz es un grupo de operaciones relacionadas con la semántica. • Identificar quién lo empleará y cómo. • Establecer el nivel de detalle requerido. • Determinar los límites del proceso a describir. Los pasos a seguir para construir el diagrama de flujo son: • Establecer el alcance del proceso a describir. De esta manera quedará fijado el comienzo y el final del diagrama. Frecuentemente el comienzo es la salida del proceso previo y el final la entrada al proceso siguiente. • Identificar y listar las principales actividades/subprocesos que están incluidos en el proceso a describir y su orden cronológico. • Si el nivel de detalle definido incluye actividades menores, listarlas también. • Identificar y listar los puntos de decisión. • Construir el diagrama respetando la secuencia cronológica y asignando los correspondientes símbolos. • Asignar un título al diagrama y verificar que esté completo y describa con exactitud el proceso elegido.
58.3 Tipos de diagramas de flujo • Formato vertical: En él, el flujo y la secuencia de las operaciones, va de arriba hacia abajo. Es una lista ordenada de las operaciones de un proceso con toda la información que se considere necesaria, según su propósito. • Formato horizontal: En él, el flujo o la secuencia de las operaciones, va de izquierda a derecha. • Formato panorámico: El proceso entero está representado en una sola carta y puede apreciarse de una sola mirada mucho más rápido que leyendo el texto, lo que facilita su comprensión, aun para personas no familiarizadas. Registra no solo en línea vertical, sino también horizontal, distintas acciones simultáneas y la participación de más de un puesto o departamento que el formato vertical no registra. • Formato Arquitectónico: Describe el itinerario de ruta de una forma o persona sobre el plano arquitectónico del área de trabajo. El primero de los flujogramas es eminentemente descriptivo, mientras que los utilizados son fundamentalmente representativos.
58.2 Descripción En UML 1.x, un diagrama de actividades es una variación del diagrama de estado UNL donde los “estados”representan operaciones, y las transiciones representan las actividades que ocurren cuando la operación se completa. El diagrama de mensajes de UML 2.0, mientras que es similar en aspecto al diagrama de actividades UML 1.x, ahora tiene semánticas basadas en redes de Petri. En UML 2.0, el diagrama general de interacción está basado en el diagrama de actividades. El diagrama de actividad
58.4 Simbología y significado • Óvalo o Elipse: Inicio y Final (Abre y cierra el diagrama). • Rectángulo: Actividad (Representa la ejecución de una o más actividades o procedimientos). • Rombo: Decisión (Formula una pregunta o cuestión).
112 • Círculo: Conector (Representa el enlace de actividades con otra dentro de un procedimiento).
CAPÍTULO 58. DIAGRAMA DE FLUJO
58.6 Historia
• Triángulo boca abajo: Archivo definitivo (Guarda un documento en forma permanente). • Triángulo boca arriba: Archivo temporal (Proporciona un tiempo para el almacenamiento del docuLa paternidad del diagrama de flujo es en principio algo mento). difusa. El método estructurado para documentar gráficamente un proceso como un flujo de pasos sucesivo y alternativos, el“proceso de diagrama de flujo”, fue expuesto 58.5 Cursograma por Frank Gilbreth, en la Sociedad Americana de Ingenieros Mecánicos (ASME), en 1921, bajo el enunciado Se trata de la más común y práctica entre todas las clases de “Proceso de Gráficas-Primeros pasos para encontrar de diagramas de flujo. Describe el flujo de información el mejor modo”. Estas herramientas de Gilbreth rápidaen un ente u organización, sus procesos, sistemas admi- mente encontraron sitio en los programas de ingeniería nistrativos y de control. Permite la impresión visual de los industrial. procedimientos y una clara y lógica interpretación. Al principio de los 30, un ingeniero industrial, Allan H. Mogensen comenzó la formación de personas de nego58.5.1 Simbología y normas del cursogra- cios en Lake Placid, Nueva York, incluyendo el uso del diagrama de flujo. Art Spinanger, asistente a las clases de ma Mogesen, utilizó las herramientas en su trabajo en Procter & Gamble, donde desarrolló su“Programa Metódico • Círculo: Procedimiento estandarizado. de Cambios por Etapas”. Otro asistente al grupo de gra• Cuadrado: Proceso de control. duados en 1944, Ben S. Graham, director de ingeniería • Línea continua: Flujo de información vía formula- de Formcraft Standard Register Corporation, adaptó la gráfica de flujo de procesos al tratamiento de la informario o documentación en soporte de papel escrito. ción en su empresa. Y desarrolló la gráfica del proceso • Línea interrumpida: Flujo de información vía for- de múltiples flujos en múltiples pantallas, documentos, y mulario digital. sus relaciones. En 1947, ASME adoptó un conjunto de símbolos derivados de la obra original de Gilbreth como • Rectángulo: Formulario o documentación. Se graNorma ASME para los gráficos de procesos (preparada fíca con el doble de ancho que su altura. Mishad, Ramsan y Raiaan). • Rectángulo Pequeño: Valor o medio de pago (che- Sin embargo, según explica Douglas Hartree fueron orique, pagaré, etc.). Se grafíca con el cuádruple de an- ginalmente Herman Goldstine y John von Neumann quiecho que su altura, siendo su ancho igual al de los for- nes desarrollaron el diagrama de flujo (inicialmente llamularios. mado“diagrama”) para planificar los programas de ordenador. Las tablas de programación original de flujo de Goldstine y von Neumann, aparecen en un informe no pu• Triángulo Invertido (base superior): Archivo blicado, “Planificación y codificación de los problemas Transitorio. de un instrumento de computación electrónica, la Parte II, Volumen 1 "(1947), reproducido en las obras comple• Semióvalo: Demora. tas de von Neumann. • Rombo: División entre opciones. Inicialmente los diagramas de flujo resultaron un medio popular para describir algoritmos de computadora, y aún • Trapezoide: Carga de datos al sistema. se utilizan con este fin. Herramientas como los diagra• Elipsoide: Acceso por pantalla. mas de actividad UML, pueden ser considerados como evoluciones del diagrama de flujo. • Hexágono: Proceso no representado. En la década de 1970 la popularidad de los diagramas de • Pentágono: Conector. flujo como método propio de la informática disminuyó, • Cruz de Diagonales: Destrucción de Formularios. con el nuevo hardware y los nuevos lenguajes de programación de tercera generación. Y por otra parte se conSegún la normativa, el flujo presupuesto es de izquierda virtieron en instrumentos comunes en el mundo emprea derecha y de arriba hacia abajo, siendo optativo el uso sarial. Son una expresión concisa, legible y práctica de de flechas. Cuando el sentido es invertido (de derecha a algoritmos. Actualmente se aplican en muchos campos izquierda o de abajo hacia arriba), es obligatorio el uso de del conocimiento, especialmente como simplificación y la flecha. expresión lógica de procesos, etc. • Triángulo (base inferior): Archivo definitivo.
58.9. VÉASE TAMBIÉN
113
58.7 Ventajas de los diagramas de 58.9 Véase también flujo 58.10 Referencias • Favorecen la comprensión del proceso al mostrarlo como un dibujo. El cerebro humano reconoce muy fácilmente los dibujos. Un buen diagrama de flujo reemplaza varias páginas de texto. • Permiten identificar los problemas y las oportunidades de mejora del proceso. Se identifican los pasos, los flujos de los reprocesos, los conflictos de autoridad, las responsabilidades, los cuellos de botella, y los puntos de decisión. • Muestran las interfaces cliente-proveedor y las transacciones que en ellas se realizan, facilitando a los empleados el análisis de las mismas. • Son una excelente herramienta para capacitar a los nuevos empleados y también a los que desarrollan la tarea, cuando se realizan mejoras en el proceso. • Al igual que el pseudocódigo, el diagrama de flujo con fines de análisis de algoritmos de programación puede ser ejecutado en un ordenador, con un IDE como Free DFD.
58.8 Software para diseño de diagramas de flujo Actualmente existe una gran cantidad de software para la elaboración de diagramas de flujo. A continuación se listan los programas más comunes para elaborar diagramas de flujo. • Microsoft Office ofrece 3 herramientas útiles para la elaboración de diagramas. Uno de ellos es Microsoft Office Word, que nos permite crear diagramas de flujo básicos a través de la opción“Formas”que tiene un apartado especial para diagramas de flujo. De igual manera Microsoft Office Power Point ofrece las mismas opciones para crear los diseños de diagramas de flujo. Otra herramienta un poco más sofisticada es Microsoft Office Visio, que además de la simbología básica de los diagramas de flujo cuenta con una variedad de herramientas para elaborar otros tipos de diagramas como es el caso diagramas UML entre otros tipos de diagramas de flujo. • Otro programa eficiente y muy fácil de usar es el programa “Dia”que brinda una solución rápida para la creación de diagramas de flujo además de otro tipo de diagramas usados en el ambiente informático. Es considerado la versión no comercial de Microsoft Visio.
[1] Bellows, Jeannie, Castek (2000). Activity Diagrams and Operation Architecture. Technologies Group Inc.
58.11 Enlaces externos •
Wikimedia Commons alberga contenido multimedia sobre Diagrama de flujoCommons.
•
Wikimedia Commons alberga contenido multimedia sobre diagrama de actividadesCommons.
• Documentos de la Especificación UML 2.0 • Introducción a los Diagramas de Actividades UML 2 • Microsoft Office Visio Tutorial • PSeInt herramienta para asistir a un estudiante en sus primeros pasos en programación.
Capítulo 59
Diagrama Nassi-Shneiderman En programación de computadores un diagrama NassiShneiderman (o NSD por sus siglas en inglés), también conocido como diagrama de Chapin* [1]* [2] es una representación gráfica que muestra el diseño de un programa estructurado.
do lo que se puede representar con un diagrama NassiShneiderman se puede representar con un diagrama de flujo. Las únicas excepciones se dan en las instrucciones GOTO, break y continue.
59.2 Referencias [1] Molina Marco, A.; Letelier Torres, P.; Sánchez Palma, P.; Sánchez Díaz, J. (1997). «Métodos para especificación de módulos». Metodología y tecnología de la programación. Valencia: Universidad Politécnica de Valencia. p. 50. ISBN 8477215197. Consultado el 26 de agosto de 2013. [2] Eslava Muñoz, V.J. (2012). «Diseño de algoritmos». Aprendiendo a programar paso a paso con C. Bubok Publishing. p. 42. ISBN 9788468610610. Consultado el 26 de agosto de 2013.
Ejemplo de un diagrama Nassi-Shneiderman.
Fue desarrollado en 1972 por Isaac Nassi y Ben Shneiderman. Este diagrama también es conocido como estructograma, ya que sirve para representar la estructura de los programas. Combina la descripción textual del pseudocódigo con la representación gráfica del diagrama de flujo.
59.1 Descripción
• Nassi, I.; Shneiderman, B.: Técnicas de diagramas de flujo para programación estructurada, SIGPLAN Notices XII, Agosto 1973.
59.3 Enlaces externos
• Wikimedia Commons alberga contenido mulBasado en un diseño top-down (de lo complejo a lo simtimedia sobre Diagrama Nassi-Shneiderman. ple), el problema que se debe resolver se divide en subCommons problemas cada vez más pequeños - y simples - hasta que solo queden instrucciones simples y construcciones para • A short history of structured flowcharts (Nassiel control de flujo. El diagrama Nassi-Shneiderman reShneiderman Diagrams), por Ben Shneiderman fleja la descomposición del problema en una forma simple usando cajas anidadas para representar cada uno de los subproblemas. Para mantener una consistencia con los 59.3.1 Software fundamentos de la programación estructurada, los diagramas Nassi-Shneiderman no tienen representación para las • Structorizer – Editor de diagramas Nassiinstrucciones GOTO. Shneiderman para Linux, Mac OS X & Microsoft Windows, distribuido bajo GNU General Public Los diagramas Nassi-Shneiderman se utilizan muy raraLicense mente en las tareas de programación formal. Su nivel de abstracción es muy cercano al código de la programación • Nessi – Editor e intérprete de diagramas Nassiestructurada y ciertas modificaciones requieren que se reShneiderman, multiplataforma (Java), distribuido dibuje todo el diagrama. bajo GNU General Public License Los diagramas Nassi-Shneiderman son (la mayoría de las veces) isomórficos con los diagramas de flujo. To114
Capítulo 60
diff En informática, diff es una utilidad para la comparación de archivos que genera las diferencias entre dos archivos o los cambios realizados en un archivo determinado comparándolo con una versión anterior del mismo archivo. Diff expone los cambios realizados por línea en los archivos de texto. Las implementaciones modernas también soportan archivos binarios.* [1] El resultado se conoce como diff o patch ya que el mismo puede ser aplicado con el programa Unix patch. El resultado de la comparación de un archivo similar también se llama “diff”. De la misma manera que se usa la palabra "grep" para describir la acción de buscar, la palabra diff se usa en la jerga como un verbo que se refiere al cálculo de cualquier diferencia. Un ejemplo de diff.
60.1 Historia La utilidad diff fue desarrollada a comienzos de los años setenta en el sistema operativo Unix que estaba creándose en AT&T Bell Labs en Murray Hill, Nueva Jersey. La versión final, que apareció por primera vez con la 5ª edición de Unix en 1974, fue toda ella escrita por Douglas McIlroy. Este trabajo fue publicado en un artículo de 1976 co-escrito con James W. Hunt que desarrolló un prototipo inicial de diff.* [2] El trabajo de McIlroy fue precedido e influido por el programa comparison de Steve Johnson en GECOS y por el programa proof de Mike Lesk también originado en Unix y, como diff, producía cambios línea a línea e incluso utilizaba paréntesis angulares (">" y "<") para presentar las inserciones y borrados de línea en el resultado del programa. Las heurísticas utilizadas en estas primeras aplicaciones fueron, sin embargo, juzgadas como no fiables. La utilidad potencial de la herramienta diff provocó que McIlroy acometiese la investigación y diseño de una herramienta más robusta que podía usarse en una gran variedad de tareas pero que al tiempo se condujese bien en los procesos y con las limitaciones de tamaño del hardware de PDP-11. Su análisis del problema lo llevó a cabo con la colaboración de distintas personas de Bell Labs como Alfred Aho, Elliot Pinson, Jeffrey Ullman y Harold S. Stone.
veía diff con la habilidad natural para crear órdenes de edición útiles. Estas órdenes de edición, cuando se grababan en un archivo, podían, junto con el archivo original, ser reconstituidas completamente por ed en el archivo modificado. Esto reducía enormemente el necesario almacenamiento secundario para mantener las distintas versiones de un archivo. McIlroy consideró escribir un post-procesador para diff donde una variedad de formatos de resultados pudiesen ser diseñados e implementados, pero encontró que era más frugal y sencillo hacer que diff fuese el responsable de generar la sintaxis y la información de entrada de orden contrario aceptada por el comando ed. En 1985, Larry Wall compuso una utilidad separada, patch, que generalizó y extendió la habilidad para modificar archivos con resultado diff. Los modos de Emacs permiten también convertir el formato de patches e incluso editar patches interactivamente. En los primeros años de diff, los usos habituales eran la comparación de cambios en la fuente del código del software y el marcado de documentos técnicos, la verificación de la salida de errores de programa, la comparación de listados de sistemas de archivos y el análisis del código del montaje del ordenador. La salida apuntada por ed fue modificada para proporcionar compresión a una secuencia de modificaciones hecha a un archivo. La Source Code Control System (SCCS) y su habilidad para archivar revisiones apareció a finales de los años setenta como consecuencia de almacenar órdenes de edición de diff. El Project Xanadu es un predecesor conceptual de diff. Era un proyecto de hipertexto concebido por primera vez en 1960 que debía incluir una versión de un sistema de seguimiento necesario para su característica de“transpointing windows”. La característica subsumía las diferencias de archivos en el término expansivo "transclusión", en el que un documento incluía en él partes de otros documentos o revisiones.
60.2 Algoritmo La operación de diff se basa en resolver el problema Problema de Subsecuencia Común mas Larga (LCS).
En el contexto de Unix, el uso del editor de línea ed pro- En el problema LCS, se tienen dos secuencias de ítems: 115
116 abcdfghjqzabcdefgijkrxyz
CAPÍTULO 60. DIFF
60.4 Variantes
y se desea encontrar la secuencia más larga de ítems que se presenta las dos secuencias originales en el mismo orden. Esto es, se quiere encontrar una nueva secuencia que pueda obtenerse de la primera secuencia eliminando algunos ítems, y de la segunda secuencia eliminando otros ítems. Se quiere también que esta secuencia sea tan larga como sea posible. En este caso es:
La mayoría de las implementaciones de diff se han mantenido aparentemente sin cambios desde 1975. Las modificaciones consisten en mejoras en el algoritmo base, la adición de características útiles al comando y el diseño de un nuevos formatos de salida. El algoritmo básico se describe en el artículo An O(ND) Difference Algorithm and its Variations de Eugene W. Myers* [4] y en A File abcdfgjz Comparison Program de Webb Miller and Myers.* [5] El De la subsecuencia común más larga solo hay un pequeño algoritmo fue descubierto independientemente y descripaso para conseguir un resultado del tipo de diff: to en Algorithms for Approximate String Matching, de E. Ukkonen.* [6] Las primeras ediciones del programa diff ehiqkrxy+-+-++++ fueron diseñadas para la comparación de líneas de archivos de texto dejando que el carácter newline delimitase las líneas. En los años ochenta, la ayuda para los archivos binarios dio lugar a un cambio en el diseño y la implementación de la aplicación.
60.3 Uso Es invocado desde la línea de comando con los nombres de dos archivos: diff original new. El resultado del comando representa los cambios requeridos para hacer que el archivo original se convierta en el nuevo archivo.
60.4.1 Edit script Un edit script puede generarse por medio de versiones modernas de diff con la opción -e. option. El edit script resultante para el ejemplo anterior es el siguiente:
24a Este párrafo contiene importantes nuevas adiciones a este documento. . 17c detenidamente este documento. Si original y nuevo son directorios, entonces diff se ejecu- Por . 8,14c comprimir nada. . 0a Esta es una importante tará sobre cada archivo que exista en ambos directorios. noticia! Debería por lo tanto ser situada al comienzo de Una opción, -r, hará que cualesquiera subdirectorios em- este documento! . parejados comparen archivos entre directorios. Todos los ejemplos en el artículo usan los archivos original y nuevo: El comando diff original nuevo produce el siguiente resultado diff normal: 0a1,6 > Esta es una importante > noticia. ¡Debería > por lo tanto situarse al > comienzo de este > documento! > 8,14c14 < comprimir el tamaño de los < cambios. < < Este párrafo contiene < texto que está anticuado. < Será borrado en < breve. --- > comprimir nada. 17c17 < deternidamente este documento. Por --- > detenidamente este documento. Por 24a25,28 > > Este párrafo contiene > importantes nuevas adiciones > a este documento.
En este formato de salida tradicional, a sustituye a añadido, d a borrado (deleted) y c a cambiado. Los números de línea del archivo original aparecen antes de a/d/c y los del archivo modificado después. Los paréntesis angulares aparecen al comienzo de las líneas que son añadidas, borradas o cambiadas. Las líneas añadidas se incluyen en el archivo original para aparecer en el archivo nuevo. Las líneas borradas se eliminan del archivo original para ser borradas en el archivo nuevo. Por defecto, las líneas comunes a los dos archivos no se muestran. Las líneas que se han movido se muestran como añadidas en su nuevo lugar y como borradas en su antiguo lugar.* [3]
60.5 Referencias [1] MacKenzie et al. “Binary Files and Forcing Text Comparison”in Comparing and Merging Files with GNU Diff and Patch. Descargado el 28 de abril de 2007. [2] James W. Hunt and M. Douglas McIlroy (June 1976). «An Algorithm for Differential File Comparison». Computing Science Technical Report, Bell Laboratories 41. [3] David MacKenzie, Paul Eggert, and Richard Stallman (1997). Comparing and Merging Files with GNU Diff and Patch. ISBN 0-9541617-5-0. [4] E. Myers (1986). «An O(ND) Difference Algorithm and Its Variations». Algorithmica 1 (2): 251–266. [5] Webb Miller and Eugene W. Myers (1985). «A File Comparison Program». Software ̶Practice and Experience 15 (11): 1025–1040. doi:10.1002/spe.4380151102. [6] E. Ukkonen (1985). «Algorithms for Approximate String Matching». Information and Control 64: 100–118. doi:10.1016/S0019-9958(85)80046-2.
60.6 Véase también • Distancia de Levenshtein
60.7. ENLACES EXTERNOS
60.7 Enlaces externos • Sitio oficial (en inglés)
117
Capítulo 61
Dirección de retorno Dirección de retorno es un término de programación informática con el que se refiere a un dato almacenado dentro de la pila, dato que le indica al programa en qué línea situarse luego de finalizar una función.
118
Capítulo 62
Diseño estructurado En programación y diseño de algoritmos, el diseño estructurado persigue elaborar algoritmos que cumplan la propiedad de modularidad, para ello, dado un problema que se pretende resolver mediante la elaboración de un programa de ordenador, se busca dividir dicho programa en módulos siguiendo los principios de diseño de Descomposición por refinamientos sucesivos, creación de una Jerarquía modular y elaboración de módulos Independientes.
Ciencias de la Computación Niklaus Wirth, que consiste precisamente en volver a aplicar el estudio descendente Top-Down a cada subproblema una y otra vez hasta obtener subproblemas suficientemente pequeños, que puedan ser resueltos por módulos que cumplan, en la medida de lo posible, las características deseables en un módulo en el ámbito de la programación. En palabras del propio Niklaus Wirth: • En cada paso (del refinamiento), una o varias instrucciones del programa dado, se descomponen en instrucciones más detalladas. Esta descomposición sucesiva o refinamiento de especificaciones termina cuanto todas las instrucciones están expresadas en términos de la computadora usada o del lenguaje de programación...
62.1 Etapas del Diseño estructurado 62.1.1
Descomposición
• Conforme se refinan las tareas, también los datos pueden ser refinados, descompuestos o estructurados, siendo lo natural refinar las especificaciones del programa y de los datos en paralelo.
Para ello se requiere un adecuado análisis de dicho problema, siendo necesario definir primeramente el problema, para lo cual deberá de contener una detallada pero concisa descripción del mismo, un problema bien definido es aquel que lleva implícitas tanto una situación inicial como final claras
• Cada paso de refinamiento implica algunas decisiones de diseño. Es importante que el programador sea consciente de los criterios subyacentes (en las decisiones de diseño adoptadas) y de la existencia de soluciones alternativas...
¿Por qué descomponer un problema en partes? Experimentalmente está comprobado que:
• Un problema complejo cuesta más de resolver que Problema del refinamiento sucesivo otro más sencillo (de Perogrullo). • La complejidad de un problema global es mayor que ¿Cuándo parar el refinamiento?. Un refinamiento excesiel valor de las complejidades de cada una de sus par- vo podría dar lugar a un número tan grande de módulos que haría poco práctica la descomposición. Se tendrán en tes por separado. cuenta estos criterios para dejar de descomponer: Según esto, merece la pena el esfuerzo de dividir un problema grande en subproblemas más pequeños. Si el objetivo es elaborar un programa para resolver dicho problema grande, cada subproblema (menos complejo) podrá ser resuelto por un módulo (subalgoritmo) relativamente fácil de implementar (más que el programa global No dividido). Ahora la cuestión es ¿cómo realizar la descomposición?; realizando un estudio descendente Top-Down que nos lleve desde la concepción del problema (programa o algoritmo) global hasta identificar sus partes (módulos). Esta técnica se repite aplicando una estrategia llamada de refinamiento sucesivo propuesta por el experto en
• Cuando no haya tareas bien definidas. • Cuando la interfaz de un módulo sea tan complicada como el propio módulo
62.1.2 Jerarquía de módulos Ésta es una consecuencia directa de la descomposición del problema mediante refinamientos sucesivos, el resultado será un conjunto de módulos estratificados en capas a modo de pirámide donde en la cima habrá un único
119
120
CAPÍTULO 62. DISEÑO ESTRUCTURADO
módulo que representará al programa global y en los niveles inferiores aparecerán los módulos resultantes de las sucesivas divisiones. Al final, debe obtenerse una estructura piramidal donde los módulos de los niveles superiores se encargan de las tareas de coordinación, lógica de la aplicación y manipulación de los módulos inferiores; estos otros deberán realizar tareas de cálculo, tratamiento y entrada/salida de información.
62.1.3
Independencia
• Acoplamiento Común.- Dos módulos acceden a un mismo recurso común, típicamente memoria compartida, una variable global o un fichero. Una variante de este tipo de acoplamiento es el acoplamiento externo: • Acoplamiento externo.- Los módulos están ligados a componentes externos. Por ejemplo, dispositivos de E/S, protocolos de comunicaciones... etc. • Acoplamiento de contenido.- Ocurre cuando un módulo necesita acceder a una parte de otro módulo.
Ver 'Independencia en Características de un módulo.
62.2.2 Cohesión Se define como la medida de fuerza o relación funcional existente entre las sentencias o grupos de sentencias de un mismo módulo. Un módulo cohesionado Para evaluar o determinar cómo es de bueno un diseño ejecutará una única tarea sencilla interactuando muy poco estructurado se utilizan los conceptos de acoplamiento o nada con el resto de módulos del programa. Se persigue y cohesión; éstos están muy relacionados entre sí, tanto que los módulos tengan una alta cohesión. que difícilmente se puede variar uno sin que eso afecte al otro. También cabe decir que estos conceptos no son En el diseño estructurado podemos encontrarnos con los medidas que se puedan cuantificar numéricamente, son siguientes 7 tipos de cohesión (de la mejor o más deseable más bien magnitudes cualitativas. También se tienen en a la menos recomendable): consideración los conceptos de fan-in y fan-out. • Cohesión funcional: Los elementos del módulo están relacionados en el desarrollo de una única fun62.2.1 Acoplamiento ción.
62.2 Evaluando el diseño
Se define como el grado de interdependencia que hay entre los distintos módulos de un programa; lo deseable es que esta interdependencia sea lo menor posible, es decir, un bajo acoplamiento. Los niveles de acoplamiento, ordenados de menor (más deseable) a mayor (menos deseable) son: • Acoplamiento normal.- Un módulo llama a otro de un nivel inferior y tan solo intercambian datos (parámetros de entrada/salida). Dentro de este tipo de acoplamiento podemos encontrarnos 3 subtipos, dependiendo de los datos que intercambien los módulos: • Acoplamiento de datos: Los módulos se comunican mediante parámetros. • Acoplamiento de marca o por estampado: Los módulos se pasan datos con estructura de registro. No es muy deseable si el módulo receptor sólo requiere parte de los datos que se le pasan. • Acoplamiento de control: Los datos que se intercambian entre los módulos son controles. Debido a que en este subtipo un módulo controla la ejecución del otro, no es un buen acoplamiento, ya que impide que sean totalmente independientes.
• Cohesión secuencial: Un módulo realiza distintas tareas en secuencia, de forma que las entradas de cada tarea son las salidas de la tarea anterior. No es una mala cohesión si las tareas implicadas no son muy complejas y requieren pocas líneas de código. • Cohesión comunicacional: El módulo realiza actividades paralelas usando los mismos datos de entrada y salida. Como en el caso anterior, tampoco se trata de un mal tipo de cohesión si las tareas son relativamente sencillas. • Cohesión procedimental: El módulo tiene una serie de funciones relacionadas por un procedimiento efectuado por el código (a modo de biblioteca). Es similar a la secuencial, pero puede incluir el paso de controles. Será deseable que las funciones estén relacionadas o realicen tareas dentro del mismo ámbito (p.e. la biblioteca string.h de C contienen funciones para operar con cadenas de caracteres). • Cohesión temporal: Los elementos del módulo están implicados en actividades relacionadas con el tiempo. • Cohesión lógica: Las actividades que realiza el módulo tienen la misma categoría. Esto es, es como si se tuvieran partes independientes dentro del mismo módulo.
62.3. VÉASE TAMBIÉN • Cohesión casual o coincidente: Los elementos del módulo contribuyen a las actividades relacionándose mutuamente de una manera poco significativa. Este tipo de cohesión viola el principio de independencia y de caja negra de los módulos.
62.2.3
Fan-In y Fan-Out
Además de los dos conceptos anteriores, se deben tener en cuenta el grado de absorción (fan-in) y la diseminación del control (fan-out) de los módulos para garantizar la calidad del diseño. • Fan-In: También llamado grado de absorción. Es el número de superordinados inmediatos que tiene el módulo en cuestión. Es conveniente maximizar el fan-in durante el proceso de diseño, ya que cada instancia de fan-in múltiple indica que se ha evitado la duplicación de código. • Fan-Out: También llamado diseminación del control. Es el número de subordinados inmediatos que tiene el módulo en cuestión. Conviene no tener un fan-out ni muy alto ni muy bajo, ya que eso es un posible indicador de un diseño pobre. Si no es posible evitarlo, es preferible un fan-out bajo antes que uno alto.
62.3 Véase también • Diseño orientado a objetos • Programación estructurada • Programación modular • Dinámica de sistemas • Sistema complejo • Sistema dinámico • Encapsulamiento (programación orientada a objetos) • Abstracción (programación orientada a objetos)
121
Capítulo 63
Distancia de Damerau-Levenshtein En la teoría de la información y en la ciencia de computadores, se llama distancia de Damerau-Levenshtein o distancia de edición al número mínimo de operaciones requeridas para transformar una cadena de caracteres en otra. Se entiende por operación, bien una inserción, eliminación, sustitución o transposición de dos caracteres. Lo que la distingue de la distancia de Levenshtein es que esta última cuenta como una sola operación de edición a cualquiera de las tres primeras, pero cuenta la transposición como dos operaciones de edición.
63.1 Véase también • Ispell
63.2 Enlaces externos • Implementación en C++ de la distancia de Damerau-Levenshtein como UDF para MySQL
63.3 Referencias
122
Capítulo 64
Distancia de Levenshtein La distancia de Levenshtein, distancia de edición o distancia entre palabras es el número mínimo de operaciones requeridas para transformar una cadena de caracteres en otra, se usa ampliamente en teoría de la información y ciencias de la computación. Se entiende por operación, bien una inserción, eliminación o la sustitución de un carácter. Esta distancia recibe ese nombre en honor al científico ruso Vladimir Levenshtein, quien se ocupó de esta distancia en 1965. Es útil en programas que determinan cuán similares son dos cadenas de caracteres, como es el caso de los correctores de ortografía.
lenStr2+1 columns declare int d[0..lenStr1, 0..lenStr2] // i and j are used to iterate over str1 and str2 declare int i, j, cost for i from 0 to lenStr1 d[i, 0] := i for j from 0 to lenStr2 d[0, j] := j for i from 1 to lenStr1 for j from 1 to lenStr2 if str1[i] = str2[j] then cost := 0 else cost := 1 d[i, j] := minimum( d[i-1, j] + 1, // deletion d[i, j-1] + 1, // insertion d[i-1, j-1] + cost // substitution ) return d[lenStr1, lenStr2]
El invariante mantenido a través del algorítmo es que pueda transformar el segmento inicial str1[1..i] en str2[1..j] empleando un mínimo de d[i,j] operaciones. Al final, el Por ejemplo, la distancia de Levenshtein entre “casa”y elemento ubicado en la parte INFERIOR derecha de la “calle”es de 3 porque se necesitan al menos tres ediciones matriz contiene la respuesta. elementales para cambiar uno en el otro. 1. casa → cala (sustitución de 's' por 'l')
64.2 Implementación
2. cala → calla (inserción de 'l' entre 'l' y 'a') A continuación se puede ver la implementación de la función para varios lenguajes de programación. Otros lenSe le considera una generalización de la distancia de guajes de más alto nível, como php o la funciones de Hamming, que se usa para cadenas de la misma longitud usuario de MySQL, las incorporan ya, sin necesidad de y que solo considera como operación la sustitución. Hay implementarla para ser usada. otras generalizaciones de la distancia de Levenshtein, como la distancia de Damerau-Levenshtein, que consideran el intercambio de dos caracteres como una operación. 64.2.1 C 3. calla → calle (sustitución de 'a' por 'e')
Como buena“distancia”, cumple (aunque es complicado int Levenshtein(char *s1,char *s2) { int demostrarlo formalmente), que: t1,t2,i,j,*m,costo,res,ancho; // Calcula tamanios Dist(A,B) == Dist(B,A) strings t1=strlen(s1); t2=strlen(s2); // Verifica que exista algo que comparar if (t1==0) reDist(A,B) + Dist(B,C) >= Dist(A,C) turn(t2); if (t2==0) return(t1); ancho=t1+1; // Reserva matriz con malloc m[i,j] = m[j*ancho+i] !! m=(int*)malloc(sizeof(int)*(t1+1)*(t2+1)); if 64.1 El algoritmo (m==NULL) return(−1); // ERROR!! // Rellena primera fila y primera columna for (i=0;i<=t1;i++) m[i]=i; Se trata de un algoritmo de tipo bottom-up, común en for (j=0;j<=t2;j++) m[j*ancho]=j; // Recorremos resto programación dinámica. Se apoya en el uso de una ma- de la matriz llenando pesos for (i=1;i<=t1;i++) for triz (n + 1) × (m + 1), donde n y m son las longitudes de (j=1;j<=t2;j++) { if (s1[i-1]==s2[j-1]) costo=0; else las cadenas. Aquí se indica el algoritmo en pseudocódigo costo=1; m[j*ancho+i]=Minimo(Minimo(m[j*ancho+ipara una función LevenshteinDistance que toma dos ca- 1]+1, // Eliminacion m[(j-1)*ancho+i]+1), // Insercion denas, str1 de longitud lenStr1, y str2 de longitud lenStr2, m[(j-1)*ancho+i-1]+costo); } // Sustitucion // Devoly calcula la distancia Levenshtein entre ellos: vemos esquina final de la matriz res=m[t2*ancho+t1]; int LevenshteinDistance(char str1[1..lenStr1], char free(m); return(res); } str2[1..lenStr2]) // d is a table with lenStr1+1 rows and 123
124
64.2.2
CAPÍTULO 64. DISTANCIA DE LEVENSHTEIN
C++
#include #include #include using namespace std; int levenshtein(const string &s1, const string &s2) { int N1 = s1.size(); int N2 = s2.size(); int i, j; vector T(N2+1); for ( i = 0; i <= N2; i++ ) T[i] = i; for ( i = 0; i < N1; i++ ) { T[0] = i+1; int corner = i; for ( j = 0; j < N2; j++ ) { int upper = T[j+1]; if ( s1[i] == s2[j] ) T[j+1] = corner; else T[j+1] = min(T[j], min(upper, corner)) + 1; corner = upper; } } return T[N2]; }
64.2.5 Perl
sub fastdistance { my $word1 = shift; my $word2 = shift; return 0 if $word1 eq $word2; my @d; my $len1 = length $word1; my $len2 = length $word2; $d[0][0] = 0; for (1.. $len1) { $d[$_][0] = $_; return $_ if $_!=$len1 && substr($word1,$_) eq substr($word2,$_); } for (1.. $len2) { $d[0][$_] = $_; return $_ if $_!=$len2 && substr($word1,$_) eq substr($word2,$_); } for my $i (1.. $len1) { my $w1 = substr($word1,$i-1,1); for (1.. $len2) { $d[$i][$_] = _min($d[$i-1][$_]+1, $d[$i][$_1]+1, $d[$i-1][$_-1]+($w1 eq substr($word2,$_-1,1) ? 0 64.2.3 C# : 1)); } } return $d[$len1][$len2]; } sub _min { return public int LevenshteinDistance(string s, string t, out $_[0] < $_[1] ? $_[0] < $_[2] ? $_[0] : $_[2] : $_[1] < double porcentaje) { porcentaje = 0; // d es una tabla $_[2] ? $_[1] : $_[2]; } con m+1 renglones y n+1 columnas int costo = 0; int m = s.Length; int n = t.Length; int[,] d = new int[m + 1, n + 1]; // Verifica que exista algo que comparar if (n == 64.2.6 Python 0) return m; if (m == 0) return n; // Llena la primera columna y la primera fila. for (int i = 0; i <= m; d[i, 0] = def distance(str1, str2): d=dict() for i in rani++) ; for (int j = 0; j <= n; d[0, j] = j++) ; /// recorre la ge(len(str1)+1): d[i]=dict() d[i][0]=i for i in ranmatriz llenando cada unos de los pesos. /// i columnas, ge(len(str2)+1): d[0][i] = i for i in range(1, len(str1)+1): j renglones for (int i = 1; i <= m; i++) { // recorre for j in range(1, len(str2)+1): d[i][j] = min(d[i][j-1]+1, para j for (int j = 1; j <= n; j++) { /// si son iguales en d[i-1][j]+1, d[i-1][j-1]+(not str1[i-1] == str2[j-1])) posiciones equidistantes el peso es 0 /// de lo contrario el return d[len(str1)][len(str2)] peso suma a uno. costo = (s[i - 1] == t[j - 1]) ? 0 : 1; d[i, j] = System.Math.Min(System.Math.Min(d[i - 1, j] + 1, //Eliminacion d[i, j - 1] + 1), //Inserccion d[i - 1, j - 1] 64.2.7 Ruby + costo); //Sustitucion } } /// Calculamos el porcentaje de cambios en la palabra. if (s.Length > t.Length) class String def levenshtein(other) other = other.to_s disporcentaje = ((double)d[m, n] / (double)s.Length); tance = Array.new(self.size + 1, 0) (0..self.size).each do else porcentaje = ((double)d[m, n] / (double)t.Length); |i| distance[i] = Array.new(other.size + 1) distance[i][0] = i end (0..other.size).each do |j| distance[0][j] = j end return d[m, n]; } (1..self.size).each do |i| (1..other.size).each do |j| distance[i][j] = [distance[i - 1][j] + 1, distance[i][j - 1] + 1, distance[i - 1][j - 1] + ((self[i - 1] == other[j - 1]) ? 0 : 1)].min end end distance[self.size][other.size] end end 64.2.4 Java puts “casa”.levenshtein “calle”#=> 3 Implementado como una clase estática. public class LevenshteinDistance { private static int minimum(int a, int b, int c) { if(a<=b && a<=c) { return a; } if(b<=a && b<=c) { return b; } return c; } public static int computeLevenshteinDistance(String str1, String str2) { return computeLevenshteinDistance(str1.toCharArray(), str2.toCharArray()); } private static int computeLevenshteinDistance(char [] str1, char [] str2) { int [][]distance = new int[str1.length+1][str2.length+1]; for(int i=0;i<=str1.length;i++) { distance[i][0]=i; } for(int j=0;j<=str2.length;j++) { distance[0][j]=j; } for(int i=1;i<=str1.length;i++) { for(int j=1;j<=str2.length;j++) { distance[i][j]= minimum(distance[i-1][j]+1, distance[i][j-1]+1, distance[i-1][j-1]+ ((str1[i-1]==str2[j1])?0:1)); } } return distance[str1.length][str2.length]; } }
64.2.8 PHP
64.2.9 Delphi function LevenshteinDistance(Str1, Str2: String): Integer; var d : array of array of Integer; Len1, Len2 : Integer; i,j,cost:Integer; begin Len1:=Length(Str1); Len2:=Length(Str2); SetLength(d,Len1+1); for i := Low(d) to High(d) do SetLength(d[i],Len2+1); for i := 0 to Len1 do d[i,0]:=i; for j := 0 to Len2 do d[0,j]:=j; for i:= 1 to Len1 do for j:= 1 to Len2 do begin if Str1[i]=Str2[j] then cost:=0 else cost:=1; d[i,j]:= Min(d[i-1, j] + 1, //
64.3. APLICACIONES
125
deletion, Min(d[i, j-1] + 1, // insertion d[i-1, j-1] + cost) == s2[j - 1]) c = 0; else c = 1; var r = d[j * a + i - 1] + // substitution ); end; Result:=d[Len1,Len2]; end; 1; var s = d[(j - 1) * a + i] + 1; var t = d[(j - 1) * a + i - 1] + c; d[j * a + i] = Math.min(Math.min(r, s), t); } } return(d[l2 * a + l1]); }
64.2.10
VB.NET
Public Function Levenshtein(ByVal s1 As String, ByVal s2 As String) As Integer Dim coste As Integer = 0 Dim n1 As Integer = s1.Length Dim n2 As Integer = s2.Length Dim m As Integer(,) = New Integer(n1, n2) {} For i As Integer = 0 To n1 m(i, 0) = i Next For i As Integer = 1 To n2 m(0, i) = i Next For i1 As Integer = 1 To n1 For i2 As Integer = 1 To n2 coste = If((s1(i1 - 1) = s2(i2 - 1)), 0, 1) m(i1, i2) = Math.Min(Math.Min(m(i1 - 1, i2) + 1, m(i1, i2 - 1) + 1), m(i1 - 1, i2 - 1) + coste) Next Next Return m(n1, n2) End Function
64.2.11
ActionScript 3.0
public class StringUtils { public static function levenshtein(s1:String, s2:String):int { if (s1.length == 0 || s2.length == 0) return 0; var m:uint = s1.length + 1; var n:uint = s2.length + 1; var i:uint, j:uint, cost:uint; var d:Vector.> = new Vector.>(); for (i = 0; i < m; i++) { d[i] = new Vector.(); for (j = 0; j < n; j++) d[i][j] = 0; } for (i = 0; i < m; d[i][0] = i++) ; for (j = 0; j < n; d[0][j] = j++) ; for (i = 1; i < m; i++) { for (j = 1; j < n; j++) { cost = (s1.charAt(i - 1) == s2.charAt(j - 1)) ? 0 : 1; d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1), d[i - 1][j - 1] + cost); } } return d[m-1][n-1]; } }
64.3 Aplicaciones • El proyecto ASJP usa la distancia de Levenshtein total en una lista de palabras en diferentes lenguas del mundo, para medir la “similaridad”o “cercanía”de las mismas, esa distancia calculada puede emplearse para proponer una clasificación filogenética tentativa de las lenguas del mundo.* [1] • La distancia de Damerau-Levenshtein es una generalización de la distancia de Levenshtein usada por los correctores ortográficos y en la detección de fraudes en listas de datos.
64.4 Véase también • Distancia de Damerau-Levenshtein • Algoritmo Needleman-Wunsch • Algoritmo Smith-Waterman • Algoritmo Bitap • Autómata de Levenshtein • Espacio métrico • Agrep
64.2.12 ColdFusion function levDistance(s,t) { var d = ArrayNew(2); var i = 1; var j = 1; var s_i = “A"; var t_j = “A"; var cost = 0; var n = len(s)+1; var m = len(t)+1; d[n][m]=0; if (n is 1) { return m; } if (m is 1) { return n; } for (i = 1; i lte n; i=i+1) { d[i][1] = i-1; } for (j = 1; j lte m; j=j+1) { d[1][j] = j-1; } for (i = 2; i lte n; i=i+1) { s_i = Mid(s,i-1,1); for (j = 2; j lte m; j=j+1) { t_j = Mid(t,j1,1); if (s_i is t_j) { cost = 0; } else { cost = 1; } d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1); d[i][j] = min(d[i][j], d[i1][j-1] + cost); } } return d[n][m]; }
64.2.13
JavaScript (NodeJS)
function levenshtein(s1, s2) { var l1 = s1.length; var l2 = s2.length; var d = []; var c = 0; var a = 0; if(l1 == 0) return l2; if(l2 == 0) return l1; var d = new Buffer((l1 + 1) * (l2 + 1)); a = l1 + 1; for(var i = 0; i <= l1; d[i] = i++); for(var j = 0; j <= l2; d[j * a] = j++); for(var i = 1; i <= l1; i++) { for(var j = 1; j <= l2; j++) { if(s1[i - 1]
• Ratcliff/Obershelp • Dynamic time warping • Distancia de Jaro-Winkler
64.5 Referencias [1] ASJP - World Language Tree
Capítulo 65
DLO La expresión DLO (Document Like Object) está ampliamente reconocida en la literatura sobre metadatos para aludir a los documentos de Internet (texto, imagen, audio, video, etc.) y se utiliza para referirse a una unidad documental o al documento digital mínimo, que forma parte de una colección digital, al cual se le aplican metadatos para su descripción y recuperación. El acrónimo DLO surge en el desarrollo de metadatos del Dublin Core, concretamente en el primer taller que se llevó a cabo en Ohio (Estados Unidos), donde empezó a utilizarse para diferenciar nociones individuales que constituyen un objeto discreto, digno de una descripción individual a través de metadatos. En el tercer taller que se realizó se amplió su significado para referirse a cualquier recurso de información específico que se caracterizase por ser estable (es decir, que tenía un contenido idéntico para cada usuario).
65.1 Enlaces externos Glosario web y proyecto de investigación de efectividad de metadatos Página oficial de Dublin Core
126
Capítulo 66
Driver Chain Manager Driver Chain Manager (DCM) es una tecnología de 66.1.2 Capacidades de DCM Microsoft que facilita instalar y trabajar con múltiples 1. Cuando múltiples drivers están instalados y solo se tecnologías de asistencia que utilizan la interfaz del driestá ejecutando uno, los demás no interferirán en ésver de la pantalla (Display Driver Interface o DDI) en un ta independientemente de su posición. mismo equipo. DCM permite a un programa tener conocimiento de la existencia de las otras aplicaciones de asistencia. Permite evitar que se produzcan problemas entre ellas., como fallos, mal funcionamiento, que se corrompan o incluso que no funcionen.
2. Un usuario puede instalar o desinstalar un driver en cualquier momento sin afectar a los demás.
La tecnología DCM viene instalada en Windows. La biblioteca se actualiza cuando se actualizan las ayudas. Un programador puede utilizar DCM en sus aplicaciones programando desde Microsoft Visual Studio empleando la biblioteca MSDN.
4. Todos los drivers de la cadena usarán el mismo código de escape para controlar la comunicación entre los usuarios y los controladores.
3. Existen aplicaciones de control remoto que también se basan en este encadenamiento.
5. En caso de que se cambie el adaptador de la pantalla se detectará si el ajuste de la cadena puede llevarse a cabo. 6. Los drivers instalados no interferirán con los nuevos.
66.1 ¿Qué hace? DCM es un conjunto de rutinas de la biblioteca MSDN usada por la tecnología de asistencia de Windows. Permite la instalación, desinstalación y mantenimiento de interceptadores del driver gráfico.
66.1.3 Cuestiones fuera del alcance de DCM 1. DCM no garantiza que 2 drivers se puedan ejecutar al mismo tiempo. Esto queda en manos de los desarrolladores de éstos.
Las aplicaciones de asistencia utilizan éstas rutinas para saber en que posición de la cadena de drivers deben colocar el suyo, de manera que no interfieran con las demás aplicaciones y éstas con ella
66.1.1
2. Para los vendedores que soportan DCM, Los drivers instalados pueden permanecer después de los que usan DCM. Sin embargo DCM no tendrá conocimiento de ellos. 3. Puede haber otros driver que no usen DCM, pero DCM no tendrá conocimiento de ellos.
Objetivos
4. DCM no soporta usuarios con múltiples monitores.
1. Proporcionar suficiente información sobre los objetos en la pantalla.
66.2 Sotrware que utiliza DCM 2. Asegurarse de que otras aplicaciones de asistencia instaladas en el sistema no interfieran con las que ya 66.2.1 se están ejecutando.
Aplicaciones que utilizan DCM
Las siguientes aplicaciones ya utilizan esta tecnología. 3. Asegurarse de que varias aplicaciones de asistencia pueden ejecutarse simultáneamente. 127
• Dolphin Computer Access:
128
CAPÍTULO 66. DRIVER CHAIN MANAGER • Hal 5.20 y superior, • Lunar 5.20 y superior, • Lunar Plus 5.20 y superior, • Supernova 5.20 y superior.
• Freedom Scientific: • JAWS 4.51 y superior, • Magic 8.1 y superior. • GW Micro: • Window-Eyes 4.21 y superior. • Ai Squared:
haya eliminado la información que el segundo necesita, imposibilitando su funcionamiento. Actualmente no existe ninguna regla que diga en que orden se ejecutan los controladores, eso sin tener en cuenta que puede haber más de un lector o magnificador instalados en la misma máquina. En caso de haber 2 magnificadores surgiría el problema de cual magnífica la pantalla o si se amplía 2 veces consecutivas (ampliación de la ampliación). Además las dos aplicaciones no tienen conocimiento una de la otra, por lo que no pueden solucionar el problema. El problema se agrava si son software de diferentes compañías.
Otro problema se crea al desinstalar uno de los drivers, • ZoomText 7,11 con el programa de utilidad pudiéndose producir que se rompa la cadena y por ello que se pierda el controlador final. del driver. • ZoomText 8.0 o superior (DCM built-in).
66.3.2 Forma de solucionarlo 66.2.2
Empresas desarrolladoras
66.2.3
Sistemas operativos que soportan 66.4 ‘DCM
DCM aporta a los desarrolladores de estas aplicaciones DCM es el resultado de un esfuerzo común de Microsoft una aplicación llamada“DCMUtil”que les permite may de las empresas asociadas Ai Squared, Dolphin Com- nejar el orden de los drivers y ajustarlos para un correcto funcionamiento. puter Access, GW Micro, y Freedom Scientific.
DCM 1.0 es compatible con Windows NT versión 4, Windows 2000 y Windows XP.
66.3 Funcionamiento de la cadena de drivers
Otras aplicaciones que utilizan DCM
Existen otras aplicaciones, de distintas tipologías, que pueden utilizar DCM. De ellas se destaca el software de acceso remoto, el cual necesita capturar la imagen de la pantalla y enviarla por la red.
66.5 Véase también El sistema operativo Windows permite instalar una cadena de drivers para la generación de la imagen de la pantalla. El primer driver obtendrá la información de las aplicaciones y se la pasará al siguiente driver y así sucesivamente con el resto de los drivers, esta cadena acabará en el driver de la tarjeta gráfica. Al colocar otros drivers lo que se pretende es capturar y/o modificar la información. Por ejemplo, un lector de pantalla no modificará la información que reciba, pero capturará los datos necesarios que requiera para poder leer por el altavoz. Por el contrario un magnificador de pantalla recortará un rectángulo de la entrada y se lo pasará al siguiente driver.
66.3.1
El problema
El problema es que el orden de la cadena no es aleatorio. Algunas aplicaciones deben ejecutar sus rutinas antes que otras. Por ejemplo, si ejecutamos el magnificador antes que un lector de pantalla, es posible que el primero
• Tiflotecnología. • Windows. • MSDN.
66.6 Fuentes y referencias 1. biblioteca MSDN: DCM (en inglés).
Capítulo 67
Dublin Core Dublin Core es un modelo de metadatos elaborado y auspiciado por la DCMI (Dublin Core Metadata Initiative), una organización dedicada a fomentar la adopción extensa de los estándares interoperables de los metadatos y a promover el desarrollo de los vocabularios especializados de metadatos para describir recursos para permitir sistemas más inteligentes el descubrimiento del recurso.
• Elementos relacionados principalmente con el contenido del recurso. • Elementos relacionados principalmente con el recurso cuando es visto como una propiedad intelectual.
• Elementos relacionados principalmente con la instanciación del recurso. Las implementaciones de Dublin Core usan generalmente XML y se basan en el Resource Description Framework. Dublin Core se define por ISO en su norma ISO 15836 Dentro de cada clasificación encontramos los siguientes del año 2003, y la norma NISO Z39.85-2007. elementos: El nombre viene por Dublin, Ohio, Estados Unidos, ciu- Contenido: dad que en 1995 albergó la primera reunión a nivel mundial de muchos de los especialistas en metadatos y Web • Título: el nombre dado a un recurso, habitualmente de la época. por el autor. Etiqueta: DC.Title
67.1 Descripción general Dublin Core es un sistema de 15 definiciones semánticas descriptivas que pretenden transmitir un significado semántico a las mismas. Estas definiciones: • Son opcionales
• Claves: los temas del recurso. Típicamente, Subject expresará las claves o frases que describen el título o el contenido del recurso. Se fomentará el uso de vocabularios controlados y de sistemas de clasificación formales. Etiqueta: DC.Subject
• Se pueden repetir • Pueden aparecer en cualquier orden Este sistema de definiciones fue diseñado específicamente para proporcionar un vocabulario de características “base”, capaces de proporcionar la información descriptiva básica sobre cualquier recurso, sin que importe el formato de origen, el área de especialización o el origen cultural.
67.2 Clasificación y elementos
• Descripción: una descripción textual del recurso. Puede ser un resumen en el caso de un documento o una descripción del contenido en el caso de un documento visual. Etiqueta: DC.Description • Fuente: secuencia de caracteres usados para identificar unívocamente un trabajo a partir del cual proviene el recurso actual. Etiqueta: DC.Source
En general, podemos clasificar estos elementos en tres grupos que indican la clase o el ámbito de la información que se guarda en ellos: 129
• Tipo del Recurso: la categoría del recurso. Por ejemplo, página personal, romance, poema, diccionario, etc.
130
CAPÍTULO 67. DUBLIN CORE Etiqueta: DC.Type
• Relación: es un identificador de un segundo recurso y su relación con el recurso actual. Este elemento permite enlazar los recursos relacionados y las descripciones de los recursos. Etiqueta: DC.Relation • Cobertura: es la característica de cobertura espacial y/o temporal del contenido intelectual del recurso. La cobertura espacial se refiere a una región física, utilizando por ejemplo coordenadas. La cobertura temporal se refiere al contenido del recurso, no a cuándo fue creado (que ya lo encontramos en el elemento Date). Etiqueta: DC.Coverage Propiedad Intelectual: • Autor o Creador: la persona u organización responsable de la creación del contenido intelectual del recurso. Por ejemplo, los autores en el caso de documentos escritos; artistas, fotógrafos e ilustradores en el caso de recursos visuales. Etiqueta: DC.Creator • Editor: la entidad responsable de hacer que el recurso se encuentre disponible en la red en su formato actual.
• Fecha: una fecha en la cual el recurso se puso a disposición del usuario en su forma actual. Esta fecha no se tiene que confundir con la que pertenece al elemento Coverage, que estaría asociada con el recurso en la medida que el contenido intelectual está de alguna manera relacionado con aquella fecha. Etiqueta: DC.Date • Formato: es el formato de datos de un recurso, usado para identificar el software y, posiblemente, el hardware que se necesitaría para mostrar el recurso. Etiqueta: DC.Format • Identificador del Recurso: secuencia de caracteres utilizados para identificar unívocamente un recurso. Ejemplos para recursos en línea pueden ser URLs y URNs. Para otros recursos pueden ser usados otros formatos de identificadores, como por ejemplo ISBN (“International Standard Book Number” ). Etiqueta: DC.Identifier • Lengua: lengua/s del contenido intelectual del recurso. Etiqueta: DC.Language
67.3 Usos
Cualquier persona puede utilizar los metadatos de Dublin Core para describir los recursos de un sistema de inforEtiqueta: DC.Publisher mación. Las páginas Web son uno de los tipos más comunes de recursos que utilizan las descripciones de Dublin • Otros Colaboradores: una persona u organización Core. que haya tenido una contribución intelectual significativa, pero que esta sea secundaria en comparación Los metadatos de Dublin Core están siendo utilizados cocon las de las personas u organizaciones especifi- mo la base para los sistemas descriptivos para varios grucadas en el elemento Creator. (por ejemplo: editor, pos de interés como por ejemplo: ilustrador y traductor). • Organizaciones educativas Etiqueta: DC.Contributor • Bibliotecas • Derechos: son una referencia (por ejemplo, una URL) para una nota sobre derechos de autor, para un servicio de gestión de derechos o para un servicio que dará información sobre términos y condiciones de acceso a un recurso. Etiqueta: DC.Rights Instanciación:
• Instituciones del gobierno. • Sector científico de la investigación. • Autores de páginas Web. • Negocios que requieren lugares más investigables. • Corporaciones con sistemas de gerencia extensos en conocimiento
67.5. ENLACES EXTERNOS
67.4 Ventajas • La simplicidad • La flexibilidad • La independencia sintáctica • La interoperabilidad semántica • Alto nivel de normalización formal • Crecimiento y evolución del estándar a través de una institución formal consorciada: la DCMI. • Consenso internacional • Modularidad de Metadatos en la Web • Arquitectura de Metadatos para la Web
67.5 Enlaces externos • • Página web oficial (en inglés) • SEDIC • y documentos XML/RDF para Recuperación
131
Capítulo 68
eAthena eAthena es emulador de código abierto de Ragnarok Online. Está escrito en C, aunque se está trabajando en una versión en C++ llamada eApp(eA++). eAthena soporta Linux 32bit y 64bit y Win32/64, aunque se recomienda el uso de Linux para su mejor desempeño y seguridad. eAthena está bajo licencia GPL. eAthena posee 2 versiones, TXT y SQL. Como sus nombres lo dicen SQL trabaja con bases de datos MySQL mientras que txt trabaja con archivos de texto. Se recomienda utilizar SQL para un mejor desempeño. Está actualizado según el cliente coreano de Ragnarok Online (kRO) ya que es el que tiene las últimas novedades de Ragnarok Online. Muchos de los servidores Ragnarok Online son creados sobre la base de eAthena ya que estos son muy modificables y no son el juego en si, es solo una emulación a diferencia de los servidores basados en el mismo código de Ragnarok Online que son ilegales ya que violan los Derechos de autor que impone Gravity Corp.. Algunos de los servidores más populares funcionan bajo eAthena, debido a ser normalmente gratuitos Cabe resaltar que todo el material que se encuentra en la parte del cliente, es el que se distribuye sin costo alguno en los oficiales y que Gravity Corp, solamente exime a Gravity de toda responsabilidad por ello, incluido su servidor gratuito de prueba.
68.1 Enlaces externos • Foro oficial de eAthena • Foro oficial de Soporte en Español de eAthena • Repositorio SVN oficial de eAthena
132
Capítulo 69
Efecto Hover El efecto Hover consiste en la alteración del aspecto de un elemento de la interfaz gráfica* [1] cuando se sitúa el puntero sobre el mismo, pero no se ha seleccionado aún.* [2]
69.1 Referencias [1] Ejemplo de efecto Hover sobre un enlace. [2] Blog de Andrés Nieto
69.2 Enlaces de interés • Efecto Hover según W3C. (en inglés) • Programación de efecto Hover en JavaScript. • Más ejemplos de programación. • Efecto Hover en Microsoft. • Efecto Hover en Developing Webs dot Net (en inglés) • Tutorial de Efecto Hover en Texto
133
Capítulo 70
Emtp EMTP es un programa de computadora destinado al aná- sistema simulado. lisis de circuitos eléctricos, especialmente en régimen transitorio. El programa permite modelar matemáticamente sistemas eléctricos, mecánicos y de control, mo- 70.4 Distribución de EMTP-ATP nofásicos y polifásicos. Su nombre proviene del acrónimo inglés ElectroMagnetic Transients Program. El ATP se distribuye por medio de los grupos de usuarios existentes en varias regiones del mundo. Cualquier persona puede solicitar los materiales del programa siempre 70.1 Historia que esté de acuerdo con la licencia y que sea aprobado por el grupo de usuarios. El programa EMTP fue desarrollado como contrapar- Algunos grupos de usuarios son: te del Transient Network Analyzer (TNA, Analizador de transitorios en redes) en los años finales de la década de • Canadian/American EMTP User Group 1960 por Hermann W. Dommel. Años más tarde él cede• European EMTP-ATP Users Group Assoc. ría los derechos de autor sobre el programa a la Bonneville (EEUG) Power Administration (BPA) de los Estados Unidos. • Japanese ATP User Group (JAUG) • Latin American EMTP User Group (CAUE)
70.2 ATP
• Argentinian EMTP User Group (CAUE) El programa ATP, Alternative Transients Program surge del año 1984 cuando los Drs. W. Scott Meyer y Tsu-huei Liu no aprobaron la comercialización del EMTP por parte de DCG (EMTP Development Coordination Group de la BPA) y EPRI (Electric Power Research Institute). Los Drs. Meyer y Liu empezaron el desarrollo del ATP como una alternativa no comercializada del EMTP, pero basado en una copia de éste colocada en el dominio público.
• Australian EMTP User Group (AEUG) • Korean EMTP User Group • Republic of China EMTP User Group • Indian EMTP User Group • South African ATP User Group
Aunque el programa puede ser adquirido sin costo, ATP no es del dominio público, se requiere una licencia antes 70.5 Enlaces externos que los materiales puedan ser recibidos por el interesado. Los requerimientos para usar el ATP son honestidad en su manejo y el compromiso de no participación en la Página principal de EMTP-ATP con historia e informacomercialización de EMTP o de otros programas de si- ción de contacto de los grupos de usuarios mulación de transitorios.* [1] Grupo de usuarios de EMPT-ATP de Europa En términos generales, el programa es el mismo y suele mencionarse como EMTP, ATP o bien EMTP-ATP.
70.3 Método de solución
• SIMULACIÓN DE SISTEMAS ELÉCTRICOS CON ATP-EMTP APLICACIONES
70.6 Referencias
El programa EMTP-ATP utiliza el método de integración trapezoidal para resolver las ecuaciones diferenciales del 134
[1] Historia y licencia del programa ATP
Capítulo 71
Enlace dinámico Un enlace dinámico es aquel en el cual una biblioteca de código es enlazada cuando un determinado programa se ejecuta (en oposición a un enlace estático, que se produce en tiempo de compilación). La ventaja de este tipo de enlace es que el programa es más liviano, y que evita la duplicación de código (por ejemplo, cuando dos programas requieren usar la misma biblioteca, se necesita sólo una copia de ésta). Las bibliotecas de enlace dinámico, o bibliotecas compartidas, suelen encontrarse en directorios específicos del sistema operativo, de forma que, cada vez que un programa necesite usar alguna, el sistema operativo conozca el lugar en el que se encuentra, para así poder enlazarla. Esto ocasiona algunos problemas de dependencias, principalmente entre diferentes versiones de una misma biblioteca. Muchos programas tienen procedimientos a los que no llaman, salvo en circunstancias excepcionales. Haciendo uso de bibliotecas de enlace dinámico, después del ensamblaje, podemos enlazar cada procedimiento en el momento en que es llamado.
135
Capítulo 72
Enlace estático Una biblioteca estática es aquella que se enlaza en tiempo de compilación (en oposición a una de enlace dinámico, que se enlaza en tiempo de ejecución). La ventaja de este tipo de enlace es que hace que un programa no dependa de ninguna biblioteca (puesto que las enlazó al compilar), haciendo más fácil su distribución. El enlazado permite al programador y al propio sistema operativo dividir un programa en varios archivos llamados módulos, que pueden ensamblarse por separado y enlazarse en una ocasión posterior, el enlace puede ser de naturaleza estática o dinámica. El enlace estático da como resultado, un archivo ejecutable con todos los símbolos y módulos respectivos incluidos en dicho archivo.
136
Capítulo 73
Enlazado Enlazado, es un proceso que une el código de los módulos y bibliotecas que forman un programa para generar el ejecutable final. Este proceso es realizado muchas veces directamente por el compilador y coloca las referencias externas (como a las DLL) de manera que funcionen directamente, como puede ser la situación de las funciones de manera numérica. En algunos compiladores viene un ejecutable específico link.exe para esta función.
137
Capítulo 74
Entrada chapuza En computación el antipatrón de diseño Chapuza de entrada ocurre cuando la entrada de datos de un programa específico no se maneja adecuadamente. Por ejemplo, si un programa acepta la entrada de cualquier texto por parte del usuario final y se utiliza un algoritmo que manipule mediante muchas combinaciones todas las cadenas posibles tanto si son válidas como si no lo son. Por lo general es difícil para un programador detectar, en una prueba de unidad, todas las posibles combinaciones erróneas de una entrada de datos. Sin embargo es muy fácil para el usuario final reconocer que la cadena de entrada es incorrecta y así bloquear el programa. De hecho, el Desbordamiento de búfer es un ejemplo de agujero de seguridad provocado por los problemas que causa un mal manejo de los datos de entrada. Para evitar la Chapuza de entrada se pueden utilizar algoritmos de validación que determinen que datos deben ser válidos y evitar el tratamiento de los datos no válidos. Por ejemplo, realizar el análisis léxico y/o sintáctico utilizando software específico tales como la Herramienta de programación lex, Yacc y GNU_Bison que permiten obtener un control robusto de texto compuesto por expresiones regulares y gramáticas libres de contexto del lenguaje. Se recomienda el empleo de estas tecnologías para asegurar el manejo adecuado de entradas inesperadas.
74.1 Véase también • Antipatrón de diseño • Patrón de diseño • Herramienta de programación lex • GNU Bison • Yacc
74.2 Enlaces externos • Input Kludge AntiPattern Problem by Sourcemaking Teaching IT Professionals
138
Capítulo 75
Error de software realidad, el término “bug”ya formaba parte del idioma, al menos desde que Thomas Alva Edison lo utilizó en 1889 refiriéndose a interferencias y mal funcionamiento. Es posible que Hopper lo haya asociado por primera vez a la informática, en este caso, relacionado a un insecto real. Por otra parte, aunque durante los años 50 del siglo XX, Hopper también empleó el término“debug”al hablar de la depuración de errores en los códigos de programación, el primer uso registrado del término se encuentra en la Journal of the Royal Aeronautical Society de 1945.* [7]
Foto del origen de la leyenda acerca del primer“bug”informático conocido.
75.2 Defectos de diseño de programas • Diseños con colores inapropiados para las personas que padecen daltonismo
Un error de software, comúnmente conocido como bug («bicho»), es un error o fallo en un programa de computador o sistema de software que desencadena un resultado indeseado. Los programas que ayudan a la detección y eliminación de errores de programación de software son denominados depuradores (debuggers).
• Diseños que usan textos con tipografías de difícil lectura por su tamaño o diseño • Diseños que fuerzan el uso del ratón o mouse sin dejar alternativas de teclado para personas con disfunciones motrices
Entre las numerosas incidencias notables causadas por este tipo de error se incluyen la destrucción, en 1962, de la sonda espacial Mariner 1,* [1] en 1996, del Ariane 5 501.* [2] y, en 2015, el Airbus A400M* [3]
• Diseños con implicaciones culturales, por ejemplo usando partes del cuerpo que en una determinada cultura sean objeto de vergüenza o burla o símbolos con características de identidad cultural o religiosa • Estimar que el equipo donde se instalará tiene determinadas características (como la resolución de la pantalla, la velocidad del procesador, la cantidad de memoria o conectividad a internet) propias de un equipo de gama alta, en vez de diseñar el software para su ejecución en equipos normales
75.1 Orígenes del término En 1967, los creadores de Mark III informaron del primer caso de error en un ordenador causado por un bug. El Mark II, ordenador sucesor de ASCC Mark II, construido en 1944, sufrió un fallo en un relé electromagnético. Cuando se investigó ese relé, se encontró una polilla (bug) que provocó que el relé quedase abierto. Grace Murray Hopper, licenciada en física y destacada matemática que trabajó como programadora en el Mark II, pegó el insecto con cinta adhesiva en la bitácora.* [4]
75.3 Errores de programación comunes
Este incidente es erróneamente referido como el origen de la utilización del término inglés bug («bicho») para indicar un problema en un aparato o sistema.* [5]* [6] En 139
• División por cero • Ciclo infinito
140
CAPÍTULO 75. ERROR DE SOFTWARE
• Problemas aritméticos como desbordamientos Abre el archivo “miarchivo”para escritura comienza a (overflow) o subdesbordamientos (underflow). escribir datos en mi archivo cierra el archivo Si “miarchivo”no existe (o el programa o el usuario no tienen privilegios suficientes para abrirlo), el sistema Utilizar una variable no inicializada operativo regresará un error que el programa no atrapará y tendremos un mensaje como “El archivo “miarchiAcceder a memoria no permitida (Violación de ac- vo”no puede ser abierto para escritura”y botones paceso) ra reintentar, cancelar y abortar (en el sistema operativo Windows), que no tendrán otra acción que repetirse inPérdida de memoria (memory leak) definidamente sin posibilidad de salir de ese ciclo como Desbordamiento o subdesbordamiento de la pila (es- no sea dando por terminado violentamente el programa. tructura de datos) Un código que permitiese atrapar el error en tiempo de ejecución sería: Desbordamiento de búfer (buffer overflow) Abre el archivo“miarchivo”para escritura Si el sistema Bloqueo mutuo (deadlock) operativo lo permite comienza a escribir datos en“miarchivo”si no lo permitió informa al usuario de lo que suceIndizado inadecuado de tablas en bases de datos. de regresa al usuario a un punto donde no haya conflicto Desbordamiento de la pila de recursión, cuando se (el menú principal, por ejemplo) Continúa operando normalmente dejan demasiadas llamadas en espera.
• Exceder el tamaño del array • • • • • • • •
75.4 Defectos de instalación o programación • Eliminación o sustitución de bibliotecas comunes a más de un programa o del sistema (DLC Hell). • Reiniciar arbitrariamente la sesión de un usuario para que la instalación tenga efecto.
Los diferentes lenguajes de programación permiten diferentes construcciones lógicas a los programadores para atrapar y resolver errores en tiempo de ejecución, como pueden ser las sentencias assert, try y on error en diferentes lenguajes de programación.
75.6 Véase también • Last Error
• Suponer que el usuario tiene una conexión permanente a internet.
• Agujero de seguridad
• Utilizar como fuente enlaces simbólicos a ficheros que pueden cambiar de ubicación.
• Hotfix
• Bugzilla
• Depurador
75.5 Códigos de errores de lenguajes de programación La mayor parte de los lenguajes de programación presentan al menos dos tipos de errores que permiten a los programadores manejar las fallas de los programas de una manera eficiente y que no resulte agresiva con el usuario final. Dichos errores son de compilación y errores en tiempo de ejecución. Los errores de compilación normalmente inhiben que el código fuente derive en un programa ejecutable, mientras que los errores en tiempo de ejecución son situaciones específicas en las que un evento externo al programa impide su ejecución. Regularmente un programador eficiente debe intentar imaginar como debe responder ante esos eventos de manera que sea el programa y no el usuario o el sistema operativo los que resuelvan el problema. Así por ejemplo un bloque de error no manejado podría hacer lo siguiente:
• Depuración de programas • Ingeniería de software
75.7 Referencias [1] (en inglés) «History's Worst Software Bugs.», p. 1. Wired. Consultado el 20 de marzo de 2014. [2] (en inglés) «History's Worst Software Bugs.», p. 2. Wired. Consultado el 20 de marzo de 2014. [3] (en inglés) «Airbus Cites Assembly Problem in A400M Crash». Consultado el 22 de junio de 2015 [4] (en inglés) «Rear Admiral Grace Murray Hopper, USNR, (1906-1992)»: imagen: Photo #: NH 96566-KN. Naval History and Heritage Command. Consultado el 20 de marzo de 2014. [5] bug
75.8. ENLACES EXTERNOS
[6] La polilla que voló dentro de un ordenador y el origen de «bug informático» | Microsiervos (Leyendas Urbanas) [7] (en inglés) «bug». World Wide Words. Consultado el 20 de marzo de 2014.
75.8 Enlaces externos • Buscador de Vulnerabilidades por productos de INTECO-CERT
141
Capítulo 76
Estilo de programación Estilo de programación (también llamado estándares de o bien: código o convención de código) es un término que des- if(horas < 24 && minutos < 60 && segundos < 60) { cribe convenciones para escribir código fuente en ciertos return true; } else { return false; } lenguajes de programación. El estilo de programación es frecuentemente dependien- con algo como: te del lenguaje de programación que se haya elegido para escribir. Por ejemplo el estilo del lenguaje de programa- if(horas<24&&minutos<60&&segundos<60){return true;} else{return false;} ción C variará con respecto al del lenguaje BASIC.
76.1 Características del estilo 76.1.1
Nombres de variable apropiadas
Los primeros dos ejemplos son mucho más fáciles de leer porque están bien indentados, y los bloques lógicos de código se agrupan y se representan juntos de forma más clara.
Una piedra clave para un buen estilo es la elección apropiada de nombres de variable. Variables pobremen- 76.1.3 Valores booleanos en estructuras de te nombradas dificultan la lectura del código fuente y su decisión comprensión. Como ejemplo, considérese el siguiente extracto de Algunos programadores piensan que las estructuras de decisión como las anteriores, donde el resultado de la depseudocódigo: cisión es meramente una computación de un valor booget a b c if a < 24 and b < 60 and c < 60 return true leano, son demasiado prolijos e incluso propensos al else return false error. Prefieren hacer la decisión en la computación por Debido a la elección de nombres de variable, es difícil sí mismo, como esto: darse cuenta de la función del código. Compárese ahora return horas < 12 && minutos < 60 && segundos < 60; con la siguiente versión: La diferencia es, con frecuencia, puramente estilística y get horas minutos segundos if horas < 24 and minutos < sintáctica, ya que los compiladores modernos producirán 60 and segundos < 60 return true else return false código objeto idéntico en las dos formas. La intención el código es ahora más sencilla de discernir, “dado una hora en 24 horas, se devolverá true si es válida y false si no”. 76.1.4 Bucles y estructuras de control El uso de estructuras de control lógicas para bucles también es parte de un buen estilo de programación. Ayuda a Estilo de indentación, en lenguajes de programación que alguien que esté leyendo el código a entender la secuencia usan llaves para indentar o delimitar bloques lógicos de de ejecución (en programación imperativa). Por ejemplo, código, como por ejemplo C, es también un punto clave el siguiente pseudocódigo: el buen estilo. Usando un estilo lógico y consistente hace cuenta = 0 while cuenta < 5 print cuenta * 2 cuenta = el código de uno más legible. Compárese: cuenta + 1 endwhile
76.1.2
Estilo de indentación
if(horas < 24 && minutos < 60 && segundos < 60){ El extracto anterior cumple con las dos recomendaciones return true; }else{ return false; } de estilo anteriores, pero el siguiente uso de la construcción for hace el código mucho más fácil de leer: 142
76.3. ENLACES EXTERNOS for cuenta = 0, cuenta < 5, cuenta=cuenta+1 print cuenta *2 En muchos lenguajes, el patrón frecuentemente usado “por cada elemento en un rango”puede ser acortado a: for cuenta = 0 to 5 print cuenta * 2
143 (traducción al español) • Guía de estilo para código Python (traducción al español) • Estándar de código: C# (Philips Medical Systems) • Estilo de programación para Mono
76.1.5
Espaciado
Los lenguajes de formato libre ignoran frecuentemente los espacios en blanco. El buen uso del espaciado en la disposición del código de uno es, por tanto, considerado un buen estilo de programación. Compárese el siguiente extracto de código C:
• Guía de calidad y estilo Ada 95: Directrices para programadores profesionales • Guía de estilo programación Java • Estándares de código Java de Ambysoft • Estándares de código de PHP::Pear
int cuenta; for(cuenta=0;cuenta<10;cuenta++){printf("%d” • Estándares de código Symbian OS C++ ,cuenta*cuenta+cuenta);} con:
76.3.3 Convenciones de código de proyecint cuenta; for (cuenta = 0; cuenta < 10; cuenta++) { tos printf("%d”, cuenta * cuenta + cuenta); } En los lenguajes de programación de la familia C se recomienda también evitar el uso de caracteres tabulador en medio de una línea, ya que diferentes editores de textos muestran su anchura de forma diferente. El lenguaje de programación Python usa indentación para indicar estructuras de control, por tanto se requiere obligatoriamente una buena indentación. Haciendo esto, la necesidad de marcar con llaves ({ y }) es eliminada, y la legibilidad es mejorada sin interferir con los estilos de codificación comunes. Con todo, esto lleva frecuentemente a problemas donde el código es copiado y pegado dentro de un programa Python, requiriendo un tedioso reformateado. Adicionalmente, el código Python se vuelve inusable cuando es publicado en un foro o página web que elimine el espacio en blanco.
76.2 Véase también • Estilo de indentación • Bug
76.3 Enlaces externos 76.3.1
Convenciones de código en castellano
• Manual de Estilo de programación, en formato PDF y licencia CreativeCommons
76.3.2
Convenciones de código en inglés
• Convenciones de código para el lenguaje Java
• Estándares de codificación de GNU • Guía de estilo para codificación en Mozilla • Guía de estilo para el núcleo Linux • Guía de estilo para el código de NetBSD
Capítulo 77
Eventos del ratón Un evento del ratón es una acción realizada por el usuario de una interfaz de usuario utilizando el ratón de computadora (mouse). La interpretación de estas acciones mediante software desarrollado para ello, permite ejecutar una función asociada a dicha acción. Algunos ejemplos de eventos de ratón son: • mouse over: se produce cuando el cursor o puntero del ratón se encuentra por encima de una determinada zona. • mouse out: se produce cuando el cursor abandona una determinada zona. • mouse clicked: se produce cuando se pulsa un botón del ratón. • mouse double-clicked: se produce cuando se pulsa dos veces en un intervalo pequeño de tiempo un mismo botón del ratón. La programación de los eventos del mouse se lleva a cabo mediante llamadas a rutinas específicas que se ejecutan cuando se produce una acción. Además, la acción que se llevará a cabo será diferente dependiendo de en qué parte de la pantalla se sitúe este, por ejemplo, si se pulsa el botón izquierdo y el puntero está en una parte externa a una aplicación, no ocurrirá nada, pero si por el contrario, en puntero se encuentra sobre un área que contiene un botón, al pulsar sobre el ratón se deberá ejecutar la rutina asociada a ese botón.
77.1 Véase también • Clic (informática) • Doble clic
144
Capítulo 78
Exclusión mutua (informática) Los algoritmos de exclusión mutua (comúnmente abreviada como mutex por mutual exclusion) se usan en programación concurrente para evitar el ingreso a sus secciones críticas por más de un proceso a la vez. La sección crítica es el fragmento de código donde puede modificarse un recurso compartido.
semáforo y ambos se quedan a la espera de que el otro proceso libere el semáforo. Otros efectos comunes incluyen la Inanición, en el cual un proceso esencial no se ejecuta durante el tiempo deseado, y la inversión de prioridades, en el que una tarea de prioridad elevada espera por otra tarea de menor prioridad, así como la latencia alta en La mayor parte de estos recursos son las señales, conta- la que la respuesta a las interrupciones no es inmediata. dores, colas y otros datos que se emplean en la comuni- La mayor parte de la investigación actual en este campo, cación entre el código que se ejecuta cuando se da servi- pretende eliminar los efectos anteriormente descritos. Si cio a una interrupción y el código que se ejecuta el resto bien no hay un esquema perfecto conocido, hay un indel tiempo. Se trata de un problema de vital importan- teresante esquema no clásico de envío de mensajes entre cia porque, si no se toman las precauciones debidas, una fragmentos de código que, aunque permite inversiones de interrupción puede ocurrir entre dos instrucciones cua- prioridad y produce una mayor latencia, impide los interlesquiera del código normal y esto puede provocar graves bloqueos. fallos. Algunos ejemplos de algoritmos clásicos de exclusión La técnica que se emplea por lo común para conseguir la mutua son: exclusión mutua es inhabilitar las interrupciones durante el conjunto de instrucciones más pequeño que impedi• El algoritmo de Dekker. rá la corrupción de la estructura compartida (la sección • El algoritmo de Peterson. crítica). Esto impide que el código de la interrupción se ejecute en mitad de la sección crítica. En un sistema multiprocesador de memoria compartida, se usa la operación indivisible test-and-set sobre una bandera, para esperar hasta que el otro procesador la despeje. La operación test-and-set realiza ambas operaciones sin liberar el bus de memoria a otro procesador. Así, cuando el código deja la sección crítica, se despeja la bandera. Esto se conoce como spin lock o espera activa.
78.1 Véase también
Algunos sistemas tienen instrucciones multioperación indivisibles similares a las anteriormente descritas para manipular las listas enlazadas que se utilizan para las colas de eventos y otras estructuras de datos que los sistemas operativos usan comúnmente. La mayoría de los métodos de exclusión mutua clásicos intentan reducir la latencia y espera activa mediante las colas y cambios de contexto. Algunos investigadores afirman que las pruebas indican que estos algoritmos especiales pierden más tiempo del que ahorran. A pesar de todo lo dicho, muchas técnicas de exclusión mutua tienen efectos colaterales. Por ejemplo, los semáforos permiten interbloqueos (deadlocks) en los que un proceso obtiene un semáforo, otro proceso obtiene el
145
• Cierre de exclusión mutua o locks • Semáforo (inventado por Edsger Dijkstra) • Monitor (concurrencia)(inventado por C. A. R. Hoare) (sin interbloqueos)
Capítulo 79
Expresión regular Una expresión regular, a menudo llamada también re- Agrupación Los paréntesis pueden usarse para definir gex, es una secuencia de caracteres que forma un patrón el ámbito y precedencia de los demás operadores. de búsqueda, principalmente utilizada para la búsqueda Por ejemplo, "(p|m)adre”es lo mismo que “pade patrones de cadenas de caracteres u operaciones de dre|madre”, y "(des)?amor”se corresponde con sustituciones. Por ejemplo, el grupo formado por las caamor y con desamor. denas Handel, Händel y Haendel se describe con el patrón “H(a|ä|ae)ndel”. La mayoría de las formalizaciones proporcionan los siguientes constructores: una expresión regular es una forma de representar a los lenguajes regulares (finitos o infinitos) y se construye utilizando caracteres Los constructores pueden combinarse libremente dentro de la misma expresión, por lo que“H(ae?|ä)ndel”equivale del alfabeto sobre el cual se define el lenguaje. a “H(a|ae|ä)ndel”. En informática, las expresiones regulares proveen una manera muy flexible de buscar o reconocer cadenas de La sintaxis precisa de las expresiones regulares cambia según las herramientas y aplicaciones consideradas, y se texto. describe con más detalle a continuación.
79.1 Construcción de expresiones regulares Específicamente, las expresiones regulares se construyen utilizando los operadores unión, concatenación y clausura de Kleene. Toda expresión regular tiene algún autómata finito asociado.
79.2 Aplicaciones
Su utilidad más obvia es la de describir un conjunto de Alternación Una barra vertical separa las alternativas. cadenas para una determinada función, resultando de utiPor ejemplo,“marrón|castaño”se corresponde con lidad en editores de texto y otras aplicaciones informáticas para buscar y manipular textos. marrón o castaño. Cuantificación Un cuantificador tras un carácter espe- Numerosos editores de texto y otras herramientas utilizan cifica la frecuencia con la que éste puede ocurrir. expresiones regulares para buscar y reemplazar patrones en un texto. Por ejemplo, las herramientas proporcionaLos cuantificadores más comunes son ?, + y *: das por las distribuciones de Unix (incluyendo el editor ? El signo de interrogación indica que el carácter sed y el filtro grep) popularizaron el concepto de expreque le precede puede aparecer como mucho sión regular entre usuarios no programadores, aunque ya una vez. Por ejemplo, “ob?scuro”se corres- era familiar entre los programadores. ponde con oscuro y obscuro. Inicialmente, este reconocimiento de cadenas se progra+ El signo más indica que el carácter que le prece- maba para cada aplicación sin mecanismo alguno inhede debe aparecer al menos una vez. Por ejem- rente al lenguaje de programación pero, con el tiempo, se plo,“ho+la”describe el conjunto infinito hola, ha ido incorporado el uso de expresiones regulares para hoola, hooola, hoooola, etcétera. facilitar programar la detección de ciertas cadenas. Por * El asterisco indica que el carácter que le prece- ejemplo, Perl tiene un potente motor de expresiones rede puede aparecer cero, una, o más veces. Por gulares directamente incluido en su sintaxis. Otros lenejemplo,“0*42”se corresponde con 42, 042, guajes lo han incorporado como funciones específicas sin 0042, 00042, etcétera. incorporarlo a su sintaxis. 146
79.3. LAS EXPRESIONES REGULARES EN PROGRAMACIÓN
147
79.3 Las expresiones regulares en programación
• C++: Desde su versión C++11 es posible utilizar expresiones regulares mediante la biblioteca estándar, usando la cabecera .
Nota: Para el entendimiento completo de esta sección es necesario poseer conocimientos generales acerca de lenguajes de programación o programación en general.
• Java: existen varias bibliotecas hechas para java que permiten el uso de RegEx, y Sun planea dar soporte a estas desde el SDK
En el área de la programación las expresiones regulares son un método por medio del cual se pueden realizar búsquedas dentro de cadenas de caracteres. Sin importar la amplitud de la búsqueda requerida de un patrón definido de caracteres, las expresiones regulares proporcionan una solución práctica al problema. Adicionalmente, un uso derivado de la búsqueda de patrones es la validación de un formato específico en una cadena de caracteres dada, como por ejemplo fechas o identificadores. Para poder utilizar las expresiones regulares al programar es necesario tener acceso a un motor de búsqueda con la capacidad de utilizarlas. Es posible clasificar los motores disponibles en dos tipos según su uso: motores para el programador y motores para el usuario final. Motores para el usuario final: son programas que permiten realizar búsquedas sobre el contenido de un archivo o sobre un texto extraído y colocado en el programa. Están diseñados para permitir al usuario realizar búsquedas avanzadas usando este mecanismo, sin embargo es necesario aprender a redactar expresiones regulares adecuadas para poder utilizarlos eficientemente. Algunos programas disponibles de este tipo son:
• •
•
• Perl: es el lenguaje que hizo crecer a las expresiones regulares en el ámbito de la programación hasta llegar a lo que son hoy en día. • PCRE: biblioteca de ExReg para C, C++ y otros lenguajes que puedan utilizar bibliotecas dll (Visual Basic 6 por ejemplo). • PHP: tiene dos tipos diferentes de expresiones regulares disponibles para el programador, aunque la variante POSIX (ereg) va a ser desechada en PHP 6. • Python: lenguaje de scripting con soporte de expresiones regulares mediante su librería . • .Net Framework: provee un conjunto de clases mediante las cuales es posible utilizar expresiones regulares para hacer búsquedas, reemplazar cadenas y validar patrones.
Nota: de las herramientas mencionadas con anterioridad operativos se utilizan el EditPad Pro y el .Net Framework para dar ejemplos, aunque es posible utilizar las expresiones resed: programa de los sistemas operativos gulares con cualquier combinación de las herramientas Unix/Linux que permite la modificación de la mencionadas. Aunque en general las Expresiones Regulares utilizan un lenguaje común en todas las herramiensalida. tas, las explicaciones prácticas acerca de la utilización de PowerGrep: versión de grep para los sistemas ope- las herramientas y los ejemplos de código deben ser interrativos Windows. pretados de forma diferente. También es necesario hacer RegexBuddy: ayuda a crear las expresiones regulares notar que existen algunos detalles de sintaxis de las expreen forma interactiva y luego le permite al usuario siones regulares que son propios del .Net Framework que se utilizan en forma diferente en las demás herramienusarlas y guardarlas. tas de programación. Cuando estos casos se den se hará EditPad Pro: permite realizar búsquedas con expre- notar en forma explícita para que el lector pueda buscar siones regulares sobre archivos y las muestra por información respecto a estos detalles en fuentes adiciomedio de código de colores para facilitar su lectu- nales. En el futuro se incluirán adicionalmente ejemplos ra y comprensión. de otras herramientas y lenguajes de programación.
• grep: programa Unix/Linux. •
• JavaScript: a partir de la versión 1.2 (ie4+, ns4+) JavaScript tiene soporte integrado para expresiones regulares.
de
los
sistemas
Motores para el programador: permiten automatizar el proceso de búsqueda de modo que sea posible utilizarlo muchas veces para un propósito específico. Estas son algunas de las herramientas de programación disponibles que ofrecen motores de búsqueda con soporte a expresiones regulares:
Expresiones regulares como motor de búsqueda
Las expresiones regulares permiten encontrar porciones específicas de texto dentro de una cadena más grande de caracteres. Así, si es necesario encontrar el texto“lote”en la expresión“el ocelote saltó al lote contiguo”cualquier motor de búsqueda sería capaz de efectuar esta labor. Sin embargo, la mayoría de los motores de búsqueda encon• AWK: Forma una parte esencial del lenguaje y por trarían también el fragmento“lote”de la palabra“oceloextensión de la herramienta awk de Unix/Linux te”, lo cual podría no ser el resultado esperado. Algunos
148
CAPÍTULO 79. EXPRESIÓN REGULAR
motores de búsqueda permiten adicionalmente especificar que se desea encontrar solamente palabras completas, solucionando este problema. Las expresiones regulares permiten especificar todas estas opciones adicionales y muchas otras sin necesidad de configurar opciones adicionales, sino utilizando el mismo texto de búsqueda como un lenguaje que permite enviarle al motor de búsqueda exactamente lo que deseamos encontrar en todos los casos, sin necesidad de activar opciones adicionales al realizar la búsqueda.
79.4.2 La admiración "!"
Expresiones regulares como lenguaje
79.4.3 La barra inversa o antibarra "\"
Para especificar opciones dentro del texto a buscar se utiliza un lenguaje o convención mediante el cual se le transmite al motor de búsqueda el resultado que se desea obtener. Este lenguaje le da un significado especial a una serie de caracteres. Por lo tanto cuando el motor de búsqueda de expresiones regulares encuentre estos caracteres no los buscará en el texto en forma literal, sino que buscará lo que los caracteres significan. A estos caracteres se les llama algunas veces“meta-caracteres”. A continuación se listan los principales meta-caracteres y su función y cómo los interpreta el motor de expresiones regulares.
79.4 Descripción de las expresiones regulares 79.4.1
El punto ".”
El punto se interpreta por el motor de búsqueda como “cualquier carácter”, es decir, busca cualquier carácter SIN incluir los saltos de línea. Los motores de Expresiones regulares tienen una opción de configuración que permite modificar este comportamiento. En .Net Framework se utiliza la opción RegexOptions.Singleline para especificar la opción de que busque todos los caracteres incluidos el salto de línea (\n). El punto se utiliza de la siguiente forma: Si se le dice al motor de RegEx que busque“g.t”en la cadena“el gato de piedra en la gótica puerta de getisboro goot”el motor de búsqueda encontrará “gat”, “gót”y por último “get”. Nótese que el motor de búsqueda no encuentra “goot"; esto es porque el punto representa un solo carácter y únicamente uno. Si es necesario que el motor encuentre también la expresión “goot”, será necesario utilizar repeticiones, las cuales se explican más adelante. Aunque el punto es muy útil para encontrar caracteres que no conocemos, es necesario recordar que corresponde a cualquier carácter y que muchas veces esto no es lo que se requiere. Es muy diferente buscar cualquier carácter que buscar cualquier carácter alfanumérico o cualquier dígito o cualquier no-dígito o cualquier no-alfanumérico. Se debe tomar esto en cuenta antes de utilizar el punto y obtener resultados no deseados.
Se utiliza para realizar una “búsqueda anticipada negativa”. La construcción de la expresión regular es con el par de paréntesis, el paréntesis de apertura seguida de un signo de interrogación y un signo de exclamación. Dentro de la búsqueda tenemos la expresión regular. Por ejemplo, para excluir exactamente una palabra, habrá que utilizar "^(palabra.+|(?!palabra).*)$"
Se utiliza para escapar el siguiente carácter de la expresión de búsqueda de forma que este adquiera un significado especial o deje de tenerlo. O sea, la barra inversa no se utiliza nunca por sí sola, sino en combinación con otros caracteres. Al utilizarlo por ejemplo en combinación con el punto "\.”este deja de tener su significado normal y se comporta como un carácter literal. De la misma forma, cuando se coloca la barra inversa seguida de cualquiera de los caracteres especiales que discutiremos a continuación, estos dejan de tener su significado especial y se convierten en caracteres de búsqueda literal. Como ya se mencionó con anterioridad, la barra inversa también puede darle significado especial a caracteres que no lo tienen. A continuación hay una lista de algunas de estas combinaciones: • \t ̶Representa un tabulador. • \r ̶Representa el“retorno de carro”o“regreso al inicio”o sea el lugar en que la línea vuelve a iniciar. • \n ̶Representa la“nueva línea”el carácter por medio del cual una línea da inicio. Es necesario recordar que en Windows es necesaria una combinación de \r\n para comenzar una nueva línea, mientras que en Unix solamente se usa \n y en Mac_OS clásico se usa solamente \r. • \a ̶Representa una “campana”o “beep”que se produce al imprimir este carácter. • \e ̶Representa la tecla “Esc”o “Escape” • \f ̶Representa un salto de página • \v ̶Representa un tabulador vertical • \x ̶Se utiliza para representar caracteres ASCII o ANSI si conoce su código. De esta forma, si se busca el símbolo de derechos de autor y la fuente en la que se busca utiliza el conjunto de caracteres Latin-1 es posible encontrarlo utilizando "\xA9”. • \u ̶Se utiliza para representar caracteres Unicode si se conoce su código. "\u00A2”representa el símbolo de centavos. No todos los motores de Expresiones Regulares soportan Unicode. El .Net Framework lo hace, pero el EditPad Pro no, por ejemplo.
79.4. DESCRIPCIÓN DE LAS EXPRESIONES REGULARES
149
• \d ̶Representa un dígito del 0 al 9. • • • • •
con la barra inversa dentro de los corchetes es la propia barra inversa. La expresión regular "[\dA-Fa-f]" nos per\w ̶Representa cualquier carácter alfanumérico. mite encontrar dígitos hexadecimales. Los corchetes nos permiten también encontrar palabras aún si están escri\s ̶Representa un espacio en blanco. tas de forma errónea, por ejemplo, la expresión regular \D ̶Representa cualquier carácter que no sea un “expresi[oó]n”permite encontrar en un texto la palabra dígito del 0 al 9. “expresión”aunque se haya escrito con o sin tilde. Es necesario aclarar que sin importar cuantos caracteres se \W ̶Representa cualquier carácter no alfanumériintroduzcan dentro del grupo por medio de los corchetes, co. el grupo sólo le dice al motor de búsqueda que encuentre \S ̶Representa cualquier carácter que no sea un es- un solo carácter a la vez, es decir, que“expresi[oó]n”no encontrará “expresion”o “expresión”. pacio en blanco.
• \A ̶Representa el inicio de la cadena. No un carácter sino una posición. 79.4.5
La barra "|"
• \Z ̶Representa el final de la cadena. No un carácter Sirve para indicar una de varias opciones. Por ejemplo, sino una posición. la expresión regular “a|e”encontrará cualquier “a” • \b ̶Marca la posición de una palabra limitada por o “e”dentro del texto. La expresión regular “esespacios en blanco, puntuación o el inicio/final de te|oeste|norte|sur”permitirá encontrar cualquiera de los nombres de los puntos cardinales. La barra se utiliza couna cadena. múnmente en conjunto con otros caracteres especiales. • \B ̶Marca la posición entre dos caracteres alfanuméricos o dos no-alfanuméricos.
79.4.6 El signo de dólar "$" Notas: • Utilidades como Charmap.exe de Windows o gucharmap de GNOME permiten encontrar los códigos ASCII/ANSI/UNICODE para utilizarlos en Expresiones Regulares.
Representa el final de la cadena de caracteres o el final de la línea, si se utiliza el modo multi-línea. No representa un carácter en especial sino una posición. Si se utiliza la expresión regular "\.$" el motor encontrará todos los lugares donde un punto finalice la línea, lo que es útil para avanzar entre párrafos.
• Algunos lenguajes, como Java, asignan su propio significado a la barra invertida, por lo que deberá repetirse para que sea considerada una expresión re- 79.4.7 El acento circunflejo "^" gular (ej. String expresion="\\d.\\d”para indicar el patrón \d.\d). Este carácter tiene una doble funcionalidad, que difiere cuando se utiliza individualmente y cuando se utiliza en conjunto con otros caracteres especiales. En primer lugar 79.4.4 Los corchetes "[ ]" su funcionalidad como carácter individual: el carácter "^" La función de los corchetes en el lenguaje de las expre- representa el inicio de la cadena (de la misma forma que siones regulares es representar “clases de caracteres”, el signo de dólar "$" representa el final de la cadena). Por o sea, agrupar caracteres en grupos o clases. Son útiles tanto, si se utiliza la expresión regular "^[a-z]" el motor cuando es necesario buscar uno de un grupo de caracte- encontrará todos los párrafos que den inicio con una leres. Dentro de los corchetes es posible utilizar el guion "- tra minúscula. Cuando se utiliza en conjunto con los cor" para especificar rangos de caracteres. Adicionalmente, chetes de la siguiente forma "[^\w ]" permite encontrar los metacaracteres pierden su significado y se convierten cualquier carácter que NO se encuentre dentro del grupo en literales cuando se encuentran dentro de los corche- indicado. La expresión indicada permite encontrar, por tes. Por ejemplo, como vimos en la entrega anterior "\d” ejemplo, cualquier carácter que no sea alfanumérico o un nos es útil para buscar cualquier carácter que represente espacio, es decir, busca todos los símbolos de puntuación un dígito. Sin embargo esta denominación no incluye el y demás caracteres especiales. punto ".”que divide la parte decimal de un número. Para buscar cualquier carácter que representa un dígito o un punto podemos utilizar la expresión regular "[\d.]". Como se hizo notar anteriormente, dentro de los corchetes, el punto representa un carácter literal y no un metacarácter, por lo que no es necesario antecederlo con la barra inversa. El único carácter que es necesario anteceder
La utilización en conjunto de los caracteres especiales "^" y "$" permite realizar validaciones en forma sencilla. Por ejemplo "^\d$" permite asegurar que la cadena a verificar representa un único dígito "^\d\d/\d\d/\d\d\d\d$" permite validar una fecha en formato corto, aunque no permite verificar si es una fecha válida, ya que 99/99/9999 también sería válido en este formato; la validación completa
150
CAPÍTULO 79. EXPRESIÓN REGULAR
de una fecha también es posible mediante expresiones re- definen grupos “anónimos”, sin embargo el signo de gulares, como se ejemplifica más adelante. pregunta en conjunto con los paréntesis triangulares "<>" permite “nombrar”estos grupos de la siguiente forma: "^(?\d\d)\/(?\d\d)\/(?\d\d\d\d)$"; 79.4.8 Los paréntesis "()" Con lo cual se le especifica al motor de búsqueda que los primeros dos dígitos encontrados llevarán la etiqueta De forma similar que los corchetes, los paréntesis sirven “Día”, los segundos la etiqueta “Mes”y los últimos para agrupar caracteres, sin embargo existen varias dife- cuatro dígitos llevarán la etiqueta “Año”. rencias fundamentales entre los grupos establecidos por medio de corchetes y los grupos establecidos por parén- NOTA: a pesar de la complejidad y flexibilidad dada por los caracteres especiales estudiados hasta ahora, en su tesis: mayoría nos permiten encontrar solamente un carácter a la vez, o un grupo de caracteres a la vez. Los meta• Los caracteres especiales conservan su significado caracteres enumerados en adelante permiten establecer dentro de los paréntesis. repeticiones. • Los grupos establecidos con paréntesis establecen una “etiqueta”o “punto de referencia”para el motor de búsqueda que puede ser utilizada poste- 79.4.10 Las llaves "{}" riormente como se denota más adelante. Comúnmente las llaves son caracteres literales cuando se • Utilizados en conjunto con la barra "|" permite ha- utilizan por separado en una expresión regular. Para que cer búsquedas opcionales. Por ejemplo la expresión adquieran su función de metacaracteres es necesario que regular “al (este|oeste|norte|sur) de”permite bus- encierren uno o varios números separados por coma y que car textos que den indicaciones por medio de puntos estén colocados a la derecha de otra expresión regular cardinales, mientras que la expresión regular “es- de la siguiente forma: "\d{2}" Esta expresión le dice al te|oeste|norte|sur”encontraría“este”en la palabra motor de búsqueda que encuentre dos dígitos contiguos. “esteban”, no pudiendo cumplir con este propósito. Utilizando esta fórmula podríamos convertir el ejemplo "^\d\d/\d\d/\d\d\d\d$" que servía para validar un formato • Utilizados en conjunto con otros caracteres especiade fecha en "^\d{2}/\d{2}/\d{4}$" para una mayor clales que se detallan posteriormente, ofrece funcionaridad en la lectura de la expresión. lidad adicional. "\d{2,4}" Esta forma añade un segundo número separado por una coma, el cuál indica al motor de búsqueda que 79.4.9 El signo de interrogación "?" como máximo debe aparecer 4 veces la expresión regular \d. Los posibles valores son: El signo de interrogación tiene varias funciones dentro del lenguaje de las expresiones regulares. La primera de • "^\d\d$" (mínimo 2 repeticiones) ellas es especificar que una parte de la búsqueda es opcional. Por ejemplo, la expresión regular “ob?scuridad” • "^\d\d\d$"(tiene 3 repeticiones, por lo tanto entra en permite encontrar tanto “oscuridad”como “obscuriel rango 2-4) dad”. En conjunto con los paréntesis redondos permite • "^\d\d\d\d$" (máximo 4 repeticiones) especificar que un conjunto mayor de caracteres es opcional; por ejemplo“Nov(\.|iembre|ember)?" permite encontrar tanto “Nov”como “Nov.”, “Noviembre” Nota: aunque esta forma de encontrar elementos repetiy “November”. Como se mencionó anteriormente, los dos es muy útil, algunas veces no se conoce con claridad paréntesis nos permiten establecer un “punto de refe- cuantas veces se repite lo que se busca o su grado de rerencia”para el motor de búsqueda. Sin embargo, algunas petición es variable. En estos casos los siguientes metaveces, no se desea utilizarlos con este propósito, como caracteres son útiles. en el ejemplo anterior “Nov(\.|iembre|ember)?". En este caso el establecimiento de este punto de referencia (que se detalla más adelante) representa una inversión 79.4.11 El asterisco "*" inútil de recursos por parte del motor de búsqueda. Para evitarlo se puede utilizar el signo de pregunta El asterisco sirve para encontrar algo que se encuentra rede la siguiente forma: “Nov(?:\.|iembre|ember)?". petido 0 o más veces. Por ejemplo, utilizando la expresión Aunque el resultado obtenido será el mismo, el motor "[a-zA-Z]\d*" será posible encontrar tanto “H”como de búsqueda no realizará una inversión inútil de recursos “H1”,“H01”,“H100”y“H1000”, es decir, una letra en este grupo, sino que lo ignorará. Cuando no sea seguida de un número indefinido de dígitos. Es necesario necesario reutilizar el grupo, es aconsejable utilizar tener cuidado con el comportamiento del asterisco, ya que este formato. De forma similar, es posible utilizar el éste, por defecto, trata de encontrar la mayor cantidad posigno de pregunta con otro significado: Los paréntesis sible de caracteres que correspondan con el patrón que se
79.4. DESCRIPCIÓN DE LAS EXPRESIONES REGULARES busca. De esta forma si se utiliza "\(.*\)" para encontrar cualquier cadena que se encuentre entre paréntesis y se lo aplica sobre el texto“Ver (Fig. 1) y (Fig. 2)" se esperaría que el motor de búsqueda encuentre los textos "(Fig. 1)" y "(Fig. 2)", sin embargo, debido a esta característica, en su lugar encontrará el texto "(Fig. 1) y (Fig. 2)". Esto sucede porque el asterisco le dice al motor de búsqueda que llene todos los espacios posibles entre los dos paréntesis. Para obtener el resultado deseado se debe utilizar el asterisco en conjunto con el signo de interrogación de la siguiente forma: "\(.*?\)" Esto es equivalente a decirle al motor de búsqueda que “Encuentre un paréntesis de apertura y luego encuentre cualquier secuencia de caracteres hasta que encuentre un paréntesis de cierre”.
79.4.12
151
Luego asumiendo que el texto que se desea examinar con la expresión regular se encuentra en la variable “sText” podemos recorrer todas las instancias encontradas de la siguiente forma: foreach(Match CurrentMatch in _TagParser.Matches(sText)){ // ----- Código extra aquí ----} Luego se puede utilizar la propiedad Groups de la clase Match para traer el resultado de la búsqueda: foreach(Match CurrentMatch in _TagParser.Matches(sText)){ String sTagName = CurrentMatch. Groups[1].Value; }
El signo de suma "+" Grupos nominales
Se utiliza para encontrar una cadena que se encuentre repetida una o más veces. A diferencia del asterisco, la expresión "[a-zA-Z]\d+" encontrará“H1”pero no encontrará “H”. También es posible utilizar este metacarácter en conjunto con el signo de interrogación para limitar hasta donde se efectúa la repetición.
Los grupos nominales son aquellos a los que se les asigna un nombre, dentro de la expresión regular para poder utilizarlos posteriormente. Esto se hace de forma diferente en los distintos motores de búsqueda, a continuación se explica como hacerlo en el motor del .Net Framework.
Utilizando el ejemplo anterior es posible convertir "<([azA-Z]\w*?)>" en "<(?[a-zA-Z]\w*?)>" Pa79.4.13 Grupos anónimos ra encontrar etiquetas HTML. Nótese el signo de pregunta y el texto“TagName”encerrado entre paréntesis trianLos grupos anónimos se establecen cada vez que se en- gulares, seguido de éste. Para utilizar este ejemplo en el cierra una expresión regular en paréntesis, por lo que la .Net Framework es posible utilizar el siguiente código: expresión "<([a-zA-Z]\w*?)>" define un grupo anónimo. Regex _TagParser = new Regex("<(?[aEl motor de búsqueda almacenará una referencia al grupo zA-Z]\w*?)>"); foreach(Match CurrentMatch in anónimo que corresponda a la expresión encerrada entre _TagParser.Matches(sText)){ String sTagName = Culos paréntesis. rrentMatch. Groups["TagName"]. Value; } La forma más inmediata de utilizar los grupos que se definen, es dentro de la misma expresión regular, lo Es posible definir tantos grupos como sea nececual se realiza utilizando la barra inversa "\" seguida sario, de esta forma se puede definir algo como: del número del grupo al que se desea hacer referen"<(?[a-zA-Z]\w*?) ?(?.*?)>" cia de la siguiente forma: "<([a-zA-Z]\w*?)>.*?\1>" para encontrar no solo el nombre del tag HTML sino Esta expresión regular encontrará tanto la cadena también sus atributos de la siguiente forma: "Esta" como la cadena "prueba" en el texto "Esta es una prueba" a Regex _TagParser = new Regex("<(?[apesar de que la expresión no contiene los literales“font” zA-Z]\w*?) ?(?.*?)>"); foreach(Match CurrentMatch in _TagParser.Matches(sText)){ String y “B”. sTagName = CurrentMatch. Groups["TagName"]. Otra forma de utilizar los grupos es en el lenguaje de proValue; String sAttributes = CurrentMatch. gramación que se esté utilizando. Cada lenguaje tiene una Groups["Attributes"]. Value; } forma distinta de acceder a los grupos. Los ejemplos enumerados a continuación utilizan las clases del .Net Framework, usando la sintáxis de C# (la cual puede fácil- Pero es posible ir mucho más allá de la siguiente forma: mente adaptarse a VB .Net o cualquier otro lenguaje del "(?[a-zA-Z][\w\r\n]*?) ?(?:(?[\w-\r\n]*?)='?"?(?[\w-:;,\./= \r\n]*?)'?"? Para utilizar el motor de búsqueda del .Net Framework ?)>" es necesario en primer lugar hacer referencia al espacio de nombres System.Text.RegularExpressions. Luego es Esta expresión permite encontrar el nombre de la etiquenecesario declarar una instancia de la clase Regex de la ta, el nombre del atributo y su valor. siguiente forma: Sin embargo, una etiqueta HTML puede tener más de un Regex _TagParser = new Regex("<([a-zA-Z]\w*?)>");
152 atributo. Este puede resolverse utilizando repeticiones de la siguiente forma: "(?[a-zA-Z][\w\r\n]*?) ?(?:(?[\w-\r\n]*?)='?"?(?[\w-:;,\./= \r\n]*?)'?"? ?)*?>" Y en el código puede utilizarse de la siguiente forma: Regex _TagParser = new Regex("(?[azA-Z][\w\r\n]*?)? (?:(?[\w-\r\n]*?)='?"? (?[\w-:;,\./= \r\n]*?)'?"? ?)*?>"); foreach(Match CurrentMatch in _TagParser.Matches(sText)){ String sTagName = CurrentMatch. Groups["TagName"]. Value; foreach(Capture CurrentCapture in CurrentMatch. Groups["Attribute"]. Captures){ AttributesCollection. Add(CurrentCapture. Value) } foreach(Capture CurrentCapture in CurrentMatch. Groups["value"]. Captures){ ValuesCollection. Add(CurrentCapture. Value) } } Es posible profundizar utilizando una expresión regular como esta: "(?[a-zA-Z][\w\r\n]*?) ?(?:(?[\w-\r\n]*?)='?"?(?[\w-:;,\./= \r\n]*?)'?"? ?)*?>(?.*?)\1>" La cual permitiría encontrar el nombre de la etiqueta, sus atributos, valores y el contenido de esta, todo con una sola expresión regular.
79.5 Enlaces externos • Editor regex en línea (en inglés) • Tutorial Expresiones Regulares en Python (en inglés) • Expresiones Regulares en Perl • Manual sobre Expresiones Regulares • Portal de Información Expresiones Regulares en General (en inglés)
CAPÍTULO 79. EXPRESIÓN REGULAR
Capítulo 80
Flag En programación, la bandera o flag se refiere a uno o más bits que se utilizan para almacenar un valor binario o código que tiene asignado un significado. Las banderas normalmente forman parte de una determinada estructura de datos, como un registro de una base de datos, y el significado del valor que figura en una bandera típicamente se definirá en relación a la estructura de datos de la que forma parte. En muchos casos el valor binario de la bandera se entenderá como la representación de uno de los posibles estados. En otras ocasiones, los valores binarios pueden representar uno o más atributos de un campo de bits, a menudo relacionados con habilidades o permisos, como “se puede escribir”o “puede ser borrado”. De todos modos, hay muchos otros posibles significados que pueden asignarse a los valores de la bandera. Un uso común de las banderas es marcar o designar estructuras de datos para un posterior tratamiento. Dentro de los microprocesadores y otros dispositivos lógicos, las banderas se utilizan mayoritariamente para controlar o indicar el estado intermedio o final o el resultado de diferentes operaciones. Por ejemplo, los microprocesadores suelen tener un registro de estado que se compone de varias de estas banderas que se usarán para indicar varias condiciones establecidas como resultado de una operación, como podría ser hacer notar que ha habido un desbordamiento en una operación aritmética. Una vez establecidas, las banderas pueden utilizarse en operaciones posteriores como el control de flujo en una operación de salto condicional. Por ejemplo, la instrucción en lenguaje ensamblador de Intel x86 je (salta si igual) comprobará el flag Z (cero) del registro de estado y si está establecido (por una operación anterior) ejecutará un salto a la dirección indicada. A los diferentes parámetros de control de una shell de línea de comandos también se les suele llamar banderas. Estas shells utilizan un analizador sintáctico para traducir los parámetros pasados en banderas al uso de las vistas en este artículo.
80.1 Véase también • Registro de estado
153
Capítulo 81
Front-end y back-end Front-end y back-end son términos que se refieren a la separación de intereses entre una capa de presentación y una capa de acceso a datos, respectivamente. Pueden traducirse al español el primero como interfaz, final frontal o frontal y el segundo como motor, dorsal final* [1]o zaga,* [2] aunque es común dejar estos términos en inglés.
presentación simbólico-fonética y el back-end convierte la representación fonética y simbólica en el sonido.
Muchos programas tienen su concepto de diseño dividido en front-ends y back-ends, pero en la mayoría de los casos, el back-end está oculto del usuario final y solo pueden utilizarlo el cliente intermedio o el administrador que se encargará de gestionar el sistema de información. Sin embargo, muchos programas están escritos para servir de simple front-end para otros que ya existen, como es el ca81.1 Informática so de las interfaces gráficas construidas sobre una interfaz de línea de órdenes. Este tipo de front-end es común en En diseño de software el front-end es la parte del software entornos de escritorio Unix (como los GUI), donde los que interactúa con el o los usuarios y el back-end es la programas son desarrollados siguiendo la filosofía de diparte que procesa la entrada desde el front-end. La se- seño de muchos programas pequeños capaces de ejecutarparación del sistema en front-ends y back-ends es un tipo se independientemente o combinados. de abstracción que ayuda a mantener las diferentes partes del sistema separadas. La idea general es que el front-end sea el responsable de recolectar los datos de entrada del 81.2 Tecnología usuario, que pueden ser de muchas y variadas formas, y los transforma ajustándolos a las especificaciones que demanda el back-end para poder procesarlos, devolviendo En radiotelescopios y antenas parabólicas, el front-end generalmente una respuesta que el front-end recibe y ex- consiste en un paquete que contiene a la antena de bopone al usuario de una forma entendible para este. La co- cina y a la guía de ondas, como un requisito para que las nexión del front-end y el back-end es un tipo de interfaz. antenas detecten la señal de radio. El back end se refiere al amplificador y al filtro que refina y modifica la señal En diseño web (o desarrollo web) hace referencia a la vi- antes de presentarla al usuario. sualización del usuario navegante por un lado (front-end), y del administrador del sitio con sus respectivos sistemas En la automatización de diseño electrónico, el ciclo del diseño, que es el front-end, equivale al diseño lógico y por el otro (back-end). eléctrico (ej. captura esquemática, síntesis lógica). A veMuchos métodos conocidos para interactuar con ordenaces el boceto de una estructura (del inglés floorplanning), dores pueden ser conceptualizados en términos de front- es considerado como un front-end. Un place and route end y back-end. Por ejemplo, un administrador de archi- (del idioma inglés, un lugar y ruta) o un diseño personavos gráfico como Windows Explorer, Dolphin, Nautilus lizado de la capa de verificación física (design rule checy Finder puede ser considerado como un front-end para king), o una disposición (layout) versus esquemática, son el sistema de archivos de la computadora. Otro ejemplo considerados como back-end. consiste en considerar al Shell como front-end que sirve como interfaz para interactuar con el núcleo del sistema En diseño de circuitos integrados de radiofrecuencia el front-end hace referencia a los bloques de la cadena de operativo que cumple el rol back-end. recepción que se encargan de filtrar, amplificar y traslaEn un compilador el front-end traslada el lenguaje del có- dar la señal de RF a banda base. Generalmente los blodigo fuente a una representación intermedia que a su vez ques comprendidos son balun, amplificador de bajo ruido funciona con el back-end para producir en la salida el có- (LNA), filtros y mezcladores de señal. Por otro lado, acdigo. tualmente las tecnologías de radio definida por software En sintetizadores del habla, el front-end se refiere a la par- (SDR) y radio cognitiva (CR), entre otras, implementan te del sistema que convierte la entrada del texto en una re- front-ends que no necesariamente integran todos los blo154
81.4. REFERENCIAS ques anteriormente citados.
81.3 Véase también • Arquitectura de software • Cliente-servidor • Programación por capas
81.4 Referencias [1] http://forum.wordreference.com/showthread.php?t= 215444 [2] http://es.bab.la/diccionario/ingles-espanol/back-end
155
Capítulo 82
Fuga de memoria Una fuga de memoria (más conocido por el término inglés memory leak) es un error de software que ocurre cuando un bloque de memoria reservada no es liberada en un programa de computación. Comúnmente ocurre porque se pierden todas las referencias a esa área de memoria antes de haberse liberado.
tos terminan su vida. A diferencia de la recolección de basura, RAII tiene las ventajas de: saber cuándo los objetos existen y saber cuándo no. Se puede comparar los siguientes ejemplos en C y C++:
/* Versión en C */ #include void f(int n) { int* array = calloc(n, sizeof(int)); realiDependiendo de la cantidad de memoria perdida y el zar_otras_operaciones(); free(array); } tiempo que el programa siga en ejecución, este proble- // Versión en C++. #include void f(int n) { ma puede llevar al agotamiento de la memoria disponible std::vector array (n); realizar_otras_operaciones(); en la computadora. } Este problema se da principalmente en aquellos lenguajes de programación en los que el manejo de memoria es manual (C o C++ principalmente), y por lo tanto es el programador el que debe saber en qué momento exacto puede liberar la memoria. Otros lenguajes utilizan un recolector de basura o conteo de referencias que automáticamente efectúa esta liberación. Sin embargo todavía es posible la existencia de fugas en estos lenguajes si el programa acumula referencias a objetos, impidiendo así que el recolector llegue a considerarlos en desuso.
La versión en C requiere que el desarrollador haga la liberación de memoria, a diferencia de la versión en C++. Esto evita la sobrecarga de los esquemas de la recolección de basura, e incluso puede ser aplicado a otros recursos como:
Existen varias formas de luchar contra este problema. Una forma es el uso de un recolector de basura incluso en el caso en el que éste no sea parte estándar del lenguaje. El más conocido recolector de basura usado de esta manera es el Boehm-Demers-Weiser conservative garbage collector. Otras técnicas utilizadas son la adopción de esquemas de conteo de referencias o el uso de pools de memoria (técnica menos popular, utilizada en el servidor Apache y en el sistema de versiones Subversion). También hay herramientas para“auscultar”un programa y detectar las fugas. Una de las herramientas más conocidas es Valgrind.
82.1 RAII
•“Handles”a archivos, que la recolección de basura “mark-and-sweep”no maneja tan efectivamente • Ventanas que han de ser cerradas • Iconos en el área de notificación que han de ser ocultados • Código de sincronización como monitores, secciones críticas, etc. que deben ser liberados para permitir que otros hilos de ejecución(“threads”) los obtengan •“Handles”al registro de Windows que están abiertos • Conexiones de red • Objetos GDI de Windows • Acciones a realizar cuando se termina una función (o bloque de código) en cualquier punto posible (la acción la realiza el destructor de un objeto creado cuando empieza la función)
"Adquirir Recursos es Inicializar", a menudo referido por sus siglas en inglés RAII (de “Resource Acquisi- 82.2 Fugas de memoria en lenguation Is Initialization”), es un popular patrón de diseño jes con recolector de basura en varios lenguajes de programación orientados a objetos como C++, y Ada. RAII soluciona las fugas de memoria relacionando objetos con los recursos adquiridos, y Las fugas de memoria en lenguajes como JavaScript tamautomáticamente liberando los recursos cuando los obje- bién son comunes, por ejemplo pueden ocurrir cuando 156
82.3. VÉASE TAMBIÉN hay referencias circulares entre los objetos. Por ejemplo un objeto ventana tiene una referencia a cada uno de sus controles (botones, imágenes, etc), a su vez cada control tiene una referencia a la ventana que lo contiene. Los recolectores de memoria que usan conteo de referencias pueden no darse cuenta que una ventana ya no es usada porque sigue habiendo referencia a ella (de sus controles). Estas fugas de memoria son muy comunes cuando se programa en forma despreocupada. Hay técnicas para evitarlas (por ejemplo eliminar alguna de las referencias para cortar el círculo). En JavaScript ocurren también referencias circulares cuando se escriben funciones dentro de otras, porque cuando una función es escrita dentro de otra se mantiene una referencia a la que la incluye (para poder usar sus variables). El concepto de clausura explica estos comportamientos.
82.3 Véase también • Memoria dinámica • Conteo de referencias • Recolector de basura
157
Capítulo 83
Generación de código En programación, la generación de código es una de las fases mediante el cual un compilador convierte un programa sintácticamente correcto en una serie de instrucciones a ser interpretadas por una máquina. La entrada en esta fase viene representada, típicamente, por un Árbol Sintáctico, un Árbol de Sintaxis Abstracta, o una Representación Intermedia; la máquina destino puede ser un microprocesador o una máquina abstracta tal como una máquina virtual o un lenguaje intermedio, legible por un humano. Compiladores más sofisticados realizan múltiples traducciones en cadena (pipelining) con el fin de poder construir código para múltiples plataformas y evitar tener que construir todas las capas del compilador. En términos más generales, la generación de código: es usada para construir programas de una manera automática evitando que los programadores tengan que escribir el código a mano. La generación de código puede realizarse en tiempo de ejecución, Tiempo de carga, o Tiempo de compilación. Los compiladores JIT son un ejemplo de generadores de código.
83.1 Enlaces externos • FRAWA Framework for Web Applications development • Frawa
158
Capítulo 84
Generador de números aleatorios internamente) un valor x0 , que llamaremos semilla, y, a partir de él, se van generando x1 , x2 , x3 , ... Siempre que se parta de la misma semilla, se obtendrá la misma secuencia de valores. Por la condición anterior, es evidente que todos los valores generados por este procedimiento son números enteros entre 0 y m−1 . El número máximo de cifras distintas que pueden obtenerse con el procedimiento descrito es m , así que llegará un momento en que el primer número generado se repetirá produciéndose un ciclo. El ciclo dónde inevitablemente caerá el generador interesa que sea de la mayor longitud posible (como máximo m Un generador de números aleatorios es un dispositivo ), para evitar que se repitan pronto los valores aleatorios. informático o físico diseñado para producir secuencias de Por ejemplo, para los valores a = 3 , c = 5 , x0 = 2 y m = 32 se obtiene la siguiente secuencia de valores: números sin un orden aparente. 2−11-6-23-10-3-14-15-18-27-22-7-26-19-30-312−11-6
84.1 Algoritmos
La secuencia generada tiene como longitud 16 números (el número generado en la decimoséptima posición es el Los algoritmos para la generación de valores uni- 2 inicial, por lo que toda la secuencia se repite a partir de formemente distribuidos están presentes en todas las ahí), muy inferior a la longitud máxima que podría tener calculadoras y lenguajes de programación, y suelen estar ( m =32). Determinadas elecciones de parámetros del gebasados en congruencias numéricas del tipo: nerador ( x0 , a , c y m ) conducen a ciclos de amplitud máxima. x ≡ (ax + c) (mod m) n+1
n
El éxito de este tipo de generadores de valores de una variable aleatoria depende de la elección de los cuatro parámetros que intervienen inicialmente en la expresión anterior:
• Si c≠0: • m.c.d.(c, m) = 1 • a ≡ 1 (mod p) para cada primo p de m • a ≡ 1 (mod 4) si 4 es divisor de m
• El valor inicial o semilla: x0
• Si c=0:
• La constante multiplicativa: a
• m es primo
• La constante aditiva: c • El número m respecto al cual se calculan los restos
• am−1/p ≡ 1 (mod m) La condición es que NO SEA congruente para cada factor primo p de m-1.
Estos cuatro valores deben ser números enteros no nega- Por ejemplo, tomando como valores m = 25 = 32 , tivos y que cumplan la siguiente condición: x0 , a, c < m a = 5 , x0 = 1 y c = 3 se obtiene la siguiente secuencia . de números, que tiene longitud máxima: La mayor parte de los generadores de números aleatorios 1−8-11-26-5-28-15-14-9-16-19-2-13-4-23-22-17-24son, en realidad, pseudoaleatorios; se calcula (o introduce 27-10-21-12-31-30-25-0-3-18-29-20-7-6-1 159
160
CAPÍTULO 84. GENERADOR DE NÚMEROS ALEATORIOS
El standard POSIX C define para la función de generación de números seudoaleatorios los valores de c = 12345 , m = 32768 y a = 1103515245 . Recientemente se ha descubierto que es posible generar verdaderos números aleatorios mediante software.* [1]* [2]* [3]
84.2 Bibliografía • Alberto, Marva; Schwer, Ingrid; Cámara, Viviana; Fumero, Yanina (2005). Matemática Discreta. Universidad Nac. del Litoral. p. 295. ISBN 9789875084315. • Blanco Castañeda, Liliana (2004). Probabilidad. textos. Univ. Nacional de Colombia. p. 295. ISBN 9789587014495.
84.3 Enlaces externos • Generador de números aleatorios on-line • Generador simple de números aleatorios on-line [1] True random numbers generator C++ [2] CPU Time Jitter Based Non-Physical True Random Number Generator [3] Software Random Number Generation Based on Race Conditions
Capítulo 85
Gledplay GledPlay es un SDK para desarrollar juegos para cepto de Sprite. Las características principales de Gleddispositivos móviles. Los juegos construidos con Gled- Draw son: Play corren sobre PC de escritorio con Microsoft Windows, PocketPC and Smartphones. • copiado rápido de superficies, con transparencia alpha blending o color clave. GledPlay contiene 4 módulos de desarrollo: • GledDraw: Un framework de gráficos 2D orientado a Superficies, basado en DirectDraw. • GledVideo: Un reproductor de video integrado con GledDraw. • GledSave: Un módulo de abstracción del Sistema de archivos, que permita la lectura y escritura de archivos en paquetes. • GledApplication: Un módulo específico para manejar los detalles de programación no relacionados con la lógica del juego.
• Cambio de tamaño, rotación, e inversión de superficies. • Carga de archivos JPG, GIF, PNG y BMP. • Escritura de archivos PNG y BMP. • Superficies de 3 o 4 canales para simplificar las operaciones con transparencia. • Escritura de texto, con fuentes normales o con alpha blended. • Manejo de animaciones • Clipping opcional
85.1 Dispositivos Soportados
• Utilización de Shaders del sistema o personalizados, para personalizar los efectos del copiado de superficies.
'GledPlay está construido para: • Microsoft Windows para computadores personales de escritorio. • Pocket PC
• Traducción de Surface desde o hacia un HDC, para permitir el uso de la librería estandard de windows GDI sobre las superficies. • Puntos, líneas, y rectángulos, con manejo de transparencia.
• Smartphones GledPlay fomenta el desarrollo sobre PC de escritorio, sin utilizar emuladores o dispositivos móviles reales. Una vez finalizado el desarrollo con GledPlay para computadores de escritorio, la aplicación se compila para las plataformas deseadas utilizando el mismo código. De esta manera se reduce el tiempo de desarrollo.
85.2 GledDraw GledDraw es un framework de gráficos 2D orientado a Superficies, basado en DirectDraw. Se maneja con entidades llamadas superficies, que serían similares al con161
• Clase panel, para utilizar coordenadas relativas en los métodos de dibujo, y facilitar la modularización. • Fullscreen en PC. (Los modos soportados son: 320X240, 640X480, 800X600, 1024X768) • Zoom X2 opcional en desktop PC para facilitar la detección de errores. • Soporte para Dispositivos de Altas Resoluciones (VGA en PPC, QVGA en SP, y dispositivos de pantallas cuadradas). • Soporte para Pocket Pcs y Smartphones con pantallas cuadradas.
162
85.3 GledVideo Las principales funcionalidades de GledVideo son: • reproducción de videos OGG Theora • Manejo de subtitulos, utilizando an archivo de subtitulos SubRip
85.4 GledSave GledSave provee un API común para acceder a diferentes sistemas de archivo, basado en Jakarta's Common Virtual File System. Es una interfaz simple que permite acceder a diferentes sistemas de la misma manera. Funciona para: • Computadores de escritorio con MS Windows. • Pocket PC • Smartphones • Archivos ZIP
85.5 GledApplication GledApplication maneja los detalles específicos de la programación que no están relacionadas con la lógica del juego como la inicialización de threads, el manejo de eventos, el ciclo del juego, los estados del juego, etc. • Manejo de la aplicación como inicio y fin. • Configuración de la máquina de estados para usar diferentes ciclos. • Manipulación de los fps.
85.6 Enlaces externos • GledPlay site(en inglés) • GledPlay source code • Wiki de GledPlay con tutoriales y artículos(en inglés) • Foro de GledPlay Forum en PocketMatrix
CAPÍTULO 85. GLEDPLAY
Capítulo 86
GPGPU GPGPU o General-Purpose Computing on Graphics Processing Units es un concepto reciente dentro de informática que trata de estudiar y aprovechar las capacidades de cómputo de una GPU.
que generalmente no se puede leer y escribir en la misma textura, si esta operación es imprescindible para el desarrollo del algoritmo, éste se debe dividir en varias pasadas.
Una GPU es un procesador diseñado para los cómputos implicados en la generación de gráficos 3D interactivos. Algunas de sus características (bajo precio en relación a su potencia de cálculo, gran paralelismo, optimización para cálculos en coma flotante), se consideran atractivas para su uso en aplicaciones fuera de los gráficos por computadora, especialmente en el ámbito científico y de simulación. Así, se han desarrollado técnicas para la implementación de simulaciones de fluidos, bases de datos, algoritmos de clustering, etc.
Pese a que cualquier algoritmo que sea implementable en una CPU lo es también en una GPU, esas implementaciones no serán igual de eficientes en las dos arquitecturas. En concreto, los algoritmos con un alto grado de paralelismo, sin necesidad de estructuras de datos complejas y con una alta intensidad aritmética son los que mayores beneficios obtienen de su implementación en la GPU.
86.1 Modelo GPU
de
programación
Debido a las diferencias fundamentales entre las arquitecturas de la GPU y la CPU, no cualquier problema se puede beneficiar de una implementación en la GPU. En concreto, el acceso a memoria plantea las mayores dificultades. Las CPU están diseñadas para el acceso aleatorio a memoria. Esto favorece la creación de estructuras de datos complejas, con punteros a posiciones arbitrarias en memoria. En cambio, en una GPU, el acceso a memoria está mucho más restringido. Por ejemplo, en un procesador de vértices (la parte de una GPU diseñada para transformar vértice en aplicaciones 3D), se favorece el modelo scatter, en el que el programa lee en una posición predeterminada de la memoria, pero escribe en una o varias posiciones arbitrarias. En cambio, un procesador de píxeles, o fragmentos, favorece el modelo gather, pudiendo el programa leer de varias posiciones arbitrarias, pero escribir en sólo una posición predeterminada. La tarea del diseñador de algoritmos GPGPU consiste principalmente en adaptar los accesos a memoria y las estructuras de datos a las características de la GPU. Generalmente, la forma de almacenar datos es en un buffer 2D, en lugar de lo que normalmente sería una textura. El acceso a esas estructuras de datos es el equivalente a una lectura o escritura de una posición en la textura. Puesto
86.2 Herramientas Tradicionalmente, el desarrollo de software GPGPU se había hecho bien en lenguaje ensamblador, o bien en alguno de los lenguajes específicos para aplicaciones gráficas usando la GPU, como GLSL, Cg o HLSL. Pero recientemente han surgido herramientas para facilitar el desarrollo de aplicaciones GPGPU, al abstraer muchos de los detalles relacionados con los gráficos, y presentar una interfaz de más alto nivel. Una de ellas es BrookGPU, desarrollada en la Universidad de Stanford, consistente en una extensión a ANSI C que proporciona nuevos tipos de datos y operaciones (“stream”, “kernel”, “reduction”, etc.) automáticamente convertidos a una implementación que aprovecha la GPU sin intervención explícita por parte del programador. Otra herramienta con objetivos similares es Sh, una extensión de C++ para metaprogramación con una implementación automática en la GPU. La opción más extendida en la actualidad es CUDA, de NVidia, una extensión de C que permite la codificación de algoritmos en GPU de NVidia. Por último, podemos incluir en esta discusión a OpenCL, una combinación de interfaz y lenguaje de programación para el desarrollo de aplicaciones paralelas que puedan ser ejecutadas, de forma transparente, en diversas unidades de procesamiento (CPU multinúcleo, GPU, etc.).
163
164
86.3 Críticas Pese a que las ventajas del uso de la GPU para ciertas aplicaciones es evidente, no faltan las críticas, generalmente referidas a la inconveniencia de usar un procesador para fines completamente diferentes a lo que se pensaba al diseñarlos. Un argumento común es la falta de continuidad de las arquitecturas usadas. Debido a la rápida evolución del hardware gráfico, implementaciones de algoritmos que funcionaban óptimamente en un modelo de GPU, dejan de hacerlo, o lo hacen subóptimamente en un modelo posterior. Otra crítica es la falta de precisión de los registros de coma flotante presentes en las GPU. Generalmente, se utilizan 2 o 4 bytes para representar un número real en una GPU, que en comparación con los 4, 8 o más usados en las CPU modernas, no es suficiente para muchas aplicaciones científicas.
86.4 Otros Microsoft ha terminado de desarrollar la nueva versión 11 de su API Direct3D. A pesar de que la anterior versión, Direct3D 10, es relativamente nueva, debido a la cantidad de novedades que están apareciendo últimamente en el mundo de las tarjetas gráficas, entre ellas el teselado, Microsoft desarrolló esta nueva versión, en la que cabe destacar la nueva tecnología de computación de “shaders”para permitir que la GPU no sea solamente usada para gráficos 3D y así puedan los desarrolladores tomar ventaja de las tarjetas gráficas como procesadores en paralelo. El proyecto de computación distribuida Folding@home, creado por la Universidad de Stanford, ha dado soporte para utilizar la potencia computacional de la GPU, además de la CPU. Pruebas recientes hablan de que son posibles ganancias de rendimiento de hasta 40 veces una CPU Intel Pentium 4, aunque claro, todo esto depende de la GPU utilizada.
86.5 Véase también • CUDA • Close to Metal • Graphics Processing Unit • Larrabee (GPU) • OpenCL • Intel MIC • Direct Rendering Manager
CAPÍTULO 86. GPGPU
86.6 Enlaces externos • Portal que aglomera noticias, publicaciones y enlaces sobre el avance de, GPGPU (en inglés). • Página del proyecto BrookGPU (en inglés). • Página de soporte GPU para Folding@home (en inglés). • Página del proyecto Sh (en inglés). • Explicación sobre sus posibilidades (en español). • Artículo que explica algunos beneficios (en inglés).
Capítulo 87
Hackathon Un hackathon o hackatón, es un término usado en las comunidades hacker para referirse a un encuentro de programadores cuyo objetivo es el desarrollo colaborativo de software, aunque en ocasiones puede haber también un componente de hardware. Estos eventos pueden durar entre dos días y una semana. El objetivo es doble: por un lado hacer aportes al proyecto de software libre que se desee y, por otro, aprender sin prisas.* [1]
[2] Caldeiro, Graciela; Merpert, Ariel y Odetti, Valeria. Nuestro primer Hackaton (2013). PENT, Flacso Argentina, Disponible en: http://www.pent.org.ar/publicaciones/ nuestro-primer-hackaton
87.2 Enlaces externos
El término integra los conceptos de maratón y hacker, aludiendo a un experiencia colectiva que persigue la meta común de desarrollar aplicaciones de forma colaborativa en un lapso corto. Se cree que el término fue creado en 1999 de forma independiente por los desarrolladores de OpenBSD y el equipo de marketing de Sun Microsystems. Algunos hackatons tienen propósitos educativos o sociales, aunque en muchos casos el objetivo es crear un software utilizable. Los Hackatons tienden a tener un enfoque específico, que puede incluir el lenguaje de programación utilizado, el sistema operativo, una aplicación, una API, el destinatario o el grupo demográfico de los programadores. En otros casos, no hay ninguna restricción sobre el tipo de software que está siendo creado en el evento. El hackatón, desde el punto de vista organizativo, supone una dinámica horizontal e intensiva en donde los participantes complementan experiencias y habilidades individuales con el propósito de desarrollar soluciones concretas. De allí que para los especialistas en educación, el hackatón posea ciertas características propias de un dispositivo pedagógico en tanto promueve el trabajo colaborativo entre pares orientado a la resolución de problemas, hace foco sobre el proceso de trabajo como instancia de aprendizaje y favorece la motivación intrínseca de los participantes. En 2015, en el campeonato de hackathon internacional en Barcelona, Pablo Pardo Alcócer, el representante de Bolivia, ganó el primer puesto.* [2]
87.1 Referencias [1] «Harán una hackatón para promover alternativas a los problemas porteños». diario “La nación”. Consultado el 13 de mayo de 2013.
165
• CyberCamp Hackathon organizado por el INCIBE • Hackathon en la Universidad de Granada • HackathonExpress en la Ciudad de Corrientes • El Club de Emprendedores de la CEU-UAO organiza el maratón “BCN Thinking Challenge”
Capítulo 88
Hacker El término hacker tiene diferentes significados. Según el diccionario de los hackers,* [1] es todo individuo que se dedica a programar de forma entusiasta, o sea un experto entusiasta de cualquier tipo, que considera que poner la información al alcance de todos constituye un extraordinario bien.* [2] De acuerdo a Eric Raymond el motivo principal que tienen estas personas para crear software en su tiempo libre, y después distribuirlos de manera gratuita, es el de ser reconocidos por sus iguales.* [3]El término hacker nace en la segunda mitad del siglo XX y su origen está ligado con los clubes y laboratorios del MIT.
depuran y arreglan errores en los sistemas (“White hats”) y a los de moral ambigua como son los“Grey hats”. • Una comunidad de entusiastas programadores y diseñadores de sistemas originada en los sesenta alrededor del Instituto Tecnológico de Massachusetts (MIT), el Tech Model Railroad Club (TMRC) y el Laboratorio de Inteligencia Artificial del MIT.* [5]Esta comunidad se caracteriza por el lanzamiento del movimiento de software libre.«How To Become A Hacker».El [[Request for
88.1 Otros significados
comments|RFC]] 1392* [6] amplia este significado como “persona que se disfruta de un conocimiento profundo del En informática, un hacker,* [4] es una persona que perte- funcionamiento interno de un sistema, en particular de nece a una de estas comunidades o subculturas distintas, computadoras y redes informáticas” Leer historia del pero no completamente independientes: término • La comunidad de aficionados a la informática doméstica, centrada en el hardware posterior a los setenta y en el software (juegos de computadora, crackeo de software, la demoscene) de entre los ochenta/noventa. • Se utiliza la palabra Hacker, para describir a una persona que practica la programación informática, con una especie de pasión artística, o que forma parte de la cultura de los hackers, es decir al grupo de programadores que históricamente están en los orígenes de Internet, en Linux y en la World Wide Web.
El emblema hacker, un proyecto para crear un símbolo reconocible para la percepción de la cultura hacker.
• Desde que se usó por primera vez la palabra Hacker ésta ha sido mal utilizada, mal interpretada y encasillada en un contexto errado, antes que nada, aclaremos que el término Hacker no tiene nada que ver con actividades delictivas, si bien muchos Hackers cometen errores, la definición no tiene nada que ver con ello.
• En seguridad informática este término concierne principalmente a entradas remotas no autorizadas por medio de redes de comunicación como Internet “ ( Black hats”). Pero también incluye a aquellos que
• Definición 1: Término para designar a alguien con talento, conocimiento, inteligencia e ingenio, especialmente relacionadas con las operaciones de computadora, redes, seguridad, etc.
166
88.2. HISTORIA
167
• Definición 2: Persona que disfruta aprendiendo de- Los hackers de MIT crearon su propio sistema operativo, talles de los sistemas de programación y cómo ex- el ITS que usaba el lenguaje LISP.* [10] tender sus capacidades, tan intensamente como, al contrario, muchos usuarios prefieren aprender sólo 88.2.2 UNIX el mínimo necesario. No obstante, más allá de las definiciones del término “Hacker”vinculadas al mundo informático o tecnológico, cabe destacar el uso de esta palabra por extensión (y de hecho así fue en sus inicios el origen de la misma) a toda persona que implementa soluciones para cualquier sistema, sea informático o no, de manera que éste pueda emplearse de formas no pensadas por quienes crearon dichos sistemas. Así mismo, el término Hacker está indisolublemente unido a toda persona que manipula o que posee conocimientos prácticos que modifican los usos de Placa que dice“vive libre o muere UNIX* *marca registrada de las cosas de modo que éstas puedan emplearse para fines laboratorios Bell no previstos en su origen. De ahí el uso de los términos de“hackeado”como sinónimo de“alterado en su fines” Al mismo tiempo que ARPANET nacía, también era para cumplir otras funciones. creado el sistema
88.2 Historia En 1961 el MIT, el Massachusetts Institute of Technology, adquirió la microcomputadora PDP-1, lo que atrajo la curiosidad de un grupo de estudiantes que formaban parte del Tech Model Railroad Club, TMRC, ya que podrían interactuar directamente con ella mediante códigos de programación. Debido a que la microcomputadora tardaba mucho en encender, se quedaba prendida toda la noche haciendo que los miembros del TMRC tuvieran acceso a ella y pudieran empezar a experimentar, uno de los logros más famosos de estos experimentos fue la creación del videojuego Spacewar. Tiempo después algunos miembros del TMRC se volvieron miembros del Laboratorio de Inteligencia Artificial del MIT y se llevaron con ellos la tradición de jugarse bromas inocentes entre ellos, a las cuales llamaban hacks. Fueron los miembros de este laboratorio los primeros en autonombrarse hackers.* [7] Esta comunidad se caracteriza por el lanzamiento del movimiento de software libre. La World Wide Web e Internet en sí misma son creaciones de hackers.* [8]
88.2.1
ARPANET
Después de 1969 el laboratorio de Inteligencia Artificial del MIT fue conectado a la ARPANET desde donde pudo tener contacto con otros departamentos de investigación informática de otras universidades como Stanford y Bolt Beranek & Newman. Con ésta nueva forma de comunicación los estudiantes empezaron a colaborar con otros a pesar de la distancia. A partir de este momento se empezó a formar una cultura y nació el Jargon file, documento que tenía una lista de términos que se usaban en su jerga coloquial y que se originó en Standford en 1987..* [9]
operativo UNIX en los laboratorios bell. UNIX, junto con el lenguaje C eran muy portables y compatibles con las máquinas, de hecho UNIX tenía incluso su propia conexión con otras máquinas que tuvieran UNIX y el cual recibió el nombre de Usenet. Para 1980 los primeros sitios en Usenet empezaban a transmitir noticias, formando una gran red de distribución que crecería más que ARPANET.* [11] Ambos grupos de hackers estaban divididos y era poco común que alguien que usara UNIX también usara ARPANET. En 1983 se canceló la distribución de la PDP10, la cual fuera una de las microcomputadoras favoritas de los hackers y en la cual se construyó el ITS. Después de la cancelación de esta microcomputadora por parte de la Digital Equipment Corporation la variante de UNIX creada en Berkeley se convirtió en el sistema hacker por excelencia,* [12] y fue por esa época que Richard M. Stallman, inventor del editor Emacs, creó la Free Software Foundation
88.2.3 GNU En 1983 Stallman buscaba crear un propio sistema operativo de tipo UNIX que estuviese disponible de forma libre* [13], y fundó el proyecto GNU (acrónimo de GNU No es UNIX). Stallman sustituyó el copyright o todos los derechos reservados, por el copyleft o todos los derechos reversados, con lo que buscaba que cualquier programa publicado en la red por la FSF pudiera ser utilizado y modificado bajo una licencia de la Fundación y con la condición de difundir las modificaciones que se llegasen a hacer al programa también respetando las libertades del usuario. Otro de sus logros fue haber popularizado el término "software libre" en un intento de conseguir su objetivo y ponerle nombre al producto de toda cultura hacker.* [14]
168
88.2.4
CAPÍTULO 88. HACKER
LINUX
muy poca ética”y la catalogan como“un grito de batalla -que- no pone límites a los hackers”* [18] Sin embargo, para otras personas, como Linus Torvalds ésta ética va de acuerdo al trabajo del hacker que es “interesante, emocionante y algo que se goza”, adjetivos que en ocasiones son usados por los mismos hackers para describir su trabajo, lo que también limita la restricción que tienen sobre la libertad de usar información.* [19]
En 1991, un estudiante de la Universidad de Helsinki, Linus Torvalds diseñaba su propio UNIX sobre la base de la fundación y publicó la fuente de su código en la red pidiendo ayuda para perfeccionarlo. Con ayuda de cientos de programadores que se pusieron a la tarea de ayudar a Linux con el código, se desarrolla el sistema operativo Linux, que originalmente tenía el nombre de Freix. Hoy De acuerdo a Raymond, la ética social del hacker se basa en día es promocionado por diferentes gobiernos, como en tres principios: el de Francia, y siempre está en código abierto y sin derechos de propiedad sobre él.* [15] 1. La creencia de que compartir información es bueno
88.3 Ética hacker
2. Que los hackers tienen una responsabilidad ética de compartir la información con la que trabajan 3. Que los hackers deberían facilitar el acceso a computadoras cuando sea posible* [20]
88.4 Controversia
Steven Levy, autor de Hackers: heroes of the computer revolution
En 1984, Steven Levy publica el libro Hackers: heroes of the computer revolution en el cual se ve por primera ocasión la idea de la ética hacker, donde se manifiesta una ética de libre acceso a la información y código fuente del software. Levy se basó en entrevistas para poder identificar seis principios básicos relacionados con las creencias y operaciones de hackers para hacer ésta ética.* [16] De acuerdo a Levy los seis fundamentos del hacker son:
En la actualidad se usa de forma corriente para referirse mayormente a los criminales informáticos, debido a su utilización masiva por parte de los medios de comunicación desde la década de 1980.* [21] Según Helen Nissenbaum que los hackers sean mal vistos ayuda al gobierno y a los poderes privados con dos cosas: 1) a definir lo que es normal en el mundo computacional haciendo creer que un buen ciudadano es todo lo que el hacker no es; 2) a justificar la seguridad, la vigilancia y el castigo.* [22] A los criminales se le pueden sumar los llamados "script kiddies", gente que invade computadoras, usando programas escritos por otros, y que tiene muy poco conocimiento sobre cómo funcionan. Este uso parcialmente incorrecto se ha vuelto tan predominante que, en general, un gran segmento de la población no es consciente de que existen diferentes significados.
Mientras que los hackers aficionados reconocen los tres 1. El acceso a los computadores debe ser ilimitado y tipos de hackers y los hackers de la seguridad informática aceptan todos los usos del término, los hackers del total. software libre consideran la referencia a intrusión informática como un uso incorrecto de la palabra, y se re2. Toda información debería ser libre fieren a los que rompen los sistemas de seguridad como 3. Es necesario promover la descentralización y des- "crackers" (analogía de “safecracker”, que en español confiar de las autoridades se traduce como “un ladrón de cajas fuertes”). 4. Los hackers deberían ser juzgados por su labor y no por cosas como su raza, edad o posición social
88.4.1 Ambigüedad y debate
5. Se puede crear arte y belleza en un computador Los términos hacker y hack pueden tener connotaciones 6. Las computadoras pueden cambiar tu vida para me- positivas y negativas. Los programadores informáticos jor* [17][www.hackerethic.org] suelen usar las palabras hacking y hacker para expresar admiración por el trabajo de un desarrollador cualificado Sin embargo, la ética hacker genera controversia y hay de soporte lógico, pero también se puede utilizar en un personas, como el estudiante de derecho Patrick S. Ryan sentido negativo (delincuentes informáticos) para descrique critican que la [[ética hacker]] y consideran que“hay bir una solución rápida pero poco elegante a un problema.
88.6. TERMINOLOGÍA Algunos* [¿quién?] desaprueban el uso del hacking como un sinónimo de cracker, en marcado contraste con el resto del mundo,* [¿dónde?] en el que la palabra hacker se utiliza normalmente para describir a alguien que se infiltra en un sistema informático con el fin de eludir o desactivar las medidas de seguridad.* [23]
169 clasificada que se considera debe estar, por definición, a disposición de la sociedad (casos de WikiLeaks o las filtraciones de Snowden sobre las actividades militares y casos de espionaje gubernamentales).
Por tanto, el fenómeno hacker tiene un importante componente de aperturismo y liberación de conocimientos e En un principio se utilizaba “hack”como verbo para información que, a través del activismo de estos especiaexpresar “perder el tiempo”(e.j. “Puedo hackear con listas, benefician a la sociedad en general. el computador”), el significado del término ha cambiado En este caso, los roles de un hacker pueden entenderse en a lo largo de décadas desde que empezó a utilizarse en un cuatro aspectos: contexto informático. Como su uso se ha extendido más ampliamente, el significado primario de la palabra, por • Apoyar procesos de apropiación social o comunitaparte de los nuevos usuarios, ha pasado a uno que entra ria de las tecnologías. en conflicto con el énfasis original.
88.5 Activismo
• Poner a disposición del dominio público el manejo técnico y destrezas alcanzadas personal o grupalmente. • Crear nuevos sistemas, herramientas y aplicaciones técnicas y tecnológicas para ponerlas a disposición del dominio público. • Realizar acciones de hacktivismo tecnológico con el fin de liberar espacios y defender el conocimiento común y abierto.
88.6 Terminología En sentido amplio el término Hacker o Hacking se puede asociar a movimientos sociales que promueven cambios en los modos de vida.
Desde el año 2002-2003, se ha ido configurando una perspectiva más amplia del hacker, pero con una orientación a su integración al hacktivismo en tanto movimiento. Aparecen espacios autónomos denominados hacklab o hackerspace y los hackmeeting como instancias de diálogo de hackers. Desde esta perspectiva, se entiende al hacker como una persona que es parte de una conciencia colectiva que promueve la libertad del conocimiento y la justicia social. Se entiende, por tanto, el Hacktivismo como el empleo de las destrezas técnicas más diversas, en pro de fines sociales, ecológicos, humanitarios o de cualquier otra índole con repercusión o tendente a la defensa de los derechos humanos. Así, el Hacktivismo debe ser entendido no desde un prisma reduccionista como equivalente siempre al desarrollo de actividades subversivas. Encontramos ramificaciones del hacktivismo en la liberación de conocimiento (como puede ser la misma Wikipedia, en la que los conocimientos informáticos y técnicos de sus creadores dieron lugar a toda una revolución en el modo de crear y compartirse el conocimiento humano más allá de barreras académicas o comerciales); O en la liberación de información
88.6.1 OverHat Un término acuñado a mediados del año 2014 por un Hacker de la comunidad Underground llamado T4r4t3uX* [24], quien definió como “sobre el sombrero”a todos los profesionales vinculados con las artes Hacking. En un corto escrito, explica como a través del tiempo deben comprender y aprender todas las formas existentes de“Hackeo”. Lo cual causa una doble moral, por un lado existe la ética a la cual han sido fieles y por ello prestan servicios profesionales a miles de empresas en el mundo asegurando su infraestructura; por otro, conocer y usar métodos propios de los BlackHat que incluyen ataques de denegación de servicio e ingeniería social agresiva entre otros. Según el escrito, están por encima del bien y del mal electrónico, lo cual concluye que solo una amplia capacidad moral autodeterminada por ellos mismos los convierte en profesionales con la capacidad de determinar adecuadamente y con las regulaciones de la actual sociedad.
88.6.2 White hat y black hat Un hacker de sombrero blanco (del inglés, white hat), en jerga informática, se refiere a una ética hacker que se centra en asegurar y proteger los sistemas de tecnologías
170
CAPÍTULO 88. HACKER
de la información y la comunicación.* [25] Estas perso- 88.6.5 Lamer o script-kiddie nas suelen trabajar para empresas de seguridad informática las cuales los denominan, en ocasiones, «zapatillas o Es un término coloquial inglés aplicado a una persona falequipos tigre».* [26] ta de habilidades técnicas, generalmente no competente Por el contrario, los hackers de sombrero negro (del en la materia, que pretende obtener beneficio del hacinglés, black hat), también conocidos como "crackers" king sin tener los conocimientos necesarios. Su alcance muestran sus habilidades en informática rompiendo sis- se basa en a buscar y descargar programas y herramientas temas de seguridad de computadoras, colapsando servi- de intrusión informática, cibervandalismo, propagación dores, entrando a zonas restringidas, infectando redes o de software malicioso para luego ejecutarlo como simple apoderándose de ellas, entre otras muchas cosas utilizan- usuario, sin preocuparse del funcionamiento interno de estos ni de los sistemas sobre los que funcionan. En mudo sus destrezas en métodos hacking. chos casos presume de conocimientos o habilidades que En los últimos años, los términos sombrero blanco y no posee. sombrero negro han sido aplicados a la industria del posicionamiento en buscadores (search engine optimization, SEO), originando la denominación black hat SEO. 88.6.6 Newbie Las tácticas de posicionamiento en buscadores de los hackers de sombrero negro, también llamada spamdexing, in- Newbie es un alguien nuevo al hacking o al phreaking tento de redireccionar los resultados de la búsqueda a pá- y que no posee casi nada de conocimiento o experienginas de destino particular, son una moda que está en con- cia en el manejo de tecnología y hacking. El origen del tra de los términos de servicio de los motores de busque- término es incierto. Usos más tempranos probablemente da, mientras que los hackers de sombrero blanco, utilizan datan de finales del siglo XX Estados Unidos Fuerzas Armétodos que son generalmente aprobados por los motores madas jerga , aunque posibles términos precursoras son de búsqueda. mucho más temprano. Formas variantes del nombre incluyen Newby y newbee, mientras que el término relacionado novato (n00b menudo deletreado) se utiliza a menudo en los juegos en línea.
88.6.3
Samurái
Normalmente es alguien contratado para investigar fallos de seguridad, que investiga casos de derechos de privacidad, esté amparado por la primera enmienda estadounidense o cualquier otra razón de peso que legitime acciones semejantes. Los samuráis desdeñan a los crackers y a todo tipo de vándalos electrónicos. También se dedican a hacer y decir cómo saber sobre la seguridad con sistemas en redes* [27]
88.6.4
Phreaker
De phone freak (“monstruo telefónico”). Son personas con conocimientos amplios tanto en teléfonos modulares (TM) como en teléfonos móviles. La meta de los phreakers es generalmente superar retos intelectuales de complejidad creciente, relacionados con incidencias de seguridad o fallas en los sistemas telefónicos, que les permitan obtener privilegios no accesibles de forma legal. El término “Phreak”es una conjunción de las palabras phone (teléfono en inglés), hack y freak (monstruo en inglés). También se refiere al uso de varias frecuencias de audio para manipular un sistema telefónico, ya que la palabra phreak se pronuncia de forma similar a frequency (frecuencia).
88.7 Véase también 88.8 Referencias [1] Jargon file, The Jargon File, version 4.4.8, sitio digital 'Catb'. [2] {{cita libro|apellidos1=Himanen|nombre1=Peka|título=La ética del hacker y el espíritu de la era de la información|fecha=2002|páginas=5-11|fechaacceso=9 de febrero de 2015}} [3] {{cita libro|apellidos1=Raymond|nombre1=Eric|título=The Art of Unix Programming|fecha=2003|páginas=8791|url=http://www.catb.org/esr/writings/taoup/ html/|fechaacceso=9 de febrero de 2015}} [4] «Hacker culture(s): Origins». Archivado desde el original el 30 de noviembre de 2015. [5] http://www.catb.org/~{}esr/writings/cathedral-bazaar/ hacker-history/ar01s02.html [6] «RFC 1392 - Internet Users\x27 Glossary». [7] Raymond, Eric (2003). The Art of Unix Programming. pp. 87–91. Consultado el 9 de febrero de 2015. [8] {{cita web | url =http://catb.org/~{}esr/faqs/ hacker-howto.html#what_is | título =How To Become A Hacker }}
88.9. DESCRIPCIÓN
171
[9] {{cita libro|apellidos1=Raymond|nombre1=Eric|título=The [23] {{cita publicación|apellido=Rodríguez|nombre=Pablo Art of Unix Programming|fecha=2003|páginas=87Gustavo|título=La criminalización discursiva de los 91|url=http://www.catb.org/esr/writings/taoup/ hackers en los medios de prensa|publicación=VII html/|fechaacceso=9 de febrero de 2015}} Jornadas Nacionales de Investigadores en Comunicación|fecha=18 de septiembre de 2004|año=2004|url=http: [10] Raymond, Eric Steven (2000). A Brief History of Hacker//sedici.unlp.edu.ar/handle/10915/5347|fechaacceso=19 dom. de junio de 2014}} [11] Raymond, Eric Steven (2000). A Brief History of Hackerdom. [12] {{cita libro|apellidos1=Raymond|nombre1=Eric Steven|título=A Brief History of Hackerdom|fecha=2000|fechaacceso=12 de febrero de 2015}} [13] {{cita web|url=http://gnu.org
[24] [25] [http://searchsecurity.techtarget.com/sDefinition/0, ,sid14_gci550882,00.html ¿Qué es sombrero blanco? una definición de Whatis.com (en inglés)] [26] [http://www.catb.org/jargon/html/T/tiger-team.html tiger team (en inglés)]
[14] {{cita libro|apellidos1=Raymond|nombre1=Eric|título=The [27] «Delitos Informaticos - Hacking». Consultado el 2009. Art of Unix Programming|fecha=2003|páginas=8791|url=http://www.catb.org/esr/writings/taoup/ html/|fechaacceso=9 de febrero de 2015}}
88.9 Descripción
[15] Castells, Manuel (2003). «Internet, libertady sociedad: una perspectiva analítica». Polis.Revista Latinoamericana. Consultado el 8 de febrero de 2015.
• Definición de hacker en el Jargon File (inglés)
[16] {{cita publicación|apellidos1=Greenhill|nombre1=Kathryn|título=Transformando la biblioteca pública: de conservadores de ediciones impresas a creadores de contenido digital|publicación=Congreso Nacional de Bibliotecas Públi• Wikimedia Commons alberga contenido multicas|fecha=2010|url=http://www.mcu.es/bibliotecas/ media sobre HackerCommons. docs/MC/2010/CongresoBP/KathrynGreenhill. pdf|fechaacceso=9 de febrero de 2015}} • Oficina Federal de Investigaciones (en inglés) y (en
88.10 Enlaces externos
[17] {{cita libro|apellidos1=Levy|nombre1=Steven|título=Hackers: heroes of the computer revolution|fecha=1984|fechaacceso=12 de febrero de 2015}}
español) •
Contact Us En Español (Sic) [18] {{cita publicación|apellidos1=Ryan|nombre1=Patrick|título=War, Peace, or Stalemate: Wargames, Wardialing, Wardriving and the Emergint Market for Hacker Ethics.|publicación=Papers.ssrn.com|url=http: //papers.ssrn.com/sol3/papers.cfm?abstract_id= 585867|fechaacceso=5 de febrero de 2015}} [19] {{cita publicación|apellidos1=Chance|nombre1=Tom|título=The Hacker Ethic and Meaningful Work|fecha=2005|url=http: //flosshub.org/system/files/chance.pdf|fechaacceso=12 de febrero de 2015}} [20] {{cita publicación|apellidos1=Chance|nombre1=Tom|título=The Hacker Ethic and Meaningful Work|fecha=2005|url=http: //flosshub.org/system/files/chance.pdf|fechaacceso=12 de febrero de 2015}} [21] {{cita libro|apellidos1=Himanen|nombre1=Peka|título=La ética del hacker y el espíritu de la era de la información|fecha=2002|páginas=5-11|fechaacceso=9 de febrero de 2015}} [22] {{cita publicación|apellidos1=Nissenbaum|nombre1=Helen|título=Hackers and the contested ontology of cyberspace|publicación=New Media & Society|fecha=2004|volumen=6|número=2|páginas=195217|doi=10.1177/1461444804041445|fechaacceso=12 de febrero de 2015}}
Capítulo 89
Heisenbug En jerga de programación, un heisenbug es un tipo de bug que parece desaparecer o comportarse de otro modo al intentar ser observado en detalle.* [1] El término es un juego de palabras a partir del nombre de Werner Heisenberg, el físico que dedujo el efecto de observación de la mecánica cuántica, según el cual el mero hecho de observar un sistema de una manera determinada altera el estado de este.
89.2 Enlaces externos
Términos similares como bohrbug, mandelbug,* [2]* [3]* [4] y schrödinbug* [5]* [6] han sido propuestos ocasionalmente para otro tipo de bugs inusuales;* [7]* [8] de todos modos, no son tan conocidos ni empleados como el “heisenbug”.* [9]
89.1 Referencias [1] «The Jargon File: heisenbug». [2] «The Jargon File: Mandelbug». Catb.org. Consultado el 5 de septiembre de 2013. [3] Raymond, Eric S.; The New Hacker's Dictionary, 3rd edition, 1996 [4] Clarke, Arthur C., The Ghost from the Grand Banks, Bantam Books, 1990 [5] «The Jargon File: Schroedinbug». Catb.org. Consultado el 5 de septiembre de 2013. [6] Raymond, Eric S.; The New Hacker's Dictionary, 3rd edition, 1996 [7] The following article investigates the various definitions of bohrbug, mandelbug and heisenbug proposed in the literature, as well as the statements made about the relationships between these fault types: Grottke, Michael; and Trivedi, Kishor S.; Software Faults, Software Aging and Software Rejuvenation, Journal of the Reliability Engineering Association of Japan, Vol. 27, No. 7, pp. 425-438, 2005. [8] Grottke, Michael; and Trivedi, Kishor S.; Fighting Bugs: Remove, Retry, Replicate, and Rejuvenate, IEEE Computer vol. 40, no. 2 (February 2007), pp. 107-109 [9] A February 2012 Google Books search returns about 70 hits for “schroedinbug”, 100 for “mandelbug”, 400 for “bohrbug”or “heisenbug”.
172
• The Heisenberg Debugging Technology • A Story About Magic
Capítulo 90
Hoja de estilo Las hojas de estilo (style sheets) son conjuntos de instrucciones, a veces en forma de archivo anexo, que se asocian a los archivos de texto y se ocupan de los aspectos de formato y de presentación de los contenidos: tipo, fuente y tamaño de letras, alineación y posicionamiento del texto, colores y fondos, etc. Las hojas de estilo permiten liberar la composición del texto de los aspectos visuales y favorecen que se estructure y anote mediante códigos que permiten un tratamiento más eficaz de los contenidos. El uso adecuado de las hojas de estilo es uno de los aspectos clave de la edición digital. Las hojas de estilo son una herramienta de gran utilidad de los programas de tratamiento de textos, como OpenOffice.org o Microsoft Word. Asimismo, constituyen una parte esencial de los lenguajes de marcas para edición digital: LaTeX, XML y XHTML. Dos lenguajes de hojas de estilo son CSS y XSL.
• Hojas de estilo para la Web: Trucos y sugerencias para CSS (Este documento es una traducción del tutorial “CSS tips & tricks”propiedad de Bert Bos publicado en el sitio de W3C.)
90.3 Referencias
90.1 Véase también • Em (tipografía) • LaTeX • XML • XHTML • CSS • XSL • CMS
90.2 Enlaces externos • Ejercicios de Hojas de Estilo, preparados para un curso de edición digital de la Universidad de Deusto. • Tutorial de Hojas de Estilo, con ejemplos y el listado de las propiedades reconocidas. • Hojas de Estilo Web (Este documento es una traducción del documento“Web Style Sheets”propiedad de Bert Bos publicado en el sitio de W3C.) 173
Capítulo 91
Hola mundo 91.2 Enlaces externos • Hello World! Más de 200 ejemplos de Hola Mundo (en inglés). Versión del sitio guardada en el Internet Archive. • The Hello World Collection Otra extensísima lista de ejemplos (en inglés). Resultado de la ejecución de un programa Hola mundo en una Interfaz gráfica de usuario.
91.3 Referencias
En informática, un programa Hola mundo es el que imprime el texto «¡Hola, mundo!» en un dispositivo de visualización, en la mayoría de los casos una pantalla de monitor. Este programa suele ser usado como introducción al estudio de un lenguaje de programación, siendo un primer ejercicio típico, y se lo considera fundamental desde el punto de vista didáctico. El programa Hola Mundo también puede ser útil como prueba de configuración para asegurar que el compilador, el entorno de desarrollo y el entorno de ejecución estén instalados correctamente y funcionando. En algunos lenguajes, configurar un conjunto de herramientas básicas completo desde cero hasta el punto en que los programas triviales puedan ser compilados y ejecutados involucra una cantidad de trabajo sustancial. Por esta razón, generalmente es usado un programa muy simple para probar un nuevo conjunto de herramientas. En los sistemas basados en microcontroladores empleados para el aprendizaje, se suele considerar “Hola mundo”al programa que permite poner en modo intermitente un led.* [1] El programa consiste en mandar alternativamente un nivel alto y uno bajo por uno de los puertos del sistema, dando a cada uno de dichos niveles un valor de retardo.
91.1 Véase también • Ejemplos de implementación del «Hola mundo» 174
[1] González, Juan (2008). «Taller de Robótica Básico - Skybot v1.4. - SESION 3 - “Hola mundo“en Linux». Consultado el 12 de abril de 2009.
Capítulo 92
Homebrew alterar el normal funcionamiento del ordenador en forma de virus informático son en su mayoría programas homebrew también. Este amplio colectivo ha dedicado su esfuerzo en forma de trabajo individual o en proyectos comunes que van acumulando en internet funcionalidades y librerías de código abierto que son utilizadas y ampliadas por nuevos programadores autodidactas. El homebrew es importante porque: abre las puertas a que muchos de los aficionados a desarrollarlo puedan conseguir un empleo remunerado y, además, a que otros desarrolladores continúen ampliando el uso comercial de nuevos y viejos productos, a que surja la posibilidad profeCaptura de pantalla de Duck Attack!, homebrew para Atari sional de nuevos sistemas operativos, se amplíe la oferta 2600. de aplicaciones... etc. Lo que conlleva a la evolución tecnológica de la sociedad y al abaratamiento de recursos Se suele denominar homebrew (software casero no ofique de otra manera solo estarían disponibles para unos cial) a las aplicaciones y juegos creados por programapocos privilegiados. dores -aficionados y expertos- para cualquier plataforma, * generalmente videoconsolas propietarias. [1] Reciente- Aunque su uso más conocido es la creación de softwamente, se han desarrollado consolas diseñadas específi- re para videoconsolas recreativas portátiles o de sobrecamente para la ejecución de software homebrew, el cual mesa, se ha adaptado software desarrollado para cualquier tipo de aparato; como software original libre en prose caracteriza por ser gratuito y en su mayoría abierto. gramas operativos para maquinaria computerizada industrial, diccionarios y agendas electrónicas, teléfonos, emisores o receptores de gps, maquinaria de uso médico y 92.1 Generalidades ordenadores actuales o antiguos de los 80 y 90, que ya no están a la venta por lo sencillo de su interfaz. El softwaHomebrew consiste en software de todo tipo creado por re nuevo original se ha desarrollado muchas veces como programadores aficionados o expertos. Ya los primeros prácticas en lenguajes informáticos relativamente poco programas desarrollados por la industria privada en los conocidos como C++, LUA, Palib, etc, o por otros moinicios de la informática, eran juegos y, poco más tar- tivos. Son muy conocidos por ser noticia desarrollos de de, aplicaciones de ofimática hechas en casa por aficio- lenguajes de programación cuyo uso afecta a millones de nados. Hoy en día, en la mayoría de los casos conocidos, personas o algoritmos con aplicaciones homebrew destilos programas homebrew son versiones de prueba com- nadas a la industria, agricultura, banca, tratamiento mépartidas como freeware o shareware que se distribuyen dico, lectura, enseñanza... y que vuelven millonarios a sus libremente por internet. Muchas veces, estas herramien- creadores. Algunos autores incluso han realizado su softtas han sido desarrolladas en importantes universidades ware para optar a premios de entidades públicas o privapor grupos de estudiantes que distribuyen versiones de das, obtener becas de especialización o conseguir un emprueba de su software bajo licencias de uso público y sin pleo remunerado. Aparte de la tradicional forma de pago, afán de lucro, aunque también hay programadores a ni- existen otros autores que se conforman con menos, desde vel individual que desarrollan interesantes aplicaciones los que llegan al presupuesto insertando publicidad en su autodidactas que desde su domicilio particular llegan a software o los que se ven recompensados por el reconodiversas partes del mundo y de este modo le dan a co- cimiento del público, como ocurrió en el caso del autor nocer como autor creativo o prestigian el nivel tecnoló- de Facebook. Muchas de las licencias empleadas por los gico del autor o de su país. Ejemplos muy conocidos son creadores permiten el uso gratuito de su software, siemAudacity y Emule. Los malwares que tienen por objeto 175
176 pre y cuando se respeten sus derechos y se les acredite como autores del mismo. Muchas veces podemos mandar un mensaje de felicitación si nos ha gustado su trabajo o ponernos en contacto con el autor o los autores o con sus representantes para fines particulares o comerciales. Muchas empresas privadas han comercializado legalmente el software creado en un principio como homebrew.
CAPÍTULO 92. HOMEBREW
integrados para el usuario se utilizan dentro de los cartuchos de NES para ampliar las capacidades del sistema, la mayoría son difíciles de replicar, excepto al eliminar cartuchos usados. El mecanismo de bloqueo de hardware de la NES complica aún más la construcción de cartuchos físicos utilizables. Sin embargo, la NES-101 elimina el chip de cierre 10NES para cualquier juego, ya sea homeLa palabra «homebrew» tiene relación con el Homebrew brew, sin licencia, o de otra región de un partido oficial, se reproduce. El chip 10NES finalmente se puede desacComputer Club, aunque se desconoce si fue éste el origen. En Japón estos juegos son llamados Dojin Soft, que tivar de forma permanente mediante la realización de un pequeño cambio en el hardware. es la manera de decir que este software no es ilegal, en principio, aunque depende del uso que se haga de él. Suele cuestionarse la legalidad del homebrew; sin embargo, su uso está muy extendido entre los usuarios avanzados. 92.2.3 Super Nintendo Entertainment Además, su uso, excluyendo las copias de seguridad no System (SNES) propietarias, es completamente legal. Después de la interrupción de los juegos en 1998, y la producción en 1999, los fans de la Super Nintendo En92.2 Homebrew en diferentes con- tertainment System hicieron imágenes ROM homebrew, incluso sin el apoyo de Nintendo para la consola. Dessolas pués del lanzamiento de la SNES había un gran interés en la ingeniería inversa del sistema para permitir jugar homebrew y copias de seguridad. Nintendo equipado la 92.2.1 Sega Dreamcast máquina con varias medidas de seguridad, tales como el La Sega Dreamcast (DC) es, en muchos aspectos, una de chip de bloqueo para evitar que código no autorizado que las pioneras en incorporar homebrew. Para lograr correr se ejecuta en la máquina. Finalmente, la comunidad hoeste tipo de software era necesario utilizar una puerta tra- mebrew descubierto cómo los juegos corrían en el hardsera que permitía iniciar la consola desde discos compac- ware SNES y fueron capaces de eludir sus mecanismos de tos convencionales (la DC utilizaba un formato especial seguridad. Empresas como TAPÓN plugins hardware liberados como la serie SF doctor Game. Los usuarios que llamado GD-ROM). pueden no solo los juegos de copia, sino también para eje• Aplicaciones: Reproductores de MP3 y de video, cutar juegos caseros elaborados en el hardware de SNES. ROMs Homebrew se podrían convertir en el formato SF visores de Flash, y versiones de Linux entre otras. Médico juego y poner en un 3 1/2 “disquete. Juegos tan grandes como 12 Mbits (1.5 megabytes) podrían poner• Emuladores: Con el tiempo, la consola ha llegado se en disquetes formateados de 1.6 megabytes. Un disa ejecutar emuladores de SNES, Genesis, NES, Neo positivo alternativo fue el Super Flash, por Tototek, que Geo y Neo Geo CD, entre otros. permitía múltiples juegos para quemarla en un chip de memoria flash de cartucho (que permite hasta 48Mbits). • Juegos: Se han realizado ports del clásico Doom y Este chip es el rom máscara para el cartucho flash Súper de la primera y segunda versión de Quake entre otras desarrollo. El dispositivo es fácil de usar y tiene una inadaptaciones. Además, se ha desarrollado un sinnú- terfaz de usuario en el extremo del ordenador. Conectar mero de juegos freeware y de código abierto, des- el cartucho de Super Flash y cargar los juegos que quieras tacándose los clones de Tetris y de juegos de naves simplemente. Esto permitió a los usuarios hacer un jue(shoot'em ups). go de SNES y juegan en un cartucho real en lugar de un disquete. La legalidad de homebew SNES lanzamientos de juegos no ha sido probado en los tribunales, y es dis92.2.2 Nintendo Entertainment System cutible si o no pasar por sus medidas de seguridad caería en conflicto con las leyes modernas de ingeniería inver(NES) sa. Presumiblemente juegos caseros se pueden producir Varios compiladores están disponibles para la Nintendo legalmente los SNES, siempre y cuando se incluye ninEntertainment System, pero como el Atari 2600, la mayo- gún material con derechos de autor. Anteriormente, en la ría del desarrollo se aplica directamente en lenguaje en- década de 1990, Nintendo demandó Color Dreams para samblador. Un impedimento para la NES desarrollo ho- producir juegos de NES sin licencia oficial. El resultado mebrew es la relativa dificultad involucrada con la pro- fue un acuerdo no revelado, pero los sueños de color siducción de cartuchos físicos, aunque cartuchos flash de guió produciendo juegos sin licencia. La fuerza del color terceros existen, haciendo posible homebrew en el hard- de la posición de los sueños se encuentra con que trabaware original de NES. Muchas variedades de circuitos jaron todo el código de chip de cierre 10NES en lugar de
92.2. HOMEBREW EN DIFERENTES CONSOLAS duplicar ilegalmente.
92.2.4
Nintendo DS
Para ejecutar homebrew en la Nintendo DS se necesita una tarjeta o cartucho flash como M3 DS Real, Supercard, acekard, ez-flash, R4DS o análogas.* [2] Dicha tarjeta se usa como medio de almacenamiento para los programas, los archivos multimedia y los juegos. Existen muchos sitios en Internet dedicados a la distribución y difusión del homebrew.
177 • Versiones: Han surgido infinidad de versiones para este sistema PSP entre las que se incluyen el primer homebrew que surgió llamado DevHook, seguido ya de otras generaciones y los llamados CFW(Custom Firmwares), que han tenido un gran desarrollo gracias a hackers como Dark_Alex, Total Noob, Virtuous Flame, Coolbird, Neur0n y Lktd9 los cuales actualmente han sacado CFW firmados como por ejemplo: PRO-(A,A1,A2,A3..B,1,2,3,4,5,6,7,8,9,10 ,TN-HEN/-A-B... , ME 1,2,3..(6.39), CLFW 1,2,3..(6.39),LK-A,LK-II v1,Lk-B,etc
• Aplicaciones: Reproductores de música, Repro92.2.6 Microsoft Xbox ductores de videos en muchos formatos, incluyendo Avi, calculadoras graficadoras, diccionarios interacXbox ha sido una de las plataformas más prolíficas en mativos, lectores de libros electrónicos como DS Libris teria de homebrew, dada su versatilidad y su arquitectura para EPUB, linux, voip, aplicaciones... x86. Se logra ejecutar este tipo de software ya sea con un modchip o aprovechando un agujero de seguridad. Se ha • Emuladores: Emuladores de NES, Sega Megadri- desarrollado un kit de programación completamente libre ve, Gameboy Color, Gameboy Advance, Amiga, llamado OpenXDK, para uso exclusivo con la consola. NeoGeo, Master System, SuperNintendo, Amstrad, Comodore, MAME, Scumm, Spectrum • Aplicaciones: Reproductores de música y videos en diversos formatos incluyendo DVD; administrado• Juegos: Muchos títulos caseros res de archivos y, más notoriamente, distribuciones de Linux.
92.2.5
Sony PSP
Para ejecutar homebrew en la PSP es necesario tener un firmware alternativo llamado Custom Firmware.
• Emuladores: Emuladores de todo tipo han sido programados para esta consola, entre los que se destacan PCSX y Surreal, de PSX y Nintendo 64 respectivamente.
• Downgrades: Se llama“downgrade”al mecanismo para bajar de versión a una PSP para así llegar a una versión con menores restricciones, pudiendo de esta manera instalar un firmware alternativo (Custom Firmware) que sea capaz de hacer funcionar homebrew y copias de seguridad, entre otras funciones.
• Juegos: Una serie de ports han sido adaptados para Xbox, generalmente han sido más sencillos de desarrollar dada la mencionada potencia y versatilidad de la consola.
• Aplicaciones: Pequeños reproductores multimedia, exploradores, programas de información, plugins con diferentes funciones (como visualizar la pantalla de la PSP en el PC, etc) aunque también dispone -entre otras cosas- de completos shells que disponen de una gran variedad de funciones. • Emuladores: Los emuladores más importantes son los de Game Boy Advance, Play Station, SNES , Genesis, Nintendo 64 entre otros. • Plugins: Los plugins son pequeñas aplicaciones con una función específica, en la PSP se ejecutan a través del Recovery Mode (modo de recuperación). Su función en esta plataforma es bastante interesante, algunos plugins pueden, por ejemplo, permitir la ejecución de códigos gameshark, hacer capturas de pantalla o ampliar las funciones del firmware en general.
92.2.7 Microsoft Xbox 360 Xbox 360, la sucesora directa de la Xbox, tenía un fallo en el firmware oficial, que se solucionó con una posterior actualización y que permite tener acceso a todo el hardware. La explotación por parte de hackers de este fallo pasó a conocerse como el hack Jtag.* [3] • Emuladores: Emuladores de todo tipo han sido programados para esta consola, entre los pocos que hay algunos son de Gameboy, Snes, NES, Sega, Etc. • Copias de seguridad: Existen aplicaciones que nos permiten cargar copias de seguridad desde algún disco duro externo, o desde el mismo disco duro de la consola, no está de más decir que cambiando el firmware del lector de la Xbox 360 también podremos cargar backups grabados en DVD doble capa.
178
92.2.8
CAPÍTULO 92. HOMEBREW
Nintendo Wii
La Wii permite la incorporación de homebrew mediante la explotación de diversos fallos, de acuerdo a la versión del software oficial que se posea.* [4] La ejecución de las diversas aplicaciones se realiza por medio del Homebrew Channel, programa que se puede instalar y ejecutar desde el menú principal de la consola.* [5] • Aplicaciones: Reproductores de MP3 y de vídeo (desde SD, USB o DVD), editores de texto o utilidades que utilizan las características especiales del mando wii (tales como un módulo que permite dibujar en la pantalla utilizando el mando como pincel. • Emuladores: Existen emuladores de consolas como NES, SNES, Sega Genesis, Sega Master System, MSX, Game Boy Color, Game Boy Advance, MAME, Neo Geo Pocket, Nintendo 64, PC Engine, PSX, SCUMM, ZX Spectrum, Chip-8, Amstrad CPC, Atari 2600 y Neo Geo. • Juegos: Entre los juegos, nos encontramos desde clásicos como Pong, Asteroides o Tetris hasta otros más modernos como Quake. Destacar el GuitarFun, versión del Guitar Hero realizada por un español. • Copias de seguridad: Además el Homebrew se puede utilizar para que la consola cargue copias de seguridad, sistema popularmente conocido como piratear sin chip. O incluso instalar juegos de la Consola Virtual y WiiWare.
92.2.9
PlayStation 3
PlayStation 3 puede ser utilizada para homebrew mediante la utilización del dispositivo PS Jailbreak o sus derivados clónicos o de código abierto, únicamente con el firmware 3.41 o anteriores.* [6]* [7] Adicionalmente, es posible realizar un downgrade desde las versiones 3.42 y 3.50. En este caso, se estaría ejecutando software no firmado. También es posible instalar y ejecutar homebrew hasta la versión de firmware 3.55, a partir del descubrimiento de las claves privadas de la consola que el hacker George Hotz sacó a la luz con su firmware personalizado. versión 3.55 GeoHot* [8] En este caso, se estaría ejecutando software firmado. • Aplicaciones: Servidores FTP, cargadores de firmwares modificados, y cargadores de juegos (Backup Manager y Open Manager inicialmente; luego Multiman, Gaia y Rogero). • Emuladores: han sido lanzados emuladores de NES, SNES, Sega Genesis, Game Boy Advance, PSX, SCUMM, así como versiones del emulador
multiarcade Final Burn Arcade y del emulador multisistema Mednafen. • Juegos: Existen ports del videojuego Doom, además de versiones de reconocidos juegos como Tetris, entre otros.
92.3 Véase también • Homebrew Computer Club • Sega Dreamcast • PlayStation Portable • Anexo:Modchips para Wii
92.4 Referencias [1] «The Complete Guide to Whats Needed for Homebrew on Each Console.» (en inglés). DC Emu UK. Archivado desde el original el 28 de noviembre de 2015. Consultado el 12 de enero de 2011. [2] «Homebrew de NDS». El Otro Lado. 3 de abril de 2010. Consultado el 12 de enero de 2011. [3] «Homebrew Xbox 360». El Otro Lado. 30 de diciembre de 2010. Consultado el 12 de enero de 2011. [4] «Cargar Homebrew en Wii». El Otro Lado. 18 de diciembre de 2010. Consultado el 12 de enero de 2011. [5] «Homebrew Channel». El Otro Lado. 9 de enero de 2011. Consultado el 12 de enero de 2011. [6] «PS3 Jailbreak: un pendrive para hackear la PlayStation 3». Red Users. 21 de agosto de 2010. Consultado el 25 de octubre de 2010. [7] «PlayStation 3 ha sido hackeada». Meristation. 20 de agosto de 2010. Consultado el 25 de octubre de 2010. [8] «Hackers se hacen con las claves de seguridad secretas de PlayStation 3». Meristation. 3 de enero de 2011. Consultado el 6 de enero de 2011.
Capítulo 93
ICONIX ICONIX es una metodología pesada-ligera de desarrollo • Modelo de casos de usos del Software que se halla a medio camino entre un RUP (Rational Unified Process) y un XP (eXtreme Program93.2.2 Fase 2: Análisis y diseño preliminar ming). Iconix deriva directamente del RUP y su fundamento es Dentro de esta fase se realizan las siguientes tareas: el hecho de que un 80% de los casos pueden ser resueltos tan solo con un uso del 20% del UML, con lo cual se sim• Descripción de los casos de uso plifica muchísimo el proceso sin perder documentación al dejar solo aquello que es necesario. Esto implica un uso • Diagramas de robustez dinámico del UML de tal forma que siempre se pueden utilizar otros diagramas además de los ya estipulados si se cree conveniente. Iconix se guía a través de casos de uso y sigue un ciclo de vida iterativo e incremental. El 93.2.3 Fase 3: Diseño objetivo es que a partir de los casos de uso se obtenga el Dentro de esta fase se realiza la siguiente tarea: sistema final. • Diagramas de secuencia
93.1 Ventajas de Iconix
93.2.4 Fase 4: Implementación
• Proceso ágil para obtener un sistema informático.
• Dedicada a la construcción de sistemas de gestión de Dentro de esta fase se realiza la siguiente tarea: pequeña y mediana complejidad con la participación de los usuarios finales. • Escribir y generar código Tareas de la metodología Iconix = La metodología está formada por cuatro fases principales que son:
93.3 Referencias • 1. Rosenberg, Doug; Stephens, Matt (2007). Use Case Driven Object Modeling with UML: Theory and Practice. Apress. ISBN 1590597745.
93.2 Tareas de la metodología Iconix
• 2. Rosenberg, Doug; Stephens, Matt; Collins-Cope, Mark (2005). Agile Development with ICONIX Process. Apress. ISBN 1590594649.
La metodología está formada por cuatro fases principales que son:
93.2.1
Fase 1: Análisis de requisitos
93.4 Conceptos Relacionados
Dentro de esta fase se realizan las siguientes tareas:
• Dynamic Systems Development Method (DSDM)
• Modelo del dominio
• Extreme Programming
• Elaboración rápida de prototipos
• Rational Unified Process 179
180
CAPÍTULO 93. ICONIX
• URDAD, the Use Case Driven Analysis and Design methodology is a methodology for technology neutral design. • RATF, using Robustness Analysis in combination with Technology Forecasting, to further investigate future software evolution alternatives.
93.5 Enlaces externos • Página oficial ICONIX • Página de la ICONIX Process • ICONIX UML and SysML Jumpstart Training • Introducción a los Procesos ICONIX • Robustness Diagrams • Metodología ICONIX • Uso de la metodología ICONIX
93.5.1
Fase 2: Análisis y diseño preliminar
Dentro de esta fase se realizan las siguientes tareas:
93.7 Conceptos Relacionados • Dynamic Systems Development Method (DSDM) • Extreme Programming • Rational Unified Process • URDAD, the Use Case Driven Analysis and Design methodology is a methodology for technology neutral design. • RATF, using Robustness Analysis in combination with Technology Forecasting, to further investigate future software evolution alternatives.
93.8 Enlaces externos • Página oficial ICONIX • Página de la ICONIX Process • ICONIX UML and SysML Jumpstart Training • Introducción a los Procesos ICONIX • Robustness Diagrams • Metodología ICONIX • Uso de la metodología ICONIX
• Descripción de los casos de uso • Diagramas de robustez
93.5.2
Fase 3: Diseño
Dentro de esta fase se realiza la siguiente tarea: • Diagramas de secuencia
93.5.3
Fase 4: Implementación
Dentro de esta fase se realiza la siguiente tarea: • Escribir y generar código
93.6 Referencias • 1. Rosenberg, Doug; Stephens, Matt (2007). Use Case Driven Object Modeling with UML: Theory and Practice. Apress. ISBN 1590597745. • 2. Rosenberg, Doug; Stephens, Matt; Collins-Cope, Mark (2005). Agile Development with ICONIX Process. Apress. ISBN 1590594649.
Capítulo 94
Anexo:Implementaciones de Smalltalk En informática, el lenguaje de programación Smalltalk, está normalizado desde 1998 en el estándar ANSI NCITS 319-1998. Una implementación de Smalltalk es un sistema de programación que conforma al estándar si implementa todas las características definidas tal como están especificadas en ese documento. Cada implementación de Smalltalk, suele incluir como propias: • Una Máquina virtual. • Un archivo llamado 'Archivo de imagen virtual' que sirve como contenedor de objetos. • Un Entorno de desarrollo que funciona como un sistema en tiempo de ejecución, por ello de dice que es interactivo. En el caso de no poseer un entorno interactivo orientado a controles visuales, es llamado de scripting. • Una biblioteca de clases. Esta página incluye un listado de implementaciones conocidas del lenguaje de programación Smalltalk, y una tabla comparativa de algunas características relevantes para cada implementación:
181
Capítulo 95
Anexo:Implementaciones para algoritmo de rut A continuación se presentan diversas implementaciones de algoritmos validadores de RUN/RUT en algunos de los más populares lenguajes de programación:
95.1 Objective-C //validation with parse logic from RUT string format XX.XXX.XXX-Y + (BOOL)validRUT:(NSString*)rut{ //remove any dots or signs from RUT string with format XX.XXX.XXX-Y //http://es.wikipedia.org/wiki/Rol_ %C3%9Anico_Tributario rut = [rut stringByReplacingOccurrencesOfString:@".”withString:@""]; rut = [rut stringByReplacingOccurrencesOfString:@"-" withString:@""]; //get rut validator digit (Y) char dv = [rut characterAtIndex:[rut length]−1]; NSLog(@"DV: %c”, dv); //get rut numeric value from (XX.XXX.XXX) int rutnumber = [[rut substringToIndex:[rut length]−1] integerValue]; NSLog(@"RUT NUMBER: %d”, rutnumber); //check valid RUT number (XX.XXX.XXX) with validator digit (Y) return [self validRUT:rutnumber with:dv]; } //algorithm module 11 based on the Java version + (BOOL)validRUT:(int)rut with:(char)dv { //to accept 'k' lowercase to avoid issues with “K”clients dv = (dv == 'k')?'K':dv; NSLog(@"RUT DV: %c”, dv); int m = 0, s = 1; for (; rut != 0; rut /= 10) { s = (s + rut % 10 * (9 - m++ % 6)) % 11; } //generate DV to check char dvcheck = (char) (s != 0 ? s + 47 : 75); NSLog(@"RUT DV: %c”, dv); NSLog(@"GEN DV: %c”, dvcheck); return dv == dvcheck; }
95.2 C++ char digito_verificador_rut(unsigned rut) { unsigned sum = 0, factor = 2; while(rut) { sum += (rut%10)*factor; rut/=10; factor = factor==7 ? 2 : factor+1; } const unsigned res = 11 - sum%11; return res == 11? '0' : res == 10? 'k' : res+'0'; }
95.3 Visual Basic MS Excel Public Function RutDigito(ByVal Rut As Long) As String Dim Digito As Integer Dim Contador As Integer Dim Multiplo As Integer Dim Acumulador As Integer Contador = 2 Acumulador = 0 While Rut <> 0 Multiplo = (Rut Mod 10) * Contador Acumulador = Acumulador + Multiplo Rut = Rut \ 10 Contador = Contador + 1 If Contador > 7 Then Contador = 2 End If Wend Digito = 11 - (Acumulador Mod 11) RutDigito = CStr(Digito) If Digito = 10 Then RutDigito =“K”If Digito = 11 Then RutDigito =“0”End Function
95.4 C# private string digitoVerificador(int rut) { int Digito; int Contador; int Multiplo; int Acumulador; string RutDigito; Contador = 2; Acumulador = 0; while (rut != 0) { Multiplo = (rut % 10) * Contador; Acumulador = Acumulador + Multiplo; rut = rut/10; Contador = Contador + 1; if (Contador == 8) { Contador = 2; } } Digito = 11 - (Acumulador % 11); RutDigito = Digito.ToString().Trim(); if (Digito == 10 ) { RutDigito = “K"; } if (Digito == 11) { RutDigito = “0"; } return (RutDigito); } } } /// Una versión mas corta public static string Dv(string r) { int suma = 0; for (int x = r.Length - 1; x >= 0; x--) suma += int.Parse(char.IsDigit(r[x])?r[x].ToString():"0”) * (((r.Length - (x + 1)) % 6) + 2); int numericDigito = (11 suma % 11); string digito = numericDigito == 11 ?“0”: numericDigito == 10 ?“K”: numericDigito.ToString(); return digito; } /// Una versión funcional public static char GenerarDV (int num) { return “0K987654321” [ Enumerable.Range (0, (int) Math.Floor (Math.Log10 (num)) + 2) .Select (i => ((i % 6) + 2) * ((num / (int) Math.Pow (10, i)) % 10)) .Sum () % 11]; }
182
95.10. PSEINT
183
95.5 Perl 6
h=r-(10^7*a+10^6*b+10^5*c+10^4*d+10^3*e+100*f+10*g); sum=h*2+g*3+f*4+e*5+d*6+c*7+b*2+a*3; #!/usr/bin/perl6 my ($RUT, @RUT, $digito); $RUT = resto=sum-floor(sum/11)*11; verif=11-resto; disp('El @*ARGS; # leemos el argumento pasado al programa numero verificador es:') if (verif<10) disp(verif) end if @RUT = $RUT.split('').reverse; # lo pasamos a array y (verif==11) disp('0') end if (verif==10) disp('K') end le damos la vuelta $digito = [+](@RUT <<*>> (2..7)); # cálculo del dígito verificador $digito = 11 - $digito % 11; $digito = ( 0 .. 9, 'K', 0 )[$digito]; say "$RUT-$digito"; 95.10 PSeInt # salida Proceso digito_verificador Definir rut, a1, pa, c, sum, di, digi Como Enteros; Escribir “Este programa define su dígito verificador "; Escribir “Ingrese su rut sin el 95.6 Javascript dígito verificador "; Leer rut; pa<-rut; c<−2; sum<−0; dv = function(T) { var M=0,S=1; Mientras rut>0 Hacer a1<-rut%10; rut<-trunc(rut/10); for(;T;T=Math.floor(T/10)) S=(S+T%10*(9- sum<-sum+(a1*c); c<-c+1; Si c=8 Entonces c<−2; FinM++%6))%11; return S?S-1:'K'; } alert('El digito Si FinMientras di<-sum%11; digi<−11-di; Si digi=11 verificador del rut ingresado es '+ dv(prompt('Ingrese rut Entonces Escribir “El dígito verificador es 0"; Escribir pa,"−0"; Sino Si digi=10 Entonces Escribir “El dígito para mostrar su digito verificador:'))); verificador es K"; Escribir pa,"-K"; Sino Escribir “El dígito verificador es ",digi; Escribir pa,"-",digi; FinSi FinSi FinProceso
95.7 PHP function dv($r){ $s=1; for($m=0;$r!=0;$r/=10) $s=($s+$r%10*(9-$m++%6))%11; echo 'El digito verificador del rut ingresado es ',chr($s?$s+47:75); }
95.8 Transact-SQL CREATE FUNCTION RutDigito (@Rut as integer) RETURNS varchar(1) AS BEGIN declare @Digito as integer declare @Contador as integer declare @Multiplo as integer declare @Acumulador as integer declare @retorno as varchar(1) set @Contador = 2 set @Acumulador = 0 WHILE @Rut <> 0 BEGIN set @Multiplo = (@Rut % 10) * @Contador set @Acumulador = @Acumulador + @Multiplo set @Rut = @Rut / 10 set @Contador = @Contador + 1 If @Contador > 7 set @Contador = 2 END set @Digito = 11 - (@Acumulador % 11) select @retorno = case when @Digito = 10 then 'K' when @Digito = 11 then '0' else cast(@Digito as varchar(1)) end return @retorno END
95.9 MATLAB
95.11 Python def digito_verificador(rut): value = 11 - sum([ int(a)*int(b) for a,b in zip(str(rut).zfill(8), '32765432')])%11 return {10: 'K', 11: '0'}.get(value, str(value))
95.12 Ruby def digito_verificador(rut) dv = (11(rut.split('').map(&:to_i).reverse.each_with_index.map { |e, i| e*(2+i%6) }).inject(:+))%11 if dv < 10 then dv.to_s else 'k' end end
95.13 Java public static boolean ValidarRut(int rut, char dv) { int m = 0, s = 1; for (; rut != 0; rut /= 10) { s = (s + rut % 10 * (9 - m++ % 6)) % 11; } return dv == (char) (s != 0 ? s + 47 : 75); }
r=input('Ingrese rut:'); a=floor(r/10^7); b=floor(r/10^6)(10*a); c=floor(r/10^5)-(100*a+10*b); d=floor(r/10^4)(10^3*a+100*b+10*c); e=floor(r/10^3)- 95.14 Pl/pgsql de PostgreSql (10^4*a+10^3*b+100*c+10*d); f=floor(r/10^2)CREATE OR REPLACE FUNCTION sp_rut_cl( (10^5*a+10^4*b+10^3*c+100*d+10*e); rut VARCHAR ) RETURNS CHARACTER(1) AS g=floor(r/10^1)-(10^6*a+10^5*b+10^4*c+10^3*d+100*e+10*f);
184
CAPÍTULO 95. ANEXO:IMPLEMENTACIONES PARA ALGORITMO DE RUT
$BODY$ DECLARE rec record; suma INTEGER := 0; serie INTEGER := 2; resto INTEGER; dv CHARACTER(1); BEGIN --raise notice 'rut: %',rut; if (rut is null) then return null; end if; rut := btrim(rut); rut := replace(rut, '.', ''); if (rut is null) then return null; end if; rut := btrim(rut); for rec in select * from ( select substring(rut from i for 1)::char as bit from generate_series(length(rut),1,−1) as i --where bit = '1' ) q1 LOOP --raise notice '1'; --raise notice 'rec.bit: %',rec.bit; --raise notice '2'; if rec.bit is not null and rec.bit ~ '[0-9]+' then suma := suma + rec.bit::INTEGER * serie; end if; --raise notice '3'; --raise notice 'serie: %',serie; if serie = 7 then serie := 1; end if; serie := serie + 1; end loop; --raise notice 'suma: %',suma; resto := 11 - suma % 11; --raise notice 'resto: %',resto; dv := case resto when 11 then '0' when 10 then 'K' else resto::CHARACTER end; return dv; end; $BODY$ LANGUAGE 'plpgsql' volatile;
Capítulo 96
Inanición (informática) En informática, inanición (starvation en inglés) es un problema relacionado con los sistemas multitarea, donde a un proceso o un hilo de ejecución se le deniega siempre el acceso a un recurso compartido. Sin este recurso, la tarea a ejecutar no puede ser nunca finalizada. La inanición es una situación similar al interbloqueo, pero las causas son diferentes. En el interbloqueo, dos procesos o dos hilos de ejecución llegan a un punto muerto cuando cada uno de ellos necesita un recurso que es ocupado por el otro. En cambio, en este caso, uno o más procesos están esperando recursos ocupados por otros procesos que no se encuentran necesariamente en ningún punto muerto. Un caso de inanición la ilustra perfectamente la paradoja conocida como la cena de los filósofos de Edsger Dijkstra cuando se da el caso de que todos los filósofos cogen el tenedor a la vez. La utilización de prioridades en muchos sistemas operativos multitarea podría causar que procesos de alta prioridad estuvieran ejecutándose siempre y no permitieran la ejecución de procesos de baja prioridad, causando inanición en estos. Es más, si un proceso de alta prioridad está pendiente del resultado de un proceso de baja prioridad que no se ejecuta nunca, entonces este proceso de alta prioridad también experimenta inanición (esta situación se conoce como inversión de prioridades). Para evitar estas situaciones los planificadores modernos incorporan algoritmos para asegurar que todos los procesos reciben un mínimo de tiempo de CPU para ejecutarse.
185
Capítulo 97
Indirección La in-dirección es una técnica de programación. El concepto se basa en hacer referencia indirecta a los datos usando las direcciones de memoria que los contienen o mediante punteros que señalan hacia esos datos o a las direcciones que los contienen. En la memoria no sólo se almacenan datos de los programas (como letras, caracteres gráficos, números naturales, números enteros, coma flotante, etc.) sino también direcciones de memoria, que al fin y al cabo también son datos. Para efectos de almacenamiento y manipulación por el microprocesador, todos estos datos no son más que una secuencia de bytes en diferentes celdas. El que una secuencia de bits determinada se intérprete como un número o como una dirección depende del programador. El mecanismo de in-dirección se puede encadenar de manera arbitrariamente larga. La dirección que contiene la dirección de un dato, a su vez se puede almacenar de nuevo en memoria. Es posible almacenar las direcciones de tal forma que haya que seguir un encadenamiento de indirecciones para llegar finalmente a acceder al dato. En el siguiente ejemplo, la“celda”(dirección de memoria 0x00000100) contiene el dato 0x00000200 que a su vez representa la dirección de la nueva“celda”que contiene el dato que corresponde a una dirección que contiene un dato que representa la dirección 0x00000400 que finalmente contiene el dato que nos interesa. Y así podemos definir a voluntad o conveniencia los diferentes niveles de in-dirección que necesitemos.
186
Capítulo 98
Infraestructura de lenguaje común 2001. En abril del año 2003 ISO ratificó este estándar con el denominación ISO/IEC 23271:2003 . Para comprender mejor la inclusión de cada una de las partes principales de la arquitectura de CLI es interesante analizar los objetivos de diseño que se plantearon desde su concepción. Según su especificación, la arquitectura de CLI debe: • Permitir escribir componentes ínteroperables independientemente de la plataforma subyacente y del lenguaje de programación utilizado. • Exponer todas las entidades programáticas a través de un único sistema unificado de tipos (en la especificación, este sistema es conocido como CTS, o Common Type System). • Empaquetar todos los tipos en unidades completamente auto descriptivas y portables.
Representación visual, en inglés, de la infraestructura de lenguaje común.
La infraestructura de lenguaje común (en inglés Common Language Infrastructure o CLI) es una especificación estandarizada que describe un entorno virtual para la ejecución de aplicaciones, cuya principal característica es la de permitir que aplicaciones escritas en distintos lenguajes de alto nivel puedan luego ejecutarse en múltiples plataformas tanto de hardware como de software sin necesidad de reescribir o recompilar su código fuente. Si bien el CLI tuvo sus orígenes en Microsoft (en principio se pensaba desarrollar un entorno de ejecución compartido para COM con el nombre de Common Object Runtime, que luego se extendió y generalizó para dar lugar a CLI), sus especificaciones fueron llevadas ante ECMA (European Computer Manufacturers Association), una importante organización europea de estándares, para su estandarización en el año 2000. Luego de un año de trabajo conjunto entre ECMA, Microsoft y otras empresas que co-patrocinaron el proceso (Intel, HP, IBM y Fujitsu entre otras), el estándar ECMA-335 que define el entorno CLI finalmente vio la luz en diciembre de 187
• Cargar los tipos de forma tal que se encuentren aislados unos de otros en tiempo de ejecución, pero que puedan a su vez compartir recursos. • Resolver dependencias entre tipos en tiempo de ejecución usando una política flexible que pueda tener en cuenta la versión, atributos de localización y políticas administrativas. • Ejecutar aplicaciones bajo la supervisión de un entorno privilegiado que permita controlar y hacer cumplir políticas en tiempo de ejecución. • Diseñar toda la infraestructura y servicios basándose en metadatos extensibles, de manera tal que toda la arquitectura pueda acomodarse con poco impacto a nuevas incorporaciones y cambios. • Poder realizar tareas de bajo nivel, como carga de tipos en memoria, enlace con librerías y compilación a código nativo sólo cuando sea necesario (este enfoque se conoce típicamente como“on demand” , o “just in time”). • Proveer una serie de funcionalidades comunes mediante un grupo de librerías de programación que los desarrolladores puedan utilizar para construir sus aplicaciones.
188
CAPÍTULO 98. INFRAESTRUCTURA DE LENGUAJE COMÚN
Microsoft .NET de hecho es un súper conjunto de esta especificación, es decir, provee todo lo necesario para cumplir con la misma y además agrega una serie de herramientas, librerías y funcionalidades no contempladas por ella originalmente y que proveen una enorme utilidad y flexibilidad a los desarrolladores (por ejemplo, librerías para la creación de aplicaciones y servicios web, acceso a motores de bases de datos, controles gráficos, herramientas para desensamblar assemblies, debuggers, etc.). Si bien es gratuito, su código fuente no es abierto, y es distribuido por Microsoft en versiones para sistemas operativos Windows 98 y sus sucesores únicamente. La especificación del CLI está formada por cuatro partes: • Sistema común de tipos, en inglés Common Type System (CTS). • Metadatos. • Especificaciones de lenguaje común, en inglés Common Language Specification (CLS). • Sistema de ejecución virtual, del inglés Virtual Execution System (VES).
98.1 Véase también • Microsoft .NET • ECMA
Capítulo 99
Ingeniería de software Ingeniería de software es la aplicación de un enfoque sistemático, disciplinado y cuantificable al desarrollo, operación y mantenimiento de software,* [1] y el estudio de estos enfoques, es decir, la aplicación de la ingeniería al software.* [2] Integra matemáticas, ciencias de la computación y prácticas cuyos orígenes se encuentran en la ingeniería.* [3]
Indistintamente se utilizan los términos “ingeniería de software”o “ingeniería del software"; aunque menos común también se suele referenciar como“ingeniería en software”.* [5]* [6]* [7] En Hispanoamérica los términos más comúnmente usados son los dos primeros.
La creación del software es un proceso intrínsecamente creativo y la ingeniería del software trata de sistematizar Se citan las definiciones más reconocidas, formuladas por este proceso con el fin de acotar el riesgo del fracaso en prestigiosos autores: la consecución del objetivo, por medio de diversas técnicas que se han demostrado adecuadas sobre la base de la • Ingeniería de software es el estudio de los principios experiencia previa. y metodologías para el desarrollo y mantenimiento La IS se puede considerar como la ingeniería aplicada al de sistemas software (Zelkovitz, 1978). software, esto es, por medios sistematizados y con herra• Ingeniería de software es la aplicación práctica del mientas preestablecidas, la aplicación de ellos de la maneconocimiento científico al diseño y construcción de ra más eficiente para la obtención de resultados óptimos; programas de computadora y a la documentación objetivos que siempre busca la ingeniería. No es sólo de la asociada requerida para desarrollar, operar y mante- resolución de problemas, sino más bien teniendo en cuennerlos. Se conoce también como desarrollo de soft- ta las diferentes soluciones, elegir la más apropiada. ware o producción de software (Bohem, 1976). • La ingeniería de software trata del establecimiento de los principios y métodos de la ingeniería a fin de 99.1 Historia obtener software de modo rentable, que sea fiable y trabaje en máquinas reales (Bauer, 1972). Cuando aparecieron las primeras computadoras digitales en la década de 1940,* [8]el desarrollo de software era • La ingeniería de software es la aplicación de un algo tan nuevo que era casi imposible hacer prediccioenfoque sistemático, disciplinado y cuantificable al nes de las fechas estimadas de finalización del proyecto y desarrollo, operación, y mantenimiento del softwamuchos de ellos sobrepasaban los presupuestos y tiempo * re. [1] estimados.. Los desarrolladores tenían que volver a escribir todos sus programas para correr en máquinas nuevas En 2004, la U. S. Bureau of Labor Statistics (Oficina de Estadísticas del Trabajo de Estados Unidos) contó 760 que salían cada uno o dos años, haciendo obsoletas las ya 840 ingenieros de software de computadora.* [4] El tér- existentes. mino “ingeniero de software”, sin embargo, se utiliza de manera genérica en el ambiente empresarial, y no todos los que se desempeñan en el puesto de ingeniero de software poseen realmente títulos de ingeniería de universidades reconocidas.
El término Ingeniería del software apareció por primera vez en a finales de la década de 1950. La Ingeniería de software fue estimulada por la crisis del software de las décadas de entre 1960 y 1980. La Ingeniería del software viene a ayudar a identificar y corregir mediante princiAlgunos autores consideran que“desarrollo de software” pios y metodologías los procesos de desarrollo y mantees un término más apropiado que“ingeniería de softwa- nimiento de sistemas de software. re”para el proceso de crear software. Personas como Pete Aparte de la crisis del software de las décadas de entre McBreen (autor de“Software Craftmanship”) cree que 1960 y 1980, la ingeniería de software se ve afectada por el término IS implica niveles de rigor y prueba de proce- accidentes que conllevaron a la muerte de tres personas; sos que no son apropiados para todo tipo de desarrollo de esto sucedió cuando la máquina de radioterapia Therac25 emite una sobredosis masiva de radiación y afecto consoftware. 189
190
CAPÍTULO 99. INGENIERÍA DE SOFTWARE
tra la vida de estas personas.* [9] Esto remarca los riesgos ternet; esto hace que los desarrolladores tuviesen que made control por software,* [10] afectando directamente al nejar imágenes mapas y animaciones para optimizar la nombre de la ingeniería de software. visualización/almacenamiento de imágenes (como el uso * A principios de los 1980, [11] la ingeniería del software de imágenes en miniatura). El uso de los navegadores y ya había surgido como una genuina profesión, para estar utilización de lenguaje HTML cambia drásticamente la al lado de las ciencias de la computación y la ingeniería visión y recepción de la información. tradicional. Antes de esto, las tareas eran corridas poniendo tarjetas perforadas como entrada en el lector de tarjetas de la máquina y se esperaban los resultados devueltos por la impresora.
Las amplias conexiones de red crea la proliferación de virus informáticos y la basura en los correos electrónicos (E-mail) esto pone en una carrera contra el tiempo los desarrolladores para crear nuevos sistemas de bloqueo o Debido a la necesidad de traducir frecuentemente el soft- seguridad de estas anomalías en la informática ya *que se ware viejo para atender las necesidades de las nuevas má- volvían sumamente tediosas y difíciles de arreglar [10] quinas, se desarrollaron lenguajes de orden superior. A Después de una fuerte y creciente demanda surge la medida que apareció el software libre, las organizaciones necesidad de crear soluciones de software a bajo costo, de usuarios comúnmente lo liberaban. esto conlleva al uso de metodologías más simples y Durante mucho tiempo, solucionar la crisis del software rápidas que desarrollan software funcional. Cabe señalar fue de suma importancia para investigadores y empresas que los sistemas más pequeños tenían un enfoque más simple y rápido para poder administrar el desarrollo de que se dedicaban a producir herramientas de software. cálculos y algoritmos de software. Para la década de 1980, el costo de propiedad y mantenimiento del software fue dos veces más caro que el propio desarrollo del software, y durante la década de 1990, el costo de propiedad y mantenimiento aumentó 30 % con respecto a la década anterior. En 1995, muchos de 99.2 Objetivos los proyectos de desarrollo estaban operacionales, pero no eran considerados exitosos. El proyecto de software La ingeniería de software aplica diferentes normas y mémedio sobrepasaba en un 50 % la estimación de tiempo todos que permiten obtener mejores resultados, en cuanpreviamente realizada, además, el 75 % de todos los gran- to al desarrollo y uso del software, mediante la aplicación des productos de software que eran entregados al cliente correcta de estos procedimientos se puede llegar a cumtenían fallas tan graves, que no eran usados en lo absolu- plir de manera satisfactoria con los objetivos fundamento o simplemente no cumplían con los requerimientos del tales de la ingeniería de software. cliente.* [10] Entre los objetivos de la ingeniería de software están: Algunos expertos argumentaron que la crisis del software era debido a la falta de disciplina de los programadores. • Mejorar el diseño de aplicaciones o software de tal Cada nueva tecnología y práctica de la década de 1970 a modo que se adapten de mejor manera a las necela de 1990 fue pregonada como la única solución a todos sidades de las organizaciones o finalidades para las los problemas y el caos que llevó a la crisis del software. cuales fueron creadas. Lo cierto es que la búsqueda de una única clave para el éxito nunca funcionó. El campo de la ingeniería de soft• Promover mayor calidad al desarrollar aplicaciones ware parece un campo demasiado complejo y amplio pacomplejas. ra una única solución que sirva para mejorar la mayoría de los problemas, y cada problema representa sólo una • Brindar mayor exactitud en los costos de proyectos pequeña porción de todos los problemas de software. y tiempo de desarrollo de los mismos. El auge del uso del Internet llevó a un vertiginoso crecimiento en la demanda de sistemas internacionales de des• Aumentar la eficiencia de los sistemas al introducir pliegue de información en la World Wide Web. Los desaprocesos que permitan medir mediante normas esrrolladores se vieron en la tarea de manejar ilustraciones, pecíficas, la calidad del software desarrollado, busmapas, fotografías y animaciones, a un ritmo nunca antes cando siempre la mejor calidad posible según las nevisto, con casi ningún método para optimizar la visualicesidades y resultados que se quieren generar. zación y almacenamiento de imágenes. También fueron necesarios sistemas para traducir el flujo de información • Una mejor organización de equipos de trabajo, en el en múltiples idiomas extranjeros a lenguaje natural huárea de desarrollo y mantenimiento de software. mano, con muchos sistemas de software diseñados para uso multilenguaje, basado en traductores humanos. • Detectar a través de pruebas, posibles mejoras paLa ingeniería de software contribuyo alrededor de 90,000 ra un mejor funcionamiento del software desarrollamillones de dólares por año ya que entra en juego el Indo.* [12]
99.5. NOTACIONES
99.3 Recursos 99.3.1
Recurso humano
191 proyectos exitosos donde se han usado métodos de ingeniería de software incluyen a GNU/Linux, el software del transbordador espacial, los cajeros automáticos y muchos otros.
Son todas aquellas personas que intervienen en la planificación de cualquier instancias de software (por ejemplo: gestor, ingeniero de software experimentado, etc.), El nú- 99.5 mero de personas requerido para un proyecto de software sólo puede ser determinado después de hacer una estima- 99.5.1 ción del esfuerzo de desarrollo...
Notaciones LUM (lenguaje unificado de modelado) o UML
Es un lenguaje de modelado muy reconocido y utilizado actualmente que se utiliza para describir o especificar métodos. También es aplicable en el desarrollo de softSon aquellos componentes de un software que son usa- ware. dos en otras aplicaciones de la misma índole, ya sea para Las siglas UML significan lenguaje unificado de modereducir costos o tiempo. lado esto quiere decir que no pretende definir un modelo estándar de desarrollo, sino únicamente un lenguaje de modelado.* [14] 99.3.3 Recursos de entorno
99.3.2
Recursos de software reutilizables
Un lenguaje de modelado consiste de vistas, elementos de Es el entorno de las aplicaciones (software y hardware) modelo y un conjunto de reglas: sintácticas, semánticas y el hardware proporciona el medio físico para desarrollar pragmáticas que indican cómo utilizar los elementos. las aplicaciones (software), este recurso es indispensable.* [13]
99.5.2 BPMN (notación para el modelado de procesos de negocios)
99.4 Implicaciones socioeconómicas
El objetivo de la notación para el modelado de procesos de negocios es proporcionar de una manera fácil de definir y analizar los procesos de negocios públicos y privados simulando un diagrama de flujo. La notación ha 99.4.1 Económicamente sido diseñada específicamente para coordinar la secuencia de los procesos y los mensajes que fluyen entre los En los Estados Unidos, el software contribuyó a una ocparticipantes del mismo, con un conjunto de actividades tava parte de todo el incremento del PIB durante la dérelacionadas. Características básicas de los elementos de cada de 1990 (alrededor de 90,000 millones de dólares BPMN por año), y un noveno de todo el crecimiento de productividad durante los últimos años de la década (alrededor • Objetos de flujo: eventos, actividades, rombos de de 33.000 millones de dólares estadounidenses por año). control de flujo (gateways). La ingeniería de software contribuyó a US$ 1 billón de crecimiento económico y productividad en esa década. • Objetos de conexión: flujo de secuencia, flujo de Alrededor del globo, el software contribuye al crecimienmensaje, asociación. to económico de maneras similares, aunque es difícil de • Swimlanes (carriles de piscina): pool, lane. encontrar estadísticas fiables. * [cita requerida] Además, con la industria del lenguaje está hallando cada vez más campos de aplicación a escala global.
• Artefactos: objetos de datos, grupo, anotación.* [14]
99.5.3 Diagrama de flujo de datos (DFD) 99.4.2
Socialmente
Un diagrama de flujo de datos permite representar el movimiento de datos a través de un sistema por medio de modelos que describen los flujos de datos, los procesos que tranforman o cambian los datos, los destinos de datos y los almacenamientos de datos a la cual tiene acceso el sistema.
La ingeniería de software cambia la cultura del mundo debido al extendido uso de la computadora. El correo electrónico (e-mail), la WWW y la mensajería instantánea permiten a la gente interactuar de nuevas maneras. El software baja el costo y mejora la calidad de los servicios de salud, los departamentos de bomberos, las depen- Su inventor fue Larry Constantine, basado en el modelo dencias gubernamentales y otros servicios sociales. Los de computación de Martin y Estrin: flujo gráfico de datos.
192
CAPÍTULO 99. INGENIERÍA DE SOFTWARE
Con los diagramas de flujo de datos determina la manera en que cualquier sistema puede desarrollarse, ayuda en la identificación de los datos de la transacción en el modelo de datos y proporciona al usuario una idea física de cómo resultarán los datos a última instancia.* [14]
presentan, los motivos que crean insatisfacción y aquellos que deben ser cubiertos a plenitud. Por ejemplo: ¿El contenido de los reportes generados, satisface realmente las necesidades del usuario? ¿Los tiempos de respuesta ofrecidos, son oportunos?, etc.
99.6 Herramienta CASE
Hay que definir las funciones que realizara el software ya que estas ayudan al usuario final y al funcionamiento del mismo programa.
Se tiene que tener en cuenta como será el comportamiento Las Herramienta CASE son herramientas computaciona- del software ante situaciones inesperadas como lo son por les (software) que están destinadas a asistir en los proce- ejemplo una gran cantidad de usuarios usando el software sos de ciclo de vida de un software, facilitan la producción o una gran cantidad de datos entre otros. del software, varias se basan principalmente en la idea de un modelo gráfico.* [15] Análisis de requisitos
99.7 Metodología Un objetivo de décadas ha sido el encontrar procesos y metodologías, que sean sistemáticas, predecibles y repetibles, a fin de mejorar la productividad en el desarrollo y la calidad del producto software, en pocas palabras, determina los pasos a seguir y como realizarlos para finalizar una tarea.
Extraer los requisitos de un producto software es la primera etapa para crearlo. Durante la fase de análisis, el cliente plantea las necesidades que se presenta e intenta explicar lo que debería hacer el software o producto final para satisfacer dicha necesidad mientras que el desarrollador actúa como interrogador, como la persona que resuelve problemas. Con este análisis, el ingeniero de sistemas puede elegir la función que debe realizar el software y establecer o indicar cual es la interfaz más adecuada para el mismo.* [16]
El análisis de requisitos puede parecer una tarea sencilla, pero no lo es debido a que muchas veces los clientes piensan que saben todo lo que el software necesita para La ingeniería de software requiere llevar a cabo numero- su buen funcionamiento, sin embargo se requiere la habisas tareas agrupadas en etapas, al conjunto de estas etapas lidad y experiencia de algún especialista para reconocer se le denomina ciclo de vida. Las etapas comunes a casi requisitos incompletos, ambiguos o contradictorios. Estodos los modelos de ciclo de vida son las siguientes: tos requisitos se determinan tomando en cuenta las necesidades del usuario final, introduciendo técnicas que nos permitan mejorar la calidad de los sistemas sobre los que Obtención de los requisitos se trabaja.* [17]
99.7.1
Etapas del proceso
Se debe identificar sobre que se está trabajando, es decir, el tema principal que motiva el inicio del estudio y creación del nuevo software o modificación de uno ya existente. A su vez identificar los recursos que se tienen, en esto entra el conocer los recursos humanos y materiales que participan en el desarrollo de las actividades. Es importante entender el contexto del negocio para identificar adecuadamente los requisitos.
El resultado del análisis de requisitos con el cliente se plasma en el documento ERS (especificación de requisitos del sistema), cuya estructura puede venir definida por varios estándares, tales como CMMI. Asimismo, se define un diagrama de entidad/relación, en el que se plasman las principales entidades que participarán en el desarrollo del software. La captura, análisis y especificación de requisitos (incluso pruebas de ellos), es una parte crucial; de esta etapa depende en gran medida el logro de los objetivos finales. Se han ideado modelos y diversos procesos metódicos de trabajo para estos fines. Aunque aún no está formalizada, ya se habla de la ingeniería de requisitos.
Se tiene que tener dominio de la información de un problema, lo cual incluye los datos fuera del software(usuarios finales, otros sistemas o dispositivos externos), los datos que salen del sistema (por la interfaz de usuario, interfaces de red, reportes, gráficas y otros medios) y los almacenamientos de datos que recaban y orga- La IEEE Std. 830-1998 normaliza la creación de las esnizan objetos persistentes de datos (por ejemplo, aquellos pecificaciones de requisitos de software (Software Requirements Specification). que se conservan de manera permanente). También hay que ver los puntos críticos, lo que signifi- Finalidades del análisis de requisitos: ca tener de una manera clara los aspectos que entorpecen • Brindar al usuario todo lo necesario para que puey limitan el buen funcionamiento de los procedimientos da trabajar en conjunto con el software desarrollado actuales, los problemas más comunes y relevantes que se
99.7. METODOLOGÍA obteniendo los mejores resultados posibles.
193 Arquitectura
• Tener un control más completo en la etapa creación La integración de infraestructura, desarrollo de aplicaciodel software, en cuanto a tiempo de desarrollo y cos- nes, bases de datos y herramientas gerenciales, requieren de capacidad y liderazgo para poder ser conceptualizatos. dos y proyectados a futuro, solucionando los problemas • Utilización de métodos más eficientes que permitan de hoy. El rol en el cual se delegan todas estas actividades el mejor aprovechamiento del software según sea la es el del Arquitecto. finalidad de uso del mismo. El arquitecto de software es la persona que añade valor a los procesos de negocios gracias a su valioso aporte de • Aumentar la calidad del software desarrollado al dis- soluciones tecnológicas. minuir los riesgos de mal funcionamiento.* [18] La arquitectura de sistemas en general, es una actividad de planeación, ya sea a nivel de infraestructura de red y No siempre en la etapa de “análisis de requisitos”las hardware, o de software. distintas metodologías de desarrollo llevan asociado un estudio de viabilidad y/o estimación de costes. El más co- Lo principal en este punto es poner en claro los aspectos nocido de los modelos de estimación de coste del software lógicos y físicos de las salidas, modelos de organización y representación de datos, entradas y procesos que compoes el modelo COCOMO nen el sistema, considerando las bondades y limitaciones de los recursos disponibles en la satisfacción de las pacificaciones brindadas para el análisis. Limitaciones* [14] Los software tienen la capacidad de emular inteligencia creando un modelo de ciertas características de la inteligencia humana pero sólo posee funciones predefinidas que abarcan un conjunto de soluciones que en algunos campos llega a ser limitado. Aun cuando tiene la capacidad de imitar ciertos comportamientos humanos no es capaz de emular el pensamiento humano porque actúa bajo condiciones. Otro aspecto limitante de los software proviene del proceso totalmente mecánico que requiere de un mayor esfuerzo y tiempos elevados de ejecución lo que lleva a tener que implementar el software en una máquina de mayor capacidad.
Especificación La especificación de requisitos describe el comportamiento esperado en el software una vez desarrollado. Gran parte del éxito de un proyecto de software radicará en la identificación de las necesidades del negocio (definidas por la alta dirección), así como la interacción con los usuarios funcionales para la recolección, clasificación, identificación, priorización y especificación de los requisitos del software.
Hay que tener en consideración la arquitectura del sistema en la cual se va a trabajar, elaborar un plan de trabajo viendo la prioridad de tiempo y recursos disponibles. En los diseños de salidas entra los que es la interpretación de requerimientos lo cual es el dominio de información del problema, las funciones visibles para el usuario, el comportamiento del sistema y un conjunto de clases de requerimientos que agrupa los objetos del negocio con los métodos que les dan servicio. La arquitectura de software consiste en el diseño de componentes de una aplicación (entidades del negocio), generalmente utilizando patrones de arquitectura. El diseño arquitectónico debe permitir visualizar la interacción entre las entidades del negocio y además poder ser validado, por ejemplo por medio de diagramas de secuencia. Un diseño arquitectónico describe en general el cómo se construirá una aplicación de software. Para ello se documenta utilizando diagramas, por ejemplo: • Diagramas de clases • Diagramas de base de datos • Diagrama de despliegue • Diagrama de secuencia
Siendo los dos primeros los mínimos necesarios para desEntre las técnicas utilizadas para la especificación de recribir la arquitectura de un proyecto que iniciará a ser quisitos se encuentran: codificado. Dependiendo del alcance del proyecto, complejidad y necesidades, el arquitecto elegirá cuales de los • Caso de uso diagramas se requiere elaborar. • Historias de usuario Siendo los primeros más rigurosas y formales, los segundas más ágiles e informales.
Las herramientas para el diseño y modelado de software se denominan CASE (Computer Aided Software Engineering) entre las cuales se encuentran: • Enterprise Architect
194 • Microsoft Visio for Enterprise Architects Programación Implementar un diseño en código puede ser la parte más obvia del trabajo de ingeniería de software, pero no necesariamente es la que demanda mayor trabajo y ni la más complicada. La complejidad y la duración de esta etapa está íntimamente relacionada al o a los lenguajes de programación utilizados, así como al diseño previamente realizado. Desarrollo de la aplicación Para el desarrollo de la aplicación es necesario considerar cinco fases para tener una aplicación o programa eficiente, estas son: • Desarrollo de la infraestructura: Esta fase permite el desarrollo y la organización de los elementos que formaran la infraestructura de la aplicación, con el propósito de finalizar la aplicación eficientemente. • Adaptación del paquete: El objetivo principal de esta fase es entender de una manera detallada el funcionamiento del paquete, esto tiene como finalidad garantizar que el paquete pueda ser utilizado en su máximo rendimiento, tanto para negocios o recursos. Todos los elementos que componen el paquete son inspeccionados de manera detallada para evitar errores y entender mejor todas las características del paquete. • Desarrollo de unidades de diseño de interactivas: En esta fase se realizan los procedimientos que se ejecutan por un diálogo usuario-sistema. Los procedimientos de esta fase tienen como objetivo principal: 1. Establecer específicamente las acciones que debe efectuar la unidad de diseño.
CAPÍTULO 99. INGENIERÍA DE SOFTWARE • Desarrollo de unidades de diseño manuales: En esta fase el objetivo central es proyectar todos los procedimientos administrativos que desarrollarán en torno a la utilización de los componentes computarizados.* [19] Pruebas de software Consiste en comprobar que el software realice correctamente las tareas indicadas en la especificación del problema. Una técnica es probar por separado cada módulo del software, y luego probarlo de manera integral, para así llegar al objetivo. Se considera una buena práctica el que las pruebas sean efectuadas por alguien distinto al desarrollador que la programó, idealmente un área de pruebas; sin perjuicio de lo anterior el programador debe hacer sus propias pruebas. En general hay dos grandes maneras de organizar un área de pruebas, la primera es que esté compuesta por personal inexperto y que desconozca el tema de pruebas, de esta manera se evalúa que la documentación entregada sea de calidad, que los procesos descritos son tan claros que cualquiera puede entenderlos y el software hace las cosas tal y como están descritas. El segundo enfoque es tener un área de pruebas conformada por programadores con experiencia, personas que saben sin mayores indicaciones en qué condiciones puede fallar una aplicación y que pueden poner atención en detalles que personal inexperto no consideraría. De acuerdo con Roger S. Pressman, el proceso de pruebas se centra en los procesos lógicos internos del software, asegurando que todas las sentencias se han comprobado, y en los procesos externos funcionales, es decir, la realización de pruebas para la detección de errores. Se requiere poder probar el software con sujetos reales que puedan evaluar el comportamiento del software con el fin de proporcionar realimentación a los desarrolladores. Es importante que durante el proceso de desarrollo del software no se pierda contacto con los interesados o solicitantes del desarrollo de Software, de esta manera los objetivos del proyecto se mantendrán vigentes y se tendrá una idea clara de los aspectos que tienen que probarse durante el período de pruebas.* [20]
2. La creación de componentes para sus procedimien- Implementación tos. Una Implementación es la realización de una especifica3. Ejecutar pruebas unitarias y de integración en la uni- ción técnica o algoritmos con un programa, componente dad de diseño. software, u otro sistema de cómputo. Muchas especificaciones son dadas según a su especificación o un están• Desarrollo de unidades de diseño batch: En esta dar. Las especificaciones recomendadas según el ´World fase se utilizan una serie de combinación de técnicas, Wide Web Consortium, y las herramientas de desarrollo como diagrama de flujo, diagramas de estructuras, del software contienen implementaciones de lenguajes de tablas de decisiones, etc. Cualquiera a utilizar será programación. El modelo de implementación es una cobeneficioso para plasmar de manera clara y objetiva lección de componentes y los subsitemas que contienen. las especificaciones y que así el programador tenga Componentes tales como: ficheros ejecutables, ficheros mayor comprensión a la hora de programar y probar de código fuente y todo otro tipo de ficheros que sean nelos programas que le corresponden. cesarios para la implementación y despliegue del sistema.
99.8. MODELOS Y CICLOS DE VIDA DEL DESARROLLO DE SOFTWARE Documentación Es todo lo concerniente a la documentación del propio desarrollo del software y de la gestión del proyecto, pasando por modelaciones (UML), diagramas de casos de uso, pruebas, manuales de usuario, manuales técnicos, etc; todo con el propósito de eventuales correcciones, usabilidad, mantenimiento futuro y ampliaciones al sistema.
195
99.8 Modelos y Ciclos de Vida del Desarrollo de Software
La ingeniería de software, con el fin de ordenar el caos que era anteriormente el desarrollo de software, dispone de varios modelos, paradigmas y filosofías de desarrollo, estos los conocemos principalmente como modelos o ciclos de vida del desarrollo de software, esto incluye el proceso que se sigue para construir, entregar y hacer evolucionar el software, desde la concepción de una idea Mantenimiento hasta la entrega y el retiro del sistema y representa todas Fase dedicada a mantener y mejorar el software para co- las actividades y artefactos (productos intermedios) ne* rregir errores descubiertos e incorporar nuevos requisi- cesarios para desarrollar una aplicación, [23] entre ellos tos. Esto puede llevar más tiempo incluso que el desarro- se puede citar: llo del software inicial. Alrededor de 2/3 del tiempo de ciclo de vida de un proyecto* [21] está dedicado a su mantenimiento. Una pequeña parte de este trabajo consiste 99.8.1 Modelo en cascada o clásico eliminar errores (bugs); siendo que la mayor parte reside en extender el sistema para incorporarle nuevas funcioEn ingeniería de software el modelo en cascada ―tamnalidades y hacer frente a su evolución. bién llamado desarrollo en cascada o ciclo de vida clásico ―se basa en un enfoque metodológico que ordena rigurosamente las etapas del ciclo de vida del software, esto * 99.7.2 Ventajas [22] sugiere una aproximación sistemática secuencial hacia el proceso de desarrollo del software, que se inicia con la esDesde el punto de vista de gestión pecificación de requisitos del cliente y continúa con la planificación, el modelado, la construcción y el despliegue • Facilitar la tarea de seguimiento del proyecto para culminar en el soporte del software terminado.* [24] • Optimizar el uso de recursos • Facilitar la comunicación entre usuarios y desarro- 99.8.2 lladores
Modelo de prototipos
En ingeniería de software, el modelo de prototipos perte• Facilitar la evaluación de resultados y cumplimiento nece a los modelos de desarrollo evolutivo. Este permite de objetivos que todo el sistema, o algunos de sus partes, se construyan rápidamente para comprender con facilidad y aclarar ciertos aspectos en los que se aseguren que el desarrollaDesde el punto de vista de los ingenieros de Software dor, el usuario, el cliente estén de acuerdo en lo que se necesita así como también la solución que se propone pa• Ayudar a comprender el problema ra dicha necesidad y de esta manera minimizar el riesgo y la incertidumbre en el desarrollo, este modelo se encarga • Permitir la reutilización del desarrollo de diseños para que estos sean analizados y prescindir de ellos a medida que se adhieran nuevas espe• Facilitar el mantenimiento del producto final cificaciones, es ideal para medir el alcance del producto, pero no se asegura su uso real. • Optimizar el conjunto y cada una de las fases del Este modelo principalmente se aplica cuando un cliente proceso de desarrollo define un conjunto de objetivos generales para el software a desarrollarse sin delimitar detalladamente los requisitos de entrada procesamiento y salida, es decir cuando Desde el punto de vista de cliente o usuario final el responsable no está seguro de la eficacia de un algoritmo, de la adaptabilidad del sistema o de la manera en que • Garantizar el nivel de calidad del producto final interactúa el hombre y la máquina. • Obtener el ciclo de vida adecuado para el proyecto • Confianza en los plazos del tiempo mostrados en la definición del proyecto
Este modelo se encarga principalmente de ayudar al ingeniero de sistemas y al cliente a entender de mejor manera cuál será el resultado de la construcción cuando los requisitos estén satisfechos.* [25]
196
99.8.3
CAPÍTULO 99. INGENIERÍA DE SOFTWARE
Modelo en espiral
El modelo en espiral, que Barry Boehm propuso originalmente en 1986, es un modelo de proceso de software evolutivo que conjuga la naturaleza iterativa de la construcción de prototipos con los aspectos controlados y sistemáticos del modelo en cascada, es decir, cuando se aplica este modelo, el software se desarrolla en una serie de entregas evolutivas (ciclos o iteraciones), cada una de estas entregando prototipos más completas que el anterior, todo esto en función del análisis de riesgo y las necesidades del cliente. Aunque el modelo espiral representa ventajas por sobre el desarrollo lineal, el cálculo de los riesgos puede ser muy complicado y por lo cual su uso en el ámbito real es muy escaso.* [26]
99.8.4
Modelo de desarrollo por etapas
99.8.5 Modelo Incremental o Iterativo Desarrollo iterativo y creciente (o incremental) es un proceso de desarrollo de software, creado en respuesta a las debilidades del modelo tradicional de cascada, es decir, este modelo aplica secuencias lineales como el modelo en cascada, pero de una manera iterativa o escalada según como avance el proceso de desarrollo y con cada una de estas secuencias lineales se producen incrementos (mejoras) del software.* [27] Se debe tener en cuenta que el flujo del proceso de cualquier incremento puede incorporar el paradigma de construcción de prototipos, ya que como se mencionó anteriormente, este tipo de modelo es iterativo por naturaleza, sin embargo se diferencia en que este busca la entrega de un producto operacional con cada incremento que se le realice al software.
Este desarrollo incremental es útil principalmente cuando Es un modelo en el que el software se muestra al cliente en el personal necesario para una implementación completa etapas refinadas sucesivamente. Con esta metodología se no está disponible. desarrollan las capacidades más importantes reduciendo el tiempo necesario para la construcción de un producto; Modelo estructurado el modelo de entrega por etapas es útil para el desarrollo de la herramienta debido a que su uso se recomienda Este modelo ―como su nombre lo indica ―utiliza las para problemas que pueden ser tratados descomponién- técnicas del diseño estructurado o de la programación dolos en problemas más pequeños y se caracteriza princi- estructurada para su desarrollo, también se utiliza en la palmente en que las especificaciones no son conocidas en creación de los algoritmos del programa. Este formato detalle al inicio del proyecto y por tanto se van desarro- facilita la comprensión de la estructura de datos y su conllando simultáneamente con las diferentes versiones del trol.* [28] Entre las principales características de este mocódigo. delo se encuentan las siguientes: En este modelo pueden distinguirse las siguientes fases: • Especificación conceptual. • Análisis de requisitos.
• Generalmente se puede diferenciar de una manera más clara los procesos y las estructuras de datos. • Existen métodos que se enfocan principalmente en ciertos datos.
• Diseño inicial.
• La abstracción del programa es de un nivel mucho mayor.
• Diseño detallado (codificación, depuración, prueba y liberación).
• Los procesos y estructuras de datos son representados jerárquicamente.* [28]
Cuando es por etapas, en el diseño global estas fases pue- Este modelo también presenta sus desventajas entre las den repetirse según la cantidad de etapas que sean reque- cuales podemos mencionar algunas: ridas. • Se podía encontrar datos repetidos en diferentes Entre sus ventajas tenemos: partes del programa.* [28] • Detección de problemas antes y no hasta la única entrega final del proyecto.
• Cuando el código se hace muy extenso o grande su manejo se complica demasiado.* [29]
En el modelo estructurado las técnicas que comúnmente • Eliminación del tiempo en informes debido a que se utilizan son: cada versión es un avance. • Estimación de tiempo por versión, evitando errores en la estimación del proyecto general. • Cumplimiento a la fecha por los desarrolladores.
• El modelo entidad-relación, esta técnica se relaciona principalmente con los datos. • El diagrama de flujo de datos, esta es utilizada principalmente para los procesos.* [30]
99.8. MODELOS Y CICLOS DE VIDA DEL DESARROLLO DE SOFTWARE Modelo orientado a objetos Estos modelos tienen sus raíces en la programación orientada a objetos y como consecuencia de ella gira entorno al concepto de clase, también lo hacen el análisis de requisitos y el diseño. Esto además de introducir nuevas técnicas, también aprovecha las técnicas y conceptos del desarrollo estructurado, como diagramas de estado y transiciones. El modelo orientado a objetos tiene dos características principales, las cuales ha favorecido su expansión: • Permite la reutilización de software en un grado significativo. • Su simplicidad facilita el desarrollo de herramientas informáticas de ayuda al desarrollo, el cual es fácilmente implementada en una notación orientada a objetos llamado UML.* [31]
99.8.6
197
estado hecho al estado cambios en espera. Este modelo de desarrollo se utiliza a menudo como el paradigma de desarrollo de aplicaciones cliente/servidor. Un sistema cliente/servidor se compone de un conjunto de componentes funcionales. Cuando se aplica a cliente/servidor, el modelo de proceso concurrente define actividades en dos dimensiones: una división de sistemas y una división de componentes. Los aspectos del nivel de sistemas se afrontan mediante dos actividades: diseño y realización. La concurrencia se logra de dos maneras: • Las actividades del sistema y de componente ocurren simultáneamente y pueden modelarse con el enfoque orientado a objetos descrito anteriormente; • Una aplicación cliente/servidor típica se implementa con muchos componentes, cada uno de los cuales se pueden diseñar y realizar concurrentemente.
Modelo RAD (rapid application de- En realidad, el modelo de desarrollo concurrente es aplivelopment) cable a todo tipo de desarrollo de software y proporciona
una imagen exacta del estado actual de un proyecto. En vez de confinar actividades de ingeniería de software a una secuencia de sucesos, define una red de actividades, todas las actividades de la red existen simultáneamente con otras. Los sucesos generados dentro de una actividad dada o algún otro lado de la red de actividad inicia las Esta es una metodología que posibilita la construcción de transiciones entre los estados de una actividad. sistemas computacionales que combinen técnicas y utilidades CASE (Computer Aided Software Engineering), 99.8.8 Proceso unificado del desarrollo de la construcción de prototipos centrados en el usuario y el software seguimiento lineal y sistemático de objetivos, incrementando la rapidez con la que se producen los sistemas meEl proceso unificado es un proceso de software genérico diante la utilización de un enfoque de desarrollo basado que puede ser utilizado para una gran cantidad de tipos de en componentes.* [32] sistemas de software, para diferentes áreas de aplicación, Si se entienden bien los requisitos y se limita el ámbi- diferentes tipos de organizaciones, diferentes niveles de to del proyecto, el proceso RAD permite que un equipo competencia y diferentes tamaños de proyectos. de desarrollo cree un producto completamente funcional Provee un enfoque disciplinado en la asignación de tadentro de un periodo muy limitado de tiempo sin reducir reas y responsabilidades dentro de una organización de en lo más mínimo la calidad del mismo.* [33] desarrollo. Su meta es asegurar la producción de software de muy alta calidad que satisfaga las necesidades de los usuarios finales, dentro de un calendario y presupues99.8.7 Modelo de desarrollo concurrente to predecible.* [34] El modelo de desarrollo concurrente es un modelo de tipo El proceso unificado tiene dos dimensiones: de red donde todas las personas actúan simultáneamente o al mismo tiempo. Este tipo de modelo se puede repre• Un eje horizontal que representa el tiempo y muestra sentar a manera de esquema como una serie de activilos aspectos del ciclo de vida del proceso a lo largo dades técnicas importantes, tareas y estados asociados a de su desenvolvimiento ellas. • Un eje vertical que representa las disciplinas, las El modelo de proceso concurrente define una serie de cuales agrupan actividades de una manera lógica de acontecimientos que dispararan transiciones de estado a acuerdo a su naturaleza. estado para cada una de las actividades de la ingeniería El RAD (rapid application development:ʻdesarrollo rápido de aplicacionesʼ), es un modelo de proceso de software incremental, desarrollado inicialmente por James Maslow en 1980, que resalta principalmente un ciclo corto de desarrollo.
del software. Por ejemplo, durante las primeras etapas del diseño, no se contempla una inconsistencia del modelo de La primera dimensión representa el aspecto dinámico del análisis. Esto genera la corrección del modelo de análi- proceso conforme se va desarrollando, se expresa en térsis de sucesos, que disparara la actividad de análisis del minos de fases, iteraciones e hitos (milestones).
198
CAPÍTULO 99. INGENIERÍA DE SOFTWARE
La segunda dimensión representa el aspecto estático del para el usuario el producto final es la información que de proceso: cómo es descrito en términos de componentes cierto modo soluciona el problema planteado por el usuadel proceso, disciplinas, actividades, flujos de trabajo, ar- rio. tefactos y roles. El refinamiento más conocido y documentado del proceso unificado es el RUP (proceso unificado racional). El proceso unificado no es simplemente un proceso, sino un marco de trabajo extensible que puede ser adaptado a organizaciones o proyectos específicos. De la misma manera, el proceso unificado de rational, también es un marco de trabajo extensible, por lo que muchas veces resulta imposible decir si un refinamiento particular del proceso ha sido derivado del proceso unificado o del RUP. Por dicho motivo, los dos nombres suelen utilizarse para referirse a un mismo concepto.* [35]
99.10 Naturaleza de la Ingeniería de Software La ingeniería de software es una disciplina que está orientada a aplicar conceptos y métodos de ingeniería al desarrollo de software de calidad. Matemáticas
Los programas tienen muchas propiedades matemáticas. Por ejemplo la corrección y la complejidad de muchos algoritmos son conceptos matemáticos que pueden ser ri99.9 Producto gurosamente probados. El uso de matemáticas en la IS es El software se ha convertido en algo muy necesario en llamado métodos formales. nuestra sociedad actual, es la máquina que conduce a la toma de decisiones comerciales, sirve para la investiga- Creación ción científica moderna, es un factor clave que diferencia productos y servicios modernos, etc. Esto se da porque el Los programas son construidos en una secuencia de pasoftware está inmerso en sistemas de todo tipo alrededor sos. El hecho de definir propiamente y llevar a cabo esde nosotros. tos pasos, como en una línea de ensamblaje, es necesario El software de computadora es el producto que diseñan y construyen los ingenieros de software. Esto abarca programas que se ejecutan dentro de una computadora de cualquier tamaño y arquitectura, después de estar construido casi cualquier persona en el mundo industrializado, ya sea directa o indirectamente. Los productos se pueden clasificar en:
para mejorar la productividad de los desarrolladores y la calidad final de los programas. Este punto de vista inspira los diferentes procesos y metodologías que se encuentran en la IS. Gestión de Proyecto
El desarrollo de software de gran porte requiere una ade• Productos genéricos: Son los producidos por una or- cuada gestión del proyecto. Hay presupuestos, estableciganización para ser vendidos al mercado. miento de tiempos de entrega, un equipo de profesionales • Productos hechos a medida: Sistemas que son desa- que liderar. Recursos (espacio de oficina, insumos, equirrollados bajo pedido a un desarrollador específico. pamiento) por adquirir. Para su administración se debe tener una clara visión y capacitación en gestión de proEstos productos deben cumplir varias características al yectos. ser entregados, estas son: • Mantenibles: El software debe poder evolucionar mientras cumple con sus funciones.
99.11 Participantes y papeles
• Confiabilidad: No debe producir daños en caso de Para el desarrollo de un sistema de software es necesaria la colaboración de muchas personas con diversas compeerrores. tencias, capacidades e intereses. Al conjunto de personas • Eficiencia: El software no debe desperdiciar los re- involucradas en el proyecto se les conoce como particicursos. pantes. • Utilización adecuada: Debe contar con una interfaz Al conjunto de funciones y responsabilidades que hay de usuario adecuada y su documentación. dentro del proyecto o sistema se le conoce como roles o papeles. Los roles están asociados a las tareas que son Lo que constituye el producto final es diferente para el asignadas a los participantes, en consecuencia, una persoingeniero y los usuarios, para el ingeniero son los progra- na puede desempeñar uno o múltiples roles, así también mas, datos y documentos que configuran el software pero un mismo rol puede ser representado por un equipo.* [36]
99.11. PARTICIPANTES Y PAPELES
99.11.1
Cliente
Es frecuente el uso de los términos“usuarios”,“usuarios finales”y “clientes”como sinónimos, lo cual puede provocar confusión; estrictamente, el cliente (persona, empresa u organización) es quién especifica los requisitos del sistema,* [37] en tanto que el usuario es quien utiliza u opera finalmente el producto software, pudiendo ser o no el cliente.
99.11.2
Desarrolladores
Esta clase de participantes están relacionados con todas las facetas del proceso de desarrollo del software. Su trabajo incluye la investigación, diseño, implementación, pruebas y depuración del software.* [38]
99.11.3
Gestores
En el contexto de ingeniería de software, el gestor de desarrollo de software es un participante, que reporta al director ejecutivo de la empresa que presta el servicio de desarrollo. Es responsable del manejo y coordinación de los recursos y procesos para la correcta entrega de productos de software, mientras participa en la definición de la estrategia para el equipo de desarrolladores, dando iniciativas que promuevan la visión de la empresa.* [39]
99.11.4
Usuarios finales
El usuario final es quien interactúa con el producto de software una vez es entregado.* [40] Generalmente son los usuarios los que conocen el problema, ya que día a día operan los sistemas.
99.11.5
Código ético de un ingeniero de software
Un ingeniero de software debe tener un código donde asegura, en la medida posible, que los esfuerzos realizados se utilizarán para realizar el bien y deben comprometerse para que la ingeniería de software sea una profesión benéfica y respetada. Para el cumplimiento de esta norma, se toman en cuenta ocho principios relacionados con la conducta y las decisiones tomadas por el ingeniero; donde estos principios identifican las relaciones éticamente responsables de los individuos, grupos y organizaciones donde participen. Los principios a los que deben sujetarse son sobre la sociedad, cliente y empresario, producto, juicio, administración, profesión, colegas y por último el personal. • Sociedad: Los ingenieros de software deben actuar de manera congruente con el interés social, aceptando la responsabilidad total de su trabajo, moderan-
199 do los intereses con el bienestar social, aprobando el software solamente si se tiene una creencia bien fundamentada, cooperando en los esfuerzos para solucionar asuntos importantes de interés social, ser justo y veraz en todas las afirmaciones relativas al software o documentos asociados. • Cliente y empresario: Se debe actuar de manera tal que se llegue a conciliar los mejores intereses de los clientes y empresarios, congruentemente con el interés social. Estos deberán prestar servicios en sus áreas de competencia, siendo honestos y francos sobre las limitaciones, no utilizar un software que se obtenga ilegalmente o sin ética, usar la propiedad de los clientes o empresarios de manera autorizada, mantener secreto cualquier documento de información confidencial. • Producto: Hay que asegurarse que los productos y sus modificaciones cumplan con los estándares profesionales más altos posibles, procurando la alta calidad, costos aceptables y una agenda razonable asegurando que los costos y beneficios sean claros y aceptados por el empresario y el cliente. Asegurar que las metas y objetivos de cualquier proyecto sean adecuados y alcanzables. • Juicio: Se debe mantener una integridad e independencia en el juicio profesional, moderando todo juicio técnico por la necesidad de apoyar y mantener los valores humanos, mantener la objetividad profesional con respecto a cualquier software o documento relacionado, no involucrarse en prácticas financieras fraudulentas. • Administración: Se deberá asegurar una buena administración para cualquier proyecto en el cual se trabaje, utilizando procedimientos efectivos para promover la calidad y reducir riesgos, asegurándose también que se conozcan las políticas y procedimientos del empresario para proteger contraseñas, archivos e información confidencial. • Profesión: Se debe incrementar la integridad y reputación de la profesión en conjunto con el interés social, ayudando al desarrollo de un ambiente organizacional favorable para actuar, promoviendo el conocimiento público de la ingeniería de software, extendiendo el conocimiento de la ingeniería de software por medio de participaciones en organizaciones, reuniones y publicaciones profesionales. • Colegas: Cada ingeniero deberá apoyar y ser justos con los colegas, motivando a sus colegas sujetándose al código, ayudando también a su desarrollo profesional, reconocer los trabajos de otros y abstenerse a atribuirse de méritos indebidos, revisar los trabajos de manera objetiva, sincera y propiamente documentada.
200
CAPÍTULO 99. INGENIERÍA DE SOFTWARE
• Personal: Los ingenieros de software participaran toda su vida en el aprendizaje con la práctica y promoverán un enfoque ético de la profesión, mejorando su conocimiento de los avances en el análisis, especificación, diseño, desarrollo, mantenimiento, pruebas del software y documentos relacionados en conjunto con administración del proceso de desarrollo.* [41]
99.12 Educación ética 99.12.1
Organizaciones
• IEEE Computer Society • Association for Computing Machinery (ACM). • Software Engineering Institute (SEI). • British Computer Society (BCS). • RUSSOFT Association • Society of Software Engineers
99.13 Véase también • Anexo:Filosofías del desarrollo de software • Ingeniería informática • Gestión de la configuración • Proceso para el desarrollo de software • Mantenimiento de software • Fragilidad del software • Error de software
[3] ACM (2006). «Computing Degrees & Careers». ACM. Consultado el 23 de noviembre de 2010. [4] Bureau of Labor Statistics, U.S. Department of Labor, USDL 05-2145: Occupational Employment and Wages, November 2004, Table 1. [5] Universidad Siglo XXI,Argentina, [6] Universidad Autónoma de Guadalajara, México, [7] Tecnológico de Antioquía, Colombia, [8] Leondes (2002). intelligent systems: technology and applications. CRC Press. ISBN 978-0-8493-1121-5. [9] An Investigation of Therac-25 Accidents [10] Computer Risks [11]“Software engineering... has recently emerged as a discipline in its own right.”cita libro | apellidos=Sommerville| nombre=Ian| título=Software Engineering| editorial=Addison-Wesley| año=1985| año-original=1982| isbn = 0-201-14229-5| postscript= [12] Universidad Politécnica de Madrid. «Objetivos de ingeniería del software». [13] Pressman, Roger S. (2003). «El proceso». Ingeniería del software, un enfoque práctico. México: Mc Graw Hill, quinta edición. [14] Ingenieria de SoftwareUML, artículo en el sitio web Monografías. [15] Monografias.com Ingeniería del software [16] [http://yaqui.mxl.uabc.mx/~{}molguin/as/IngReq.htm [17] [http://www.slideshare.net/marfonline/ analisis-de-requerimientos-ingenieria-de-software [18] [http://www.slideshare.net/marfonline/ analisis-de-requerimientos-ingenieria-de-software
• Usabilidad
[19] «Unidad 2: Fundamentos de la ingeniería del software», artículo en el sitio web Ing Software.
• MÉTRICA
[20]
• Historia de la ingeniería del software • Crisis del software • No hay balas de plata
99.14 Referencias [1]“IEEE Standard Glossary of Software Engineering Terminology,”IEEE std 610.12-1990, 1990. ISBN 155937067X. [2] SWEBOK executive editors, Alain Abran, James W. Moore; editors, Pierre Bourque, Robert Dupuis. (2004). Pierre Bourque and Robert Dupuis, ed. Guide to the Software Engineering Body of Knowledge - 2004 Version. IEEE Computer Society. pp. 1–1. ISBN 0-7695-2330-7.
[21] Pressman, Roger S. (2003). «El proceso». Ingeniería del software, un enfoque práctico. México: Mc Graw Hill, quinta edición. [22] Metodologia de ingeniería de software, artículo en el sitio web Slide Share. [23] Ingeniería de software: ciclos de vida y metodologías, artículo publicado en el sitio web de la Facultad de Ingeniería de la Universidad de Los Andes. [24] Pressman, Roger S.: Ingeniería del software: un enfoque práctico. Sexta edición, pág. 50-51. [25] Lawrence Peleeger, Shari: Ingeniería de software: modelo de prototipos. Universidad Estatal de Milagro. [26] Pressman, Roger S.: Ingeniería del software: un enfoque práctico. Sexta edición, pág. 58-60.
99.16. ENLACES EXTERNOS
[27] Pressman, Roger S.: Ingeniería del software: un enfoque práctico. Sexta edición, pág. 52-53. [28] Diseño estructurado, artículo en el sitio web Slide Share. [29] , cuadro comparativo de programación estructurada y programación orientada objeto . [30] , Benet Campderrich Falgueras, Editorial UOC, 2002 320 páginas. [31] Campderrich Falgueras, Benet (2002): Ingeniería de software. Barcelona: Editorial UOC, 2002. 320 páginas. [32] , What is Rapid Application Development? [33] Pressman, Roger S.: Ingeniería del software: un enfoque práctico. Sexta edición, pág. 53-54. [34] «Proceso unificado del desarrollo de software», artículo en el sitio web Yaqui. [35] Pressman, Roger S.: Ingeniería del software: un enfoque práctico. Sexta edición, pág. 67-72. [36] Bernd Bruegge & Allen H.Dutoit. Object-Oriented Software Engineering, Prentice Hall, Pag. 11. [37] Pressman, 2002, p. 39 [38] «O*NET Code Connector - Software Developers, Systems Software - 15-1133.00». Onetcodeconnector.org. Consultado el 4 de agosto de 2014. [39] «Software Development Manager Position Description». interfacing.com. Consultado el 4 de agosto de 2014. [40] Pressman, 2002, p. 39 [41] «Ingeniería de Software Código de Ética y Práctica Profesional». SEERI, East Tennessee State University. 1999.
99.15 Bibliografía • Ingeniería de software (sexta edición), Ian Sommerville. Addison Wesley. Sitio en Inglés • Pressman, Roger S.: Ingeniería del software: un enfoque práctico (información en inglés). McGraw Hill Higher Education, sexta edición, pág. 50-51.
99.16 Enlaces externos •
Wikiversidad alberga proyectos de aprendizaje sobre Ingeniería de software.Wikiversidad
• «Is software engineering actually engineering?», artículo publicado en The Iron Warrior, publicación de la University of Waterloo Engineering Society.
201
Capítulo 100
Instancia (informática) En el paradigma de la orientación a objetos, una instancia la que pertenece y, por tanto, puede llamar a los métodos (en inglés, instance) se refiere a una realización específica de instancia que hayan sido declarados como de instancia, de una clase o prototipo determinados. así como a todos aquellos que hayan sido heredados por En general, cuando se ejecuta un programa en un compu- la jerarquía de herencia estática entre clases. tador, se dice que éste se instancia. En lenguajes que crean objetos a partir de clases, un objeto es una instancia de una clase. Esto es, un miembro de una clase que tiene atributos en lugar de variables. En un contexto del mundo real, podríamos pensar en “Perro”como una clase y en un perro concreto es una instancia de esta clase.* [1] En este caso no nos importa la raza del perro. Si fuese de nuestro interés modelarla, y diferenciásemos entre un dóberman y un chihuahua, no solo cada instancia sería diferente, sino que pertenecerían a clases o prototipos diferentes, c.f. herencia (informática).
100.1 Etimología El término en informática procede del inglés, en donde instance viene del significado que podría traducirse por caso o ejemplo en castellano. Aunque la palabra existe en el idioma inglés por incorporación desde el latín como instantia (que es de donde lo hace también la palabra en castellano), pero posteriormente también adquirió (del latín también) parte de la semántica de instāns, que en nuestro caso derivó únicamente en instante.* [2] Esta incorporación desde el inglés tendría la consideración de préstamo semántico, aunque esta acepción no está contemplada todavía por la Real Academia Española.* [3]
100.2 Programación basada en clases
Ciertos lenguajes de programación permiten utilizar clases mixin, que permiten además realizar asociaciones entre instancias de objetos para establecer relaciones similares a la herencia en tiempo de ejecución.
100.2.1 Clases como objetos Multitud de lenguajes de programación basados en clases proporcionan mecanismos de reflexión o introspección, esto es, permiten que el programa pueda observar (e incluso modificar) su propia estructura de alto nivel. Si estos mecanismos siguen el paradigma de orientación a objetos también, entonces las clases serán representadas también como instancias de objetos. En particular, si el lenguaje no permite dos definiciones de una misma clase (puede hacerlo para permitir ejecuciones concurrentes de distintas versiones de una clase)* [Nota 1] entonces las clases serán representadas utilizando un Singleton. En Java, por ejemplo, si tenemos una clase definida como: public class Perro {} Podremos acceder a la instancia que representa la clase (y es una instancia de la clasejava.lang.Class), en un programa principal de clase Main, del siguiente modo: public class Main { public static void main(String... args) { Class> perroClass = Perro.class; System.out.println(perroClass); } }
En este apartado hablaremos de la programación orienta100.3 Programación basada en da a objetos basada en clases, que es la que implementa la mayoría de lenguajes de programación orientados a obprototipos jetos. En el modelo basado en prototipos, que es el de lenguajes como JavaScript, los términos que se refieren a En el estilo de programación orientada a objetos basada clases han de sustituirse por los prototipos de los objetos, en prototipos las instancias son los objetos creados a partir pero por lo demás, son de aplicación similar. de los prototipos. En general, los prototipos también son En este modelo, un objeto tiene una referencia a la clase a objetos creados a partir de otros prototipos, con lo que 202
100.5. REFERENCIAS las propiedades y métodos se heredan en la profundidad completa del árbol de herencia de prototipados. En el caso particular de JavaScript, aunque no se puede cambiar el prototipo de un objeto una vez instanciado, sí se pueden cambiar las propiedades y métodos que tiene el prototipo, afectando a todas las instancias (en profundidad) de ese prototipo. En el caso particular de este lenguaje, en el que todos los objetos son instancias de Object, modificar o añadir métodos a Object tendrá como consecuencia la modificación de esos métodos u objetos entodos los demás objetos que no los hayan redefinido posteriormente, incluyendo los ya instanciados. Este es el mecanismo que utilizan algunas bibliotecas de JavaScript* [Nota 2] para proporcionar funciones que no hayan implementado ciertos motores a ciertos objetos del lenguaje.
100.4 Notas [1] Erlang, por ejemplo, permite la ejecución concurrente de varias versiones de un mismo programa, véase change-3 http://www.erlang.org/doc/man/gen server.html#Module:code change-3, y CLOS. [2] http://augmentjs.com, por ejemplo, proporciona métodos al objeto Array.prototype, cambiando todos los Array del programa.
100.5 Referencias [1] http://whatis.techtarget.com/definition/instance (en inglés) [2] Véase Etymology en http://www.wordreference.com/ definition/instance [3] http://lema.rae.es/drae/?val=instancia
203
Capítulo 101
Instrucción (informática) Se denomina instrucción en informática al conjunto de datos insertados en una secuencia estructurada o específica que el procesador interpreta y ejecuta.
101.2 Tipos
Los tipos de instrucción permitidos están definidos y determinados dentro de cada plataforma en el conjunto de instrucciones (en inglés ISA, instruction set architecture), que también determina los registros de origen y destino de la CPU, y en ocasiones un dato inmediato (aquellos que son especificados explícitamente en la instrucción). Estas instrucciones del computador son las que determinan el funcionamiento de la CPU que las ejecuta. La CPU puede realizar una diversidad de funciones, que son el reflejo de la variedad de las instrucciones definidas para dicha CPU. El programador tiene un repertorio de instrucciones como medio para controlar la CPU.
• Instrucciones de transferencia de datos: en este tipo de instrucciones, se transfieren datos desde una localización a otra. Los pasos que se siguen para realizarlo son: 1. Determinación de las direcciones de origen y destino de memoria. 2. Realización de la transformación de memoria virtual a memoria real. 3. Comprobación de la caché. 4. Inicio del proceso de lectura/escritura en la memoria. • Instrucciones aritméticas: pueden implicar transferencia de datos antes y/o después. Realizan operaciones aritméticas de las que se encarga la ALU. Se pueden clasificar en de 1 operando (valor absoluto, negación) y 2 operandos (suma, resta).
101.1 Campos Normalmente una instrucción se divide en dos campos:
• Código de operación: Designa la operación que va a ser realizada. En lenguaje ensamblador, se asigna a su valor numérico un mnemónico. Por ejemplo, en el MIPS tenemos una instrucción con el código de operación 0224x en lenguaje ensamblador es la operación add. • Datos de la operación: Dependiendo del tipo de instrucción, este campo puede estar dividido en otros o ser único, incluso no existir. En él se suelen indicar los registros y datos con los que trabajar.
• Instrucciones lógicas: al igual que las aritméticas, la ALU se encarga de realizar estas operaciones, que en este caso son de tipo lógico. • Instrucciones de conversión: similares a las aritméticas y lógicas. Pueden implicar lógica especial para realizar la conversión. • Instrucciones de transferencia de control: actualizan el contador de programa (PC). Administran las llamadas/retornos a las subrutinas, el paso de parámetros y el enlazado. • Instrucciones de E/S (entrada/salida): administran los comandos de entrada/salida. Si hay un mapa de memoria de entrada/salida, determina la dirección de este mapa.
El tamaño (longitud en bits) de la instrucción depende de cada arquitectura, pudiendo variar de 4 hasta 128 bits. La instrucción debe almacenarse temporalmente (en el 101.3 Repertorio registro de instrucción, RI) para que la CPU analice su contenido y extraiga los datos que la forman. A este paso Las instrucciones de un lenguaje de programación se pueden clasificar en 4 grupos: se le llama decodificación. 204
101.4. VÉASE TAMBIÉN • Instrucciones de transferencias de datos: Son aquellas de entrada o lectura y de salida o escritura. En el caso de las instrucciones de entrada o lectura, se lleva el dato de entrada o lectura desde la unidad de entrada a la memoria. Si por el contrario es una instrucción de salida o escritura, se lleva el dato de la memoria a la unidad de salida. • Instrucciones de tratamiento: Se trata de las instrucciones aritmético-lógicas y las de desplazamientos. Así como suma de datos o comparaciones. • Instrucciones de flujo de control o de bifurcación y salto: Las instrucciones de flujo de control son aquellas instrucciones que alteran el orden secuencial de la ejecución de un programa. También hay instrucciones que posibilitan la interrupción de la ejecución o saltar a ejecutar otro programa. Cuando termina cualquiera de estas instrucciones, el programa continúa ejecutándose desde el punto en el que se interrumpió. • Otras instrucciones: Por ejemplo, la detención del funcionamiento del computador a la espera de una acción del usuario.
101.4 Véase también • Lenguaje de máquina. • Comando.
205
Capítulo 102
Interfaz binaria de aplicaciones Linux kernel-to-userspace ☐ ✔
La adhesión a las ABIs (las cuales pueden o no estar oficialmente estandarizadas) es normalmente trabajo del compilador, sistema operativo o de la librería, pero los programadores de aplicaciones pueden tratar con las ABIs directamente cuando escriben las aplicaciones en una mezcla de lenguajes de programación, utilizando interfaces de funciones foráneas entre ellas.
Linux kernel-internal ☐ ✘
API stability is guaranteed, source code is portable!
API stability is not guaranteed, source code portability is not a given Linux memory manager Virtual file system
API
I/O interface
Network interface
☐ no stable ABI over Linux kernel releases, ✘
☐ ✔ compatible ABI can be guaranteed,
Las ABIs difieren de las interfaces de programación de aplicaciones (APIs) en que ambas definen interfaces entre componentes de programa pero las API a nivel de código fuente.
binaries are not portable
binaries are portable
Linux OS "Alpha"
✘
DRM
in Linux kernel 3.14
MotionBuilder Siemens NX BricsCAD CATIA5 Maya et al.
ABI
IPC manager
Linux process scheduler
binary device driver
Linux OS "Bravo"
Linux OS "Charlie"
compiled against LSB 5.0 for x86-64
✘
DRM
in Linux kernel 3.7
compiled for Linux kernel 3.0
✔
compiled against LSB 5.0 for x86-64
DRM
in Linux kernel 3.0
Compilando los sistemas operativos y software comercial conforme a Linux Standard Base, resultará en una Interfaz Binaria de Aplicación (ABI) y por ello en portabilidad binaria. static int collect(const char *root) { enum { FD_FANOTIFY, /* Get the actual fs events */ FD_SIGNAL, /* We get notifications to quit early via this fd */ FD_INOTIFY, _FD_MAX }; struct pollfd pollfd[_FD_MAX] = {}; int fanotify_fd = -1, signal_fd = -1, inotify_fd = -1, r = 0; pid_t my_pid; Hashmap *files = NULL; Iterator i; char *p, *q; sigsdet_t mask; FILE *pack = NULL; char *pack_fn_new = NULL, *pack_fn = NULL; bool on_ssd, on_btrfs; struct statfs sfs; usec_t not_after; uint64_t previous_block_readahead; bool previous_block_readahead_set = false;
static int collect(const char *root) { enum { FD_FANOTIFY, /* Get the actual fs events */ FD_SIGNAL, /* We get notifications to quit early via this fd */ FD_INOTIFY, _FD_MAX }; struct pollfd pollfd[_FD_MAX] = {}; int fanotify_fd = -1, signal_fd = -1, inotify_fd = -1, r = 0; pid_t my_pid; Hashmap *files = NULL; Iterator i; char *p, *q; sigsdet_t mask; FILE *pack = NULL; char *pack_fn_new = NULL, *pack_fn = NULL; bool on_ssd, on_btrfs; struct statfs sfs; usec_t not_after; uint64_t previous_block_readahead; bool previous_block_readahead_set = false;
assert(root);
assert(root);
assert(root);
if (asprintf(&pack_fn, "%s/.readahead", root) < 0) { r = log_oom(); goto finish; }
if (asprintf(&pack_fn, "%s/.readahead", root) < 0) { r = log_oom(); goto finish; }
Linux kernel & GNU C Library (source code)
API
78 D2 03 DE 2A D1 9D 68 5D 35 5C 0B BF CA B7 7D DB 75 7E C7 1F 5E F8
3C 89 F7 B2 56 E3 18 1E 77 E4 6E 8D B3 CA 47 D9 DC FA EA F3 7E B0 51
1E B3 B3 6D AC 4C 63 7B 1D 71 02 71 63 16 F9 76 F7 EE 29 FC FC 7F E0
A6 98 65 5B 5A 4D D5 F8 BD 8E 1F 78 D7 DB F2 21 D0 CE 6C 8B 31 FD AB
4F 76 EB B8 C5 49 AA 21 7A 50 AF 31 6E 4F EB 84 C3 CF F8 2F 00 6B 6F
3D CC 56 7D CE E1 D5 34 F6 20 0F 5B B2 83 6F E8 75 A7 E5 B1 83 ED BE
06 14 56 F2 BC C2 AC 5D 24 E8 05 53 32 25 28 48 02 5B 11 76 06 F6 05
80 12 AE A4 3C 0B 5D E7 3E 09 EA EF D2 2B 2F 0C D9 D7 E6 FD 0C D2 E0
E9 12 5A 89 8E 2E B7 83 3E 18 31 37 C9 87 2F C3 6D AE CD 7A 08 D2 CC
D3 42 5D 8C 9B E0 8E FF 8E 07 76 67 CA BB E7 A0 DB E1 9F 96 8F BD 73
A6 97 6F 19 39 ED BB 7D EE B5 85 DC 48 EC F6 7F 77 F7 CF FD D1 6C CE
B2 30 FF 3D 83 F7 6E C4 5D ED 69 48 27 E1 9B BF 00 C0 A2 FC AF DC AB
A7 9F 8B 8A F2 DE BF 9A BB 71 BD D7 2F D4 6F BE F0 60 C5 33 5F B4 BB
A8 32 FE AC 8A E7 8D B5 86 87 6D 90 BF 29 C2 9C C3 30 4B C3 5F 19 FD
88 79 70 CC 0A 91 19 EB FB 3E E1 57 80 53 66 7F BC 88 C8 87 00 80 DB
55 12 01 4C 34 C7 D3 D8 1F 44 FD 54 39 70 B3 EE 1F CF CA 0D 76 59 6F
AB 93 93 26 5D 1F A6 B2 C9 99 29 BA 4F 39 35 39 F9 E7 CC 25 EC C7 19
compatible ABI can be guaranteed, machine code becomes portable
Compilation Linux kernel & GNU C Library (machine code)
ABI D7 26 27 4F A3 27 32 75 FC 55 4A B9 FE 5D DE BC 61 0B 64 2B CC 1F 36
• la convención de llamada, que controla cómo se pasan los argumentos de las funciones y se recuperan los valores devueltos; por ejemplo, si todos los parámetros se pasan a la pila o si algunos parámetros pasan a los registros, qué registros se utilizan para qué parámetros de una función, y qué parámetro pasa primero a la pila, si pasa el primero o el último
Siemens NX (source code)
API
binary compatible (same instruction set, same compilation environment)
ABI
Available cross-distribution ABIs, e.g.: LSB (Linux Standard Base)
systemd not (machine code) binary compatible 45 71 C8 F9 AA B8 5D CC 37 69 35 FB A9 F2 F8 46 D6 8F 9F 09 13 53 C1
• tamaños, disposición y alineamiento de los tipos de datos
Available documentation, e.g.: Linux manual pages: system calls The GNU C Library Reference Manual »The Linux Programming Interface«, Michael Kerrisk (2010, No Starch Press) etc.
stable API is guaranteed, source code remains portable
binary compatible (same instruction set, same compilation environment)
Las ABIs cubren aspectos como:
static int collect(const char *root) { enum { FD_FANOTIFY, /* Get the actual fs events */ FD_SIGNAL, /* We get notifications to quit early via this fd */ FD_INOTIFY, _FD_MAX }; struct pollfd pollfd[_FD_MAX] = {}; int fanotify_fd = -1, signal_fd = -1, inotify_fd = -1, r = 0; pid_t my_pid; Hashmap *files = NULL; Iterator i; char *p, *q; sigsdet_t mask; FILE *pack = NULL; char *pack_fn_new = NULL, *pack_fn = NULL; bool on_ssd, on_btrfs; struct statfs sfs; usec_t not_after; uint64_t previous_block_readahead; bool previous_block_readahead_set = false;
if (asprintf(&pack_fn, "%s/.readahead", root) < 0) { r = log_oom(); goto finish; }
systemd (source code)
102.1 Descripción
Siemens NX not binary compatible (machine code) 34 4C 4E 9C 6F 39 76 2B A0 05 E3 EF 9D 3C B9 F1 DE B7 F6 B3 AB 27 74
45 71 C8 F9 AA B8 5D CC 37 69 35 FB A9 F2 F8 46 D6 8F 9F 09 13 53 C1
78 D2 03 DE 2A D1 9D 68 5D 35 5C 0B BF CA B7 7D DB 75 7E C7 1F 5E F8
3C 89 F7 B2 56 E3 18 1E 77 E4 6E 8D B3 CA 47 D9 DC FA EA F3 7E B0 51
1E B3 B3 6D AC 4C 63 7B 1D 71 02 71 63 16 F9 76 F7 EE 29 FC FC 7F E0
A6 98 65 5B 5A 4D D5 F8 BD 8E 1F 78 D7 DB F2 21 D0 CE 6C 8B 31 FD AB
4F 76 EB B8 C5 49 AA 21 7A 50 AF 31 6E 4F EB 84 C3 CF F8 2F 00 6B 6F
3D CC 56 7D CE E1 D5 34 F6 20 0F 5B B2 83 6F E8 75 A7 E5 B1 83 ED BE
06 14 56 F2 BC C2 AC 5D 24 E8 05 53 32 25 28 48 02 5B 11 76 06 F6 05
80 12 AE A4 3C 0B 5D E7 3E 09 EA EF D2 2B 2F 0C D9 D7 E6 FD 0C D2 E0
E9 12 5A 89 8E 2E B7 83 3E 18 31 37 C9 87 2F C3 6D AE CD 7A 08 D2 CC
D3 42 5D 8C 9B E0 8E FF 8E 07 76 67 CA BB E7 A0 DB E1 9F 96 8F BD 73
A6 97 6F 19 39 ED BB 7D EE B5 85 DC 48 EC F6 7F 77 F7 CF FD D1 6C CE
B2 30 FF 3D 83 F7 6E C4 5D ED 69 48 27 E1 9B BF 00 C0 A2 FC AF DC AB
A7 9F 8B 8A F2 DE BF 9A BB 71 BD D7 2F D4 6F BE F0 60 C5 33 5F B4 BB
A8 32 FE AC 8A E7 8D B5 86 87 6D 90 BF 29 C2 9C C3 30 4B C3 5F 19 FD
88 79 70 CC 0A 91 19 EB FB 3E E1 57 80 53 66 7F BC 88 C8 87 00 80 DB
55 12 01 4C 34 C7 D3 D8 1F 44 FD 54 39 70 B3 EE 1F CF CA 0D 76 59 6F
AB 93 93 26 5D 1F A6 B2 C9 99 29 BA 4F 39 35 39 F9 E7 CC 25 EC C7 19
D7 26 27 4F A3 27 32 75 FC 55 4A B9 FE 5D DE BC 61 0B 64 2B CC 1F 36
34 4C 4E 9C 6F 39 76 2B A0 05 E3 EF 9D 3C B9 F1 DE B7 F6 B3 AB 27 74
45 71 C8 F9 AA B8 5D CC 37 69 35 FB A9 F2 F8 46 D6 8F 9F 09 13 53 C1
78 D2 03 DE 2A D1 9D 68 5D 35 5C 0B BF CA B7 7D DB 75 7E C7 1F 5E F8
3C 89 F7 B2 56 E3 18 1E 77 E4 6E 8D B3 CA 47 D9 DC FA EA F3 7E B0 51
1E B3 B3 6D AC 4C 63 7B 1D 71 02 71 63 16 F9 76 F7 EE 29 FC FC 7F E0
A6 98 65 5B 5A 4D D5 F8 BD 8E 1F 78 D7 DB F2 21 D0 CE 6C 8B 31 FD AB
4F 76 EB B8 C5 49 AA 21 7A 50 AF 31 6E 4F EB 84 C3 CF F8 2F 00 6B 6F
3D CC 56 7D CE E1 D5 34 F6 20 0F 5B B2 83 6F E8 75 A7 E5 B1 83 ED BE
06 14 56 F2 BC C2 AC 5D 24 E8 05 53 32 25 28 48 02 5B 11 76 06 F6 05
80 12 AE A4 3C 0B 5D E7 3E 09 EA EF D2 2B 2F 0C D9 D7 E6 FD 0C D2 E0
E9 12 5A 89 8E 2E B7 83 3E 18 31 37 C9 87 2F C3 6D AE CD 7A 08 D2 CC
D3 42 5D 8C 9B E0 8E FF 8E 07 76 67 CA BB E7 A0 DB E1 9F 96 8F BD 73
A6 97 6F 19 39 ED BB 7D EE B5 85 DC 48 EC F6 7F 77 F7 CF FD D1 6C CE
B2 30 FF 3D 83 F7 6E C4 5D ED 69 48 27 E1 9B BF 00 C0 A2 FC AF DC AB
A7 9F 8B 8A F2 DE BF 9A BB 71 BD D7 2F D4 6F BE F0 60 C5 33 5F B4 BB
A8 32 FE AC 8A E7 8D B5 86 87 6D 90 BF 29 C2 9C C3 30 4B C3 5F 19 FD
88 79 70 CC 0A 91 19 EB FB 3E E1 57 80 53 66 7F BC 88 C8 87 00 80 DB
55 12 01 4C 34 C7 D3 D8 1F 44 FD 54 39 70 B3 EE 1F CF CA 0D 76 59 6F
AB 93 93 26 5D 1F A6 B2 C9 99 29 BA 4F 39 35 39 F9 E7 CC 25 EC C7 19
D7 26 27 4F A3 27 32 75 FC 55 4A B9 FE 5D DE BC 61 0B 64 2B CC 1F 36
34 4C 4E 9C 6F 39 76 2B A0 05 E3 EF 9D 3C B9 F1 DE B7 F6 B3 AB 27 74
• cómo una aplicación debería realizar llamadas al sistema del sistema operativo y, si la ABI especifica llamadas directas al sistema en vez de llamadas de procedimiento, las direcciones de llamada
Linux kernel y GNU C Library definen el Linux API. Tras la compilación, los binarios ofrecen una ABI; manteniendo esta ABI estable a lo largo del tiempo es importante para el vendedor independiente de software.
En software de ordenador, una interfaz binaria de aplicación (ABI) es la interfaz entre dos módulos de programa, uno de los cuales es, a menudo, una librería o sistema operativo, a nivel de lenguaje de máquina. Una ABI determina detalles como la forma de llamar a las funciones, en qué formato binario se debería pasar la información de un componente de programa al siguiente, o al sistema operativo en el caso de una llamada al sistema.
• y en el caso de un ABI de sistema operativo completo, el formato binario de los archivos objeto de las librerías de programa, etc. Un ABI completo, como el Estándar de Compatibilidad Binaria de Intel (iBCS),* [1] permite a un programa de un sistema operativo soportar dicho ABI para ejecutarse sin modificaciones en cualquier otro sistema al que se le provean de las librerías compartidas necesarias y tenga los mismos pre-requisitos.
206
102.5. ENLACES EXTERNOS Otras ABIs estandarizan detalles como la convención de nombres de funciones en C++,* [2] manejo de excepciones, propagación,* [3] y convención sobre llamadas entre compiladores de la misma plataforma que no requieren compatibilidad con otras plataformas.
102.2 EABI Una interfaz binaria de aplicación embebida (EABI) especifica convenciones estandarizadas para los formatos de archivo, tipos de datos, uso de registros, organización de la pila y paso de parámetros en funciones de una aplicación de un sistema embebido. Los compiladores que soportan EABI crean código objeto compatible con el código generado por otros compiladores, permitiendo a los desarrolladores enlazar librerías generadas con otros compiladores. Los desarrolladores que escriben su propio código en lenguaje ensamblador pueden usar EABI para interactuar con el ensamblador generado por otro compilador.
207
[4] «EABI Summary». PowerPC Embedded Application Binary Interface: 32-Bit Implementation (Version 1.0 edición). Freescale Semiconductor, Inc. 01-10-1995. pp. 28– 30. [5] «Debian ARM accelerates via EABI port». Linuxdevices.com. 19-01-2007. Archivado desde el original el 21 de enero 2007. Consultado el 11-10-2007. [6] Andrés Calderón and Nelson Castillo (14-03-2007). «Why ARM's EABI matters». Linuxdevices.com. Archivado desde el original el 31 de marzo 2007. Consultado el 11-10-2007. [7] “PowerPC Embedded Processors Application Note” [8] «ARM Information Center». Infocenter.arm.com. Consultado el 27-02-2014. [9] «Eric Christopher - mips eabi documentation». Cygwin.com. 11-06-2003. Consultado el 27-02-2014.
102.5 Enlaces externos
Las diferencias principales entre EABI y ABI para sistemas operativos de propósito general son que se permiten instrucciones privilegiadas en el código de la aplicación sin necesidad de enlazado dinámico y se utiliza un marco de pila más compacto para ahorrar memoria.* [4] La elección de EABi puede afectar al rendimiento.* [5]* [6]
• KDE Techbase Policies - Buen compendio de reglas de desarrollo (con algunos ejemplos) para no romper la compatibilidad binaria entre diferentes versiones de tu librería.
Ejemplos de EABIs ampliamente utilizadas: PowerPC,* [7] ARM EABI2* [8] y MIPS EABI.* [9]
• Debian ARM EABI port
• Mac OS X ABI Function Call Guide
• µClib: Motorola 8/16-bit embedded ABI • AMD64 (x86-64) Application Binary Interface
102.3 Véase también • Compatibilidad de código binario • Comparación entre aplicaciones de virtualización de máquinas • Interfaz de funciones foráneas • Binding • Puntero opaco • SWIG
102.4 Referencias [1] Intel Binary Compatibility Standard (iBCS) [2] Itanium C++ ABI (compatible con múltiples arquitecturas) [3] Itanium C++ ABI: Exception Handling (compatible con múltiples arquitecturas)
• Application Binary Interface (ABI) para la arquitectura ARM • Documentación sobre EABI de MIPS • Sun Studio 10 Compilers and the AMD64 ABI Buen sumario y comparación entre algunas ABIs populares •“M•CORE Applications Binary Interface Standards Manual” for the Freescale M·CORE processors
Capítulo 103
Interfaz fluida En ingeniería de software, una interfaz fluida (término acuñado por primera vez por Eric Evans y Martin Fowler) es una construcción orientada a objeto que define un comportamiento capaz de retransmitir el contexto de la instrucción de una llamada subsecuente. Generalmente, el contexto es
IConfigurationFluent { string color; int height; int length; int width; IConfigurationFluent SetColor(string color) { this.color = color; return this; } IConfigurationFluent SetHeight(int height) { this.height = height; return this; } IConfigurationFluent SetLength(int length) { this.length = length; return this; } IConfigurationFluent SetDepth(int depth) { this.depth = depth; return this; } } public class • definido a través del valor de retorno de un método ExampleProgram { [STAThread] public static void Main(string[] args) { //Ejemplo estándar IConfigurallamado tion config = new Configuration(); config.SetColor( • autoreferencial, donde el nuevo contexto es equiva- “blue”); config.SetHeight(1); config.SetLength(2); conlente al contexto anterior fig.SetDepth(3); //Ejemplo fluido IConfigurationFluent config = new ConfigurationFluent().SetColor(“blue”) • terminado por medio del retorno de un contexto va.SetHeight(1) .SetLength(2) .SetDepth(3); } } } cío (void context).
Este estilo es beneficioso debido a su capacidad de proporcionar una sensación más fluida al código, aunque algunos ingenieros encuentran el estilo difícil de leer. Una segunda crítica es que generalmente, las necesidades de programación son demasiado dinámicas para confiar en la definición estática de contacto ofrecida por una interfaz fluida.
103.1 Ejemplos El siguiente ejemplo muestra una clase implementando una interfaz no fluida, y otra implementando una contraparte fluida, junto con las diferencias en el uso. El ejemplo se escribe en C #: namespace Example.FluentInterfaces { using System; public interface IConfiguration { void SetColor(string color); void SetHeight(int height); void SetLength(int length); void SetDepth(int depth); } public interface IConfigurationFluent { IConfigurationFluent SetColor(string color); IConfigurationFluent SetHeight(int height); IConfigurationFluent SetLength(int length); IConfigurationFluent SetDepth(int depth); } public class Configuration : IConfiguration { string color; int height; int length; int width; void SetColor(string color) { this.color = color; } void SetHeight(int height) { this.height = height; } void SetLength(int length) { this.length = length; } void SetDepth(int depth) { this.depth = depth; } } public class ConfigurationFluent :
El siguiente es un ejemplo en C++ de cómo proveer una envoltura de una interfaz fluida arriba de una interfaz más tradicional:
// definición básica class GlutApp { private: int w_, h_, x_, y_, argc_, display_mode_; char **argv_; char *title_; public: GlutApp(int argc, char** argv) { argc_ = argc; argv_ = argv; } void setDisplayMode(int mode) { display_mode_ = mode; } void getDisplayMode() { return display_mode_; } void setWindowSize(int w, int h) { w_ = w; h_ = h; } void setWindowPosition(int x, int y) { x_ = x; y_ = y; } void setTitle(const char *title) { title_ = title; } void create(); }; // uso básico int main(int argc, char **argv) { GlutApp app(argc, argv); app.setDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_ALPHA|GL // Ajusta los parámetros del framebuffer app.setWindowSize(500, 500); // Ajusta los parámetros de la ventana app.setWindowPosition(200, 200); app.setTitle(“My OpenGL/GLUT App”); app.create(); } // Envoltorio fluido class FluentGlutApp : private GlutApp { public: FluentGlutApp(int argc, char **argv) : GlutApp(argc, argv) {} // hereda el constructor del pariente FluentGlutApp &withDoubleBuffer() { setDisplayMode(getDisplayMode() | GLUT_DOUBLE); return *this; } FluentGlutApp &withRGBA() { setDisplayMode(getDisplayMode() | GLUT_RGBA); return *this; } FluentGlutApp &withAlpha() { setDisplayMode(getDisplayMode() | GLUT_ALPHA); return *this; } FluentGlutApp &withDepth() { setDisplayMode(getDisplayMode() | GLUT_DEPTH); return *this;
208
103.2. ENLACES EXTERNOS } FluentGlutApp &across(int w, int h) { setWindowSize(int w, int h) { return *this; } FluentGlutApp &at(int x, int y) { setWindowPosition(x, y); return *this; } FluentGlutApp &named(const char *title) { setTitle(title); return *this; } // no tiene sentido encadenar después de create(), así que se retorna *this void create() { GlutApp::create(); } }; // uso básico int main(int argc, char **argv) { FluentGlutApp app(argc, argv) .withDouble().withRGBA().withAlpha().withDepth() .at(200, 200).across(500, 500) .named(“My OpenGL/GLUT App”); app.create(); }
103.2 Enlaces externos • Martin Fowler's original bliki entry coining the term
209
Capítulo 104
Invariante (informática) En la informática se conoce como invariante a una condición que se sigue cumpliendo después de la ejecución de determinados comandos. Se cumple tanto antes como después de estos comandos, permaneciendo sin variación, por ello se denomina invariante. Las invariantes se pueden utilizar para demostrar el buen funcionamiento de algoritmos y cumplen con un papel importante en el diseño por contrato. En estos casos se describen las precondiciones, postcondiciones e invariantes para un método de un interfaz. Este concepto se puede implementar con la ayuda de aserciones, siempre y cuando el lenguaje de programación o la API los soporte.
104.1 Enlaces externos • Programm zur automatischen Verifikation (en alemán)
210
Capítulo 105
Jframe JFrame es una clase utilizada en Swing (biblioteca gráfica) para generar ventanas sobre las cuales añadir distintos objetos con los que podrá interactuar o no el usuario. A diferencia de JPanel, JFrame posee algunas nociones típicas de una ventana como minimizar, cerrar, maximizar y poder moverla.
• addImpl(Component comp, Object constraints, int index): Añade el componente especificado al JFrame.
105.1 Herencia
• frameInit(): Llama a los constructores para inicializar el JFrame correctamente.
JFrame es una subclase que extiende de la clase Frame y que implementa WindowConstants, Accessible y RootPaneContainer.
• createRootPane(): Crea un Panel por defecto por medio de una llamada al constructor.
• getAccessibleContext(): Obtiene AccessibleContext asociado a dicho JFrame.
el
• getContentPane(): Devuelve el contenido del JFrame.
105.2 Constructores Existen 4 tipos de constructores para inicializar un objeto JFrame: • JFrame(): Construye un nuevo marco que es inicialmente invisible. • JFrame(GraphicsConfiguration): Crea una ventana con la configuración gráfica especificada en el objeto GraphicsConfiguration. • JFrame(Cadena de texto): Crea una nueva ventana a la que se le pone por título la cadena de texto que se le indique. • JFrame(Cadena de texto, GraphicsConfiguration): Crea una nueva ventana con el título y la configuración gráfica especificados.
• getDefaultCloseOperation(): Devuelve la operación por defecto cuando se cierra el JFrame. • getGlassPane(): Devuelve el objeto glassPane que corresponde a este JFrame. • getGraphics(): Obtiene las características gráficas del JFrame. • getJMenuBar(): Devuelve la barra de menú del JFrame. • getLayeredPane(): Obtiene el objeto layeredPane del JFrame. • getRootPane(): Obtiene el objeto rootPane del JFrame.
105.3 Métodos propios de la clase Además de los métodos heredados, JFrame implementa una serie de métodos propios de esta, que se describen a continuación: 211
• getTransferHandler(): Devuelve transferHandler del JFrame.
el
objeto
212 • isDefaultLookAndFeelDecorated(): Comprueba si la apariencia de la ventana JFrame es la apariencia por defecto; en caso afirmativo será cierto. • isRootPaneCheckingEnabled(): Devuelve un valor de cierto si las llamadas add y setLayout se remiten a la contentPane. • paramString(): Devuelve una representación en cadena de texto del JFrame. • processWindowEvent(WindowEvent e): Procesa los eventos que se producen en el JFrame.
CAPÍTULO 105. JFRAME • setRootPane(JRootPane root): Establece el rootPane de la ventana . • setRootPaneCheckingEnabled(boolean enabled): Establece si las llamadas add y setLayout se remiten o no a la contentPane. • setTransferHandler(TransferHandler newHandler): Define el transferHandler, que es un mecanismo de soporte de transferencia de datos dentro del JFrame. • update(Graphics g): Hace una llamada al método paint(g).
• remove(Component comp): Elimina el componente que se especifica de la ventana JFrame.
105.4 Enlaces externos • repaint(long time, int x, int y, int width, int height): Redibuja el rectángulo especificado del JFrame en el tiempo indicado en milisegundos. • setContentPane(Container contentPane): Establece el contentPane especificado en JFrame. • setDefaultCloseOperation(int operation): Especifica la operación por defecto al cerrar el JFrame. • setDefaultLookAndFeelDecorated(boolean defaultLookAndFeelDecorated): Establece la apariencia que debe tener el JFrame, como bordes, botones para distintos usos, título... • setGlassPane(Component glassPane): Establece las propiedades del objeto glassPane. • setIconImage(Image image): Define el icono que se mostrará en la parte superior izquierda del marco del JFrame. • setJMenuBar(JMenuBar menubar): Establece la barra de menú del JFrame. • setLayeredPane(JLayeredPane layeredPane): Define el objeto layeredPane del JFrame. • setLayout(LayoutManager manager): Establece la forma en que se mostrarán los distintos objetos añadidos al JFrame.
• http://docs.oracle.com/javase/7/docs/api/javax/ swing/JFrame.html
Capítulo 106
Usuario discusión:Juliasocorro Hola, Julia. Olvidé introducir el aviso «en obras». Por ello hubo un conflicto de edición. Si te convencen los cambios, mi versión era ésta:
3. Conocimiento de los CMS. 4. Dominio de las API de las redes sociales importantes: Facebook, Twitter, LinkedIn, Instagram, Youtube, Google Plus... otras.
Agente SEO es un profesional que gestiona el posicionamiento SEO de los sitios web y blogs en los motores de búsqueda de Internet, tales como Google, Bing y Yahoo.
5. Programador Web. • Personal:
Si se considera una puesta en común de las ofertas generales recientes a nivel nacional, el perfil laboral del Agente SEO, según la demanda de empleabilidad actual de las empresas en cuanto a conocimientos, habilidades y destrezas, es el siguiente:
1. Positivo, creativo, estratega. 2. Metódico, ordenado, esquemático. 3. Proactivo, que asista a congresos SEO, Analytic, Social Media, Adwords.
• Experto en Marketing online y en Analítica Web:
4. Dominio del estrés y de la presión de trabajo, ya que muchas veces se labora contra el paso del robot de Google y de otros buscadores.
1. Análisis e investigación de las palabras claves: Marketing online & SEO.
5. Capacidad de aprendizaje continuo, pasión por el trabajo, sin límite de horario.
2. Experiencia demostrable con SEMrush, Webmaster Tools, Google Analytics, Ahref y otras herramientas de auditoría y gestión SEO.
6. Trabajo por resultados.
3. Diseño de estrategias de enlaces – linkbuilding. El Agente SEO puede ser:
4. Testeo de la web, mantenimiento de backlinks. 5. Previsor de penalizaciones.
• Contratado:
6. Estratega y Auditor.
1. Freelance, con herramientas propias para trabajar por nichos de mercado y empresas.
7. Dominio de:
2. Por una empresa de alto nivel que empiece a expandir sus departamentos porque debe atender un alto porcentaje de marketing digital.
(a) Robots y algoritmos de buscadores tales como Google, Bing y Yahoo. (b) Técnicas White Hat SEO y Black Hat SEO. 8. Experiencia SEO acreditada en Google y en otros motores de búsqueda. • Webmaster:
• Parte de una Agencia. Es una profesión nueva. Muchas empresas solicitan que el Agente SEO sepa también de PPC (presupuesto por campaña). En ese caso el perfil laboral sería de Agente SEM.
1. SEO on page, optimización de la web, Web performance (HTML, PCHP, CCS, Bootstrap y Respon- El Agente SEO es un perfil profesional novel. Data de pocos años en el mercado nacional. Su demanda empieza a sive Design). aflorar ahora mismo. En el transcurso del tiempo surgi2. Bases de datos, MysQL. rán muchos cambios y especialidades. Porque, si bien en 213
214 SEO estamos en la etapa de madurez, en un momento que el SEO participa de un porcentaje del trabajo webmaster, con una porción del marketing digital, también es cierto que en España comienza a aflorar en Internet en cuanto a subida de los negocios al mundo online y más con sitios web con Diseño Web adaptado a dispositivos móviles. A medida que se implemente este perfil profesional se confirmará cada una de sus aptitudes. Una faceta positiva adicional de Wikipedia es su apertura a la visión y a valores a nivel nacional de todos y cada uno de nosotros. Por otra parte, no necesariamente el perfil del Agente SEO ha de ser equiparable con el inherente al Agente SEM. Es positivo comenzar a diseñar las líneas que los cruzan y de otras que los separan. Esta es una propuesta para empezar a diseñar el perfil laboral del Agente SEO, que no se imparte en las escuelas, sino en los negocios. • • • • •
CAPÍTULO 106. USUARIO DISCUSIÓN:JULIASOCORRO
Capítulo 107
Kanban (desarrollo) Este artículo se refiere a la gestión de procesos y método de mejora. Para el proceso de manufactura esbelta, consulte Kanban.
107.2 Los principios del método Kanban
Kanban es un método para gestionar el trabajo intelecEl método Kanban tiene sus raíces en cuatro principios tual, con énfasis en la entrega justo a tiempo, mientras no básicos: se sobrecargan a los miembros del equipo. En este enfoque, el proceso, desde la definición de una tarea hasta su 1. Comience con lo que hace ahora entrega al cliente, se muestra para que los participantes lo vean y los miembros del equipo tomen el trabajo de una El método Kanban se inicia con las funcola. ciones y procesos que ya se tienen y estiKanban se puede dividir en dos partes: mula cambios continuos, incrementales y evolutivos a su sistema. • Kanban - Un sistema de gestión de proceso visual 2. Se acuerda perseguir el cambio incremental y evoque le indica qué producir, cuándo producirlo, y lutivo cuánto producir. • El método Kanban - Una aproximación a la mejora del proceso evolutivo e incremental para las organizaciones.
107.1 El método Kanban En el desarrollo de software, utilizamos un sistema Kanban virtual para limitar el trabajo en curso. A pesar de que el nombre se origina del idioma japonés“Kanban”, y se traduce aproximadamente como“tarjeta de señal”, y hay tarjetas utilizadas en la mayoría de las implementaciones de Kanban en desarrollo de software, estas tarjetas no funcionan en realidad como señales para realizar más trabajo. Representan los elementos de trabajo. De ahí el término “virtual”porque no existe una tarjeta física. El método Kanban formulado por David J. Anderson* [1]* [2] es una aproximación al proceso gradual, evolutivo y al cambio de sistemas para las organizaciones. Utiliza un sistema de extracción limitada del trabajo en curso como mecanismo básico para exponer los problemas de funcionamiento del sistema (o proceso) y estimular la colaboración para la mejora continua del sistema. Un ejemplo del sistema de extracción es el sistema Kanban, y es después de esta popular forma de trabajo en curso, que se ha denominado el método. 215
La organización (o equipo) deben estar de acuerdo que el cambio continuo, gradual y evolutivo es la manera de hacer mejoras en el sistema y debe apegarse a ello. Los cambios radicales pueden parecer más eficaces, pero tienen una mayor tasa de fracaso debido a la resistencia y el miedo en la organización. El método Kanban anima a los pequeños y continuos cambios incrementales y evolutivos a su sistema actual. 3. Respetar el proceso actual, los roles, las responsabilidades y los cargos Tenemos que facilitar el cambio futuro; acordando respetar los roles actuales, responsabilidades y cargos, eliminamos los temores iniciales. Esto nos debería permitir obtener un mayor apoyo a nuestra iniciativa Kanban. 4. Liderazgo en todos los niveles Se debe alentar hechos de liderazgo en todos los niveles de la organización de los contribuyentes individuales a la alta dirección.
216
CAPÍTULO 107. KANBAN (DESARROLLO)
107.3 Cinco prácticas centrales del método Kanban
consenso. El método Kanban sugiere que un enfoque científico sea utilizado para implementar los cambios continuos, graduales y evolutivos. El método no prescribe un método científico específico para utilizarlo.
Anderson identificó cinco características básicas que habían sido observadas en cada implementación correcta del método Kanban. Posteriormente fueron etiquetadas como prácticas y se ampliaron con la adición de una sexta característica.* [3] 1. Visualizar Visualizar el flujo de trabajo y hacerlo visible es la base para comprender cómo avanza el trabajo. Sin comprender el flujo de trabajo, realizar los cambios adecuados es más difícil. Una forma común de visualizar el flujo de trabajo es el uso de columnas. Las columnas representan los diferentes estados o pasos en el flujo de trabajo. 2. Limitar el trabajo en curso Limitar el trabajo en curso implica que un sistema de extracción se aplica en la totalidad o parte del flujo de trabajo. El sistema de extracción actúa como uno de los principales estímulos para los cambios continuos, incrementales y evolutivos en el sistema. 3. Dirigir y gestionar el flujo Se debe supervisar, medir y reportar el flujo de trabajo a través de cada estado. Al gestionar activamente el flujo, los cambios continuos, graduales y evolutivos del sistema pueden ser evaluados para tener efectos positivos o negativos. 4. Hacer las Políticas de Proceso Explícitas Configure las reglas y directrices de su trabajo. Entienda las necesidades y asegúrese de seguir las reglas. Las políticas definirán cuándo y por qué una tarjeta debe pasar de una columna a otra. Escríbalas. Cambie las reglas cuando la realidad cambie. 5. Utilizar modelos para reconocer oportunidades de mejora Cuando los equipos tienen un entendimiento común de las teorías sobre el trabajo, el flujo de trabajo, el proceso y el riesgo, es más probable que sea capaz de construir una comprensión compartida de un problema y proponer acciones de mejora que puedan ser aprobadas por
107.4 Comportamiento emergente con Kanban Hay una creciente lista de comportamientos emergentes que hemos llegado a esperar de la implementación de Kanban, tales como* [4] • Proceso único a la medida de cada cadena de valor • Cadencias desacopladas • Trabajo programado por el costo de la demora • Valor optimizado con clases de servicio • Gestión de riesgo con asignación de capacidad • Tolerancia en la experimentación de procesos • Gestión cuantitativa • Propagación viral de Kanban en toda la organización • Pequeños equipos fusionados para crear bolsas de trabajo más fluidas.
107.5 La implementación del método Kanban Algunos profesionales han implementado Kanban en físico utilizando notas adhesivas, o tableros con ranuras. Más a menudo la señal es generada por un software de seguimiento de trabajos especiales, tales como:* [5] • Kanban Tool • JIRA Greenhopper • Cardmapping • Tablero Kanban online • Targetprocess
107.6 Referencias [1] Anderson, David (septiembre de 2003). Agile Management for Software Engineering: Applying the Theory of Constraints for Business Results. Prentice Hall. ISBN 013-142460-2.
107.7. VÉASE TAMBIÉN
[2] Anderson, David (abril de 2010). Kanban - Successful Evolutionary Change for your Technology Business. Blue Hole Press. ISBN 0-9845214-0-2. [3] http://web.archive.org/web/http://www.djaa.com/ principles-kanban-method David Anderson “The principles of the Kanban method”December 10, 2010 [4] Anderson, David (septiembre de 2010). Kanban - Successful Evolutionary Change for your Technology Business. Blue Hole Press. ISBN 978-0-9845214-0-1. [5] Robson, Sean (enero de 2013). Agile SAP: Introducing Flexibility, Transparency and Speed to SAP Implementations. IT Governance Ltd. ISBN 978-1-84928-446-2.
107.7 Véase también • Kanban • Sistema de producción Toyota • Desarrollo ágil de software • Proceso para el desarrollo de software • Metodología de desarrollo de software • Scrum
217
Capítulo 108
Kit de desarrollo de software “SDK”redirige aquí. Un kit de desarrollo de software o SDK (siglas en inglés de software development kit) es generalmente un conjunto de herramientas de desarrollo de software que le permite al programador o desarrollador de software crear aplicaciones para un sistema concreto, por ejemplo ciertos paquetes de software, frameworks, plataformas de hardware, computadoras, videoconsolas, sistemas operativos, etcétera. Es algo tan sencillo como una interfaz de programación de aplicaciones o API (del inglés application programing interface) creada para permitir el uso de cierto lenguaje de programación, o puede, también, incluir hardware sofisticado para comunicarse con un determinado sistema embebido. Las herramientas de desarrollo de software más comunes incluyen soporte para la detección de errores de programación como un entorno de desarrollo integrado o IDE (del inglés Integrated Development Environment) y otras utilidades. Los SDK frecuentemente también incluyen códigos de ejemplo y notas técnicas de soporte u otra documentación de soporte para ayudar a clarificar ciertos puntos del material de referencia primario.
puede incluir también el software añadido en sí para ser usado para el desarrollo pero no necesariamente para la redistribución. Una situación interesante surge aquí entre plataformas donde es posible desarrollar aplicaciones que pueden iniciar la configuración de un sistema sin que esté instalado el add-on, y usar una rutina de petición de entorno de tipo Gestalt (de Mac OS) para determinar si dicho add-on está instalado, y otros donde la aplicación simplemente fallará al iniciarse. En otras palabras, es posible construir un único binario que funcione en configuraciones donde el add-on esté presente o no, con una funcionalidad reducida en este último caso.
108.3 Términos más específicos Los proveedores de SDK para ciertos sistemas o subsistemas pueden utilizar un término más específico que el de “software”. Por ejemplo, tanto Microsoft como Apple proveen Driver Development Kits (DDK) o kits para el desarrollo de drivers o controladores de dispositivos para desarrollar drivers para dispositivos, y PalmSource distribuye su propio kit de desarrollo como el PalmOS Development Kit (PDK) o kit de desarrollo para PalmOS.
108.1 Incompatibilidad de licen108.4 Ejemplos cias Los SDK pueden incluir licencia de software que los hacen incompatibles para crear software que se pretenda hacer para una licencia no compatible. Por ejemplo: un SDK propietario probablemente será incompatible para el desarrollo de software gratuito. Y un SDK bajo la licencia GPL posiblemente será incompatible con el desarrollo de software propietario. Sin embargo, los SDK bajo la licencia LGPL suelen ser seguros para el desarrollo de software propietario.
108.2 SDK para añadidos Un SDK para un añadido (add-on) de un determinado sistema operativo (por ejemplo, QuickTime para Mac OS) 218
• El SDK de Virtual Earth de Microsoft.* [1] • El SDK de DirectX de Microsoft, en el que se basan, por ejemplo, la mayoría de juegos para Windows actuales. • EL .Net Framework de Microsoft, en el que se basan muchas aplicaciones basadas en formularios. • El 'SDK Java* [2] de Sun Microsystems, en el que se basa, por ejemplo, la herramienta de lucha contra el vandalismo de CryptoDerk. • Los kits de herramientas de Widgets, en los que se basan muchas utilidades desarrolladas con lenguajes de programación orientados a objetos. • Turbo Pascal.
108.7. ENLACES EXTERNOS • Clipper. • Delphi. • El Source SDK, una herramienta diseñada por Valve en el que se puede diseñar mods y mapas para juegos del motor Source. Disponible en Steam al comprar un juego que use el motor Source. • El SDK de Android, elaborado por Google para su sistema homónimo.
108.5 Referencias [1] http://dev.live.com/virtualearth/sdk/ [2] Java 2 Software Development Kit.
108.6 Véase también • Ambiente de desarrollo integrado • Interfaz de programación de aplicaciones
108.7 Enlaces externos • DirectX SDK de Microsoft. • Framework SDK para sistemas X86 Framework SDK para sistemas X86 a 64 bits y Framework SDK para sistemas IA64 de Microsoft. • Java 2 SDK de Sun Microsystems. • Software Development Kits de ABBYY para Captura de Datos y Conversión de Documentos. • SDKs para Cámaras y voz de Olympus. • SDK para emuladores de terminales de Cybele Software.
219
Capítulo 109
Kommander Kommander es definido con un conjunto de herramientas que permite la construcción de interfaces para scripts. Estos scripts pueden tener interacción con aplicaciones propias del entorno de KDE y programas compilados en algún lenguaje como por ejemplo C, C++, Phyton, etc. Estas propiedades lo hacen ser muy útil al momento de integrar soluciones.
También hay un página de fans de Kommander http://www.kommander-fanpage.de.vu/ Y ahora se une Famelix, con un wiki especial para Kommander en español http://wiki.famelix.cl/es/Kommander
Ahora Kommander, en términos más técnicos, consta de dos componentes: Editor y Ejecutor.
109.1 El editor Es la interfaz disponible para el programador, en la cual se crean las ventanas o cuadros de diálogo. Dentro de los cuadros de diálogo se pueden insertar controles o widget, tales como barras de progreso, botones, cuadros de imagen, etc.
109.2 El ejecutor Es simplemente el motor que ejecuta el código generado por el editor.
109.3 Direcciones de Kommander El paquete que contiene a Kommander es kdewebdev (web development apps from the official KDE release) http://kommander.kdewebdev.org/ La última versión está disponible en: http://sourceforge.net/projects/kommander/ Lista de correos para usuarios y desarrolladores http://mail.kdewebdev.org/mailman/listinfo/ kommander http://mail.kdewebdev.org/mailman/listinfo/ kommander-devel Un listado de muchas aplicaciones de Kommander en: http://kde-apps.org/index.php?xcontentmode=288 220
Capítulo 110
Last Error (informática) Last Error en computación, específicamente en el cam- 110.2 En DELPHI po de la programación en Windows se conoce como Last Error al último error sucedido al utilizar una de las API de function MuestraError(error: DWORD): String; var Windows. Los códigos de error son particulares de cada pString: array[0..MAX_PATH] of char; begin FormatThread que esté en ejecución. Message(FORMAT_MESSAGE_FROM_SYSTEM, Cuando una Api falla, es muy común que devuelva los Nil, error, 0, pString, MAX_PATH, Nil); Result := valores NULL o –1. Además puede registrar el error pa- pString; end; ra ser identificado por el programa que la utiliza. Este se obtiene haciendo una llamada a la API GetLastError, la cual devuelve el código de error. Otra forma es usando directamente el TIB, aunque este método puede ser en- 110.3 Enlaces externos gorroso o incluso imposible en algunos lenguajes de alto nivel. • Last Error explicación • Winerror.h • Listado de Errores • Ejemplo de FormatMessage en Delphi
110.1 Errores personalizados Una función propia o de un programa por defecto de Windows puede hacer uso de la Api SetLastError para informar que error ha ocurrido o en el caso de no haber error puede usarse para poner en cero el último error ocurrido. Una vez hecho esto, el error de la función anteriormente utilizada no se podrá determinar. Estos errores son enteros de 32 bits. Si se quiere usar SetLastError para “nuevos”errores propios de la aplicación se debe de activar el bit 29 ya que el sistema no usa errores con ese bit activado. ↓ Bit 29 ↓ 00100000 00000000 00000000 00000000 ↑ ↑ ↑ Bit 31, el más significativo ↑ Bit 0, el menos significativo Una vez activado los números serán mayores o iguales que 20000000H (en hexadecimal) o 536870912D (en decimal). El último error provocado por el sistema es un número entero que esta en el rango de (0 a 15999) según la lista publicada en Microsoft El código de error obtenido por cualquiera de las dos vías puede ser mostrado al usuario usando la API FormatMessage la cual nos da un texto explicando el error. 221
Capítulo 111
Línea de código fuente La definición de línea de código fuente es esencialmente for (i=0; i<100; ++i) {printf(“hola”);} /* ¿Cuántas ambigua para la mayor parte del software. Su significado líneas tiene este programa? */ varía de un lenguaje de programación a otro, pero también dentro de un mismo lenguaje de programación. Proviene de las siglas en inglés de Source Lines of Code Una línea de código fuente es cada una de las líneas de (SLC), en español, “Líneas de Código Fuente”(LCF) un archivo de código fuente de un programa informático. o “Líneas de Código Fuente Únicas”(LCFU). Habitualmente en cada línea se ejecuta una instrucción que tiene que ejecutar el programa. También es habitual tabular las estructuras de control del programa en cuestión 111.1 El uso de medidas de LCF para una lectura más fácil. Viene a ser como la oración en libros y textos escritos en general. De acuerdo a Andrew Tanenbaum, los valores de líneas En ocasiones los programadores hablan del número de de código fuente para diferentes sistemas operativos de “líneas de código”que tiene cierto programa para hablar la línea de productos de Microsoft Windows NT son las de la magnitud o complejidad de este. siguientes: En computación, el número de línea de una instrucción es un punto bastante útil a la hora de compilar el programa porque habitualmente los compiladores detectan errores de programación mostrando el número de línea donde se ha encontrado el error que el programador deberá corregir para una compilación satisfactoria. Como curiosidad, algunos programadores se divierten complicando la forma de programar, bien por diversión, como reto entre programadores, o para que sea imposible de entender para un programador poco experimentado. A este pasatiempo se le denomina programación ofuscada y uno de los puntos más habituales para programar ofuscadamente es no escribir una instrucción por línea y no hacer tabulaciones, en ocasiones se escriben varias instrucciones por línea o a veces se corta una instrucción en varias líneas. Los más experimentados en este tipo de pasatiempos, se atreven incluso a realizar obras de Ascii art con las líneas de su código fuente.
David A. Wheeler ha estudiado el sistema operativo Red Hat (distribución de los sistemas operativos de Linux) e informó que Red Hat versión 7.1 (lanzado en abril de 2001) contiene cerca de 30 millones de LCFU físicos. También extrapoló que, de haber sido desarrollado por medios convencionales de propiedad (medida de tiempopersona) habría requerido de unos 8.000 años/persona de esfuerzo y desarrollo y hubiesen costado más de mil millones de dólares (cotizados en el año 2000).
Un estudio similar, reveló que Debian versión 2.2 (conocido por su nombre clave “Potato”) contiene unos 55 millones de LCFU y de haber sido realizado mediante las propiedades convencionales, hubiese tardado unos 14005 años/persona y costado unos 1900 millones de dólares. Más tarde se ejecutó una de las herramientas utilizadas en el informe para la siguiente versión y se reportó que En el lenguaje de programación C, por ejemplo, una línea Debian posee 104 millones de LCFU, y a partir del año 2005, las siguientes versiones poseerán, al menos, más de de código puede ser: 213 millones de LCFU. 1. una instrucción acabada en un salto de línea,
Se pueden encontrar las cifras de los principales sistemas operativos (las distintas versiones de Windows se han presentado en una tabla de arriba).
2. una instrucción acabada en un punto y coma, 3. cualquier línea del programa que acabe en un salto de línea (comentarios incluidos). Por ejemplo:
En comparación, las cifras de algunas herramientas gráficas. 222
111.3. VÉASE TAMBIÉN
223 Get-ChildItem -recurse -include *.cxx,*.cpp,*.h,*.c | Get-Content | Measure-Object -line ls -r -i *.cxx,*.cpp,*.h,*.c | gc | measure-object -l
111.2 Programas para contar líneas de código 111.2.3 Comerciales Existen diversas tipos y aplicaciones disponibles con el propósito de contar y expresarlas líneas de código contenidas en el código fuente en forma automática. Entre los requerimientos necesarios para una herramienta métrica de este tipo, debería incluir la habilidad necesaria para procesar varios lenguajes de código fuente y no depender de un sistema operativo específico. Las compañías que usan una herramienta en C para Windows, otra en C para UNIX y una tercera en Java para Linux, no desarrollan una estimación básica para sus medidas del CMMI.
111.2.1
Software Libre/Open Source
• EZ-Metrix is a commercial web-based source code counting utility that measures more than 75 different languages, and compares two file lists to quantify differences (i.e., new, modified, deleted, unmodified). • Resource Standard Metrics is a commercial tool designed to process ANSI C, ANSI C++, C#, and Java 2.0+ while operating on Windows, UNIX, Linux and Mac OS X. • Another program for Windows, Code Counter Pro, which counts physical KLOCs and supports languages like C, C++, C#, Java, Cobol, Delphi, VB, ASP, PHP and Fortran.
• La orden más simple en UNIX para contar las líneas de código es wc. Por ejemplo, para contar el número de líneas en todos los archivos .cxx, .cpp, .h y .c 111.2.4 Basados en web dentro y debajo del directorio actual, se pueden usar • Ohloh extracts LOC and other software metrics los comandos POSIX: find y wc of open source projects from publicly accessible revision control repositories. It generates analyses find . \( -name '*.[ch]' -o -name '*.cxx' -o -name '*.cpp' and reports of development activity available as \) | xargs wc -l graphs and API-based web-services.
111.2.2
Freeware (software no libre)
• K-LOC Calculator* [5] es una herramienta para Windows para contar líneas de código físicas. • Code Analyzer* [6] es una herramienta escrita en Java para contar líneas de código. Para varios lenguajes. • LinesOfCodeWichtel* [7] es una herramienta escrita en java para contar LoC. Para varios lenguajes • LocMetrics* [8] es una herramienta gratuita para LoC en Windows en los lenguajes C#, Java, o C++ code. • Source Line of Code Counter* [9] es una herramienta para contar LoC basada en .net, admite concordancias en expresiones, trae un navegador de directorio.
111.3 Véase también • Código fuente
111.4 Referencias [1] How Many Lines of Code in Windows?, Knowing.NET, 6 de diciembre de 2005, archivado del original el 23 de noviembre de 2015, http://web.archive. org/web/http://www.knowing.net/PermaLink,guid, c4bdc793-bbcf-4fff-8167-3eb1f4f4ef99.aspx, consultado el 18 de octubre de 2007 This in turn cites Vincent Maraia's The Build Master as the source of the information.
• Source Monitor [10] es una herramienta gratuita para Windows que cuenta las líneas de código y medidas derivadas de los lenguajes C++, C, C#, Java, y de otro código fuente
[2] González-Barahona, Jesús M., Miguel A. Ortuño Pérez, Pedro de las Heras Quirós, José Centeno González, and Vicente Matellán Olivera. «Counting potatoes: the size of Debian 2.2». debian.org. Archivado desde el original el 23 de noviembre de 2015. Consultado el 12 de agosto de 2003.
• Dos maneras de contar LCFU en Windows PowerShell en todos los archivos .cxx, .cpp, .h, and .c dentro y debajo del directorio.
[3] Robles, Gregorio. «Debian Counting». Archivado desde el original el 23 de noviembre de 2015. Consultado el 16 de febrero de 2007.
*
224
[4] Jobs, Steve (agosto de 2006). «Live from WWDC 2006: Steve Jobs Keynote». Consultado el 16 de febrero de 2007. «86 million lines of source code that was ported to run on an entirely new architecture with zero hiccups. Possibly including the whole iLife suite, not just the operating system and usually bundled applications». [5] http://web.archive.org/web/http://www.analogx.com/ contents/download/program/kloc.htm [6] http://web.archive.org/20080302195407/www.geocities. com/sivaram_subr/codeanalyzer/description.htm [7] http://www.andreas-berl.de/linesofcodewichtel/en/ index.html [8] http://www.locmetrics.com [9] http://web.archive.org/web/http://thecodecentral.com/ 2007/12/26/source-line-of-code-counter [10] http://www.campwoodsw.com/sourcemonitor.html
111.5 Enlaces externos • Definiciones útiles sobre código fuente Recurse Standard Metrics (RSM) define “líneas de código fuente eficaces”con un realista medida, independientemente del estilo de programación. • Líneas de código fuente efectivas de eLOC Metrics para el popular software libre Linux Kernel 2.6.17, Firefox, Apache HPPD, MySQL, PHP usando RSM. • Wheeler, David A. «LCFUCount». Consultado el 12 de agosto de 2003. • Wheeler, David A. (junio de 2001). «Contando líneas de código fuente. (LCFU)». Consultado el 12 de agosto de 2003. • Tanenbaum, Andrew S. Sistemas operativos modernos (segunda edición). Prentice Hall. ISBN 0-13092641-8. • Howard Dahdah (24 de enero de 2007). «Tanenbaum outlines his vision for a grandma-proof OS». Consultado el 29 de enero de 2007. • C. M. Lott: Herramientas de colección métrica para códigos fuente para C y C++
CAPÍTULO 111. LÍNEA DE CÓDIGO FUENTE
Capítulo 112
Macintosh Toolbox El Macintosh Toolbox es un conjunto de APIs con un mecanismo de acceso particular. Estas APIs implementan varias de las características de alto nivel de Mac OS. El Toolbox consiste en una serie de “gestores”responsables de generar los gráficos en pantalla (componentes de software como QuickDraw), y el Gestor de Menú, que mantiene las estructuras de datos que describen la barra de menú.
225
Capítulo 113
Macro Para la fotografía, véase Macrofotografía.
113.2 Macros en programación
Para el museo, véase Museo de Arte Contemporáneo de Rosario.
113.3 Macros ocultas
Una macro (del griego μακρο, makro, que significa ʻgrandeʼ) ―abreviatura de macroinstrucción―es una serie de instrucciones que se almacenan para que se puedan ejecutar de manera secuencial mediante una sola llamada u orden de ejecución. Dicho de otra manera, una macroinstrucción es una instrucción compleja, formada por otras instrucciones más sencillas. Esto permite la automatización de tareas repetitivas.
Las macros ocultas son órdenes complejas de tipo macro que se han declarado en el código fuente pero que permanecen ocultas por motivos de seguridad, por acceso restringido, etc.
Este término ha sido popularizado por la película de ficción Tron, ambientada en un mundo informático virtual, en la que se puede escuchar una voz fuera de campo (probablemente de un programa dependiente del Control Central) que advierte a los habitantes de ese mundo que Las macros tienden a almacenarse en el ámbito del pro- tengan cuidado con las macros ocultas. pio programa que las utiliza y se ejecutan pulsando una combinación especial de teclas o un botón especialmente creado y asignado para tal efecto. La diferencia entre una macroinstrucción y un programa es que en las macroinstrucciones la ejecución es secuencial y no existe otro concepto del flujo de programa.
113.4 Véase también • Script • Macro ensamblador • Microsoft Macro Assembler
113.1 Macros de aplicaciones
• Visual Basic for Applications
Son un grupo de instrucciones que se ejecutan secuencial- Ejemplos de Macros mente y se utilizan para economizar tareas. Una macro no es más que un conjunto de instrucciones (tales como «borrar archivo», «añadir registro», etc.), y que se almacenan en una ubicación especial. Por ejemplo, en Microsoft Access se observa que hay una zona para crear macros. Una macro en Access trabajando para una base de datos podría ser un archivo que, al llamarse desde otra instrucción, borrara los registros de un cliente o accionista, luego borrara ciertos registros en otras tablas. Excel tiene incorporado el editor de VBA, se pueden crear macros con la grabadora de macros o escribiendo directamente los códigos en el Editor de VBA, esta última opción es más potente, ya que la grabadora de macros se limita a grabar cosas repetitivas que se hacen con el teclado, al escribir el código nos permite hacer otras cosas conviertiendo a Excel en una aplicación super potente al permitir programar macros mediante vba. 226
Capítulo 114
Malla de triángulos 3D La Malla de triángulos 3D es una colección de DirectX, no son compatibles con las mallas arbitrarias de triángulos y vértices que aproximan una superficie en 3D. triángulos. Sin embargo, estructuras como tiras de triánAunque el campo de aplicación de la generación auto- gulos - (donde cada triángulo, comparte un vértice con un mática de una malla triangular, ha sido tradicionalmen- vecino y otro con el próximo) y el abanicos de triángulos te la obtención de modelos digitales de elevaciones del (un conjunto de triángulos conectados por un vértice central) se tratan de manera eficiente con la necesidad de sólo terreno, su aplicación es mucho más amplia. Cualquier variable espacial relacionada con una cierta tipología, es procesar N+2 vértices para dibujar N triángulos. susceptible de ser modelizada como una superficie tridi- Una malla de triángulos, construida a partir de tiras, en mensional, en la que la cota de cada punto es el valor de abanico y posiblemente triángulos independientes, genela variable a estudiar. ralmente se obtienen mediante un mosaico de objetos poPara saber cómo podríamos descomponer un objeto con ligonales. todas sus partes, la mínima regla es la teoría del sistema de visión humano. Para interpretar cómo los seres humanos pueden descomponer un objeto en mallas, podríamos desarrollar un algoritmo de segmentación de malla ya que además éste nos permite obtener un nivel superior de descripciones del objeto en cuestión.
Otra forma de evitar la redundancia de procesamiento de vértices es compartiendo vértices explícitos. La definición de los vértices está separada de la descripción triángulo. Todo el conjunto de triángulos se define por un conjunto de índices en una matriz de vértices. El sistema gráfico procesa los vértices primero y hace el render de los triángulos después, utilizando el conjunto de índices trabajando sobre la transformación de datos.
114.1 Aplicaciones 114.2 Obtención de las mallas
Una utilidad de las mallas de triángulos podría ser para sistemas de reconocimiento de objetos, la comprensión Para la generación automática de una malla triangular de una escena, y las características del modelado. existen distintos estudios y algoritmos. Por ejemplo, hay Los gráficos por ordenador también utilizan mallas de algoritmos que parten de una nube de puntos irregulartriángulos. Se componen de un conjunto de triángulos mente distribuidos y procurando definir cada triángulo lo (normalmente en tres dimensiones) que están conectados más regular posible (el caso óptimo, triánguos equilátepor sus vértices. ros) permiten la creación de una malla de triángulos. Muchos paquetes de software de gráficos y dispositivos Partiendo de una distribución irregular de puntos a los de hardware puede funcionar de manera más eficiente que se les ha asociado una cierta variable, por ejemplo su en triángulos que se agrupan en mallas que en un gru- cota, si estamos hablando de un terreno o el valor de la po de triángulos que se presentan individualmente. Esto contaminación acústica en una cierta zona urbana, exises porque normalmente los gráficos por ordenador hacen ten técnicas para interpolar dicha variable en cualquier operaciones sobre los vértices (en las esquinas de trián- otro punto de la zona en la que no disponemos de su vagulos). Con cada uno de los triángulos, el sistema tiene lor mediante un proceso de medición directo. Mientras que funcionar en tres vértices de cada triángulo. En una que algunos de estos métodos están desarrollados a pargran malla, puede haber ocho o más triángulos reunidos tir de una interpolación que utiliza algoritmos de ʻpaten un único vértice. Así, procesando los vértices una sola chesʼ, superficies cuadráticas, interpolaciones polinómivez, es posible hacer una fracción del trabajo y lograr un cas, etc.; la técnica habitualmente utilizada es la basada efecto idéntico. en los polígonos de Voronoi y la triangulación de DelauLas dos interfaces de programación de aplicaciones nay para así obtener una malla triangular, lo más regular (APIs) más importantes del mercado gráfico, OpenGL y posible, tal que los vértices de los triángulos que confor227
228 man la malla sean los puntos inicialmente dados.
114.3 Compresión Un método de compresión de una malla con pluralidad de vértices, es decir, que cada vértice se caracteriza por un grado igual al número de bordes incidentes y con la casi totalidad de vértices en un orden consecutivo. Así generamos una lista con la tipología de los grados de los vértices en orden consecutivo y el código de secuencia de señales con la tipología de la lista.
CAPÍTULO 114. MALLA DE TRIÁNGULOS 3D
Capítulo 115
Mapeo objeto-relacional El mapeo objeto-relacional (más conocido por su nombre en inglés, Object-Relational mapping, o sus siglas O/RM, ORM, y O/R mapping) es una técnica de programación para convertir datos entre el sistema de tipos utilizado en un lenguaje de programación orientado a objetos y la utilización de una base de datos relacional como motor de persistencia. En la práctica esto crea una base de datos orientada a objetos virtual, sobre la base de datos relacional. Esto posibilita el uso de las características propias de la orientación a objetos (básicamente herencia y polimorfismo). Hay paquetes comerciales y de uso libre disponibles que desarrollan el mapeo relacional de objetos, aunque algunos programadores prefieren crear sus propias herramientas ORM.
lares simples en el programa. El mapeo objeto-relacional es utilizado para implementar la primera aproximación. El núcleo del problema reside en traducir estos objetos a formas que puedan ser almacenadas en la base de datos para recuperarlas fácilmente, mientras se preservan las propiedades de los objetos y sus relaciones; estos objetos se dice entonces que son persistentes.
115.2 Implementaciones
Los tipos de bases de datos usados mayoritariamente son las bases de datos SQL, cuya aparición precedió al crecimiento de la programación orientada a objetos en los 1990s. Las bases de datos SQL usan una serie de tablas 115.1 El problema para organizar datos. Los datos en distintas tablas están asociados a través del uso de restricciones declarativas en En la programación orientada a objetos, las tareas de lugar de punteros o enlaces explícitos. Los mismos dagestión de datos son implementadas generalmente por la tos que pueden almacenarse en un solo objeto podrían manipulación de objetos, los cuales son casi siempre va- requerir ser almacenados a través de varias tablas. lores no escalares. Para ilustrarlo, considere el ejemplo de Una implementación del mapeo relacional de objetos pouna entrada en una libreta de direcciones, que representa dría necesitar elegir de manera sistemática y predictiva a una sola persona con cero o más números telefónicos qué tablas usar y generar las sentencias SQL necesarias. y cero o más direcciones. En una implementación orienMuchos paquetes han sido desarrollados para reducir el tada a objetos, esto puede ser modelado por un “objeto persona”con “campos”que almacenan los datos de tedioso proceso de desarrollo de sistemas de mapeo relacional de objetos proveyendo bibliotecas de clases que dicha entrada: el nombre de la persona, una lista de números telefónicos y una lista de direcciones. La lista de son capaces de realizar mapeos automáticamente. Dada una lista de tablas en la base de datos, y objetos en el pronúmeros telefónicos estaría compuesta por “objetos de números telefónicos”y así sucesivamente. La entrada de grama, ellos pueden automáticamente mapear solicitudes la libreta de direcciones es tratada como un valor único de un sentido a otro. Preguntar a un objeto persona por por el lenguaje de programación (puede ser referenciada sus números telefónicos resultará en la creación y envío por una sola variable, por ejemplo). Se pueden asociar va- de la consulta apropiada a la base de datos, y los resultarios métodos al objeto, como uno que devuelva el número dos son traducidos directamente en objetos de números telefónicos dentro del programa. telefónico preferido, la dirección de su casa, etc.. Sin embargo, muchos productos populares de base de da- Desde el punto de vista de un programador, el sistema tos, como los Sistemas de Gestión de Bases de Datos debe lucir como un almacén de objetos persistentes. Uno SQL, solamente pueden almacenar y manipular valores puede crear objetos y trabajar normalmente con ellos, los escalares como enteros y cadenas, organizados en tablas cambios que sufran terminarán siendo reflejados en la banormalizadas. El programador debe convertir los valores se de datos. de los objetos en grupos de valores simples para almace- Sin embargo, en la práctica no es tan simple. Todos los narlos en la base de datos (y volverlos a convertir luego de sistemas ORM tienden a hacerse visibles en varias forrecuperarlos de la base de datos), o usar sólo valores esca- mas, reduciendo en cierto grado la capacidad de ignorar 229
230
CAPÍTULO 115. MAPEO OBJETO-RELACIONAL
la base de datos. Peor aún, la capa de traducción puede ser 115.3 Bases de datos distintas a lenta e ineficiente (comparada en términos de las sentenSQL cias SQL que escribe), provocando que el programa sea más lento y utilice más memoria que el código “escrito Las bases de datos como Caché no necesitan mapeo a mano”. objeto-relacional manual. El acceso del SQL a los valoUn buen número de sistemas de mapeo objeto-relacional res no escalares ya ha sido construido. Caché permite a se han desarrollado a lo largo de los años, pero su efec- los desarrolladores diseñar cualquier combinación de protividad en el mercado ha sido diversa. NeXT's Enter- gramación orientada a objetos y almacenamiento estrucprise Objects Framework (EOF) fue una de las prime- turado en tablas en la misma base de datos en lugar de ras implementaciones, pero no tuvo éxito debido a que depender de herramientas externas. estaba estrechamente ligado a todo el kit de NeXT's, OpenStep * [cita requerida]. Fue integrado más tarde en Otra solución puede ser el uso de un sistema de adminisNeXT's WebObjects, el primer servidor web de apli- tración de base de datos orientada a objetos (OODBMS: caciones orientado a objetos. Desde que Apple compró Object-oriented database management system), lo cual, NeXT's en 1997, EOF proveyó la tecnología detrás de los como el nombre lo sugiere, es una base de datos diseñasitios web de comercio electrónico de Apple: los servicios da específicamente para trabajar con valores orientados a .Mac y la tienda de música iTunes. Apple provee EOF en objetos. Usar un OODBMS puede eliminar la necesidad dos implementaciones: la implementación en Objective- de convertir datos desde y hacia su forma SQL, y los daC que viene con Apple Developers Tools y la implemen- tos pueden ser almacenados en su representación original tación Pure Java que viene en WebObjects 5.2. Inspirado como objetos. por EOF es el open source Apache Cayenne. Cayenne Las bases de datos orientadas a objetos aún no han contiene metas similares a las de EOF e intenta estar acorde seguido una alta aceptación y uso. Una de las principales a los estándares JPA. limitaciones reside en que, cambiar de un sistema de adUna aproximación alternativa ha sido tomada por tecno- ministración de base de datos SQL a un sistema orientalogías como RDF y SPARQL, y el concepto de“triplesto- do totalmente a objetos implica que se pierde la capacire”. RDF es una serialización del concepto objeto-sujeto- dad de crear sentencias SQL, un método ya probado para predicado, RDF/XML es una representación en XML de obtener combinaciones específicas de datos. Por esta raaquello, SPARQL es un lenguaje de consulta similar al zón, muchos programadores se encuentran más a gusto SQL, y un “triplestore”es una descripción general de trabajando con un sistema de mapeo de objetos y SQL, una base de datos que trabaja con un tercer componente. aún cuando la mayoría de las bases de datos comerciales orientadas a objetos son capaces de procesar consultas Más recientemente, un sistema similar ha comenzado a SQL de manera limitada. evolucionar en el mundo Java, conocido como Java Data Objects (JDO). A diferencia de EOF, JDO es un estándar, y muchas implementaciones están disponibles por parte de distintos distribuidores de software. La especifi- 115.4 Véase también cación 3.0 de Enterprise Java Beans (EJB) también cubre • Propel (PHP) la misma área. Han existido algunos conflictos de estándares entre ambas especificaciones en términos de pre• Doctrine (PHP) eminencia. JDO tiene muchas implementaciones comerciales, mientras que EJB 3.0 está aún en desarrollo. Sin • JPA (Java) embargo, recientemente otro estándar ha sido anuncia• Hibernate (Java) do por JCP para abarcar estos dos estándares de manera conjunta y lograr que el futuro estándar trabaje en diver• ADO.NET Entity Framework (C#) sas arquitecturas de Java. Otro ejemplo a mencionar es Hibernate, el framework de mapeo objeto-relacional más • LINQ to SQL (C# sólo para SQL Server) su sintaxis usado en Java que inspiró la especificación EJB 3. es similar a JPA En el framework de desarrollo web Ruby on Rails, el mapeo objeto-relacional juega un rol preponderante y es manejado por la herramienta ActiveRecord. Un rol similar es el que tiene el módulo DBIx::Class para el framework basado en Perl Catalyst, aunque otras elecciones también son posibles.
• NHibernate (C#) • peewee (Python)
115.5 Enlaces relacionados • Patrón de diseño Association Table Mapping: • Introducción a JPA
Capítulo 116
Máquina de estados Se denomina máquina de estados a un modelo de comportamiento de un sistema con entradas y salidas, en donde las salidas dependen no sólo de las señales de entradas actuales sino también de las anteriores.
compleja, depender de la entrada actual (no sólo del estado) y pudiendo también prescindirse de un estado inicial.
Las máquinas de estados se definen como un conjunto de estados que sirve de intermediario en esta relación de entradas y salidas, haciendo que el historial de señales de entrada determine, para cada instante, un estado para la máquina, de forma tal que la salida depende únicamente del estado y las entradas actuales.
La bibliografía a veces llama autómata finito a las aceptoras, mientras que en otros casos se emplea autómata como sinónimo de máquina de estados sin importar su tipo.
Una máquina de estados se denomina máquina de estados finitos (FSM por finite state machine) si el conjunto de estados de la máquina es finito, este es el único tipo de máquinas de estados que podemos modelar en un computador en la actualidad; debido a esto se suelen utilizar los términos máquina de estados y máquina de estados finitos de forma intercambiable. Sin embargo un ejemplo de una máquina de estados infinitos sería un computador cuántico esto es debido a que los Qubit que utilizaría este tipo de computadores toma valores continuos, en contraposición los bits toman valores discretos (0 ó 1). Otro buen ejemplo de una máquina de estados infinitos es una Máquina universal de Turing la cual se puede definir teóricamente con una “cinta”o memoria infinita.
Las aceptoras son los de mayor interés en la Teoría de la Computación, más precisamente en la Teoría de autómatas, siendo éstas ramas de la matemática. Las transductoras, en cambio, lo son en la electrónica digital y la computación práctica. Es por eso que, por lo general, en los textos sobre matemática y ciencias de la computación se suele hablar de autómatas (y se refieren a las aceptoras) mientras que los de electrónica y computación práctica hablan de máquinas de estados (y se refieren a los transductoras). En UML (Lenguaje Unificado de Modelado), dice que una máquina de estado es aquel comportamiento que permite hacer un seguimiento de la vida de un objeto en el transcurso de un tiempo finito.
La representación de una máquina de estados se realiza mediante un Diagrama de estados, sin embargo también es posible utilizar un Diagrama de flujo. Es posible clasificar las máquinas de estados en aceptoras o transductoras: • Aceptoras (también llamadas reconocedoras o discriminadoras): Son aquellas en donde la salida es binaria (sí/no), depende únicamente del estado y existe un estado inicial. Puede decirse, entonces, que cuando la máquina produce una salida“positiva”(es decir, un“si”), es porque ha“reconocido”o“aceptado”la secuencia de entrada. En las máquinas de estados aceptoras, los estados con salida “positiva” se denominan estados finales. • Transductoras: Son las más generales, que convierten una secuencia de señales de entrada en una secuencia de salida, pudiendo ésta ser binaria o más 231
Capítulo 117
Máquina desnuda En informática, cuando no hay un núcleo (S.O.) instalado en el hardware, se suele decir que es una máquina desnuda. Suelen ser sistemas sencillos, que ejecutan alguna tarea cuando se produce una interrupción, y que el resto del tiempo ejecutan una tarea idle muy básica, normalmente que no hace nada. Suelen usarse en los sistemas en tiempo real, cuando el número y complejidad de las tareas es pequeño. En las máquinas desnudas suelen usarse las máquinas de estados. Es decir, se supone que el comportamiento de nuestra máquina puede modelarse como una máquina de estados. La rutina de interrupción lo que nos daría es el estado al que tiene que cambiar. Esto fue muy popular, incluso hay herramientas que generan automáticamente el código de cambios entre estados. Pero no es buena idea para las aplicaciones complejas.
232
Capítulo 118
MCML MCML (acrónimo del inglés Media Center Markup Language, Lenguaje de Formato para Centro de Multimedios en español) es el lenguaje de formato para la interfaz de usuario para el centro de Multimedios (Media Center) de Windows Vista, el cual es la forma nativa en la cual se crean las interfaces de usuarios en este ambiente de desarrollo. MCML es un lenguaje declarativo basado en XML, optimizado para describir gráficamente interfaces de usuarios visuales ricas desde el punto de vista gráfico, tales como las creadas por medio de Macromedia Flash. XAML, XUL y UIML son otros ejemplos de lenguajes de interfaz basados en XML. En su uso típico, los archivos tipo MCML serían producidos por una herramienta de desarrollo, como Microsoft Visual Studio. El XML resultante es interpretado en forma instantánea por un sub-sistema de despliegue de Windows Vista denominado Windows Media Center, el cual está orientado a la visualización del contenido del computador a mayor distancia que la normal, similar a la que se acostumbra para un aparato de televisión y utilizando un control remoto en lugar de un teclado y un mouse. Debido a esto las interfaces de usuario para Media Center están construidas bajo premisa diferentes, pues deben tomar en cuenta el hecho de que sus usuarios estarán utlizándolas a una distancia mayor y por medio de dispositivos de control no convencionales. Los elementos de XAML se interconectan con objetos del Entorno Común de Ejecución para Lenguajes. Los atributos se conectan con propiedades o eventos de esos objetos. MCML fue diseñado para soportar las clases y métodos de la plataforma de desarrollo .NET que tienen relación con la interacción con el usuario, en especial el despliegue en pantalla.
118.1 Véase también • Media Center • Xbox 360 • XAML
233
Capítulo 119
Metaprogramación La metaprogramación consiste en escribir programas que escriben o manipulan otros programas (o a sí mismos) como datos, o que hacen en tiempo de compilación parte del trabajo que, de otra forma, se haría en tiempo de ejecución. Esto permite al programador ahorrar tiempo en la producción de código. Un ejemplo sencillo de un metaprograma sería este script de Bash: #!/bin/bash # metaprogram echo '#!/bin/bash' >program for ((I=1; I<=992; I++)); do echo“echo $I”>>program done chmod +x program Este script genera un nuevo programa que imprime por pantalla los números 1 a 992. Esto es sólo una muestra de cómo usar código para escribir más código, no la forma más eficiente de imprimir una lista de números. En cualquier caso, un buen programador puede escribir y ejecutar este metaprogama en apenas un par de minutos, y habrá generado exactamente 1000 líneas de código en esa cantidad de tiempo. La herramienta de metaprogramación más común es el compilador, el cual permite al programador escribir un programa relativamente corto en un lenguaje de alto nivel para, posteriormente, escribir un programa equivalente en lenguaje ensamblador o lenguaje máquina. Esto, por lo general, significa un buen ahorro de tiempo si se compara con la posibilidad de escribir el programa en lenguaje máquina de forma directa. Otro ejemplo bastante común de metaprogramación se puede encontrar en el uso de Lex (véase también: Flex) y Yacc (véase también: bison), que son usados para generar compiladores e intérpretes.
119.1 Enlaces externos
234
Capítulo 120
Microformatos Dublin Core Microformatos Dublin Core, es un proyecto cuyo objetivo es usar los elementos de la Iniciativa de Metadatos de Dublin Core, con la sintaxis de los microformatos, con el propósito general de describir recursos, especialmente recursos bibliográficos. Para codificar un Microformato Dublin Core, debemos crear un elemento de [X]HTML contenedor (por ejemplo el elemento DL) de la clase dublincore. Dentro de este elemento contenedor, debemos indicar de forma inequívoca el concepto que se va a expresar a través del microformato (por ejemplo, título). Por último, debemos usar una etiqueta de [X]HTML con una clase cuyo valor sea uno de los elementos de la Iniciativa de Metadatos de Dublin Core, y son los siguientes: - Elementos del conjunto de metadatos de Dublin Core: contributor, coverage, creator, date, description, format, identifier, language, publisher, relation, rights, source, subject, title y type. - Otros elementos y elementos refinados de Dublin Core: abstract, accessRights, accrualMethod, accrualPolicy, alternative, audience, avaliable, bibliographicCitation, conformsTo, created, dateAccepted, dateCopyrighted, dateSubmited, educationLevel, extent, hasFormat, hasPart, hasVersion, instructionalMethod, isFormatOf, isPartOf, isReferencedBy, isReplacedBy, isRequiredBy, issued, isVersionOf, license, mediator, medium, modified, provenance, references, replaces, requires, rightsHolder, spatial, tableOfContents, temporal y valid.
235
Capítulo 121
Modelo de prototipos El Modelo de prototipos, en Ingeniería de software, pertenece a los modelos de desarrollo evolutivo. El prototipo debe ser construido en poco tiempo, usando los programas adecuados y no se debe utilizar muchos recursos. El diseño rápido se centra en una representación de aquellos aspectos del software que serán visibles para el cliente o el usuario final. Este diseño conduce a la construcción de un prototipo, el cual es evaluado por el cliente para una retroalimentación; gracias a ésta se refinan los requisitos del software que se desarrollará. La interacción ocurre cuando el prototipo se ajusta para satisfacer las necesidades del cliente. Esto permite que al mismo tiempo el desarrollador entienda mejor lo que se debe hacer y el cliente vea resultados a corto plazo.
La construcción de prototipos se puede utilizar como un modelo del proceso independiente, se emplea más comúnmente como una técnica susceptible de implementarse dentro del contexto de cualquiera de los modelos del proceso expuestos. Sin importar la forma en que éste se aplique, el paradigma de construcción de prototipos ayuda al desarrollado de software y al cliente a entender de mejor manera cuál será el resultado de la construcción cuando los requisitos estén satisfechos. De esta manera, este ciclo de vida en particular, involucra al cliente más profundamente para adquirir el producto.
121.3 Inconvenientes • El usuario tiende a crearse unas expectativas cuando ve el prototipo de cara al sistema final. A causa de la intención de crear un prototipo de forma rápida, se suelen desatender aspectos importantes, tales como la calidad y el mantenimiento a largo plazo, lo que obliga en la mayor parte de los casos a reconstruirlo una vez que el prototipo ha cumplido su función. Es frecuente que el usuario se muestre reacción a ello y pida que sobre ese prototipo se construya el sistema final, lo que lo convertiría en un prototipo evolutivo, pero partiendo de un estado poco recomendado.
121.1 Etapas • Plan rápido. • Modelado, diseño rápido • Construcción del Prototipo • Desarrollo, entrega y retroalimentación • Comunicación
• En aras de desarrollar rápidamente el prototipo, el desarrollador suele tomar algunas decisiones de implementación poco convenientes (por ejemplo, elegir un lenguaje de programación incorrecto porque proporcione un desarrollo más rápido). Con el paso del tiempo, el desarrollador puede olvidarse de la razón que le llevó a tomar tales decisiones, con lo que se corre el riesgo de que dichas elecciones pasen a formar parte del sistema final...
• Entrega del desarrollo final
121.2 Ventajas • Este modelo es útil cuando el cliente conoce los objetivos generales para el software, pero no identifica los requisitos detallados de entrada, procesamiento o salida.
121.4 Conclusiones
• También ofrece un mejor enfoque cuando el responsable del desarrollo del software está inseguro de la eficacia de un algoritmo, de la adaptabilidad de un A pesar de que tal vez surjan problemas, la construcción sistema operativo o de la forma que debería tomar de prototipos puede ser un paradigma efectivo para la ingeniería del software. La clave es definir las reglas del la interacción humano-máquina juego desde el principio; es decir, el cliente y el desarro• Se puede reutilizar el codigo llador se deben poner de acuerdo en: 236
121.5. VÉASE TAMBIÉN • Que el prototipo se construya y sirva como un mecanismo para la definición de requisitos. • Que el prototipo se descarte, al menos en parte. • Que después se desarrolle el software real con un enfoque hacia la calidad.
121.5 Véase también • Ingeniería de software • Ingenierías del software
237
Capítulo 122
Modificador Un modificador es un conjunto de funciones de programación del lenguaje C que se aplican a las variables dentro de la estructura de un programa antes de que éste sea mostrado. Los modificadores pueden ir encadenados, y son rutinas que distorsionan la forma de los objetos de una manera determinada, sin cambiar su naturaleza. Así por ejemplo CALIF_FINAL es una variable numérica y su modificador informará si se utilizará en todo el programa o solo en parte de él.
122.1 Enlaces externos • Lenguaje C: Ámbito de funciones y variables, Richard A. Sequera.
238
Capítulo 123
Modularidad La modularidad es la capacidad que tiene un sistema 123.3 Modularidad en Economía y de ser estudiado, visto o entendido como la unión de vaen la Empresa rias partes que interactúan entre sí y que trabajan para alcanzar un objetivo común, realizando cada una de ellas una tarea necesaria para la consecución de dicho objeti- En economía y en la empresa, la modularidad de los provo. Cada una de esas partes en que se encuentre dividido ductos, servicios y procesos es un factor clave en el desa* * el sistema recibe el nombre de módulo. Idealmente un rrollo tecnológico, económico y social. [1] [2] módulo debe poder cumplir las condiciones de caja negra, es decir, ser independiente del resto de los módulos y comunicarse con ellos (con todos o sólo con una parte) 123.4 Modularidad en el diseño a través de unas entradas y salidas bien definidas.
123.1 Modularidad en Ciencias de la Computación Modularidad en Ciencias de la computación es la característica por la cual un programa de computador está compuesto de porciones que se conocen como módulos. El diseño estructurado es la técnica de diseño El llamado Phonebloks es un buen ejemplo de un diseño modude algoritmos en que se basa la programación modular, lar. paradigma de programación que persigue desarrollar programas modulares La modularidad en el diseño permite diseñar bienes basados en la modulación reticular de espacios que permitan optimizar el tiempo de construcción y debido a que son transportables, desarmables y reorganizables permiten impulsar múltiples funcionalidades y su reutilización al generar un nuevo uso diferente al que fueron fabrica123.2 Modularidad en Biología dos. Un ejemplo podría ser el proyecto Phonebloks, que permitiría diseñar un teléfono móvil en piezas separadas que el usuario podría intencambiar entre sí. En biología, la modularidad es una propiedad de los organismos (y de sus partes) por la cual estos pueden descomponerse en módulos. Los módulos son unidades coherentes que a su vez forman parte de unidades más amplias: las 123.5 Referencias células son parte de los tejidos, que a su vez son partes de los órganos, que a su vez son partes de los organismos. La [1] Baldwin, Carliss (2000) Design Rules, Vol. 1: The Power modularidad aparece también en el desarrollo; son móduof Modularity los los campos morfogenéticos, los patrones de desarrollo, los discos imaginales, los linajes celulares o los para- [2] Carliss Y. Baldwin Home Page en la Harvard Business segmentos de los insectos. School http://www.people.hbs.edu/cbaldwin 239
240
123.6 Véase también • Módulo • Programación modular • Morfología (biología) • Diseño modular
CAPÍTULO 123. MODULARIDAD
Capítulo 124
Módulo (informática) En programación un módulo es una porción de un programa de ordenador. De las varias tareas que debe realizar un programa para cumplir con su función u objetivos, un módulo realizará, comúnmente, una de dichas tareas (o varias, en algún caso).
lles internos de otros módulos. Como consecuencia de la independencia modular un módulo cumplirá: • Características de caja negra, es decir abstracción (ver abstracción en programación orientada a objetos).
En general (no necesariamente relacionado con la programación), un módulo recibe como entrada la salida que haya proporcionado otro módulo o los datos de entrada al sistema (programa) si se trata del módulo principal de éste; y proporcionará una salida que, a su vez, podrá ser utilizada como entrada de otro un módulo o bien contribuirá directamente a la salida final del sistema (programa), si se retorna al módulo principal. Particularmente, en el caso de la programación, los módulos suelen estar (no necesariamente) organizados jerárquicamente en niveles, de forma que hay un módulo principal que realiza las llamadas oportunas a los módulos de nivel inferior.
• Aislamiento de los detalles mediante encapsulamiento (ver encapsulamiento en programación orientada a objetos). La independencia modular mejora el rendimiento humano, pudiendo realizarse programación en equipo y desarrollar módulos paralelamente. También contribuye a la reutilización de software.
124.2 Véase también
Cuando un módulo es convocado, recibe como entrada los datos proporcionados por otro del mismo o superior nivel, el que ha hecho la llamada; luego realiza su tarea. A su vez este módulo convocado puede llamar a otro u otros módulos de nivel inferior si fuera necesario; cuando ellos finalizan sus tareas, devuelven la salida pertinente al módulo inmediato llamador, en secuencia reversa, finalmente se continúa con la ejecución del módulo principal.
124.1 Características de un módulo Cada uno de los módulos de un programa idealmente debería cumplir las siguientes características: • Tamaño relativamente pequeño.- Esto facilita aislar el impacto que pueda tener la realización de un cambio en el programa, bien para corregir un error, o bien por rediseño del algoritmo correspondiente. • Independencia modular.- Cuanto más independientes son los módulos entre sí más fácil y flexiblemente se trabajará con ellos, esto implica que para desarrollar un módulo no es necesario conocer deta241
• Algoritmo • Programa • Modularidad • Diseño estructurado • Programación modular
Capítulo 125
Monitor (concurrencia) En la programación paralela, los monitores son objetos destinados a ser usados sin peligro por más de un hilo de ejecución. La característica que principalmente los define es que sus métodos son ejecutados con exclusión mutua. Lo que significa, que en cada momento en el tiempo, un hilo como máximo puede estar ejecutando cualquiera de sus métodos. Esta exclusión mutua simplifica el razonamiento de implementar monitores en lugar de código a ser ejecutado en paralelo. En el estudio y uso de los semáforos se puede ver que las llamadas a las funciones necesarias para utilizarlos quedan repartidas en el código del programa, haciendo difícil corregir errores y asegurar el buen funcionamiento de los algoritmos. Para evitar estos inconvenientes se desarrollaron los monitores. El concepto de monitor fue definido por primera vez por Charles Antony Richard Hoare en un artículo del año 1974.* [1] La estructura de los monitores se ha implementado en varios lenguajes de programación, incluido Pascal concurrente, Modula-2, Modula-3 y Java, y como biblioteca de programas.
125.1 Componentes Un monitor tiene cuatro componentes: inicialización, datos privados, métodos del monitor y cola de entrada. • Inicialización: contiene el código a ser ejecutado cuando el monitor es creado • Datos privados: contiene los procedimientos privados, que sólo pueden ser usados desde dentro del monitor y no son visibles desde fuera
125.2 Exclusión mutua en un monitor Los monitores están pensados para ser usados en entornos multiproceso o multihilo, y por lo tanto muchos procesos o threads pueden llamar a la vez a un procedimiento del monitor. Los monitores garantizan que en cualquier momento, a lo sumo un thread puede estar ejecutando dentro de un monitor. Ejecutar dentro de un monitor significa que sólo un thread estará en estado de ejecución mientras dura la llamada a un procedimiento del monitor. El problema de que dos threads ejecuten un mismo procedimiento dentro del monitor es que se pueden dar condiciones de carrera, perjudicando el resultado de los cálculos. Para evitar esto y garantizar la integridad de los datos privados, el monitor hace cumplir la exclusión mutua implícitamente, de modo que sólo un procedimiento esté siendo ejecutado a la vez. De esta forma, si un thread llama a un procedimiento mientras otro thread está dentro del monitor, se bloqueará y esperará en la cola de entrada hasta que el monitor quede nuevamente libre. Aunque se la llama cola de entrada, no debería suponerse ninguna política de encolado. Para que resulten útiles en un entorno de concurrencia, los monitores deben incluir algún tipo de forma de sincronización. Por ejemplo, supóngase un thread que está dentro del monitor y necesita que se cumpla una condición para poder continuar la ejecución. En ese caso, se debe contar con un mecanismo de bloqueo del thread, a la vez que se debe liberar el monitor para ser usado por otro hilo. Más tarde, cuando la condición permita al thread bloqueado continuar ejecutando, debe poder ingresar en el monitor en el mismo lugar donde fue suspendido. Para esto los monitores poseen variables de condición que son accesibles sólo desde adentro. Existen dos funciones para operar con las variables de condición:
• Métodos del monitor: son los procedimientos que pueden ser llamados desde fuera del monitor. • Cola de entrada: contiene a los hilos que han llamado a algún método del monitor pero no han podido adquirir permiso para ejecutarlos aún. 242
• cond_wait(c): suspende la ejecución del proceso que la llama con la condición c. El monitor se convierte en el dueño del lock y queda disponible para que otro proceso pueda entrar. • cond_signal(c): reanuda la ejecución de algún proceso suspendido con cond_wait bajo la misma con-
125.4. VERIFICACIÓN DE MONITORES dición c. Si hay varios procesos con esas características elige uno. Si no hay ninguno, no hace nada. Nótese que, al contrario que los semáforos, la llamada a cond_signal(c) se pierde si no hay tareas esperando en la variable de condición c. Las variables de condición indican eventos, y no poseen ningún valor. Si un thread tiene que esperar que ocurra un evento, se dice espera por (o en) la variable de condición correspondiente. Si otro thread provoca un evento, simplemente utiliza la función cond_signal con esa condición como parámetro. De este modo, cada variable de condición tiene una cola asociada para los threads que están esperando que ocurra el evento correspondiente. Las colas se ubican en el sector de datos privados visto anteriormente. La política de inserción de procesos en las colas de las variables condición es la FIFO, ya que asegura que ningún proceso caiga en la espera indefinida, cosa que sí ocurre con la política LIFO (puede que los procesos de la base de la pila nunca sean despertados) o con una política en la que se desbloquea a un proceso aleatorio.
125.3 Tipos de monitores
243 ejecutarlo a seguir con el proceso despertante. Desventajas: • Si el proceso que ejecuta cond_signal no terminó con su ejecución se necesitarán dos cambios de contexto para que vuelva a tomar el lock del monitor. • Al despertar a un thread que espera en una variable de condición, se debe asegurar que reanude su ejecución inmediatamente. De otra forma, algún otro thread podría cambiar la condición. Esto implica que la planificación debe ser muy fiable, y dificulta la implementación.
125.3.2 Tipo Mesa Butler W. Lampson y David D. Redell en 1980 desarrollaron una definición diferente de monitores para el lenguaje Mesa que lidia con las desventajas de los monitores de tipo Hoare y añade algunas características. En los monitores de Lampson y Redell el thread que ejecuta cond_signal sobre una variable de condición continúa con su ejecución dentro del monitor. Si hay otro thread esperando en esa variable de condición, se lo despierta y deja como listo. Podrá intentar entrar el monitor cuando éste quede libre, aunque puede suceder que otro thread logre entrar antes. Este nuevo thread puede cambiar la condición por la cual el primer thread estaba durmiendo. Cuando reanude la ejecución el durmiente, debería verificar que la condición efectivamente es la que necesita para seguir ejecutando. En el proceso que durmió, por lo tanto, es necesario cambiar la instrucción if por while, para que al despertar compruebe nuevamente la condición, y de no ser cierta vuelva a llamar a cond_wait.
Antes se dijo que una llamada a la función cond_signal con una variable de condición hacía que un proceso que estaba esperando por esa condición reanudara su ejecución. Nótese que el thread que reanuda su ejecución necesitará obtener nuevamente el lock del monitor. Surgen las siguientes preguntas: ¿Qué sucede con el thread que hizo el cond_signal? ¿Pierde el lock para dárselo al thread que esperaba? ¿Qué thread continúa con su ejecución? Cualquier solución debe garantizar la exclusión mutua. Según quién continúa con la ejecución, se diferencian dos tipos Además de las dos primitivas cond_wait(c) y de monitores: Hoare y Mesa. cond_signal(c), los monitores de Lampson y Redell poseen la función cond_broadcast(c), que notifica a los 125.3.1 Tipo Hoare threads que están esperando en la variable de condición c y los pone en estado listo. Al entrar al monitor, En la definición original de Hoare, el thread que ejecuta cada thread verificará la condición por la que estaban cond_signal le cede el monitor al thread que esperaba. El detenidos, al igual que antes. monitor toma entonces el lock y se lo entrega al thread Los monitores del tipo Mesa son menos propensos a errodurmiente, que reanuda la ejecución. Más tarde cuando res, ya que un thread podría hacer una llamada incorrecta el monitor quede libre nuevamente el thread que cedió el a cond_signal o a cond_broadcast sin afectar al thread en lock volverá a ejecutar. espera, que verificará la condición y seguirá durmiendo Ventajas: si no fuera la esperada. • El thread que reanuda la ejecución puede hacerlo inmediatamente sin fijarse si la condición se cum- 125.4 Verificación de monitores ple, porque desde que se ejecutó cond_signal hasta que llegó su turno de ejecutar ningún proceso puede La corrección parcial de un monitor se puede demostrar cambiarla. verificando que los invariantes de representación del mo• El thread despertado ya estaba esperando desde an- nitor se cumplen en cualquier caso. El Invariante de retes, por lo que podría suponerse que es más urgente presentación es el conjunto de estados del monitor que lo
244
CAPÍTULO 125. MONITOR (CONCURRENCIA)
hacen correcto. Dicha verificación se puede realizar me- en espera vuelva a ser ejecutado, debe garantizarse que el diante axiomas y reglas de inferencia como, por ejemplo, invariante del monitor sigue siendo válido. los propuestos por la Lógica de Hoare. {IM ∧ L}wait(){IM ∧ L}
125.4.1
Los
procesos
bloqueados,
se
desbloquean
con
Inicialización de las variables del cond_signal o con cond_broadcast pero, esta vez, el proceso que llama a cond_signal sigue ejecutándose y monitor
utilizando el monitor. Es decir, en éste tipo de monitores, El código de inicialización debe incluir la asignación de señalar a otro proceso no puede provocar un cambio las variables del monitor antes de que los procedimientos ni en las variables locales el procedimiento ni en las del monitor puedan ser usados. La inicialización de éstas variables del monitor. * [2] variables debe estar acorde al Invariante de representación del monitor. {V }inicializacion{IM } Donde IM es el invariante del monitor.
125.4.2
Monitores tipo Hoare
En monitores con señales desplazantes, cond_signal y cond_wait hacen referencia a estados visibles del programa. cond_wait implica la cesión de la exclusión mútua del monitor. Por lo tanto, debe verificar el Invariante del monitor antes de que pueda ejecutarse. {IM ∧ L}wait(){C ∧ L} Donde: • L son el invariante del conjunto de variables locales del procedimiento. • C es la condición de desbloqueo, que se hace cierta tras terminar la ejecución de cond_wait. En cuanto a la operación signal en señales desplazantes. Cuando se llama a cond_signal, se produce la interrupción inmediata del procedimiento señalador y la reanudación de un proceso bloqueado en la cola de condición. Por lo tanto, todos los invariantes que eran ciertos antes de la ejecución de signal, se mantendrán, igualmente, como ciertos en el proceso señalado, tras la ejecución de cond_wait. {¬vacio(colaCondicion) ∧ L ∧ C}signal(){IM ∧ L} Nótese que la precondición de cond_signal coincide con la postcondición de wait, así como la precondición de cond_wait coincide con la postcondición de signal. La razón por la cual la condición de desbloqueo, c, no forma parte de la postcondición de signal es que, una vez que el proceso señalado ha reanudado su ejecución, puede hacer falsa ésta condición. Luego, no es posible garantizar que el invariante de la condición de desbloqueo sea cierto.* [1]
125.4.3
Monitores tipo Mesa
cond_wait, al igual que con señales desplazantes, bloquea el proceso y cede el uso del monitor. Cuando el proceso
125.5 Véase también • Semáforos • Cierres de exclusión mutua (Locks)
125.6 Referencias [1] Hoare, Charles Antony (octubre de 1974). «Monitors: An Operating System Structuring Concept». ACM 17: 549– 57. Consultado el 9 de diciembre de 2012. [2] Capel Tuñón, Rodríguez Valenzuela (2012). Sistemas Concurrentes y Distribuídos. Copicentro. pp. 89–92. ISBN 978-84-15536-68-0.
Capítulo 126
Anexo:Motores de persistencia Esta es una lista alfabética de los principales motores de mapeo objeto relacional, indicando si son libres o comerciales.
• Ebean • Enterprise Objects Framework • FireStorm/DAO
126.0.1
ColdFusion
• Hibernate, , muy usado.
• Arf ARF - Active Record Factory
• Hydrate
• CFCPowerTools Generación Batch de tu capa de datos en pocos minutos.
• iBATIS
• Reactor Reactor es un sencillo API para ColdFusion que abstrae la base de datos al vuelo según se necesite. • objectBreeze objectBreeze crea objetos directamente desde tu capa de persistencia. • Transfer Transfer es una librería para generar objetos de negocio al vuelo y abstraer las transacciones sobre ellos.
• intelliBO de Signsoft , implementación de JDO. • Java Data Objects (JDO) • JDBCPersistence • JDX • JPOX • Kōdō • Lychee
126.0.2
Common Lisp
• OpenAccess
• CLSQL
• OJB,
• cl-perec
• OpenJPA,
• elephant
• POEM,
• postmodern
• PriDE
• submarine
126.0.3
• SavePoint • SimpleORM
Java
• Speedo
• BuzzSQL
• TopLink de Oracle
• Carbonado
• Torque de ASF
• Castor
• WebObjects de Apple.
• Cayenne
• CocoBase PURE POJO V5 For JPA Primera he126.0.4 rramienta ORM Java (1997) • CrossDB
JavaScript
• GearsORM 245
246
126.0.5
CAPÍTULO 126. ANEXO:MOTORES DE PERSISTENCIA
.NET
• ORM.NET (open source)
• .netTiers
• Persistor.NET
• Briyante Integration Environment
• Puzzle.NPersist (open source)
• Business Logic Toolkit for .NET (open source)
• Signum Framework (open source)
• Castle ActiveRecord (open source)
• Sooda (open source)
• CodeFluent Entities
• Subsonic (DAL) (open source)
• Data Tier Modeler , reemplazado por Euss.
• Wilson ORMapper for .NET
• DataBlock (open source) • DataObjects.Net • dOOdads , (freeware) • EasyObjects.NET (open source) • EntitySpaces • eXpress Persistent Objects for .NET • Euss (Evaluant Universal Storage Services) (open source) • Genom-e
126.0.6 Perl • Class::DBI (open source) • Rose::DB::Object (open source) • OOPS (open source) • ORM (open source) • DBIx::Class (open source) • Alzabo (open source) • Tangram (Perl) (open source)
• Gentle.NET (open source) • GenWise Studio
126.0.7 PHP
• GURA
• ADOdb Active Record , (open source)
• Habanero
• CakePHP (open source)
• iBATIS.NET
• Doctrine (open source)
• IdeaBlade DevForce
• DB DataObject (open source)
• Lattice.DataMapper
• EZPDO (open source)
• LightSpeed
• Junction PHP (open source)
• LLBLGen Pro
• KohanaPHP (open source)
• LLBLGen (open source)
• Metastorage (open source)
• NConstruct
• PhpMyObject (open source)
• Neo (open source)
• PHP Object Generator (POG) (open source)
• NHibernate (open source)
• pork.dbObject (open source)
• NJDX
• Propel (open source)
• Nolics
• QCodo (open source)
• Opf3
• Symfony (open source)
• ObjectMagix
• Syrius (open source)
• ObjectMapper .NET (open source)
• xPDO (open source)
• ODX.NET (open source)
• Xyster Framework (open source)
• OpenAccess
• Yupp PHP Framework (open source)
247
126.0.8
Python
• Axiom • Ape , para [[Zope] • SQLAlchemy (open source) • SQLObject (open source) • PyDO (open source) • PyDO2 • MiddleKit, parte de Webware (open source) • Modeling • ForgetSQL (open source) • QLime (open source) • Storm (open source) • The open source Django web framework • Dejavu • Twisted Asynchronous Database Api (open source) • PyDAO
126.0.9
Ruby
• Active Record , parte de Ruby on Rails (open source) • Og part of Nitro (open source) • Rubernate • Lafcadio • Sequel • DataMapper • Momomoto , para PostgreSQL • Kansas
126.0.10
Smalltalk
• GLORP (open source)
126.0.11
C++
• DTL • DataXtend CE for C++ • Object Builder • SOCI • StactiveRecord (open source)
Capítulo 127
Método de depuración del patito de goma • Revision estructurada • Programación en pareja
127.2 Referencias [1] The Pragmatic Programmer: From Journeyman to Master. Addison Wesley. ISBN 978-0201616224. p. 95, footnote. [2] Baker, SJ, The Contribution of the Cardboard Cutout Dog to Software Reliability and Maintainability, http://www. sjbaker.org/humor/cardboard_dog.html.
127.3 Enlaces externos
El patito de goma es usado por un desarrollador para ayudar en la revisión de código
El método de depuración del patito de goma es un término informal utilizado en ingeniería de software para describir un método de revisión de código. El nombre es una referencia a una historia del libro The Pragmatic Programmer en donde un programador toma un patito de goma y revisa su código forzándose a sí mismo a explicarlo, línea por línea, al pato.* [1] Existen otros muchos términos para esta técnica, que a menudo tienen que ver con objetos inanimados. Muchos programadores han tenido una experiencia de explicar un problema de programación a alguien más, posiblemente a alguien que no sabe nada sobre programación, y luego encuentran la solución en el proceso de explicar el problema. Al comparar lo que supuestamente hace el código con lo que hace en realidad, cualquier incongruencia resulta nítida.* [2] Usando un objeto inanimado, el programador puede tratar de completar esto sin tener que involucrar además a otra persona.
127.1 Véase también • Revisión de código 248
• «Description of the method», Cant LUG, Ethernal, http://lists.ethernal.org/oldarchives/cantlug-0211/ msg00174.html. • Rubber duck debugging, http://www. rubberduckdebugging.com/: site honoring the method. • Rubber Duck Problem Solving, http: //www.codinghorror.com/blog/2012/03/ rubber-duck-problem-solving.html: Coding Horror blog.
Capítulo 128
Net Yaroze La Net Yaroze (ネットやろうぜ netto yarōze* ?) era un kit de desarrollo de software de Sony Computer Entertainment creado en 1997 para juegos de PlayStation. Estaba enfocado a los desarrolladores aficionados. Yaroze significa “Vamos a hacerlo juntos”.* [1] Costaba alrededor de los $750 USD. El pack incluía, además de la consola, que era idéntica a la Playstation pero en negro, documentación y software. No incluía bloqueo regional.* [2] Para usarla, el usuario necesitaba tener un ordenador personal IBM, Macintosh o NEC PC-9801. Así, el usuario, en el propio ordenador escribía el código del juego, lo compilaba y lo enviaba a la Net Yaroze para probarlo.
• 1 cable de comunicación, para conectar la consola al PC mediante tipo serie • 1 guía de iniciación • 1 manual de bibliotecas • 1 guía de usuario
A pesar de ser un kit de desarrollo para juegos de PlayStation, la Net Yaroze carecía de varias características que sí tenían los desarrolladores de PlayStation. No tenía hardware avanzado, software, bibliotecas, herramientas varias y una amplia asistencia técnica de Sony. Además, A pesar de no tener bloqueo regional, existían tres ver- los grupos de Usenet existentes, estaban restringidos a los siones, la japonesa, la americana y la europea/australiana. miembros de Net Yaroze, lo que provocó que la colaboLa principal diferencia entre ellas era que, las versiones ración entre usuarios fuese poco práctica. europea/australiana era en modo Pal mientras que la ver- La memoria principal de la Net Yaroze era la misma que sión japonesa y americana tenía modo NTSC. Entre la la de la PlayStation, de 2 Megabytes. Sin embargo, la Net versión japonesa y americana, la diferencia estaba en el Yaroze tenía una memoria secundaria extra que ofrecía idioma del manual, el software para PC japoneses, discos 1,5 megabytes más a la consola. Así pues, contaba con y los diferentes dibujos en las calcomanías. Extraoficial- un total de 3,5 megabytes de memoria RAM. Esta capamente, la versión japonesa es llamada DTL-3000 en lugar cidad era la que marcaba el espacio total del juego, es dede DTL-H3000. cir, lo que tenía que ocupar como mucho su código fuenLa Net Yaroze estaba sólo disponible a través de pedido te, gráficos, música y bibliotecas, pues todo esto debía por correo. No obstante, Sony, proporcionó este kit a al- de instalarse para poder ser probado. No obstante, exisgunas universidades del Reino Unido, Francia (Epita) y ten muchos títulos comerciales que están completamente instalados en la RAM, a excepción del sonido, y podrían Japón.* [3] haber sido desarrollados complemente con la Net Yaroze. El kit europeo de la Net yaroze contenía: Muchos títulos desarrollados por aficionados con la Net Yaroze fueron distribuidos con la PlayStation: The Offi• 1 Net Yaroze (textura negro mate) cial Magazine en Europa desde diciembre de 1997 hasta • 2 controladores de PlayStation (textura negro mate) marzo de 2004. El último número oficial revista PlayStation del Reino Unido, la número 108, presentó una re• Un cable de alimentación de corriente alterna (con copilación con muchos juegos de la Net Yaroze. Algunos enchufe para Reino Unido y adaptador para Francia) títulos que salieron con la revista fueron: • Un conector AV
• Haunted maze
• 1 disco de arranque (un CD de PlayStation verde)
• Terra Incognita
• 1 CD con el software de desarrollo de Net Yaroze para PC
• Blitter Boy
• 1 tarjeta de acceso negra, necesaria para el modo control remoto 249
• The Incredible CONEMAN • Hover car racing
250 • A dog tale • Adventure game • Rocksʼn'Gems • Psychon • Pushy II • Between the eyes • Super bub • Clone • Gravitation • Mah Jongg No fueron muchos, pero algunos de estos juegos prosperaron a nivel comercial, siendo el más famoso de ellos Devil Dice (Xi en Japón), que entonces llevaba el nombre de Para-Dice.
128.1 Véase también • PlayStation
128.2 Enlaces externos • Sitio de desarrollo no oficial de PlayStation 1 • Sitio no oficial de desarrollo de Net Yaroze • Net Yaroze (FAQ) Document • Video mostrando el contenido del kit Net Yaroze
128.3 Referencias [1] Absolute PlayStation, Section I. «PlayStation FAQ». Archivado desde el original el 23 de noviembre de 2015. Consultado el 15 de Junio, 2012. [2] IGN UK. «NET Yaroze». Archivado desde el original el 23 de noviembre de 2015. Consultado el 15 de Junio, 2012. [3] IGN UK. «NET Yaroze». Consultado el 15 de Junio, 2012.
CAPÍTULO 128. NET YAROZE
Capítulo 129
Nodo (informática) En informática y en telecomunicación, de forma muy general, un nodo es un punto de intersección, conexión o unión de varios elementos que confluyen en el mismo lugar. Ahora bien, dentro de la informática la palabra nodo puede referirse a conceptos diferentes según el ámbito en el que nos movamos: • En redes de computadoras cada una de las máquinas es un nodo, y si la red es Internet, cada servidor constituye también un nodo. El concepto de red puede definirse como: • En estructuras de datos dinámicas un nodo es un registro que contiene un dato de interés y al menos un puntero para referenciar (apuntar) a otro nodo. Si la estructura tiene sólo un puntero, la única estructura que se puede construir con él es una lista, si el nodo tiene más de un puntero ya se pueden construir estructuras más complejas como árboles o grafos.
129.1 Referencias [1] Castells, Manuel (1997). La era de la información. Economía, sociedad y cultura. Vol I: La sociedad red. Madrid: Alianza Editorial. ISBN 84-206-4247-9.
129.2 Enlaces externos • Nodo
251
Capítulo 130
Notación Reddick La notación Reddick en programación informática, es un sistema usado normalmente para crear los nombres de variables e identificar rápidamente su tipo de dato. El nombre de la notación proviene de su inventor Greg Reddick. Esta convención es muy utilizada en las nuevas versiones de Visual Basic y Visual Basic 2005. También es muy utilizada por los programadores de Microsoft y en tecnologías .NET. Consiste en“tags”de tres letras en minúsculas que se añaden a los nombres de las variables, y que indican su tipo. El resto del nombre indica, lo más claramente posible, la función que realiza la variable.
130.1 Ejemplo • intContador: una variable del tipo INTEGER que se usa como un contador. • strNombre: variable del tipo STRING que se usa para almacenar un nombre.
130.2 Notación para objetos Esta notación se ha expandido para ser usadas por tipos de objetos: En Visual Basic, la notación se ha adaptado a la siguiente: Object Tag Example Chart (graph) cht chtSales Check box chk chkReadOnly Combo box cbo cboIndustry Command button cmd cmdCancel Frame (object) fra fraPhoto Label lbl lblHelpMessage Line lin linVertical List box lst lstPolicyCode Option button opt optFrench Option group grp grpLanguage Page break brk brkPage1 Shape shp shpNamePanel Subform/report sub subContact Text box txt txtLoginName Toggle button tgl tglForm
130.3 Enlaces externos • Convenciones RVBA
252
Capítulo 131
Notación húngara En programación informática, la notación húngara es un sistema usado normalmente para crear los nombres de variables. También se utiliza para nombrar las instancias de objetos en lenguajes de programación visuales, como por ejemplo Delphi. El nombre de la notación proviene del hecho de que su inventor, Charles Simonyi, nació en Hungría. Esta convención es muy poco utilizada en las viejas versiones de Delphi pero es muy utilizada por los programadores de Microsoft y, en particular, en la programación del sistema operativo Windows.
editores de código inteligente que utilicemos, la mayoría de proyectos siempre acaban teniendo ciertas partes escritas en lenguajes dinámicamente tipados, en especial JavaScript, el único implementado por la mayoría de navegadores web para ejecutar código en cliente Puesto que a la hora de realizar proyectos se suelen establecer previamente unas Coding Style Guidelines (Guías de estilo de programación), no conviene hacerlas distintas para cada lenguaje y se podría definir un estándar de notación húngara que tenga un ligero compromiso con la facilidad de reconocimiento de tipos, sin que llegue a suponer un infierno sobre la complejidad de lectura de código.
Consiste en prefijos en minúsculas que se añaden a los nombres de las variables y que indican su tipo. El resto del nombre indica, lo más claramente posible, la función que realiza la variable. 131.2.1
Ejemplo notaciones de 1 carácter
Este ejemplo de notación húngara no parecerá tan crítico y extraño como el que se ha puesto de ejemplo al principio del artículo, en el cual se llegaban a utilizar hasta cuatro • nContador: la variable es un entero que se usará co- letras para denotar el tipo. mo contador.
131.1 Ejemplos
• szNombre: una cadena terminada con cero la cual almacena un nombre.
131.3 Véase también
• bRespuesta: una variable booleana que almacena una respuesta. • txtHora: una instancia de un objeto textbox que almacena la hora.
131.2 Situación actual Hoy día existen más detractores que impulsores de la notación húngara. De hecho, se suele calificar de una técnica que a la larga provoca más complejidad que ayuda a la mantenibilidad. Máxime cuando la mayoría de entornos de desarrollo actuales, en particular los que se usan con lenguajes estáticamente tipados, ofrecen mecanismos sencillos para averiguar el tipo de las variables sin recurrir a la búsqueda de su declaración. Sin embargo, parece que, como en la mayoría de las situaciones, en el medio está la virtud, pues por muchos 253
• Programación • Sistema operativo
Capítulo 132
Null El término null o nulo o DG es a menudo utilizado en la computación, haciendo referencia a la nada. En programación, null resulta ser un valor especial aplicado a un puntero (o referencia) usado para indicar que el puntero no apunta a un objeto o dato válido. Usualmente se utiliza el valor 0 (cero) para significar null, debido a que muchos sistemas operativos consideran el intentar acceder a una dirección de memoria tan baja como un error. Null es también utilizado en varias otras disciplinas y no únicamente en programación. En contexto de bases de datos null se utiliza para indicar la ausencia de valor asociado a un campo para un determinado registro. Así mismo se definen los resultados para null en operaciones lógicas: Operación “O” Verdadero O null = Verdadero Falso O null = null Operación “Y” Verdadero Y null = null Falso Y null = Falso
254
Capítulo 133
NWNScript NWNScript es el lenguaje interpretado empleado en el videojuego Neverwinter Nights y Neverwinter Nights 2.
133.1 Enlaces externos • NWN Lexicon Referencia online oficial.
255
Capítulo 134
Objeto todopoderoso En programación orientada a objetos, un objeto todopoderoso (en inglés God Object) es un objeto que conoce demasiado o hace demasiado. El objeto todopoderoso es un ejemplo de un anti-patrón.
134.2 Referencias • Ravioli code, patrones opuestos.
134.3 Enlaces externos 134.1 Historia La idea básica detrás de la Programación Estructurada es: un gran problema se divide en muchos pequeños problemas (estrategia Divide y Vencerás) y las soluciones son creadas para cada uno de ellos. Una vez que los pequeños problemas han sido resueltos, el gran problema ha sido resuelto como un todo. Sin embargo hay un solo objeto el cual necesita saber todo: el objeto en sí. De esta manera, hay un solo grupo de problemas que el objeto debe resolver: sus propios problemas. El Código del Objeto todopoderoso no sigue esta regla. En su lugar, la funcionalidad entera del programa está codificada en un solo objeto que hace todo, el cual mantiene toda la información del programa entero y contiene todos los métodos y subrutinas para manipular los datos. Como el objeto contiene muchos datos y requiere muchos métodos, su rol en el programa se convierte en Objeto Todopoderoso (Abarca todo). En lugar de objetos comunicándose entre ellos directamente, los objetos en el programa se cuelgan del Objeto Todopoderoso para manejar su información e interacción. Como el Objeto Todopoderoso es referenciado por casi todo el código, el mantenimiento se vuelve mucho más difícil, que el diseño del código de un programa mejor dividido El objeto todopoderoso es el fallo de usar subrutinas de lenguajes procedurales en orientación a objetos o de usar demasiadas variables globales para almacenar información de estados Crear un Objeto todopoderoso es típicamente considerado una mala práctica de programación, esta técnica es usada ocasionalmente para entornos de programación ajustados, donde el aumento de rendimiento ligero y la centralización es más importante que el mantenimiento y la elegancia de programación. 256
• Riel, Arthur J. (1996). «Chapter 3: Topologies of Action-Oriented Vs. Object-Oriented Applications». Object-Oriented Design Heuristics. Boston, MA: Addison-Wesley. ISBN 020163385X. «3.2: Do not create god classes/objects in your system. Be very suspicious of an abstraction whose name contains Driver, Manager, System, or Subsystem.» • Anti-Patterns and Worst Practices – Monster Objects
Capítulo 135
Oday Oday fue un descomunal bug que afectó a los sistemas operativos Windows XP y que permitía a quien lo aprovechaba escalar privilegios y acceder como SYSTEM en su ordenador (SYSTEM es la cuenta de Windows que más privilegios tiene, y que no pertenece a ningún usuario sino al sistema). El bug ya fue arreglado, pero en su día podía aprovecharse con un exploit llamado AT-EXPLOIT, con un programa en batch específico o con el modo manual echando mano del cmd.exe.
257
Capítulo 136
Offset (informática) En informática, un offset dentro de un array u otra estructura de datos es un entero que indica la distancia (desplazamiento) desde el inicio del objeto hasta un punto o elemento dado, presumiblemente dentro del mismo objeto. El concepto de distancia es solamente válido si todos los elementos del objeto son del mismo tamaño (típicamente dados en bytes o palabras). Por ejemplo, dado un array de caracteres“A”que contenga“abcdef”, se puede decir que el elemento que contiene la letra “c”tiene un offset de 2 desde el comienzo de A. En ingeniería informática y programación de bajo nivel (como el lenguaje ensamblador), un offset normalmente indica el número de posiciones de memoria sumadas a una dirección base para conseguir una dirección absoluta específica. Con este significado (que es el original) de offset, sólo se usa la unidad básica de direccionamiento, normalmente el byte de 8 bits, para especificar el tamaño del offset. En este contexto se puede llamar a veces dirección relativa.
136.1 Véase también • Offset
136.2 Referencias
258
Capítulo 137
OGNL Object-Graph Navigation Language (OGNL), creado por OGNL Technology, es un Lenguaje de Expresiones de código abierto para Java,el cual, mediante el uso de expresiones más simples que el amplio espectro que soporta Java, permite obtener y establecer propiedades (a través de métodos ya definidos getProperty y setProperty similares a los presentes en todos los JavaBeans) y la ejecución de métodos de clases Java.
137.3 Proyectos que usan OGNL • WebWork • Struts 2 (sucesor del anterior) • Tapestry • Spring Web Flow • Apache Click
137.1 Aplicaciones
• NReco (.NET integration framework for lightweight MDD)
Algunas de las ventajas de OGNL sobre Java son:
• op4j (extensión op4j-ognl) - implementación de interfaz fluida de Java.
• Las transformaciones entre tipos son más sencillas.
• MyBatis - framework de mapeo SQL
• Es un lenguaje de fuente de datos útil para mapear columnas de una tabla con su TableModel en Swing.
• The Thymeleaf Template Engine - motor de plantillas Java XML/XHTML/HTML5
• Es un sustituto del lenguaje de obtención de propiedades usado en el paquete BeanUtils.
137.2 Cadenas (chains)
• Unitils - marco (framework) de testeo modular para Java
137.4 Enlaces externos
Son la unidad fundamental de navegación. [Pueden contener:
• (en inglés) Página principal de OGNL • (en inglés) WebWork (usando OGNL)
• Nombres de propiedades. encabezado.texto • Llamadas a métodos. hashCode() • Índices de Array. listeners[0] Ejemplo: name.toCharArray()[0].numericValue.toString() Se pasa a String la propiedad “name”de la que se toma el carácter de la posición 0 y se obtiene su valor numérico que se pasa a String nuevamente. 259
Capítulo 138
OpenACS OpenACS del inglés Open Architecture Community Sys- comenzó a reescribir ACS en Java dando lugar a Red Hat tem (Arquitectura Abierta para Sistemas de Comunida- CMS. La comunidad de OpenACS asumió mantenimiendes) es un kit de herramientas libre (de código abierto) to del código escrito en Tcl. para el desarrollo rápido de aplicaciones web, con licencia GPL.
138.3 Véase también 138.1 Arquitectura
• Sistema de gestión de contenido (en inglés CMS: Content Management System)
OpenACS utiliza el servidor web AOLserver y como base de datos tanto Oracle como PostgreSQL.
138.4 Enlaces externos
OpenACS proporciona: • Un gran conjunto de aplicaciones que pueden ser usadas para desarrollar sitios web, siendo especialmente útil para aquellos que son colaborativos. Algunas de las aplicaciones más importantes son .LRN, dotFolio, WorkFlow, CMS, blogger, comercio electrónico, foros. • Un sofisticado kit de herramientas que proporciona un gran conjunto de APIs y servicios para el desarrollo rápido de nuevas aplicaciones. • Un modelo de datos que escribe la filosofía de orientación a objetos desde SQL estándar y métodos PL/SQL, haciendo elegante el soporte a distintas bases de datos (actualmente PostgreSQL y Oracle). • Un sistema robusto con capacidad de soportar una gran cantidad de tráfico sin una baja considerable de desempeño gracias a ser un sistema multi-thread. • Un sistema de documentación integrado que permite buscar fácilmente sobre el código existente en el sistema.
138.2 Historia OpenACS era originalmente desarrollado con el ArsDigita Community System, teniendo como base de datos Oracle. ACS fue la razón por la que AOLServer fue liberado. OpenACS surgió como un fork para soportar ACS con PostgreSQL. Después RedHat compró ArsDigita y 260
• openacs.org
Capítulo 139
Operaciones con archivos (informática) Los archivos informáticos son el medio de que disponemos para almacenar información no volátil en un dispositivo de almacenamiento. Los Sistemas de archivos de que disponen los sistemas operativos disponen de mecanismos para que un usuario pueda manipular los archivos (seleccionar, editar, ejecutar, borrar, ...). Desde el punto de vista de un programador un archivo es un medio para poder leer datos de entrada para su programa o donde poder guardar los resultados de su ejecución. Todo lenguaje de programación debe disponer de algún mecanismo para que el programador pueda manipular archivos desde un programa. Estos mecanismos pueden ser más o menos sofisticados o versátiles dependiendo del lenguaje de programación que estemos considerando, pero deben haber unas funciones básicas para poder acceder a un archivo, estas son: • Lectura (consulta).- Esta operación consiste el leer la información contenida en fichero sin alterarla. • Escritura (modificación).- Consiste en actualizar el contenido del fichero bien añadiéndole nuevos datos o borrando parte de los que contenía. • Apertura.- Antes de acceder a un fichero, tanto para consultar como para actualizar su información, es necesario abrirlo. Esta operación se debe realizar previamente a las operaciones de lectura o escritura. • Cierre.- Cuando se ha terminado de consultar o modificar un fichero, por lo general, del mismo modo que se tuvo que abrir para realizar alguna operación de lectura/escritura sobre él, éste deberá ser cerrado.
139.1 Véase también • Programación • Lenguajes de programación • Archivo informático • Sistema de archivos
261
Capítulo 140
Operador rés en un espacio de Banach. En este espacio, existe una norma y podemos definir una esfera de radio unidad. Se llama operador lineal acotado al operador lineal que está acotado en esta esfera. Los operadores lineales acotados entre dos espacios de Banach forman a su vez un espacio de Banach cuyo estudio es bastante interesante. Una extensión de la derivada real a los operadores es la derivada de Frechet que es un operador lineal acotado. No todos los operadores lineales interesantes son acotados: hay muchos ejemplos de operadores importantes en mecánica cuántica que no son acotados. El ejemplo más típico de operador lineal no acotado es la derivada -considerada como una aplicación entre dos d espacios de funciones reales-. El operador diferencial, dx , actúa sobre la función f (x) que se escribe a su derecha, produciendo una nueva función derivada: f ′ (x) Si un operador está definido entre dos espacios vectoriales de funciones, actúa transformando unas funciones en otras.
Operadores suma,resta, multiplicación y división
En matemáticas, el término operador puede emplearse con diversas acepciones . Algunas veces, un operador es un símbolo matemático que indica que debe ser llevada a cabo una operación especificada* [1] sobre un cierto número de operandos (número, función, vector, etc.).
140.2 Operadores bilineales o bivariantes
(Para definiciones más estrictas sobre linealidad y Los operadores suelen interpretarse como funciones, por bilinealidad, véanse los temas relacionados) ejemplo la suma + o el producto ·pueden ser entendidas como funciones de dos argumentos.O una aplicación de Su nombre depende del autor, son los operadores que actúan sobre dos objetos (escritos, generalmente, a amCxC en C. bos lados del operador) produciendo un único resultado. Véanse los casos siguientes.
140.1 Operadores en un espacio vectorial 140.3 Tipos generales de operadores Un uso frecuente del término operador es aplicación entre dos espacios vectoriales. Se usa con más frecuencia cuando alguno de ellos tiene dimensión infinita. Este sue- 140.3.1 Operadores de condición le ser el caso de un espacio vectorial cuyos elementos son funciones. Si se trata de una aplicación lineal, podemos Relacionan un término A con otro B estableciendo su llamarle operador lineal. igualdad, jerarquía o cualquier otra relación posible, coEl estudio de los operadores lineales es de particular inte- mo ejemplos tenemos: 262
140.4. OTROS OPERADORES • A = B establece que A es igual que B. En este caso hay que distinguir entre operador = de asignación y el operador = de comparación. El primero toma el valor de B y se lo asigna a A; el segundo solamente compara los valores de A y B sin modificarlos y devuelve un valor lógico o de verdad verdadero si ambos valores son iguales o falso si dichos valores no son iguales. • A ≠ B o desigualdad. Este caso es justamente el opuesto al anterior, aunque aquí no podemos hablar de asignación, pero si de comparación. Ahora el resultado de esta operación será F si los valores A y B son iguales y V si son distintos.
140.3.2
Operadores de orden
Los operadores de orden establecen o verifican clasificaciones entre números (A < B, A > B, etc.) u otro tipo de valores (caracteres, cadenas, ...). Todo tipo de dato susceptible de ser ordenado por cualquier criterio puede ser comparado con estos operadores; como los anteriores devuelven un valor de verdad en función del resultado que tenga la comparación en cada caso. • A > B Devuelve V si A es estrictamente mayor que B y F en caso contrario • A < B Devuelve V si A es estrictamente menor que B y F en caso contrario • A ≥ B Devuelve V si A es mayor o igual que B y F en caso contrario • A ≤ B Devuelve V si A es menor o igual que B y F en caso contrario
263 lógicos nos proporcionan un resultado a partir de que se cumpla o no una cierta condición. Esto genera una serie de valores que, en los casos más sencillos, pueden ser parametrizados con los valores numéricos 0 y 1, como se puede apreciar en los ejemplos de abajo. La combinación de dos o más operadores lógicos conforma una función lógica. • Los más sencillos son (nótese su relación con los operadores relacionales): • Operador NO-lógico: '¬A' significa todo lo que no es A' • Operador Y-lógico: 'A ∧ B' significa 'A y B a la vez'; resultando FALSO (0) si no se cumple y VERDADERO (1) si lo hace. • Operador O-lógico: 'A ∨ B' significa 'O bien A, o bien B, o bien los dos'; resultando FALSO (0) si no se dan ni A ni B y VERDADERO (1) si se da alguno de los dos o los dos a la vez. • Operador =: 'A = B' significa 'A debe ser igual a B'; resultando FALSO (0) si esto no es así y VERDADERO (1) en caso contrario. • Operador <: 'A < B' significa 'A debe ser menor que B'; resultando FALSO (0) si no se satisface y VERDADERO (1) en caso contrario. • Operador >: 'A > B' significa 'A debe ser mayor que B'; resultando FALSO (0) si no se satisface y VERDADERO (1) en caso contrario. • Los operadores más complejos se construyen a partir de los anteriores (podría incluirse alguno más) y ya entran dentro de lo que sería una función lógica. Un ejemplo muy utilizado sería 'SI(condición;A;B)' ('IF condición THEN A ELSE B' en la mayoría de los lenguajes de programación) cuyo resultado sería A si se satisface la 'condición' o B en caso contrario.
140.3.4 Operaciones aritméticas Las operaciones aritméticas pueden ser entendidas, desde un punto de vista operacional, como operadores bivariantes o como operadores a derecha. Por ejemplo, '2 × 3' puede ser el operador bivariante de la multiplicación actuando sobre los números 2 y 3, o el operador '2 ×' que actúa sobre 3. En este grupo se encuentran la adición, la sustracción, multiplicación y la división.
• Otros operadores relacionales menos usuales son los Otras operaciones, derivadas de las operaciones aritllamados operadores geométricos: paralelismo (A || méticas usuales son la potenciación, radicación y B), perpendicularidad y otros logaritmación.
140.3.3
Operadores lógicos
Muy utilizados en Informática, lógica proposicional y álgebra booleana, entre otras disciplinas. Los operadores
140.4 Otros operadores • Operador autoadjunto
264 • Operador diferencial • Operador hermítico • Operador cuántico • Operador lineal • Operador norma • Operador nabla • Gradiente • Divergencia • Rotacional • Laplaciano • Transformada integral • Sumatorio • Productorio
140.5 Temas relacionados • Aplicación lineal • Forma bilineal definida • Cálculo • Cálculo lógico
140.6 Referencias [1] Domingo Agustín Vázquez. «Diccionario de ciencias».
CAPÍTULO 140. OPERADOR
Capítulo 141
Operando En matemáticas, un operando es una de las entradas (ar- 141.2.2 Informática gumentos o variables) de un operador. Por ejemplo, en • Expresiones y Atribuições Escales - Fortran en UFPEL. Acessado en 23 de febrero de 2008. 3+6=9 " + " es el operador, " 3 " y " 6 " son los operandos. Si el operando va acompañado de un signo menos (" − ") se considera que es un operando negativo, en caso contrario se considera operando positivo o simplemente operando. La cantidad de operandos de un operador es denominada aridad. Basándose en la aridad, los operadores son clasificados como unarios, binarios, ternarios etc.
141.1 En informática En los lenguajes de programación de computadora, las definiciones de operador y operando son casi las mismas que las de matemáticas. Adicionalmente, en lenguaje máquina, un operando es un valor (un argumento) con el cual la instrucción, nombrada por un mnemónico, opera. El operando puede ser un registro, una dirección de memoria, una constante literal, o una etiqueta. Un ejemplo simple en la arquitectura PC es MOV DS, AX donde el valor en el operando del registro AX debe ser movido al registro DS. Dependiendo de la instrucción, puede haber cero, uno, dos o más operandos.
141.2 Conexiones externas 141.2.1
Matemática
• Otávio N. Cipriani; José Monserrat N.; Ila M. S. de Souza. Construyendo un Juego Para Uso en la Educación Matemática en UFLA. Accedido el 23 de febrero de 2008. 265
• Lenguaje Java en SENAC - Río Grande del Sur. Acedido el 23 de febrero de 2008.
Capítulo 142
Paquetes en PL/SQL Los paquetes en PL/SQL tienen el objetivo de agrupar procedimientos y funciones de forma lógica. De esta manera, se consigue agrupar en un único objeto, toda la casuística asociada a un determinado tipo de tarea. Por ejemplo, si tenemos un conjunto de procedimientos y funciones para realizar cálculos matemáticos complejos, los podemos poner en un paquete.
sores... subprogramas en PLSQL END nombre_paquete Para realizar llamadas a objetos dentro de un paquete, habría que diferenciar si la llamada es desde un subprograma dentro del mismo paquete o si la llamada es externa al paquete:
La ventaja de los paquetes es que la primera vez que se invoca, es cargado en memoria, por lo que las siguientes veces ya no será necesario hacerlo de nuevo. Además, el paquete mantiene una copia en memoria para todos los usuarios. Otra ventaja, es que podemos encapsular procedimientos y funciones que no forman parte de la interfaz de usuario. Podemos ocultar ciertos objetos y solo hacer públicos los que se necesiten. También se permite la sobrecarga dentro de los paquetes. El paquete se divide en especificación y cuerpo.
142.1 Especificación Es obligatorio en la creación de un paquete (PACKAGE). Se declaran todos los subprogramas públicos. Lo lógico es declarar en esta sección aquellos procedimientos o funciones que actúan como interfaz. También se declaran las variables o constantes que se quieren tratar como globales y que se puedan cambiar o referenciar fuera del paquete.
• Llamada interna Se pone el nombre del subprograma y entre paréntesis los parámetros que se deben pasar. Por ej. para llamar a la función “Multiplica(real r1, real r2)" desde la función “CalculaBeneficios”, se pondría “r3:= Multiplica(2.5,3.5)" • Llamada externa Hay que preceder el nombre del paquete al nombre del procedimiento o función. Además, el subprograma llamado debe ser público para que pueda ser referenciado. Por ejemplo para llamar a la función Multiplica que se encuentra en el paquete“OperacionesMatematicas”desde un procedimiento externo al paquete sería “r3:= OperacionesMatematicas.Multiplica(2.5,3.5)"
La sintaxis sería la siguiente:
Para eliminar un paquete de la base de datos tanto la esCREATE [OR REPLACE] PACKAGE nom- pecificación como el cuerpo: bre_paquete IS | AS declaraciones de variables, DROP PACKAGE nombre_paquete cursores... subprogramas en PLSQL END nombre_paquete Oracle proporciona algunos paquetes que permiten la realización de distintas tareas muy comunes al desarrollar o administrar la base de datos. Entre estos paquetes se pueden destacar: 142.2 Cuerpo En el cuerpo es donde se definen los procedimientos y funciones públicos y privados. La sintaxis sería: CREATE [OR REPLACE] PACKAGE BODY nombre_paquete IS | AS declaraciones de variables, cur266
• DBMS_SQL: para acceder a la base de datos con SQL dinámico. • DBMS_UTILITY: para el análisis de objetos. Por ejemplo se pueden compilar todos los objetos que se encuentran en un determinado esquema de base de datos.
142.2. CUERPO • UTL_FILE: añade capacidades de entrada/salida a ficheros.
267
Capítulo 143
Pascal Casing Pascal Casing es un procedimiento de programación común en el lenguaje Java y .Net. Es parecido al Camel casing con la excepción que la letra inicial del identificador debe estar en mayúscula. La nomenclatura está compuesta por tantas palabras como sean necesarias. La primera letra de cada una de las palabras irá siempre en mayúsculas. Tanto para Pascal Casing como para Camel casing, se obvia el uso de artículos. Un uso correcto de nomenclatura sería WriteInformation y no WriteTheInformation, WriteInformation y no writeInformation o Writeinformation.
143.1 Enlaces externos • History around Pascal Casing and Camel Casing
268
Capítulo 144
Patch (Unix) Patch es un comando de Unix y Unix-like que actualiza ficheros de texto de acuerdo a las instrucciones contenidas en un archivo separado, llamado archivo de parche. Este archivo (denominado patch) es un archivo de texto que consiste en una lista de las diferencias entre ficheros y se produce mediante la ejecución del comando diff comparando con el fichero original y actualizándolo con los argumentos de diff. El programa original fue escrito por Larry Wall (creador del lenguaje de programación Perl) en mayo de 1985. Una nueva versión del programa es parte del proyecto GNU y es mantenido por la FSF.
144.1 Contexto de uso El comando se utiliza con frecuencia para la actualización del código fuente a una versión más reciente. Debido a esto es utilizado frecuentemente en sistemas de control de código fuente como CVS. El programa no solo es capaz de añadir texto como puede intuirse, también es capaz de eliminarlo. Ejemplo de uso: Creación del fichero: $ diff -u oldFile newFile > mods.diff Aplicación del parche: $ patch < mods.diff
144.2 Enlaces externos • Man linux • Código fuente en GNU
269
Capítulo 145
Phrogram Phrogram (anteriormente Kid's Programming Language, or KPL) es un lenguaje de programación diseñado para ser inteligible y fácil para los niños. La versión 1 (KPL) fue finalizada en Agosto de 2005, y la versión 2 (Phrogram) es ahora mismo la versión más actual.
mado el núcleo del Phrogram Team (Equipo Phrogram), trabajando en el producto (como extensiones llamadas add-in libraries) como un programa comercial destinado a la enseñanza del software y para dar valor a Phrogram con respecto a lenguaje de programación.
El principal objetivo de The Phrogram Company es distribuir un simple pero poderoso grupo de herramientas 145.1 Detalles técnicos que hacen del aprender a programar algo fácil y divertido. Phrogram (KPL) se ha convertido en una gran herraPhrogram es un lenguaje de programación y un IDE que mienta para los programadores novatos por la facilidad guarda cierta similitud con Visual Basic. El lenguaje so- para crear programas multi-media con sprites, música, porta un número de datos complejos, incluyendo estruc- efectos sonoros, animaciones y algunas opciones más. turas. El objetivo secundario de Phrogram es proveer un lenguaje moderno con algunas opciones de lenguajes avanzados como C++, Java, Visual Basic y C#, y la sintaxis de Visual Basic, para hacer la transición entre estos lenguajes lo más sencilla posible. Phrogram (KPL) soporta programación orientada a objetos (OOP) y permite la definición de clases y de sus propiedades y métodos asoUn programa de Phrogram es una colección de bloques ciados, los cual provee a los programadores principiantes anidados. En el nivel mayor hay un bloque Program, y una introducción a la programación OOP. dentro de este, otros bloques Method y Function son definidos. Las funciones y los métodos (functions y methods) Para lograr estos objetivos, los desarrolladores de Phroson ambos un conjunto de acciones reusables, pero exis- gram construyeron la Versión 2 sobre el reciente .NET te una diferencia: las funciones devuleven un valor y los Framework Version 2 (Noviembre de 2005). Phrogram métodos no tienen esa obligación. Las estructuras (struc- intenta ser completamente compatible con otros lenguatures) son declaradas fuera de métodos y funciones. Las jes que usen.NET Framework, por lo que esas“runtime variables deben ser declaradas en el momento de decla- libraries”pueden ser redistribuidas donde o a quien se quiera. ración. Phrogram depende de Microsoft .NET Framework y provee muchas funciones y métodos para interactuar con esa plataforma. Por esto, Phrogram actualmente sólo puede usarse en la serie de sistemas operativos Microsoft Windows que soporten.NET Framework.
145.2 ¡Hola, Mundo! en KPL
145.4 Otra información
Program Hello_World Method Main() PrintLine“Hello, ( Phrogram es un software comercial con 30 días de prueWorld”) End Method End Program ba. La interfaz de usuario de Phrogram está disponible en 18 idiomas entre ellos inglés, español, ruso, chino y catalán. La web de KPL está actualmente disponible en inglés, español, francés, portugués y otros 5 idiomas. To145.3 Filosofía das las traducciones (menos inglés, que no es traducción) Jonah Stagner comenzó a desarrollar Phrogram (KPL) han sido creadas por una comunidad global de voluntacuando quiso enseñar a sus hijos a programar. Descubrió rios, y la compañía anima a los usuarios a traducir. que las herramientas y tecnologías no son en absoluto fá- A pesar de que KPL fue diseñada originalmente para niciles de usar para los principiantes. Desde entonces Jo- ños de entre 10 y 14 años (de ahí su nombre, “Lenguaje nah, Jon Schwartz, Walt Morrison y David Witus han for- de Programación para Niños”), es apropiado para pro270
145.6. ENLACES EXTERNOS gramadores principiantes de cualquier edad, y de ahí el cambio de nombre. Es usado por mucha gente adulta que lo han descargado para aprender, o para sus hijos o estudiantes. Phrogram puede ser usado como lenguaje de programación a aprender en la escuela, en cualquier nivel de educación, desde primaria y secundaria hasta la Universidad. Actualmente es usado en las universidades de muchos países como Estados Unidos, Gran Bretaña, Canadá, México, Colombia, Rusia, Japón, Islandia, Suecia, República Checa, Eslovaquia, Portugal, Brasil, China, Guam, las Filipinas y Nueva Zelanda.* [cita requerida]
145.5 The Phrogram Company KPL versión 2 fue liberada, renombrada como Phrogram. La nueva web de la comunidad es The Phrogram Company.
145.6 Enlaces externos • The Phrogram Company, website oficial de Phrogram y la Comunidad Phrogram • La antigua website de KPL • Morrison Schwartz Inc • Diapositivas introductorias a KPL para profesores y padres (<1 MB) • Diapositivas introductorias a KPL para programadores (1.7 MB) • KPL podcast by ComputerWorld • Video de KPL en Channel 9 (Requiere Windows Media Player)
271
Capítulo 146
Plataforma de desarrollo En informática, una plataforma de desarrollo es el ambiente o entorno de software común en el cual se desenvuelve la programación de un grupo definido de aplicaciones. Comúnmente se encuentra relacionada directamente a un sistema operativo; sin embargo, también es posible encontrarla ligada a una familia de lenguajes de programación o a una interfaz de programación de aplicaciones (API, por las siglas en inglés: Application Programming Interface). Cabe recordar que funciona como sistema plataforma o multiusuario.
146.1 Véase también • Multiplataforma • Entorno de desarrollo integrado
272
Capítulo 147
Plataforma virtual didáctica Las plataformas virtuales se refieren a la tecnología uti- 147.4 Autores y contribuyentes lizada para la creación y desarrollo de cursos o módulos didácticos en la Web (sibal) que se usan de manera más Muchas organizaciones para el desarrollo colaboran con amplia en la Web 2.0 mejora de la comunicación apren- voluntarios en línea para desarrollar plataformas de capadizaje y enseñanza. citación en un intento por aumentar la capacidad de las comunidades locales, instructores y personas responsables de la toma de decisiones de países en desarrollo para 147.1 Historia ayudar a enfrentar los desafíos de desarrollo.* [1] Con la llegada de Internet se produce un importante abaratamiento de los costos de desarrollo de programas, por lo que resulta más sencilla la creación de materiales cuyo objetivo es ser utilizados en línea. Sin embargo se siguen necesitando conocimientos avanzados de programación para crear un curso o un módulo didáctico, y por tanto estos cursos no son accesibles a todo el mundo. Desde mediados de los años 90 empiezan a surgir plataformas didácticas que permiten la creación y la gestión de cursos completos para la web sin que sean necesarios conocimientos profundos de programación o de diseño gráfico.
147.5 Ventajas 1. Ahorro en gastos de libros, libretas y material para escribir 2. Se disminuyen los tiempos de transporte de los usuarios que utilizan las plataformas virtuales didácticas 3. Posibilidad de utilizar los dispositivos digitales para acceder a las plataformas 4. Uso de diferentes recursos didácticos, tales como: videos, audios, libros electrónicos, pruebas digitales, que permitirán realizar un seguimiento a los alumnos que utilizan las plataformas.
147.2 Herramientas que las componen 1. Herramientas de comunicación, como foros, chats, correo electrónico.
147.6 Enlaces externos • Plataforma virtual didáctica para instituciones
2. Herramientas de los estudiantes, como autoevaluaciones, zonas de trabajo en grupo, perfiles. 3. Herramientas de productividad, como calendario, marcadores, ayuda.
147.7 Bibliografía
4. Herramientas de administración, como autorización. 5. Herramientas del curso, como tablón de anuncios, evaluaciones.
• DILLENBOUG, P (2000) Virtual learning environments pdf • GÓMEZ, F (2005) Plataformas Virtuales y Diseño De Cursos, Chile, Universidad Pontificia Católica de Valparaíso: Online • MOLIST, M. (13-4-2006) " Institutos y universidades apuestan por la plataforma libre de e-learning Moodle " en CiberP@ís.Online
147.3 Para que sirven
Sirven para acortar distancias y prolongar la comunicaoñiutk.uñvu.kuk ción sin necesidad de estar presencialmente. 273
274
147.8 Véase también • Comunidad de aprendizaje de idiomas [1] Boletín del Servicio Voluntariado en Línea
CAPÍTULO 147. PLATAFORMA VIRTUAL DIDÁCTICA
Capítulo 148
Polling Polling en computación hace referencia a una operación 148.2 Polling del registro de Winde consulta constante, generalmente hacia un dispositivo dows de hardware, para crear una actividad sincrónica sin el uso de interrupciones, aunque también puede suceder lo En cualquier versión del sistema operativo Microsoft mismo para recursos de software. Windows desde la versión 3.11 podemos encontrar apliEsto, aplicado a programación puede ser visto como una caciones pobremente desarrolladas que consultan repepobre implementación en búsqueda del sincronismo de titivamente llaves del registro de Windows en busca de procesos. Por ejemplo, se podría consultar constantemen- cambios, degradando el rendimiento general del sistema. te un directorio del sistema de archivos para indicarle al En versiones antiguas este modelo de implementación era usuario cuando lleguen nuevos contenidos a la misma sin la única alternativa, pero ahora en versiones modernas de embargo estas constantes consultas degradarían el rendi- Windows desde NT 3.1 o Windows 98 en adelante exismiento del equipo y probablemente sería mejor imple- te la función RegNotifyChangeKeyValue* [1] dentro de mentar la solución por otro medio, en particular, pidién- la biblioteca Advapi32, la cual forma parte de la API de dole al sistema operativo que informe de transferencias a Windows. Esta función permite hacer una especie de“inese directorio en particular. terrupción de software”la cual nos avisará ante cambios en el contenido de una clave de registro sin tener que consultarla directamente ni periódicamente. A pesar de la función comentada anteriormente hay aplicaciones que siguen haciendo un mal uso de los recursos del equipo e incluso programas de Microsoft (como MSN Desktop Search) pobremente desarrollados que producen polling.* [2]
148.1 Historia 148.3 Soluciones para el polling En los primeros sistemas de computación cuando una aplicación necesitaba leer la pulsación de una tecla, interrogaba continuamente al teclado esperando hasta que la tecla fuera presionada. Debido a la ausencia de sistemas multitarea, mientras se esperaba una tecla, no se podían ejecutar otras tareas. La solución a este problema apareció con la llamada interrupción de teclado en donde el controlador del dispositivo, en este caso el teclado, es quien genera una interrupción sólo cuando el dispositivo está listo para transferir datos. La CPU maneja estas interrupciones que el sistema operativo sabe como priorizar y obtener información de ellas. Estas múltiples consultas pueden referirse a uso excesivo de recursos de red, registros o ficheros, aunque también pueden relacionarse con actividades de más bajo nivel del equipo.
En sistemas de código abierto la solución simplemente abarca la corrección sobre el código de las funciones que generen el problema, empleando funciones como las nombradas anteriormente o en su defecto las apropiadas según la plataforma utilizada. El problema se torna más interesante en aplicaciones de código cerrado, en este caso la solución generalmente está en manos de la empresa desarrolladora, sin embargo, es posible aplicar prácticas de ingeniería inversa para lograr cambiar el comportamiento que causa el problema.
148.4 Referencias
275
[1] RegNotifyChangeKeyValue Function (Windows) [2] Mark's Blog : Polling and MSN Desktop Search
276
148.5 Enlaces externos • Demostración de cómo solucionar el polling en aplicaciones de Windows
CAPÍTULO 148. POLLING
Capítulo 149
Poltergeist (informática) • Análisis y diseño de modelo inestables.
En Programación orientada a objetos el antipatrón de diseño poltergeist es una clase de objetos de corta duración, normalmente sin estado, que se utiliza para realizar la inicialización o para invocar a los métodos de otras clases. La definición original es de Michael Akroyd en la Object World West Conference de 1996: “Como un poltergeist que aparece y desaparece misteriosamente, lo mismo ocurre con el objeto de breve duración. Como consecuencia, el código es más difícil de mantener y hay un desperdicio de recursos innecesario. La causa habitual de este antipatrón es un pobre diseño de objetos.”
• Pobre funcionamiento del sistema. Se generan instancias y se realizan llamadas innecesarias. • Dificultad de ampliar el programa y de realizar un buen mantenimiento.
149.2 Solución • Eliminar clases externas, que no tengan relevancia, clases transitorias y operacionales (Init, Manager, Controller, etc).
Las clases poltergeist se pueden identificar por su nombre. A menudo se llaman “manager_”, “controller_” , “start_process”, etcétera. A veces, las clases poltergeist demuestran la necesidad de una arquitectura más compleja. Por ejemplo, un poltergeist surge si el mismo método actúa como el cliente y el invocador en un patrón de comando, y el programador separa las dos fases. Sin embargo, esta arquitectura más compleja puede que nunca llegue a materializarse. No se debe confundir con objetos de larga duración que almacenan el estado de un patrón como es el caso de Modelo-vista-controlador, que traspasa el flujo de información entre las tres clases principales.
• Eliminar otras clases con poco tiempo de vida y carencia de responsabilidades.
149.3 Véase también • Antipatrón de diseño • Patrón de diseño • Modelo-vista-controlador
149.4 Enlaces externos
Para eliminar un poltergeist, se debe de eliminar la clase llamadora y tratar de insertar su funcionalidad dentro de la clase invocada mediante herencia.
149.1 Consecuencias • Proliferación de clases. • Clases con poca duración, sin estados y pocas responsabilidades. • Complejidad excesiva. Difícultad de comprender la arquitectura del programa, las asociaciones de clases y las llamadas que se realizan entre ellas. 277
• Antipattern poltergeists by Sourcemaking Teaching IT Professionals • Development Antipatterns poltergeists
Capítulo 150
Portabilidad La portabilidad (en inglés portability) es uno de los conceptos clave en la programación de alto nivel. Se define como la característica que posee un software para ejecutarse en diferentes plataformas, el código fuente del software es capaz de reutilizarse en vez de crearse un nuevo código cuando el software pasa de una plataforma a otra (ver la nota, a continuación de este párrafo). A mayor portabilidad menor es la dependencia del software con respecto a la plataforma.
150.1 Véase también • Interoperatividad.
150.2 Referencias
(Nota: la portabilidad no tiene relación directa con el código fuente de una aplicación y, por eso, tampoco tiene relación directa con la reutilización del mismo. En cambio, la portabilidad se refiere exclusivamente a la propiedad que posee un software que le permite ser ejecutado en diferentes plataformas y/o sistemas operativos. De este modo, si un determinado software compilado pudiere ser ejecutado en cualquier sistema operativo, diríamos que ese software es 100% portable. Éste es el núcleo del concepto de portabilidad. En este sentido, la afirmación precedente: “el código fuente del software es capaz de reutilizarse en vez de crearse un nuevo código cuando el software pasa de una plataforma a otra”, tiene como supuesto erróneo que tenemos acceso al código fuente, el cual podría reutilizarse (como es la meta que buscan los diseñadores de los lenguajes cuyos códigos corren sobre máquinas virtuales, como es el caso de Java y la familia DOT NET). Esto es incorrecto: la portabilidad es un concepto que se refiere exclusivamente a la relación software <-> plataforma). El prerrequisito para la portabilidad es la abstracción generalizada entre la aplicación lógica y las interfaces del sistema. Cuando un software se puede compilar en diversas plataformas (x86, IA64, amd64, etc.), se dice que es multiplataforma. Esta característica es importante para el desarrollo de reducción costos, cuando se quiere hacer una misma aplicación. En algunos casos el software es “independiente”de la plataforma y puede ejecutarse en plataformas diversas sin necesidad de ser compilado específicamente para cada una de ellas, a este tipo de software se le llama interpretado, donde un "intérprete" traduce (propiamente interpreta) las instrucciones en tiempo de ejecución para que sean entendidas por diferentes plataformas.
278
• Diccionario de Informática. “Portabilidad”. Página 254. Editorial Cultural. 1999. Madrid, España. ISBN 84-8055-256-5 • Mooney (1997). "Bringing Portability to the Software Process" (PDF). West Virginia University. Dept. of Statistics and Computer Science. Revisado el 17 de marzo de 2008. • Garey (2007),“Software Portability: Weighing Options, Making Choices”, The CPA Journal 77(11): 3
Capítulo 151
Postcondición En programación, una postcondición es una condición o predicado lógico que siempre debe cumplirse justamente después de la ejecución de una sección de código o de una operación (especificación formal). Las postcondiciones se prueban a veces mediante aserciones incluidas en el código. A menudo, las postcondiciones se incluyen simplemente en la documentación de la correspondiente sección de código. Por ejemplo: el resultado de un factorial es siempre un entero mayor o igual que 1. De este modo un programa que calcula el factorial de un número dado tendría como postcondiciones que el resultado debe ser un entero y que éste debe ser mayor o igual que 1.
151.1 Véase también • Precondición • Diseño por Contrato • Lógica de Hoare • Invariantes mantenidas por condiciones • Disparador (Bases de datos)
279
Capítulo 152
Pragma La palabra griega pragma (πραγμα), pragmata en plural (πραγματα), que significa: 'lo que ha sido hecho', un acto, un hecho, y cuyas connotaciones y los sentidos más ampliados cubren una riqueza de sentidos a este significado, incluso: acción, asunto, negocio, circunstancia, preocupación, conveniencia, innovación, trabajo, necesidad, objeto, objetivo, ocupación, oficina, papel, o trabajo de vida, asuntos privados, cosa, problema. También el pragma es un tipo de Arquetipos amatorios.
152.1 Programación Los pragmas son sentencias especiales que controlan el comportamiento del compilador, es decir son directivas de compilador. Tienen esta forma estándar: pragma Nombre (lista_de_argumentos); La lista_de_argumentos es opcional, no todos los pragmas necesitan argumentos.
152.2 Véase también • Resultado • Efecto • Pragmatismo
152.3 Enlaces externos •
Wikcionario tiene definiciones y otra información sobre pragma.Wikcionario
280
Capítulo 153
Precondición Una precondición es una condición que ha de satisfacerse justo antes del comienzo de la ejecución de una porción de código (normalmente un subprograma o método). Por ejemplo: el factorial de un número sólo está definido para valores positivos (o cero). Por tanto, un subprograma que calcule el factorial de un número exigirá que dicho número sea mayor o igual que cero. Existen lenguajes de programación que incorporan construcciones sintácticas para reflejar las precondiciones de sus subprogramas o métodos. El cálculo del factorial en el lenguaje Eiffel, por ejemplo, quedaría así: factorial(n: INTEGER): INTEGER -- Calcula el factorial de un número. No está definido para cantidades negativas. require no_negativo: n >= 0 do if n = 0 then Result := 1 else Result := n * factorial(n - 1) end end En donde la palabra require introduce la precondición del método factorial.
153.1 Véase también • Postcondición • Diseño por Contrato • Lógica de Hoare • Invariantes mantenidas por condiciones • Disparador (Bases de datos)
281
Capítulo 154
Primitiva de sincronización rendezvous Rendezvous es una primitiva de sincronización asimétrica que permite a dos procesos concurrentes, el solicitante y el llamado, intercambiar datos de forma coordinada. El proceso que solicita el rendezvous debe esperar en el punto de reencuentro hasta que el proceso llamado llegue allí. Igualmente el proceso llamado puede llegar al rendezvous antes que el solicitante y debe esperar que él llegue al punto de encuentro para poder continuar procesando. La imagen de esperar en el punto de encuentro corresponde a colocar un proceso en espera inactiva hasta que la cita se cumpla. Durante el rendezvous los procesos pueden intercambiar datos. Los datos intercambiados corresponden a parámetros de una llamada (desde el solicitante hacia el proceso llamado) y a resultados de una llamada (desde el proceso llamado hacia el solicitante), sin necesidad de almacenamiento intermediario. La desventaja de la abstracción rendezvous es que no contempla pasaje de mensajes de forma asíncrona, como en el caso de las colas. En el lenguaje de programación Ada es preciso implementar comunicación asíncrona y otras abstracciones de comunicación a partir de rendevouz combinados con procesos intermedios y encapsulamiento.
154.1 Ejemplo Ejemplo en Ada donde el proceso Cola acepta un rendevouz de nombre agregar: task type Cola is entry agregar(n: in Integer); entry eliminar(x: out Integer); ... end Cola -- Implementación de Cola task body Cola is begin ... accept agregar(n: in Integer) do ... -- Cuerpo de la operación end agregar; ... end Cola; --LLamada desde otro proceso: begin ... Cola.agregar(n) end
154.2 Enlaces externos • RendezVous, Portland Pattern Repository's Wiki
282
Capítulo 155
Proceso (informática) Este artículo se refiere al proceso informático, para otros usos véase Proceso.
Un proceso se rige en pequeñas porciones, conocidas como páginas, y cada proceso tiene su propia tabla de paginación, fungiendo como una optimización del sistema operativo ante los fallos de página.
Un proceso puede informalmente entenderse como un programa en ejecución. Formalmente un proceso es“Una unidad de actividad que se caracteriza por la ejecución de una secuencia de instrucciones, un estado actual, y un conjunto de recursos del sistema asociados”.* [1]
Esta definición varía ligeramente en el caso de sistemas operativos multihilo, donde un proceso consta de uno o más hilos, la memoria de trabajo (compartida por todos los hilos) y la información de planificación. Cada hilo consta de instrucciones y estado de ejecución.
Para entender lo que es un proceso y la diferencia entre un programa y un proceso, A. S. Tanenbaum propone la analogía “Un científico computacional con mente culinaria hornea un pastel de cumpleaños para su hija; tiene la receta para un pastel de cumpleaños y una cocina bien equipada con todos los ingredientes necesarios, harina, huevo, azúcar, leche, etcétera.”Situando cada parte de la analogía se puede decir que la receta representa el programa (el algoritmo), el científico computacional es el procesador y los ingredientes son las entradas del programa. El proceso es la actividad que consiste en que el científico computacional vaya leyendo la receta, obteniendo los ingredientes y horneando el pastel.
Los procesos son creados y eliminados por el sistema operativo, así como también éste se debe hacer cargo de la comunicación entre procesos, pero lo hace a petición de otros procesos (interrupción o tiempo de reloj). El mecanismo por el cual un proceso crea otro proceso se denomina bifurcación (fork). El proceso de arranque de GNU/Linux inicia con un sólo proceso (init) y después comienza a crear los hilos necesarios para tener el sistema listo para su uso. Los nuevos procesos pueden ser independientes y no compartir el espacio de memoria con el proceso que los ha creado o ser creados en el mismo espacio de memoria.
Cada proceso tiene su contador de programa, registros y variables, aislados de otros procesos, incluso siendo el mismo programa en ejecución 2 veces. Cuando este último caso sucede, el sistema operativo usa la misma región de memoria de código, debido a que dicho código no cambiará, a menos que se ejecute una versión distinta del programa. Los procesos son gestionados por el sistema operativo y están formados por:
En los sistemas operativos multihilo es posible crear tanto hilos como procesos. La diferencia estriba en que un proceso solamente puede crear hilos para sí mismo y en que dichos hilos comparten toda la memoria reservada para el proceso. Los procesos pueden ser cooperativos o independientes. Dos o más procesos pueden cooperar mediante señales de forma que uno obliga a detenerse a los otros hasta que reciban una señal para continuar.
• Las instrucciones de un programa destinadas a ser ejecutadas por el microprocesador. • Su estado de ejecución en un momento dado, esto es, los valores de los registros de la unidad central de procesamiento para dicho programa. • Su memoria de trabajo (memoria crítica), es decir, la memoria que ha reservado y sus contenidos.
• Se usa una variable de tipo semáforo para sincronizar los procesos. • Si un proceso está esperando una señal, se suspende hasta que la señal se envíe. • Se mantiene una cola de procesos en espera en el semáforo. • La forma de elegir los procesos de la cola en espera es mediante una política first in first out.
• Otra información que permite al sistema operativo La sincronización explícita entre procesos es un caso parsu planificación. ticular del estado “bloqueado”. En este caso, el suceso 283
284
CAPÍTULO 155. PROCESO (INFORMÁTICA)
que permite desbloquear un proceso no es una operación Salida normal, ésta se presenta cuando el proceso termide entrada/salida, sino una señal generada a propósito por na de forma voluntaria, por ejemplo, cuando se cierra en el programador desde otro proceso. navegador web o el procesador de textos. Hay cuatro eventos principales que provocan la creación Salida por error, ésta se presenta cuando el proceso tiede procesos: ne que salir debido a insuficiencia de datos, por ejemplo, cuando solicita un archivo que no existe. • El arranque del sistema.
Error fatal, éste sucede por un error en el programa, como las divisiones entre 0 o requerimiento de memoria inac• La ejecución, desde un proceso, de una llamada al cesible. sistema para la creación de otro proceso. Eliminado por otro proceso, éste es sumamente útil cuan• Una petición de usuario para crear un proceso. do un proceso se queda colgado, es decir, sin terminar, pero tampoco responde. En Unix un ejemplo es cuando • El inicio de un trabajo por lotes. se utiliza el comando kill para terminar procesos abruptamente. Los procesos pueden contener uno o más hilos, haciendo más eficiente las tareas, asimismo la complejidad de los algoritmos de sincronización, ya que podría ocurrir la 155.3 Estados de un proceso condición de carrera muy a menudo, inclusive los indeseados interbloqueos. Los estados de un proceso obedecen a su participación y disponibilidad dentro del sistema operativo y surgen de la necesidad de controlar la ejecución de cada proceso. Los 155.1 Creación de un proceso procesadores sólo pueden ejecutar un solo proceso a la vez, turnándolos para el uso de éste. Existen procesos no Básicamente hasta el día de hoy existen sólo 4 formas de apropiativos o cooperativos que básicamente ocupan todo crear un proceso: el tiempo del procesador hasta que ellos deciden dejarlo. Los procesos apropiativos son aquellos que ocupan por • Arranque del sistema. un período de tiempo el procesador hasta que una interrupción o señal llega al procesador para hacer el cambio • En la ejecución, desde un proceso, de una llamada de proceso, a esto se le conoce como cambio de contexto. al sistema para la creación del proceso. Los posibles estados que puede tener un proceso son eje• Una petición deliberada del usuario para crear un cución, bloqueado y listo: proceso. • El inicio de un trabajo por lotes. La forma de creación de procesos en Unix es a través de una llamada al sistema fork la cual creará un proceso hijo en total semejanza al padre, hasta que el recién proceso decida cambiar su imagen en memoria, incluso obtener sus propios descriptores de archivos abiertos.
• Ejecución, es un proceso que está haciendo uso del procesador. • Bloqueado, No puede ejecutarse hasta que un evento externo sea llevado a cabo. • Listo, ha dejado disponible al procesador para que otro proceso pueda ocuparlo.
Las posibles transiciones son 4. La primera se realiza cuando el sistema operativo determina que el proceso no puede continuar justo en ese momento, en algunos sisteEl ciclo de vida de un proceso es sencillo, consta de la mas se puede hacer una llamada al sistema“pause”para creación, la ejecución de instrucciones y la terminación. pasar al estado bloqueado, en Unix cuando el proceso está Cabe señalar que un proceso en el transcurso de su ciclo leyendo datos provenientes de una canalización o de un puede estar en diferentes estados. archivo especial (terminal) y no hay entrada disponible, el proceso se bloquea de forma automática. • Salida normal. Las transiciones 2 y 3 son llevadas a cabo por el planificador de procesos, siendo que el proceso no tiene conoci• Salida por error. miento de éste. La transición 2 se da cuando el planificador de procesos decide que el proceso ya estuvo el tiem• Error fatal. po suficiente en ejecución y debe dar paso a la ejecución • Eliminado por otro proceso. de otros procesos (adquieran tiempo del procesador). La
155.2 Terminación de un proceso
155.7. BIBLIOGRAFÍA transición 3 se realiza cuando todos los procesos han ocupado tiempo del procesador y debe retomarse el primer proceso. La transición 4 ocurre cuando se produce un evento externo por el que un proceso estaba en espera, por ejemplos, introducir datos desde la terminal. Si no hay otro proceso en ejecución en ese instante, la transición 3 se activa y el proceso comienza a ejecutarse; también podría pasar al estado de “listo”y esperar un momento para iniciar la ejecución.
155.4 Tipos de procesos Existen dos tipos de procesos, aquellos que se ejecutan en modo kernel y aquellos que se ejecutan en modo usuario. Los primeros son más lentos por las llamadas al sistema que realizan, sin embargo, son más seguros por la integridad que representan. Cuando hablamos de los procesos de usuario, podemos decir que el sistema operativo podría no ser multiproceso, ya que se vale de librerías (como pthread) para hacer un multiplexado y dar la apariencia de trabajar como multiproceso. Podría pensarse en otra clasificación, como son los procesos en primer plano y procesos en segundo plano. Los primeros interactúan con el usuario, es decir, el usuario proporciona los datos que el proceso utilizará. Los segundos, son creados para tareas bien definidas y no necesitan la intervención del usuario, por ejemplo, se puede tener un proceso en segundo plano para revisar la temperatura el disco duro constantemente, éstos también son conocidos como demonios.
155.5 Véase también • Memoria virtual • Multiproceso • Unix • Paginación
155.6 Referencias [1] Stallings 5º edición pag. 109
155.7 Bibliografía Tanenbaum, Andrew S. (2009). «2 Procesos e hilos». Sistemas operativos modernos (3 edición). Prentice Hall. p. 1076.
285
Capítulo 156
Proceso para el desarrollo de software El Proceso para el desarrollo de software, también denominado ciclo de vida del desarrollo de software es una estructura aplicada al desarrollo de un producto de software. Hay varios modelos a seguir para el establecimiento de un proceso para el desarrollo de software, cada uno de los cuales describe un enfoque diferente para diferentes actividades que tienen lugar durante el proceso. Algunos autores consideran un modelo de ciclo de vida un término más general que un determinado proceso para el desarrollo de software. Por ejemplo, hay varios procesos de desarrollo de software específicos que se ajustan a un modelo de ciclo de vida de espiral.
156.2 Actividades del desarrollo de software
156.1 Generalidades La gran cantidad de organizaciones de desarrollo de software implementan metodologías para el proceso de desarrollo. Muchas de estas organizaciones pertenecen a la industria armamentística, que en los Estados Unidos necesita un certificado basado en su modelo de procesos para poder obtener un contrato.
Actividades del proceso de desarrollo de software representados en el desarrollo en cascada. Hay algunos modelos más para representar este proceso.
156.2.1 Planificación
El estándar internacional que regula el método de selección, implementación y monitoreo del ciclo de vida del La importante tarea a la hora de crear un producto de software es obtener los requisitos o el análisis de los resoftware es ISO 12207. quisitos. Los clientes suelen tener una idea más bien absDurante décadas se ha perseguido la meta de encontrar tracta del resultado final, pero no sobre las funciones que procesos reproducibles y predecibles que mejoren la prodebería cumplir el software. ductividad y la calidad. Algunas de estas soluciones intentan sistematizar o formalizar la aparentemente desorgani- Una vez que se hayan recopilado los requisitos del cliente, zada tarea de desarrollar software. Otros aplican técnicas se debe realizar un análisis del ámbito del desarrollo. Este de gestión de proyectos para la creación del software. Sin documento se conoce como especificación funcional. una gestión del proyecto, los proyectos de software corren el riesgo de demorarse o consumir un presupuesto mayor que el planeado. Dada la cantidad de proyectos 156.2.2 Implementación, pruebas y documentación de software que no cumplen sus metas en términos de funcionalidad, costes o tiempo de entrega, una gestión de La implementación es parte del proceso en el que los proyectos efectiva es algo que a menudo falta. Algunas organizaciones crean un grupo propio (Software ingenieros de software programan el código para el proEngineering Process Group, abreviado SEPG) encargado yecto. de mejorar los procesos para el desarrollo de software en Las pruebas de software son parte esencial del proceso de desarrollo del software. Esta parte del proceso tiene la la organización. 286
156.3. MODELOS DE DESARROLLO DE SOFTWARE
287
función de detectar los errores de software lo antes posible. La documentación del diseño interno del software con el objetivo de facilitar su mejora y su mantenimiento se realiza a lo largo del proyecto. Esto puede incluir la documentación de un API, tanto interior como exterior.
156.2.3
Despliegue y mantenimiento
El despliegue comienza cuando el código ha sido suficientemente probado, ha sido aprobado para su liberación y ha sido distribuido en el entorno de producción. Entrenamiento y soporte para el software es de suma importancia y algo que muchos desarrolladores de software descuidan. Los usuarios, por naturaleza, se oponen al cambio porque conlleva una cierta inseguridad, es por Si se aplica este paradigma, unos de los principales proello que es fundamental instruir de forma adecuada a los blemas , es que las etapas realizadas no son autónomas de futuros usuarios del software. las siguientes, creando una dependencia estructural y en El mantenimiento o mejora del software de un software el acaso de un error atrasaría todo el proyecto. Se tiene con problemas recientemente desplegado, puede requerir que tener pautas bien definidas, y que no se incurra a momás tiempo que el desarrollo inicial del software. Es po- dificación porque implicaría en que el software no cumpla que el cliente no se sible que haya que incorporar código que no se ajusta al con su ciclo de vida. Tener en cuenta * vea afectado por la impaciencia. [3] diseño original con el objetivo de solucionar un problema o ampliar la funcionalidad para un cliente. Si los costes de mantenimiento son muy elevados puede que sea oportuno rediseñar el sistema para poder contener los costes de mantenimiento.
2. Paradigma Orientado a Objetos: Estos modelos se basan en la Programación orientada a objetos; por lo tanto, se refiere al concepto de clase, el análisis de requisitos y el diseño. El modelo o paradigma orientado a objetos posee dos características principales, las cuales son: • Permite la re-utilización de software.
156.3 Modelos de Desarrollo de Software Los modelos de desarrollo de software son una representación abstracta de una manera en particular. Realmente no representa cómo se debe desarrollar el software, sino de un enfoque común. Puede ser modificado y adaptado de acuerdo a las necesidades del software en proceso de desarrollo. * [1] Hay varios modelos para perfilar el proceso de desarrollo, cada uno de las cuales cuenta con pros y contras. El proyecto debería escoger el más apropiado para sus necesidades. En ocasiones puede que una combinación de varios modelos sea apropiado. Existen tres paradigmas de los modelos de desarrollo de software: 1. Paradigma Tradicional: Es uno de los paradigmas más antiguo, se inventó durante la creación del método estructurado. Si se elige un proyecto, el método varia en etapas.* [2] Como todo modelo, existen sus pros y contras al usar este paradigmas:
• Facilita el desarrollo de herramientas informáticas de apoyo al desarrollo, el cual es simple al implementarla en una notación orientado a objetos llamado UML.* [4] 3. Paradigma de Desarrollo Ágil: Es un paradigma de las Metodologías De Desarrollo basado en procesos ágiles. Estos intentan evitar los tediosos caminos de las metodologías tradicionales enfocándose en las personas y los resultados. Usa un enfoque basado en el Valor para construir software, colaborando con el cliente e incorporando los cambios continuamente.* [5]
156.3.1 Modelo de cascada El modelo de cascada define las siguientes etapas que deben cumplirse de forma sucesiva: 1. Especificación de requisitos 2. Diseño del software
288
CAPÍTULO 156. PROCESO PARA EL DESARROLLO DE SOFTWARE
3. Construcción o Implementación del software 4. Integración 5. Pruebas (o validación) 6. Despliegue (o instalación)
1. El énfasis se sitúa en el análisis de riesgo, y por lo tanto requiere de clientes que acepten este análisis y actúen en consecuencia. Para ello es necesaria confianza en los desarrolladores así como la predisposición a gastar más para solventar los temas, por lo cual este modelo se utiliza frecuentemente en desarrollo interno de software a gran escala.
7. Mantenimiento Siguiendo el modelo de cascada de forma estricta, sólo cuando se finaliza una fase, comienza la otra. En ocasiones se realiza una revisión antes de iniciar la siguiente fase, lo que permite la posibilidad de cambios (lo que puede incluir un proceso de control formal de cambio). Las revisiones también se utilizan para asegurar que la fase anterior ha sido totalmente finalizada; los criterios para completar una fase se conocen frecuentemente con el término inglés“gate”(puerta). Este modelo desaconseja revisitar y revisar fases que ya se han completado. Esta falta de flexibilidad en un modelo de cascada puro ha sido fuente de crítica de los defensores de modelos más flexibles.
156.3.2
Modelo de espiral
La principal característica del modelo en espiral es la gestión de riesgos de forma periódica en el ciclo de desarrollo. Este modelo fue creado en 1988 por Barry Boehm, combinando algunos aspectos clave de las metodologías del modelo de cascada y del desarrollo rápido de aplicaciones, pero dando énfasis en un área que para muchos no jugó el papel que requiere en otros modelos: un análisis iterativo y concienzudo de los riesgos, especialmente en el caso de sistema complejos de gran escala.
2. Si la implementación del riesgo de análisis afectará de forma esencial los beneficios del proyecto, no debería utilizarse este modelo. 3. Los desarrolladores de software han de buscar de forma explícita riesgos y analizarlos de forma exhaustiva para que este modelo funcione. La primera fase es la búsqueda de un plan para conseguir los objetivos con las limitaciones del proyecto para así buscar y eliminar todos los riesgos potenciales por medio de un cuidadoso análisis, y si fuera necesario incluyendo la fabricación de un prototipo. Si es imposible descartar algunos riesgos, el cliente ha de decidir si es conveniente terminar el proyecto o seguir adelante ignorando los riesgos. Por último, se evalúan los resultados y se inicia el diseño de la siguiente fase.
156.3.3 Desarrollo iterativo e incremental El desarrollo iterativo recomienda la construcción de secciones reducidas de software que irán ganando en tamaño para facilitar así la detección de problemas de importancia antes de que sea demasiado tarde. Los procesos iterativos pueden ayudar a desvelar metas del diseño en el caso de clientes que no saben cómo definir lo que quieren.* [6]
La espiral se visualiza como un proceso que pasa a través de algunas interaciones con el diagrama de los cuatro 156.3.4 cuadrantes representativos de las siguientes actividades:
Desarrollo ágil
El desarrollo ágil de software utiliza un desarrollo iterativo como base para abogar por un punto de vista más ligero y más centrado en las personas que en el caso de las soluciones tradicionales. Los procesos ágiles utilizan retroalimentación en lugar de planificación, como principal mecanismo de control. La retroalimentación se canaliza 2. Análisis de riesgos: una evaluación analítica de pro- por medio de pruebas periódicas y frecuentes versiones gramas seleccionados, para evaluar como identificar del software. y eliminar el riesgo; Hay muchas variantes de los procesos ágiles: 3. la implementación del proyecto: implementación del desarrollo del software y su pertinente verificación; • En el caso de la programación extrema (XP), las fa1. crear planes con el propósito de identificar los objetivos del software, seleccionados para implementar el programa y clarificar las restricciones en el desarrollo del software;
Modelo de espiral con énfasis en los riesgos, haciendo hincapié en las condiciones de las opciones y limitaciones para facilitar la reutilización de software, la calidad del software puede ayudar como una meta propia en la integración en el desarrollo del producto. Sin embargo, el modelo en espiral tiene algunas limitaciones, entre las que destacan:
ses se realizan en pasos muy cortos (o “continuos” ) con respecto al anterior. El primer paso (intencionalmente incompleto) por los pasos puede ocurrir en un día o en una semana, en lugar de los meses o años de cada paso completo en el modelo en cascada. En primer lugar, se crean pruebas automatizadas para proveer metas concretas al desarrollo. Después se programa el código, que será completo cuando
156.4. MODELOS DE MEJORA DE PROCESOS
289
todas las pruebas se superan sin errores, y los desa- 156.4 Modelos de mejora de procerrolladores ya no sabrían como mejorar el conjunsos to de pruebas necesario. El diseño y la arquitectura emergen a partir de la refactorización del código, y se da después de programar. El diseño lo realizan Capability Maturity Model Integration El Capability Maturity Model Integration (CMMI), en español los propios desarrolladores del código. El sistema, «Integración de Modelos de Madurez de Capaciincompleto, pero funcional se despliega para su dedades» es uno de los modelos líderes basados en mostración a los usuarios (al menos uno de los cuamejores prácticas. Son evaluaciones independientes les pertenece al equipo de desarrollo). Llegado eslas que confirman el grado con el que una organite punto, los profesionales comienzan a escribir las zación siguen sus propios procesos, que no evalúa pruebas para la siguiente parte del sistema de más la calidad de los procesos o del software que se importancia. produce. CMMI ha reemplazado a CMM y tiene un ámbito global, no sólo en procesos destinados al desarrollo del software.
156.3.5
Codificación y corrección
ISO 9000 ISO 9000 describe estándares para un proceso organizado formalmente para resultar en un producto y los métodos de gestión y monitoreo del progreso. Aunque este estándar se creó inicialmente para el sector de producción, los estándares de ISO 9000 también se han aplicado al desarrollo del software. Al igual que CMMI, que una organización está certificada con el ISO 9000 no garantiza la calidad del resultado final, sólo confirma que se ha seguido los procesos establecidos.
El desarrollo de codificación y corrección (en inglés“Code and fix”) es, más que una estrategia predeterminada, el resultado de una falta de experiencia o presión que se ejerce sobre los desarrolladores para cumplir con una fecha de entrega.* [7] Sin dedicar tiempo de forma explícita para el diseño, los programadores comienzan de forma inmediata a producir código. Antes o después comienza la fase de pruebas de software (a menudo de forma tardía) y los inevitables errores que se encuentran han de eliminarse antes de poder entregar el software. ISO 15504 ISO 15504, también conocido como Software Process Improvement Capability Determination (SPICE), en español «Determinación de la Capacidad de Mejora del Proceso de Software» es un marco para la evaluación de procesos de software. Este 156.3.6 Orientado a la Reutilización estándar tiene como objetivo un modelo claro para poder comparar procesos. SPICE se utiliza como en el caso de CMMI. Modela procesos para gestioLa reutilización de software es un proceso donde se recunar, controlar, guiar y monitorear el desarrollo del rre al uso de activos de software en las especificaciones de software. Este modelo se utiliza entonces para meanálisis, diseños, implementación y pruebas de una aplidir lo que una organización o proyecto hace durante cación o sistemas de software.* [8] el desarrollo del software. Esta información se anaLa reutilización tiene ciertos Indicadores por ejemplo: liza para identificar puntos débiles y definir acciones para subsanarlos. También identifica puntos fuertes 1. Entre el 40% y 60% de una aplicación es re-utilizable que pueden adoptarse en el resto de la organización. en otra. 2. Aproximadamente el 60% de una aplicación administrativa es re-utilizable. 3. Aproximadamente el 75% de las funciones son comunes a más de un programa.
156.5 Métodos formales
Los métodos formales son soluciones matemáticas pa4. Solo el 15% del código encontrado en muchos sistemas ra resolver problemas de software y hardware a nivel de es único y novedoso a una aplicación especifica. requisitos, especificación y diseño. Ejemplos de métoEl rango general de uso recurrente esta entre el 15% y dos formales incluyen el Método B, la red de Petri, la demostración automática de teoremas, RAISE y el VDM. 85%.* [9] La reutilización tiene Principios como la existencia de Hay varias notaciones de especificaciones formales, taparecidos en distintos sistemas de un mismo dominio, les como el lenguaje Z. Más generalmente, se puede utidonde el software puede representarse como una com- lizar la teoría de autómatas para aumentar y validar el binación de módulos y los sistemas nuevos se puede ca- comportamiento de la aplicación diseñando un sistema racterizar por diferencias respecto a los antiguos siste- de autómata finito. mas.* [10]
Las metodologías basadas en los autómatas finitos permi-
290
CAPÍTULO 156. PROCESO PARA EL DESARROLLO DE SOFTWARE
ten especificación de software ejecutable y evitar la creación convencional de código.
[7] McConnell, Steve. «7: Lifecycle Planning». Rapid Development. Redmond, Washington: Microsoft Press. p. 140.
Los métodos formales se suelen aplicar en software de aviación, especialmente si es software de seguridad crítico. Los estándares de aseguramiento del software de seguridad, tales como DO178B demandan métodos formales en el nivel más alto de categorización (Nivel A).
[8] J.Sametinger.Software engineering with reusable components. Springer Verlag, Agosto 1997 [9] Jonas A. Montilva, Nelson Arape y Juan Andres Colmenares. (14 de noviembre de2003). «Desarrollo de software basado en componentes». Consultado el 2 de abril de 2014.
La formalización del desarrollo de software está ganando en fuerza poco a poco, en otros ámbitos, con la aplica[10] «Ciclo de vida del Software». Archivado desde el original ción del lenguaje de especificación OCL2.0 (y especialiel 28 de noviembre de 2015. Consultado el 2 de abril de zaciones tales como Java Modeling Language) y particu2014. larmente con Model-driven Architecture, que permite la ejecución de diseños, incluso especificaciones. Otra tendencia que está surgiendo en el desarrollo de software es la redacción de especificaciones en algún tipo de lógica (normalmente una variación de FOL), para acto seguido ejecutar esa lógica como si se tratase de un programa. El lenguaje OWL, basado en lógica descriptiva, es un buen ejemplo. También se está trabajando en enlazar un idioma natural de forma automática con lógica, lógica que puede ejecutarse. Ejemplo en este campo es el Attempto Controlled English, una lógica de negocios de Internet, que no busca controlar el vocabulario o la sintaxis. Una características de los sistemas que apoyan el vínculo bidireccional inglés-lógica y ejecución directa de la lógica es que pueden explicar sus resultados en inglés en un nivel de negocios o científico.
156.6 Véase también • Ingeniería de software • Anexo:Filosofías del desarrollo de software • Scrum • Metodología de desarrollo de software • Desarrollo ágil de software • Programación extrema • Prototipo • Desarrollo de software
156.7 Referencias [1] [2] [https://owned030.blogspot.com/ [3] [4] Ingeniería de software [5] Ingeniería de software [6] ieeecomputersociety.org
156.8 Enlaces externos • No Silver Bullet: Essence and Accidents of Software Engineering", 1986 • Gerhard Fischer,“The Software Technology of the 21st Century: From Software Reuse to Collaborative Software Design”, 2001 • Lydia Ash: The Web Testing Companion: The Insider's Guide to Efficient and Effective Tests, Wiley, May 2, 2003. ISBN 0-471-43021-8 • SaaSSDLC.com ̶Software as a Service Systems Development Life Cycle Project • Software development life cycle (SDLC) [visual image], software development life cycle
Capítulo 157
Programa informático den ejecutar con la ayuda de un intérprete, o pueden ser empotrados directamente en hardware. De acuerdo a sus funciones, los programas informáticos se clasifican en software de sistema y software de aplicación. En las computadoras de 2015, al hecho de ejecutar varios programas de forma simultánea y eficiente, se lo conoce como multitarea.
157.1 Programación La programación de computadoras es el proceso iterativo de escribir o editar código fuente. Dicha edición de código fuente implica probar, analizar y perfeccionar, y, a veces, coordinar con otros programadores, en el caso de un programa desarrollado en conjunto. Una persona que practica esta técnica se le conoce como programador de computadoras, desarrollador de software, o codificaUn programa informático escrito en un estilo orientado a objetos. dor. El proceso, a veces a largo plazo, de programación de computadoras normalmente se lo conoce como desarrollo Un programa informático o programa de computado- de software. El término ingeniería de software se está ra es una secuencia de instrucciones, escritas para rea- convirtiendo en muy popular, ya que esta actividad es vislizar una tarea específica en una computadora.* [1] Es- ta como una disciplina de ingeniería. te dispositivo requiere programas para funcionar, por lo general, ejecutando las instrucciones del programa en un procesador central.* [2] El programa tiene un formato eje- 157.1.1 Paradigmas cutable que la computadora puede utilizar directamente para ejecutar las instrucciones. El mismo programa Los programas de ordenador se pueden clasificar según en su formato de código fuente legible para humanos, el paradigma del lenguaje de programación utilizado padel cual se derivan los programas ejecutables (por ejem- ra producirlos. Dos de los principales paradigmas son plo, compilados), le permite a un programador estudiar y imperativos y declarativos. desarrollar sus algoritmos. Una colección de programas Los programas escritos con un lenguaje imperativo espede computadora y datos relacionados se conoce como cifican un algoritmo utilizando declaraciones, expresiosoftware. nes e informes.* [4] Una declaración asocia un nombre de Generalmente, el código fuente lo escriben profesionales conocidos como programadores de computadora.* [3] Este código se escribe en un lenguaje de programación que sigue uno de los siguientes dos paradigmas: imperativo o declarativo, y que posteriormente puede ser convertido en un archivo ejecutable (usualmente llamado un programa ejecutable o un binario) por un compilador y más tarde ejecutado por una unidad central de procesamiento. Por otra parte, los programas de computadora se pue-
variable a un tipo de datos. Por ejemplo: var x: integer; . Una expresión produce un valor. Por ejemplo: 2 + 2 produce 4. Por último, una declaración puede asignar una expresión a una variable o usar el valor de una variable para alterar las estructuras de control del programa. Por ejemplo: x := 2 + 2; if x = 4 then hacer_algo(); Una crítica de los lenguajes imperativos es el efecto secundario de una sentencia de asignación en una clase de variables llamadas variables no locales.* [5]
291
292
CAPÍTULO 157. PROGRAMA INFORMÁTICO
Los programas escritos en un lenguaje declarativo especifican las propiedades que tienen o que deben cumplirse para la salida. No especifican detalles expresados en términos de flujo de control de la máquina de ejecución pero sí de las relaciones matemáticas entre los objetos declarados y sus propiedades. Los lenguajes funcionales y lógicos son dos amplias categorías de lenguajes declarativos. El principio detrás de los lenguajes funcionales (como Haskell) es el de no permitir efectos secundarios, lo que hace que sea más fácil para razonar sobre los programas como si se tratasen de funciones matemáticas.* [5] El principio detrás de los lenguajes lógicos (como Prolog) es definir el problema a ser resuelto - la meta - y dejar la solución detallada al propio sistema Prolog.* [6] El objetivo se define proporcionando la lista de sub-objetivos. Luego, cada subobjetivo se define más arriba, proporcionando la lista de sus sub-objetivos, etc. Si la ruta de sub-objetivos no encuentra una solución, entonces ese subobjetivo se retrocede y otra vía se intenta sistemáticamente.
representación intermedia eficiente para la ejecución futura. BASIC, Perl y Python son ejemplos de programas de computadora ejecutados inmediatamente. Por otra parte, los programas de computadora de Java se compilan antes de tiempo y se almacena como un código independiente de la máquina llamado bytecode. Entonces, dicho bytecode es ejecutado a petición de un intérprete llamado máquina virtual.
La principal desventaja de los intérpretes es que los programas de computadora corren más lento que cuando son compilados. La interpretación de código resulta más lenta que la ejecución de la versión compilada porque el intérprete debe decodificar cada declaración cada vez que se carga y luego realizar la acción deseada. Sin embargo, el desarrollo de software puede ser más rápido usando un intérprete porque la prueba es inmediata cuando se omite el paso de la compilación. Otra desventaja de los intérpretes es que debe estar presente al menos uno en la computadora durante la ejecución del programa de computadora. Por La forma en que se crea el programa puede ser textual o el contrario, los programas de computadora compilados visual. En un programa de lenguaje visual, los elementos no necesitan compilador presente durante la ejecución. en vez de ser textualmente especificados son manipulados No se requieren propiedades de un lenguaje de progragráficamente. mación si se está compilado exclusivamente o interpre-
157.1.2
Compilado o interpretando
Un programa de computadora bajo la forma de lenguaje de programación de computadoras legible por un humano, se lo llama código fuente. Dicho código fuente se puede convertir en una imagen ejecutable por un compilador o ejecutarse inmediatamente con la ayuda de un intérprete. Cualquiera de los programas compilados o interpretados pueden ser ejecutados en un proceso por lotes sin intervención humana, pero los programas interpretados le permiten al usuario escribir comandos en una sesión interactiva. En este caso, los programas son los comandos separados, cuya ejecución se produce secuencialmente, y por lo tanto simultáneamente. Cuando se utiliza un lenguaje para dar órdenes a una aplicación de software (como un shell de Unix u otra interfaz de línea de comandos), se le llama un lenguaje de scripts.
tándose exclusivamente. Por lo general, la clasificación refleja el método más popular de ejecución del lenguaje. Por ejemplo, BASIC se considera un lenguaje interpretado y C un lenguaje compilado, a pesar de la existencia de compiladores de BASIC e intérpretes de C. Algunos sistemas utilizan compilación en tiempo de ejecución (JIT) mediante la cual las secciones de la fuente se compilan 'sobre la marcha' y se almacenan para ejecuciones posteriores.
157.1.3 Programas que se auto-modifican
Un programa informático en ejecución normalmente es tratado como algo diferente de los datos con los cuales opera. Sin embargo, en algunos casos ésta distinción es ambigua, especialmente cuando un programa se modifica a sí mismo. El programa modificado es ejecutado secuencialmente como parte del mismo programa. En el caso de programas escritos en código máquina, lenguaje ensamLos compiladores se utilizan para traducir el código fuen- blador, Lisp, C, COBOL, PL/1 y Prolog y JavaScript (la te de un lenguaje de programación, ya sea en código ob- función eval), entre otros, es posible tener código que se jeto o código máquina.* [7] El código objeto de objeto auto-modifica. necesita procesamiento adicional para convertirse en código máquina, y el código máquina es el código nativo de la unidad central de procesamiento, listo para su ejecu157.2 Ejecución y almacenamiento ción. Los programas de computadora compilados se conocen comúnmente como ejecutables, imágenes binarias, de los programas o simplemente como binarios ̶una referencia al formato de archivo binario utilizado para almacenar el código eje- Típicamente, los programas se almacenan en una cutable. memoria no volátil (por ejemplo un disco), para que luego Los programas de computadora ̶interpretados en un lo- el usuario de la computadora, directa o indirectamente, te o una sesión interactiva ̶o bien se descodifican y lue- solicite su ejecución. Al momento de dicha solicitud, el go ejecutados inmediatamente o se decodifican en alguna programa es cargado en la memoria de acceso aleatorio
157.2. EJECUCIÓN Y ALMACENAMIENTO DE LOS PROGRAMAS
293
o RAM del equipo, bajo el control del software llamado sistema operativo, el cual puede acceder directamente al procesador. El procesador ejecuta (corre) el programa, instrucción por instrucción hasta que termina. A un programa en ejecución se le suele llamar también proceso. Un programa puede terminar su ejecución en forma normal o por causa de un error, dicho error puede ser de software o de hardware.
157.2.1
Programas empotrados en hardware Interruptores para la carga manual en una Data General Nova 3.
programa, se establecía la dirección de inicio mediante interruptores y se presionaba el botón de ejecución.* [10]
157.2.3 Programas generados automáticamente La programación automática es un estilo de programación que crea código fuente mediante clases genéricas, prototipos, plantillas, aspectos, y generadores de código para aumentar la productiviEl microcontrolador a la derecha de la Memoria USB está con- dad del programador. El código fuente se genera con herramientas de programación tal como un procesador trolada por un firmware empotrado. de plantilla o un IDE. La forma más simple de un Algunos programas están empotrados en el hardware. generador de código fuente es un procesador macro, tal Una computadora con arquitectura de programas alma- como el preprocesador de C, que reemplaza patrones de cenados requiere un programa inicial almacenado en su código fuente de acuerdo a reglas relativamente simples. ROM para arrancar. El proceso de arranque es para iden- Un motor de software da de salida código fuente o tificar e inicializar todos los aspectos del sistema, desde lenguaje de marcado que simultáneamente se vuelve los registros del procesador, controladores de dispositi- la entrada de otro proceso informático. Podemos penvos hasta el contenido de la memoria RAM.* [8] Seguido sar como analogía un proceso manejando a otro siendel proceso de inicialización, este programa inicial carga do el código máquina quemado como combustible. Los al sistema operativo e inicializa al contador de programa servidores de aplicaciones son motores de software que para empezar las operaciones normales. Independiente de entregan aplicaciones a computadoras cliente. Por ejemla computadora, un dispositivo de hardware podría tener plo, un software para wikis es un sevidor de aplicaciofirmware empotrado para el control de sus operaciones. nes que permite a los usuarios desarrollar contenido diEl firmware se utiliza cuando se espera que el programa námico ensamblado a partir de artículos. Las Wikis gecambie en raras ocasiones o nunca, o cuando el programa neran HTML, CSS, Java, y Javascript los cuales son no debe perderse cuando haya ausencia de energía.* [9] interpretados por un navegador web.
157.2.2
Programas cargados manualmen- 157.2.4 Ejecución simultánea te
Históricamente, los programas eran cargados al procesador central de forma manual mediante interruptores. Una instrucción se representaba por una configuración de estados de interruptores de abierto o cerrados. Después de establecer la configuración, se ejecutaba un botón de ejecución. Este proceso era repetitivo. Asimismo, los programas se cargaban manualmente mediante una cinta de papel o tarjetas perforadas. Después de que se cargaba el
Muchos programas pueden ejecutarse simultáneamente en la misma computadora, hecho al cual se lo conoce como multitarea, pudiéndose lograr mediante mecanismos de software o de hardware. Los sistemas operativos modernos pueden ejecutar varios programas a través del planificador de procesos ̶un mecanismo de software para conmutar con frecuencia la cantidad de procesos del procesador de modo que los usuarios puedan interactuar con cada programa mientras estos están corriendo.* [11]
294 También se puede lograr la multitarea por medio del hardware; las computadoras modernas que usan varios procesadores o procesadores con varios núcleos pueden correr muchos programas a la vez.* [12]
157.3 Categorías funcionales
CAPÍTULO 157. PROGRAMA INFORMÁTICO
[4] Wilson, Leslie B. (1993). Comparative Programming Languages, Second Edition (en inglés). Addison-Wesley. p. 75. ISBN 0-201-56885-3. [5] Wilson, Leslie B. (1993). Comparative Programming Languages, Second Edition (en inglés). Addison-Wesley. p. 213. ISBN 0-201-56885-3. [6] Wilson, Leslie B. (1993). Comparative Programming Languages, Second Edition (en inglés). Addison-Wesley. p. 244. ISBN 0-201-56885-3.
Los programas se pueden categorizar aplicando criterios funcionales. Estas categorías funcionales son software de sistema y software de aplicación. El software de sistema [7] «What is a Compiler?» (en inglés). Consultado el 10 de incluye al sistema operativo el cual acopla el hardware enero de 2012. con el software de aplicación.* [13] El propósito del sistema operativo es proveer un ambiente en el cual el softwa- [8] Silberschatz, Abraham (1994). Operating System Concepts, Fourth Edition (en inglés). Addison-Wesley. p. 30. re de aplicación se ejecuta de una manera conveniente y * ISBN 0-201-50480-4. eficiente. [13] Además del sistema operativo, el software de sistema incluye programas utilitarios que ayudan a [9] Tanenbaum, Andrew S. (1990). Structured Computer Ormanejar y configurar la computadora. Si un programa no ganization, Third Edition. Prentice Hall. p. 11. ISBN 0es software de sistema entonces es software de aplicación. 13-854662-2. (en inglés). El middleware también es un software de aplicación que acopla el software de sistema con la interfaz de usuario. [10] Silberschatz, Abraham (1994). Operating System ConTambién son software de aplicación los programas utilicepts, Fourth Edition (en inglés). Addison-Wesley. p. 6. tarios que ayudan a los usuarios a resolver problemas de ISBN 0-201-50480-4. aplicaciones, como por ejemplo la necesidad de ordena[11] Silberschatz, Abraham (1994). Operating System Conmiento. cepts, Fourth Edition (en inglés). Addison-Wesley. p. 100. ISBN 0-201-50480-4.
157.4 Véase también • Algoritmo para la relación entre los programas informáticos y algoritmos • Aplicación informática • Archivo cabra para un tipo específico de programa informático utilizado solo para liberar y estudiar los efectos de virus informáticos en los sistemas físicos y virtuales • Estructura de datos • Inteligencia artificial • Sistema multi-agente • Software
157.5 Referencias [1] Stair, Ralph M., et al. (2003). Principles of Information Systems, Sixth Edition (en inglés). Thomson Learning, Inc. p. 132. ISBN 0-619-06489-7. [2] Silberschatz, Abraham (1994). Operating System Concepts, Fourth Edition (en inglés). Addison-Wesley. p. 58. ISBN 0-201-50480-4. [3] «Algorithms and Computer Programming» (en inglés). Consultado el 8 de setiembre de 2014.
[12] Akhter, Shameem (2006). Multi-Core Programming (en inglés). Richard Bowles (Intel Press). pp. 11–13. ISBN 09764832-4-6.. [13] Silberschatz, Abraham (1994). Operating System Concepts, Fourth Edition (en inglés). Addison-Wesley. p. 1. ISBN 0-201-50480-4.
157.6 Bibliografía • Knuth, Donald E. (1997). The Art of Computer Programming, Volume 1, 3rd Edition (en inglés). Boston: Addison-Wesley. ISBN 0-201-89683-4. • Knuth, Donald E. (1997). The Art of Computer Programming, Volume 2, 3rd Edition (en inglés). Boston: Addison-Wesley. ISBN 0-201-89684-2. • Knuth, Donald E. (1997). The Art of Computer Programming, Volume 3, 3rd Edition (en inglés). Boston: Addison-Wesley. ISBN 0-201-89685-0.
157.7 Enlaces externos • Definición de“Programa”en Webopedia (en inglés) • Definición de “Computer Program” en dictionary.com (en inglés)
157.7. ENLACES EXTERNOS • Esta obra deriva de la traducción total de Computer program de Wikipedia en inglés, concretamente de esta versión, publicada por sus editores bajo la Licencia de documentación libre de GNU y la Licencia Creative Commons AtribuciónCompartirIgual 3.0 Unported.
295
Capítulo 158
Programa interactivo Un programa interactivo aquél que necesita la realimentación continúa del usuario para poder ejecutarse. Este concepto se enfrenta al de procesamiento por lotes en el cual se le indica al programa todo lo que debe hacer antes de empezar, con lo cual el usuario se puede desentender de la máquina. Sin embargo esto último requiere mayor planificación.
158.1 Frente a Procesamiento por lotes 158.1.1
Ventajas
• No es necesario conocer todas las opciones, ya que las distintas interfaces gráficas irán preguntando todo. Luego es adecuado para tareas que no se van a ejecutar muy a menudo y no merece la pena perder mucho tiempo en aprenderlas.
158.1.2
Inconvenientes
• Requieren una mayor velocidad, ya que hay que evitar el cansancio del usuario. • Obliga a hacer tareas repetitivas al usuario.
158.2 Ejemplos 158.2.1
Cajero automático
• Un sistema de menú guía al usuario para conseguir distintos propósitos: Cargar el móvil, sacar dinero, transferencia...
158.2.2
Compresor de archivos
• Se le dirá al programa qué debe comprimir, cuál es el archivo de salida, tasa de compresión y algunos parámetros extra. 296
• Como programa interactivo, se irán solicitando al usuario los distintos parámetros en distintos menús.
Capítulo 159
Programación lineal paramétrica Programación lineal paramétrica, el análisis de sensibilidad requiere el cambio de un parámetro a la vez en el modelo original para examinar su efecto sobre la solución óptima. Por el contrario, la programación lineal paramétrica (o programación paramétrica en forma más corta) se refiere al estudio sistemático de los cambios en la solución óptima cuando cambia el valor de muchos parámetros al mismo tiempo, dentro de un intervalo. Este estudio proporciona una extensión muy útil al análisis de sensibilidad; por ejemplo, se puede verificar el efecto de cambios simultáneos en parámetros“correlacionados”, causados por factores exógenos tales como el estado de la economía. sin embargo, una aplicación más importante es la investigación de los trueques entre los valores de los parámetros. por ejemplo, si los valores de cj representan la ganancia unitaria de las actividades respectivas, es posible aumentar el valor de alguna cj a costa de disminuir el de otras mediante un intercambio apropiado de personal y equipo entre las actividades. De manera parecida, si los valores de bi representan las cantidades disponibles de los respectivos recursos, es imposible aumentar alguna bi si se está de acuerdo en disminuir algunas otras. En algunos casos, el propósito del estudio es determinar el trueque más apropiado entre dos factores básicos como costos y beneficios. la forma usual de hacerlo es expresar uno de estos factores en funciónobjetivo (como minimizar el costo total) e incorporar el otro a las restricciones (por ejemplo, beneficio >= nivel mínimo aceptable). La técnica algorítmica para programación lineal paramétrica es una extensión natural del análisis de sensibilidad, por lo que también está basada en el método simplex.
159.1 Referencias • HILLER - LIEBERMAN. INVESTIGACIÓN DE OPERACIONES. Mc Graw Hill Interamericana Editores S.A. OCLC 16822487. Texto « edición: Séptima » ignorado (ayuda)
297
Capítulo 160
Programación visual La programación visual brinda los conocimientos nece- la programación orientada a objetos y permiten aprovesarios para diseñar y desarrollar aplicaciones con un en- char al máximo toda la funcionalidad que ofrecen estos torno visual amigable y fácil de utilizar para el usuario. lenguajes para el desarrollo de aplicaciones de gestión. Los lenguajes de programación visual tienden a facilitar la tarea de los programadores, dado que con los primeros lenguajes de programación crear una ventana era tarea de meses de desarrollo y de un equipo de trabajo.
160.2 Véase también • Diagrama de flujo
160.1 Programación orientada a objetos • Define los programas en términos de "clases de objetos”, objetos que son entidades que combinan estado (es decir, datos), comportamiento (esto es, procedimientos o métodos) e identidad (propiedad del objeto que lo diferencia del resto). La programación orientada a objetos expresa un programa como un conjunto de estos objetos, que colaboran entre ellos para realizar tareas. • La técnica de programación orientada a objetos, se basa en fundamentos de diseño, técnicas y metodologías unificadas (UML). • Lenguajes visuales como Visual Basic.Net, Borland Delphi, incorporan una completa implementación de la programación orientada a objetos y permiten aprovechar al máximo toda la funcionalidad que ofrecen estos lenguajes para el desarrollo de aplicaciones de gestión. Define los programas en términos de “clases de objetos”, objetos que son entidades que combinan estado (es decir, datos), comportamiento (esto es, procedimientos o métodos) e identidad (propiedad del objeto que lo diferencia del resto). La programación orientada a objetos expresa un programa como un conjunto de estos objetos, que colaboran entre ellos para realizar tareas. La técnica de programación orientada a objetos, se basa en fundamentos de diseño, técnicas y metodologías unificadas (UML). Lenguajes visuales como Visual Basic.Net, Borland Delphi, incorporan una completa implementación de 298
• Gambas lenguaje de programación visual libre derivado de Basic • Lenguaje Unificado de Modelado • snapp es un sistema de programación visual derivado de Google Blockly • VisSim es un lenguaje de programación visual.
Capítulo 161
Programador Un programador o una programadora es aquella persona que escribe, depura y mantiene el código fuente de un programa informático, es decir, el conjunto de instrucciones que ejecuta el hardware de una computadora, para realizar una tarea determinada. Un programador o programadora, es la persona que elabora programas de computadora.* [1] Los programadores también son denominados desarrolladores de software, aunque estrictamente forman parte de un equipo de personas de distintas especialidades (mayormente informáticas), y siendo que el equipo es propiamente el desarrollador. La programación es una de las principales disciplinas dentro de la informática. En muchos países, el/la programador/a es también una categoría profesional reconocida.
161.1 Reseña histórica Ada Lovelace, hija del prestigioso poeta Lord Byron, es considerada la primera programadora de la historia. Su Retrato de Ada Lovelace. contribución más notable consistió en elaborar un método para calcular los números de Bernoulli en la máquina blema y describirlo con el propósito de ser solucioanalítica de Charles Babbage. En homenaje a Ada Lovenado mediante un sistema de información. lace, fue puesto el nombre al lenguaje de programación • El programador, cuya única función consistía en Ada. trasladar las especificaciones del analista en código ejecutable para la computadora. Dichas especificaciones se recogen en un documento denominado 161.2 Funciones del programador cuaderno de carga, medio de comunicación entre ambos. El programador se encarga de la implementación de prototipos mediante un lenguaje de programación, que Hoy día se reconoce que este enfoque no es válido para compilados pueda entender la computadora. organizar tareas de tipo intelectual, como es el desarroInicialmente, la profesión se formalizó desde el enfoque llo de software. De manera que la profesión de progratayloriano de la especialización de funciones en la em- mador ha ido evolucionando. Las dificultades de comupresa. Así, el proceso de producción de software se con- nicación entre analistas y programadores (un mero docucibe como un conjunto de tareas altamente especializadas mento no basta para describir lo que se quiere hacer) dio donde está claramente definido el papel de cada categoría origen a una categoría de profesional intermedia, denoprofesional: minada analista-programador. La concepción original del programador ha desaparecido siendo sustituida por la • El analista, tiene como cometido analizar un pro- de un profesional mucho más formado y con unas funcio299
300 nes menos “mecánicas”. La profesión de analista también ha evolucionado, surgiendo el concepto diseñador (de software). Esto se debe a los avances de la ingeniería del software donde se reconoce que el análisis es una actividad compleja y distinta del diseño. Escuetamente, el análisis describe el problema (es decir, “qué”hacer) mientras que el diseño describe la solución (“cómo”hacerlo). En la mayoría de países industrializados esto ha dado lugar a la categoría diseñador o arquitecto del software.
CAPÍTULO 161. PROGRAMADOR
161.4 Notas y referencias [1] Real Academia Española (2014), «programador», Diccionario de la lengua española (23.ª edición), Madrid: Espasa, http://dle.rae.es/?w=programador&o=h
161.5 Véase también • Ambiente de desarrollo integrado • Código fuente
161.3 Especialidades Estrictamente hablando, la profesión de programador si conoce especialidades. No obstante, existen diversas ramas por las que se decantan los propios profesionales y que se ven reflejadas en la oferta de empleo. Así, es posible mencionar algunas: • Programadores de mainframe: aunque se cree extinta la actividad en los viejos grandes sistemas informáticos, lo cierto es que aún existen muchos en funcionamiento que requieren mantenimiento. La tecnología que manejan estos programadores es radicalmente distinta a la del resto, motivo por el que se puede considerar esta como la rama más especializada. Entre sus conocimientos se cuenta COBOL, RPG, JCL, base de datos jerárquicas, etc. • Programadores de“nuevas tecnologías": esta es una rama que gira en torno a Internet, los nuevos servicios como la Web 2.0 y los negocios por medios electrónicos o e-commerce. Entre sus conocimientos destacan lenguajes del lado del servidor como Java, ASP, .NET, JSP, PHP, Ruby, Python o Perl, y lenguajes del lado de cliente como HTML, XHTML, CSS, Javascript ó AJAX (conjunto de tecnologías existentes como XML y Javascript). • Programadores de firmware y videojuegos, o desarrollador de videojuegos: destacan sus conocimientos de hardware, microprocesadores, ensamblador y C. • Programadores de “sistemas abiertos": rama asociada a la Arquitectura Cliente-Servidor. Requiere conocimientos de lenguaje de programación C, lenguaje de programación Pascal, etc. • Programadores de sistemas de control y adquisición de datos: además de conocimientos de hardware, microprocesadores, ensamblador y algunos otros lenguajes, requieren formación específica de física e ingeniería de control.
• Ingeniería del software • Interfaz de programación de aplicaciones • Lenguaje de programación • Programación • Software
Capítulo 162
Pseudocódigo En ciencias de la computación, y análisis numérico, el pseudocódigo (o falso lenguaje) es una descripción de alto nivel compacta e informal* [1] del principio operativo de un programa informático u otro algoritmo.
introducción y que explica las convenciones particulares en uso. El nivel de detalle del pseudocódigo puede, en algunos casos, acercarse a la de formalizar los idiomas de propósito general.
Utiliza las convenciones estructurales de un lenguaje de programación real,* [2] pero está diseñado para la lectura humana en lugar de la lectura mediante máquina, y con independencia de cualquier otro lenguaje de programación. Normalmente, el pseudocódigo omite detalles que no son esenciales para la comprensión humana del algoritmo, tales como declaraciones de variables, código específico del sistema y algunas subrutinas. El lenguaje de programación se complementa, donde sea conveniente, con descripciones detalladas en lenguaje natural, o con notación matemática compacta. Se utiliza pseudocódigo pues este es más fácil de entender para las personas que el código del lenguaje de programación convencional, ya que es una descripción eficiente y con un entorno independiente de los principios fundamentales de un algoritmo. Se utiliza comúnmente en los libros de texto y publicaciones científicas que se documentan varios algoritmos, y también en la planificación del desarrollo de programas informáticos, para esbozar la estructura del programa antes de realizar la efectiva codificación.
Un programador que tiene que aplicar un algoritmo específico, sobre todo uno desfamiliarizado, generalmente comienza con una descripción en pseudocódigo, y luego “traduce”esa descripción en el lenguaje de programación meta y lo modifica para que interactúe correctamente con el resto del programa. Los programadores también pueden iniciar un proyecto describiendo la forma del código en pseudocódigo en el papel antes de escribirlo en su lenguaje de programación, como ocurre en la estructuración de un enfoque de Top-down y Bottom-up arriba hacia abajo.
No existe una sintaxis estándar para el pseudocódigo, aunque los ocho IDE's que manejan pseudocódigo tengan su sintaxis propia. Aunque sea parecido, el pseudocódigo no debe confundirse con los programas esqueleto que incluyen código ficticio, que pueden ser compilados sin errores. Los diagramas de flujo y UML pueden ser considerados como una alternativa gráfica al pseudocódigo, aunque sean más amplios en papel.
162.1 Aplicaciones Generalmente se utiliza pseudocódigo en los libros de texto y publicaciones científicas relacionadas con la informática y la computación numérica, para la descripción de algoritmos, de manera que todos los programadores puedan entenderlo, aunque no todos conozcan el mismo lenguaje de programación. Generalmente, en los libros de texto se adjunta una explicación que acompaña a la
162.2 Sintaxis En la actualidad y por lo general, el pseudocódigo, como su nombre lo indica, no obedece a las reglas de sintaxis de ningún idioma en particular ni es de forma estándar sistemática, a pesar de que cualquier escritor en particular vaya a pedir prestado las estructuras de control general, la sintaxis y el estilo, por ejemplo, de algún lenguaje de programación convencional. Pero en caso de que se quiera ejecutar, se debe llevar a forma tipo, para que no genere mensajes de error. Las fuentes populares incluyen la sintaxis de Pascal, BASIC, C, C++, Java, Lisp, y ALGOL. Por lo general, se omiten las declaraciones de variables. A veces, las llamadas a funciones, los bloques de código y el código contenido dentro de un loop se remplazan por una sentencia de una línea en lenguaje natural. Dependiendo del escritor, el pseudocódigo puede variar mucho en su estilo, yendo desde en un extremo, una imitación casi exacta de un lenguaje de programación real, hasta al acercarse a una descripción en prosa de formato de pseudocódigo en el otro extremo. Este es un ejemplo de pseudocódigo (para el juego matemático bizz buzz):
301
302
CAPÍTULO 162. PSEUDOCÓDIGO
162.3 Definición de datos del pseudocódigo La definición de datos se da por supuesta, sobre todo en las variables sencillas, si se emplea formaciones: pilas, colas, vectores o registros, se pueden definir en la cabecera del algoritmo, y naturalmente cuando empleemos el pseudocódigo para definir estructuras de datos, esta parte la desarrollaremos adecuadamente.
162.4 Funciones y operaciones Cada autor usa su propio pseudocódigo con sus respectivas convenciones. Por ejemplo, la instrucción“reemplace el valor de la variable x por el valor de la variable y " puede ser representado como: • asigne a x el valor de y Diagrama de flujo que muestra el funcionamiento de la instruc-
Las operaciones aritméticas se representan de la forma ción condicional. usual en matemáticas.
162.5 Estructuras de control En la redacción del pseudocódigo se utiliza tres tipos de estructuras de control: las secuenciales, las selectivas y las iterativas.
162.5.1
Estructuras secuenciales
Las instrucciones se siguen en una secuencia fija que normalmente viene dada por el número de renglón. Es decir que las instrucciones se ejecutan de arriba hacia abajo.
162.5.2
Estructuras selectivas
Las instrucciones selectivas representan instrucciones que pueden o no ejecutarse, según el cumplimiento de una condición. La condición es una expresión booleana. Instrucciones es Diagrama de flujo que muestra el funcionamiento de la instrucejecutada sólo si la condición es verdadera. ción condicional. Selectiva doble (alternativa)
Selectiva múltiple
La instrucción alternativa realiza una instrucción de dos También es común el uso de una selección múltiple que posibles, según el cumplimiento de una condición. equivaldría a anidar varias funciones de selección. La condición es una variable booleana o una función reducible a booleana (lógica, Verdadero/Falso). Si esta condición es cierta se ejecuta Instrucciones1 , si no es así, entonces se ejecuta Instrucciones2 .
En este caso hay una serie de condiciones que tienen que ser mutuamente excluyentes, si una de ellas se cumple las demás tienen que ser falsas necesariamente, hay un caso si no que será cierto cuando las demás condiciones sean
162.6. DESARROLLO DE ALGORITMOS falsas.
303 Bucle hacer
En esta estructura si Condición1 es cierta, entonces se ejecuta sólo Instrucciones1 . En general, si Condiciónᵢ es ver- El Bucle hacer se utiliza para repetir un bloque de código mientras se cumpla cierta condición. dadera, entonces sólo se ejecuta Instruccionesᵢ Selectiva múltiple-Casos
Bucle para
Una construcción similar a la anterior (equivalente en al- Una estructura de control muy común es el ciclo para, la cual se usa cuando se desea iterar un número conocigunos casos) es la que se muestra a continuación. do de veces, empleando como índice una variable que se En este caso hay un Indicador es una variable o una funincrementa (o decrementa): Plantilla:Definiciones ción cuyo valor es comparado en cada caso con los valores "Valorᵢ", si en algún caso coinciden ambos valores, la cual se define como: entonces se ejecutarán las Instruccionesᵢ correspondientes. La sección en otro caso es análoga a la sección si no Bucle para cada del ejemplo anterior. Por último, también es común usar la estructura de control para cada. Esta sentencia se usa cuando se tiene una lista o un conjunto L y se quiere iterar por cada uno de Las instrucciones iterativas representan la ejecución de sus elementos: instrucciones en más de una vez. Si asumimos que los elementos de L son L0 , L1 , . . . , Ln , entonces esta sentencia equivaldría a: Bucle mientras Que es lo mismo que:
162.5.3
Estructuras iterativas
El bucle se repite mientras la condición sea cierta, si al Sin embargo, en la práctica existen mejores formas de llegar por primera vez al bucle mientras la condición es implementar esta instrucción dependiendo del problema. falsa, el cuerpo del bucle no se ejecuta ninguna vez. Es importante recalcar que el pseudocódigo no es un lenguaje estandarizado. Eso significa que diferentes autores podrían dar otras estructuras de control o bien usar estas mismas estructuras, pero con una notación diferente. Sin embargo, las funciones matemáticas y lógicas toman el significado usual que tienen en matemática y lógica, con las mismas expresiones.
162.5.4 El anidamiento Cualquier instrucción puede ser sustituida por una estructura de control. El siguiente ejemplo muestra el pseudocódigo del ordenamiento de burbuja, que tiene varias estructuras anidadas. Este algoritmo ordena de menor a mayor los elementos de una lista L .
Diagrama de flujo que muestra el funcionamiento de la instrucción mientras
Bucle repetir
En general, las estructuras anidadas se muestran indentadas, para hacer más sencilla su identificación a simple vista. En el ejemplo, además de la indentación, se ha conectado con flechas los pares de delimitadores de cada nivel de anidamiento.
162.6 Desarrollo de algoritmos
Existen otras variantes que se derivan a partir de la anterior. La estructura de control repetir se utiliza cuando Con este pseudocódigo se puede desarrollar cualquier ales necesario que el cuerpo del bucle se ejecuten al menos goritmo que: una vez y hasta que se cumpla la condición: La estructura anterior equivaldría a escribir:
• Tenga un único punto de inicio.
304 • Tenga un número finito de posibles puntos de término. • Haya un número finito de caminos, entre el punto de inicio y los posibles puntos de término.
CAPÍTULO 162. PSEUDOCÓDIGO
162.9 Enlaces externos • Pseudocódigo - Diagramas de flujo, programación básica • Sintaxis del pseudocódigo CEE (C en español)
162.7 Funciones y procedimientos
• Foro Programación, tutoriales y ejemplos • PSEINT - PIPEH pseudointérprete
Muchas personas prefieren distinguir entre funciones y procedimientos. Una función, al igual que una función matemática, recibe uno o varios valores de entrada y regresa una salida mientras que un procedimiento recibe una entrada y no genera ninguna salida aunque en algún caso podría devolver resultados a través de sus parámetros de entrada si estos se han declarado por referencia (ver formas de pasar argumentos a una función o procedimiento). En ambos casos es necesario dejar en claro cuáles son las entradas para el algoritmo, esto se hace comúnmente colocando estos valores entre paréntesis al principio o bien declarándolo explícitamente con un enunciado. En el caso de las funciones, es necesario colocar una palabra como regresar o devolver para indicar cuál es la salida generada por el algoritmo. Por ejemplo, el pseudocódigo de una función que permite calcular an (un número a elevado a potencia n ). Un ejemplo de procedimiento seria el algoritmo de Ordenamiento de burbuja, por el que partiendo de una lista de valores estos se ordenan, nótese que en un procedimiento, no se calcula el valor de una función, sino que se realiza una acción, en este caso ordenar la lista.
162.8 Ventajas del pseudocódigo sobre los diagramas de flujo Los pseudocódigos presentan los siguientes beneficios: 1. Ocupan mucho menos espacio en el desarrollo del problema. 2. Permite representar de forma fácil operaciones repetitivas complejas. 3. Es más sencilla la tarea de pasar de pseudocódigo a un lenguaje de programación formal. 4. Si se siguen las reglas de identación se puede observar claramente los niveles en la estructura del programa. 5. En los procesos de aprendizaje de los alumnos de programación, éstos están más cerca del paso siguiente (codificación en un lenguaje determinado, que los que se inician en esto con la modalidad Diagramas de Flujo). 6. Mejora la claridad de la solución de un problema.
• Ejercicios de programación en peseudocódigo • Intérprete de algoritmos en español
162.10 Referencias [1] «Pseudocódigo - Estructuras condicionales». Consultado el 7 de diciembre de 2012. [2] «Instroducción al PseudoCódigo». Consultado el 7 de diciembre de 2012.
162.11 Bibliografía 1. Peña Marí, Ricardo (2005). Diseño de programas: formalismo y abstracción (3 edición). Pearson Alhambra. p. 488. ISBN 978-84-205-4191-4. 2. Pseudocódigos y programación estructurada (1 edición). Centro Técnico Europeo de Enseñanzas Profesionales. 2 de 1997. ISBN 978-84-8199-065-2. 3. Brassard, Gilles; Bratley, Paul (1996). Algorítmica: concepción y análisis. Peña Mari, Ricardo Tr. (1 edición). Masson, S.A. p. 384. ISBN 978-84-458-0535-0. 4. Rodeira, ed. (6 de 1994). Pseudocódigos e programación estructurada (en gallego) (1 edición). ISBN 978-84-8116-287-5. 5. Edebé, ed. (8 de 1993). Pseudocódigos y programación estructurada (1 edición). ISBN 978-84-236-31261.
162.12 Véase también
Capítulo 163
Puente de aplicación En informática, un puente de aplicación o application bridge es el código que conecta diferentes entornos de un lenguaje con otros lenguajes. Los puentes, delimitan el tráfico entre redes a las redes que tiene acceso directo y deben preservar las características de las LANs que interconectan (retardo de transmisión, capacidad de transmisión, probabilidad de pérdida, etc.). La conexión es utilizada exclusivamente para transmitir llamadas a métodos con sus propios parámetros y retornar los valores de un entorno de lenguaje a otro. Por ejemplo, se necesita un puente para acceder desde Delphi a la API de OpenOffice.org.
305
Capítulo 164
Puntero inteligente En programación, un puntero inteligente (o smart pointer) es un tipo abstracto de datos que simula el comportamiento de un puntero corriente pero añadiendo nuevas características adicionales, como recolector de basura automático y comprobador de límites. Estas características adicionales tienen como objetivo reducir errores causados por el mal uso de punteros, manteniendo la eficiencia. Los punteros inteligentes suelen llevar un registro de los objetos a los que apunta con el próposito de gestionar la memoria.
auto_ptr funcion_obvia1(); La función hace explícitamente que el“llamador”tenga la propiedad del resultado y, además, si no se hace nada, no se filtrará memoria. Del mismo modo, si la intención es devolver un puntero a un objeto gestionado en otros lugares, la función podría devolver una referencia: algun_tipo& funcion_obvia2();
El mal uso de los punteros suele ser la mayor fuente de errores: asignaciones constantes, liberación de memoria inteligentes en y la referencia, que debe ser realizada por un progra- 164.1 Punteros ma usando punteros, introduce el riesgo de pérdidas de Boost memoria. Los punteros inteligentes intentan prevenir las pérdidas de memoria, liberando automáticamente los re- La biblioteca Boost de C++ nos ofrece varios tipos de cursos: cuando un puntero (o el último de una serie de punteros inteligentes, los más importantes son: punteros) a un objeto es destruido, porque por ejemplo se sale del ámbito, el objeto apuntado también se elimi• Scoped Pointer: Puntero no copiable na. • Shared Pointer: Puntero copiable Existen varios tipos de punteros inteligentes. Algunos trabajan llevando la cuenta de referencias, otros mediante asignación de un objeto a un único puntero. Si el lengua- 164.1.1 Scoped pointer je soporta recolector de basura automático (por ejemplo, Java), el uso de los punteros inteligentes es innecesario. Un scoped pointer es una clase de puntero inteligente que En C++, los punteros inteligentes pueden ser implementados como una“template class”que imita, mediante sobrecarga de operadores, el comportamiento de los punteros tradicionales, pero proporcionando algoritmos de administación de memoria. Los punteros inteligentes pueden facilitar la programación internacional expresando el uso de un puntero en su propio tipo. Por ejemplo, si una función de C++ devuelve un puntero, no hay forma de saber cuando se debe liberar la memoria, cuando se ha terminado con el uso de la información.
no puede copiarse, por lo que solo puede existir un punto de acceso al objeto que apunta. Cuando el puntero sale del ámbito, el objeto se destruye y la memoria se libera. Sintaxis: boost::scoped_ptr MiPuntero (new MiClase(1)); MiPuntero.reset(new MiClase(2)); Se puede acceder al contenido usando el operador *, acceder a la dirección con & y acceder al puntero en bruto con el metodo get().
algun_tipo* function_ambigua(); // ¿Qué se debería Ejemplo: hacer con el resultado? #include using namespace std; #include /* Vamos a crear una clase Tradicionalmente, esto se habría resuelto con comenta- que informe de cuándo se crea y cuando se destruye, rios, pero esto puede ser propenso a errores. Devolviendo y lleve un contador de elementos creados. */ class Elemento { static int counter; int n; public: Elemenun auto_pr de C++: to():n(++counter){ cout << "* Creando Elemento " << 306
164.2. ENLACES EXTERNOS n << endl; }; void lanzar(const char * msg){ cout << "* Elemento " << n << " says: " << msg << endl; }; virtual ~Elemento(){ cout << "* So Long, Elemento " << n << endl; }; }; int Elemento::counter = 0; int main(int argc, char *argv[]) { /* Utilizamos corchetes para abrir un nuevo entorno (scope) Vemos que al terminar el scope, el scoped pointer se libera automáticamente, mientras que en el caso del puntero clásico, si no liberamos manulmente se produciría una fuga de memoria. */ cout <<“Inicio del scope”<< endl; { boost::scoped_ptr miElemento(new Elemento()); miElemento -> lanzar( “Mensaje desde myFun_1”); Elemento * classicPointer = new Elemento(); classicPointer -> lanzar ( “Mensaje del elemento con puntero clásico”); delete classicPointer; // Necesario borrarlo manualmente! } cout << “Fin del scope”<< endl; /* Si tenemos un scoped pointer como atributo de una clase, o como variable suelta, es posible asignarle un valor utilizando el método reset, que borrará lo que estuviera contenido en el puntero previamente. */ boost::scoped_ptr ptrCadena; ptrCadena.reset(new string(“Hola”)); /* Los operadores habituales se conservan. En el caso del *, se devuelve una referencia &. Para acceder al puntero en bruto se utiliza el método get(), aunque NO SE RECOMIENDA, ya que hacer modificaciones o borrar el objeto apuntado a través de get() puede producir errores. */ cout << “Longitud de cadena: " << ptrCadena -> length() << endl; cout << *ptrCadena << endl; return 0; }
307 boost::shared_ptr fan; Mirador(){ cout << tab() << "+ Creando Mirador”<< endl; } ~Mirador(){ cout << tab() << "- Borrando Mirador”<< endl; } }; /* La función popular rellena el atributo del Mirador con un shared pointer a Observado. */ void popular(Mirador & m1, Mirador & m2){ boost::shared_ptr O(new Observado); m1.fan = O; m2.fan = O; } int main(int argc, char *argv[]) { tabulados = 0; cout << "-- Inicio”<< endl; { tabulados ++; cout << tab() << "-- Inicio del primer scope”<< endl; Mirador M1; { tabulados ++; cout << tab() << "-- Inicio del segundo scope”<< endl; Mirador M2; popular(M1, M2); cout << tab() << "-- Fin del segundo scope”<< endl; } tabulados --; cout << tab() << "-- Final del primer scope”<< endl; } tabulados--; cout << "-- Fin”<< endl; return 0; }
164.2 Enlaces externos • Capítulo de muestra "Smart Pointers" del libro Modern C++ Design: Generic Programming and Design Patterns Applied por Andrei Alexandrescu, Addison-Wesley, 2001. • Código de ejemplo "countptr.hpp" del libro The C++ Standard Library - A Tutorial and Reference por Nicolai M. Josuttis • Artículo "Smart Pointers in Boost"
164.1.2
Shared pointer
Un shared pointer es un tipo de puntero inteligente que guarda un contador de referencias al objeto al que apunta. Cada vez que se hace una copia del puntero, se aumenta el contador. Cuando se destruye uno de los shared pointer, el contador disminuye. Cuando el contador llega a cero, quiere decir que no hay más punteros apuntando al objeto, por lo que este puede destruirse y liberar la memoria que ocupa. Todo esto se hace de forma transparente al usuario. Sintaxis: boost::shared_ptr MiPuntero (new MiClase(1)); boost::shared_ptr OtroPuntero = MiPuntero; MiPuntero.reset(new MiClase(2)); Ejemplo: #include #include using namespace std; int tabulados; #include /* Tenemos dos clases. La clase Mirador tiene un shared pointer a Observado. */ string tab(){ return string(tabulados, '\t'); } struct Observado{ Observado(){ cout << tab() << "+ Creando Observado” << endl; } ~Observado(){ cout << tab() << "- Borrando Observado”<< endl; } }; struct Mirador{
• Artículo "The New C++: Smart(er) Pointers" por Herb Sutter • "Smart Pointers - What, Why, Which?" por Yonat Sharon • "Smart Pointers Overview" por John M. Dlugosz • YASPER library otra implementación de punteros inteligentes en C++ • Smart Pointers en Delphi
Capítulo 165
Pure data construcción para programas escritos en el software. Esto hace el programa arbitrariamente extensible a través de una API pública, y alienta a los desarrolladores a añadir sus propias rutinas de audio y control, ya sea en el lenguaje de programación C o, con la ayuda de otros externos, en Python, Javascript, Ruby, y potencialmente otros lenguajes también. Sin embargo, Pd es un lenguaje de programación en sí mismo. Unidades de código modulares y reusables, escritas nativamente en Pd, llamadas “parches”o “abstracciones”, son usadas como programas independientes y compartidas libremente entre la comunidad de usuarios de Pd, y ninguna otra habilidad de programación es requerida para usar Pd pero ayuda. Con la adición del externo“Entorno Gráfico para Multimedia”(GEM, por su nombre en inglés), y otros externos diseñados para trabajar con él (como Pure Data Packet, PiDiP para Linux, framestein para Windows, GridFlow Captura de pantalla de Pure Data. para proceso de matrices n-dimensionales que integra PuPure Data (o Pd) es un lenguaje de programación grá- re Data con el lenguaje de programación Ruby, etc.), es fico desarrollado por Miller Puckette durante los años 90 posible crear y manipular vídeo, gráficos OpenGL, imápara la creación de música por ordenador interactiva y genes, etc, en tiempo real con aparentemente infinitas poobras multimedia. Aunque Puckette es el principal autor sibilidades de interactividad con audio, sensores exterdel software, Pd es un proyecto de código abierto y tie- nos, etc. ne una gran base de desarrolladores trabajando en nuevas Adicionalmente, Pd está diseñado nativamente para perextensiones al programa. Está publicado bajo una licen- mitir colaboración en vivo a través de redes o de Internet, cia similar a la licencia BSD. permitiendo a músicos conectados vía LAN, o incluso en Pd es muy similar en alcance y diseño al programa ori- distintas partes del mundo, hacer música juntos en tiemginal de Puckette, Max(desarrollado cuando él estaba po real. en IRCAM), y es hasta cierto grado interoperable con Max/MSP, el sucesor comercial del lenguaje Max. Ambos Pd y Max son ejemplos discutibles de lenguajes de programación de “flujo de datos”. En este tipo de lenguajes, funciones u“objetos”son conectados o“parcheados”unos con otros en un ambiente gráfico que modela el flujo del control y el audio. A diferencia de la versión original de Max, sin embargo, Pd siempre fue diseñado para hacer procesado de señales y tasas de control en la CPU nativa, en vez de descargar la síntesis y el proceso de señales a un tablero de PDS (como el Ariel ISPW que era usado para Max/FTS). El código de Pd es la base de las extensiones MSP de David Zicarelli al lenguaje Max para hacer proceso de audio en software.
Las unidades donde se programa el código se llaman “patch”o abstracciones, son utilizadas como programas independientes y compartidos libremente entre la comunidad de usuarios de Pd. Los patchs constan de diferentes objetos interconectados entre ellos. En su parte superior encontraremos las entradas, donde se les enviaran valores numéricos u otros tipos de datos, y en la inferior la salida de estos.
También existe la posibilidad de crear patchs secundarios conocidos como subpatchs. Están dentro del patch principal. Se crean escribiendo en un objeto las letras “pd” seguidas de un espacio y el nombre que se le quiera dar a ese subpatch, como se muestra en la figura. Clicando encima se nos abre la ventana donde encontramos el código Como Max, Pd tiene una base modular de código con de nuestro subpatch. externos u objetos que son utilizados como bloques de 308
165.2. OBJETOS MÁS IMPORTANTES
309 Objeto: Su comportamiento dependerá del texto que tenga introducido en él mismo. El programa tiene unos objetos predefinidos, programados por terceras personas en diferentes lenguajes como puede ser C. El Pd reconoce el tipo de objeto y esa caja ya se comporta como tal.
Subpatch.
Números: Su utilidad puede ser diversa, desde la de controlar el valor que tiene la señal en diferentes puntos del patch, hasta la de inicializar valores que se pasan a objetos que controlan, por ejemplo, un nivel de opacidad de una imagen.
Mensajes: Están provistos de información que se pasa a El programa tiene dos estados en los que se puede en- los objetos. contrar el usuario. En modo de edición o en modo de Símbolo: Este objeto guarda un símbolo hasta que recibe ejecución. Para cambiar de un estado a otro teclearemos un [bang] u otro símbolo. Es entonces cuando este símCtrl+E. Cuando estamos en el modo edición, podemos bolo sale del objeto, por la parte inferior de la caja. Estos modificar el contenido de las cajas, o la conexión entre objetos se ofrecen solo en Pd si tienes descargada y coellas. En el modo de ejecución tenemos la posibilidad de rrectamente instalada la biblioteca apropiada. No tienen poner en marcha todo el patch, e ir modificando valores porqué existir en las bibliotecas sencillas, aunque acosdurante su reproducción o cuando este, esté parado. Po- tumbran a estar incluidas en los archivos de instalación. demos enviar bangs, modificar valor de variables dentro de los objetos“números”, o activar y desactivar sectores Comentario: lo utilizaremos para incluir aclaraciones del código con el objeto [toggle], activado cuando tiene dentro de los diferentes pasos que sigue nuestro código. una cruz y desactivado cuando no.
165.1 Tipos de objetos
165.2 Objetos más importantes
Oscilador.
El objeto [osc~] nos genera una señal sinusoidal. La frecuencia de oscilación dependerá del valor que se introduzca en la entrada que tiene el objeto en la parte superior izquierda. Siempre que coloquemos un oscilador, tenemos que colocar también un multiplicador y un convertidor digital analógico(dac~). Esto se hace porque el “osc~”por defecto posee la amplitud máxima en 1, por eso la multiplicamos por 0.01 para reducir su amplitud y luego enviarla al “dac~”. El objeto “dac~”tiene dos entradas que hacen referencia a los dos canales de salida de la tarjeta de sonido de tu máquina. Un [bang] tiene como función la activación de la acción que tiene inmediatamente conectada después.
Objetos de Pd.
Metro: Envía series de [bang] periódicamente. Lo crearemos escribiendo la palabra “metro”dentro de un objeto. Este objeto tiene dos entradas, la de la izquierda
310
CAPÍTULO 165. PURE DATA mérica dada inicialmente. Lo creamos introduciendo la palabra “select (espacio)condición”. De esta manera cuando el valor de entrada sea igual a la condición, por la salida de la izquierda se enviará un bang. Si no coinciden el bang será enviado por la salida de la derecha. Se pueden introducir varias condiciones simultáneas separadas por espacios. Se crearan tantas salidas como condiciones más una final. Cuando el valor coincida con una de las condiciones, el bang será enviado por la salida que corresponda con dicho valor. Si no coincide, el [bang] siempre será enviado por la última salida, la de más a la derecha.
Bang.
metro_pd.
acepta [bangs]. Hace que el metro empiece a funcionar; asimismo acepta mensajes con el texto “stops”, deteniendo el funcionamiento del metro. También podemos enviarle cualquier número diferente de cero para activarlo. Si se le envía un cero el metro deja de enviar [bangs]. En la entrada de la derecha le introducimos el número que rige la periodicidad del envío de bangs, la unidad de este valor son los milisegundos. Dentro de la misma caja de [metro], después de la palabra metro y seguido de un espacio se introduce un número que el objeto ya lo entiende como el periodo.
Start
Start: Ejecuta los objetos del patch que tiene conectado a él mismo. El objeto [start] lo crearemos escribiendo la palabra “start”dentro de un mensaje. Stop: Detiene la ejecución del patch que está en funcionamiento. Lo crearemos escribiendo la palabra “stop” dentro de un mensaje.
Selector.
Moses: Escribiremos la palabra“moses”dentro de un objeto para poder tenerlo operativo. Contiene dos entradas y dos salidas. En la entrada de la izquierda conectamos el valor que está en el proceso y en la derecha el valor que queremos que actúe de frontera. Si el valor del proceso es inferior a la frontera, nos saca el valor de entrada por la salida de la izquierda. En cambio, si el valor es igual o superior al valor que actúa de frontera, nos sacará el número por la salida de la derecha. Podríamos asemejar el [moses] a un filtro paso bajo y paso alto simultáneo.
165.3 Instalación en GNU posibles problemas y soluciones Para instalar Pd en GNU deberemos descomprimir el paquete descargado con el programa y ejecutar el archivo con extensión“.deb”. El primer posible problema con el que nos podemos encontrar, es que la distribución Ubuntu Studio ya lleva un Pure Data instalado de serie. Debido a que es recomendable utilizar la versión Pd_extended (aunque esto es algo que varia muy a menudo) tendremos que desinstalar el Pure Data de GNU/linux Ubuntu, para que, al instalar el nuevo, no tengamos problemas con el hecho de compartir de carpetas. Otro factor muy común e importante cuando instalemos programas en GNU son las dependencias de bibliotecas secundarias que puedan existir. Es necesario instalarlas para el buen funcionamiento del programa. En el caso de Pure Data y de algunas bibliotecas externas (externals), se tienen que instalar algunas dependencias mediante el gestor de paquetes llamado Synaptic. Ahí podemos buscar cuales son las que necesitamos. Una vez probado el correcto funcionamiento del Pd, para optimizar los recursos del programa, cargamos, en el start up, las bibliotecas más comunes que se usaran, para evitar tener que importarlas cada vez que se quieran usar. De este modo al arrancar Pd en tu máquina ya se cargan automáticamente.
Select: Nos actúa de selector según una condición nu- Linux
165.6. PATCH PATRONES
Test audio/MIDI.
165.4 Introducción rápida
311
Objeto de PDP que te crea una cuadrícula que divide la imagen.
comandos, quedando así lista para su uso.
Una vez ya tenemos el Pd estable en nuestra máquina se procede a hacer un primer test del programa para comprobar que la conexión con nuestra tarjeta de sonido es correcta. Este lo encontraremos en Media>test audio and MIDI. Ahí podemos generar una señal de test (un tono, ruido rosa,…) escuchándola por nuestros altavoces, comprobando así que todo funciona correctamente. Para empezar a conocer el entorno de Pd, podemos empezar abriendo ejemplos que encontraremos en los archivos de documentación que hay dentro de la carpeta de Pd. Allí hay patchs de audio y de vídeo que sirven para familiarizarse con el programa. Cuando queramos crear nuestro propio patch, en la ventana de Pd vamos a File>New y se nos abre la ventana donde introduciremos nuestros objetos que conectaremos entre ellos creando así nuestra pdp_opencv distrains. aplicación.
165.5 Bibliotecas pdp, pidip y opencv La biblioteca PDP es una colección de objetos que se utiliza para procesar numerosos datos. Funciona en Linux y la mayoría de objetos también trabajan en Mac OSX. Una vez descargado, la instalación en Linux se hace a través del terminal, compilando y ejecutando el archivo de instalación que viene adjuntado, de la siguiente manera: ./configure sudo make
También existe otra biblioteca referente al video llamada OpenCV. Es una biblioteca abierta desarrollada por Intel. Esta biblioteca proporciona un alto nivel de funciones de procesado de imágenes. Permite al programador crear aplicaciones en el dominio de la visión digital. OpenCV es Open Source permitiendo así poder funcionar en muchas plataformas. Esta biblioteca nos permite hacer operaciones básicas, procesado de imágenes, análisis de reconocimiento del modelo, análisis estructural, reconstrucción 3D, calibración de la cámara, análisis de movimiento, interfaz gráfica y adquisición, etc. Implementa una gran variedad de herramientas para la interpretación de la imagen, como por ejemplo, detección de facciones o análisis de la forma (geometría, contorno que procesa en ese instante), entre otras.
sudo make install Cuando los datos ya están representados como un paquete dentro de Pd, es posible empezar a manipularlos. La 165.6 Patch patrones biblioteca PiDiP son objetos de video que completan la colección de objetos de PDP. La instalación es idéntica Una buena primera toma de contacto con Pd puede ser a la de PDP, desde el terminal ejecutamos los mismos la generación de un tono sinusoidal. Para esto utilizare-
312
CAPÍTULO 165. PURE DATA jeto que nos permite visualizar la imagen según nuestro sistema operativo, en Linux sería pdp_v4l (video for Linux). A este objeto también le conectamos otro mensaje donde le indicamos el canal por el que queremos enviar la información. Finalmente le conectaremos a [pdp_v4l] un [metro] dándole la información de la periodicidad con la que queremos que nos muestre las imágenes que la cámara está captando. Para tener continuidad de movimiento le daremos un valor estándar de 100ms. A gusto del usuario también podemos girar la imagen en sentido horizontal para que el efecto generado al ver la imagen sea de espejo. Para conseguir esto conectaremos la salida de [pdp_v4l] al objeto [pdp_flip_lr]. Con esto ya tenemos, en una ventana a parte, la imagen que la cámara está captando.
165.7 Véase también • Miller Puckette • Lenguaje de programación visual
165.8 Material en español • Sistemas musicales interactivos Documentos de curso de sistemas musicales interactivos por Sergi Jordà • Taller de música electrónica Documentos del curso de Taller de música electrónica por Sergi Jordà Ejemplo de oscilador.
mos el objeto [osc~]. En la entrada izquierda le conectaremos un mensaje con un número dentro que actuará de frecuencia de oscilación. Su salida la enviaremos a un multiplicador que nos convertirá esta frecuencia en audible y finalmente esto lo enviamos a un convertidor digital analógico [dac~] para poder reproducirlo por los altavoces de nuestra máquina. Una vez ya hemos creado este patch, podemos modificar la frecuencia clicando y manteniendo pulsado el ratón encima del mensaje del número y desplazando el cursor arriba abajo, aumentando y disminuyendo así el valor de la frecuencia.
• Curso de introducción a GEM Introducción a GEM y al live cinema por Carles Sora
165.9 Enlaces externos • puredata.info Portal oficial sobre PureData. • puredata-es Comunidad de Puredata en Castellano • IEM Institute of Electronic Music and Acoustics, Graz. Muchos enlaces útiles (en inglés) • Miller S. Puckette homepage con una nota biográfica y sus ocupaciones actuales (en inglés). • Pure DataBase, pdb Aquí puedes buscar objetos de pure data (en inglés) • Footils.org Sitio muy completo con prácticas abstracciones (en inglés).
Abrir dispositivo externo. Cámara web.
Para abrir un dispositivo externo, como por ejemplo una cámara web, deberemos escribir en un mensaje la palabra “open”seguido de un espacio y la ruta de donde se encuentra este dispositivo. Este, lo conectaremos al ob-
• 3 Convención Internacionale de Pd (en portugués).
Capítulo 166
QuadTIN QuadTIN es una estructura de datos en forma de árbol ideada por Renato Pajarola, Roberto Lario y Marc Antonijuan. Dicha estructura de datos se basa en la estructura del quadtree, pero, a diferencia de éste, los hijos de un nodo no han de ser del mismo tamaño, y ni siquiera ser cuadrados. De esta forma, el quadTIN permite almacenar de forma jerárquica triangulaciones irregulares.
313
Capítulo 167
Query string Query string, en español: cadena de consulta, este término generalmente se utiliza para hacer referencia a una interacción con una base de datos. Es la parte de una URL que contiene los datos que deben pasar a aplicaciones web como los programas CGI.
el valor se obtiene trás aplicar una separación de la query string mediante el símbolo /. De ésta forma se puede trabajar con Friendly Urls siguiendo las recomendaciones de los principales motores de búsqueda, sin necesidad de crear una estructura de directorios en el servidor. Una gran cantidad de sitios web utilizan esta forma de interEn los comienzos de la web las direcciones de las páginas contenían la estructura jerárquica de los directorios del pretación de la query string. sitio. Por ejemplo: www.sitiodeejemplo.net/paginaprincipal/ paginasecundaria/contenido.html
167.1 Véase también
Estos sitios eran estáticos: a menos que el administrador modifique las páginas siempre mostrarían el mismo contenido a los visitantes. Más tarde aparecieron los sitios dinámicos. En este caso, el servidor crea automáticamente la página cuando el navegante la solicita. Para ello se vale de una serie de parámetros o datos que se incluyen en la URL. Éstos normalmente están compuestos por un nombre y un valor separados por el signo igual. Un ejemplo de dirección dinámica sería: www.sitiodeejemplo.net/pagina.php?nombredevalor1= valor1&nombredevalor2=valor2 Otro ejemplo común de dirección dinámica consistiría en configurar el servidor para que asigne automáticamente a un conjunto de variables predefinidas los valores resultantes de la separación de la query string usando como símbolo de separación de la cadena el caracter /. www.sitiodeejemplo.net/paginaprincipal/ paginasecundaria/contenido De esta forma y mediante la configuración del servidor(ej. mod rewrite en servidores web apache) se podría acceder a las tres subcadenas resultantes en nuestro ejemplo, esto es, paginaprincipal, paginasecundaria y contenido accediendo mediante GET a los sendos nombres de variable que se definieron en la configuración del servidor web. Se trata de una segunda opción simplificada de pares variable-valor, con la peculiraridad de que los nombres de variable se sobreentienden y predefinen en el servidor y
314
• Página web • Web 2.0 • HTML dinámico
Capítulo 168
Quest3D Quest3D es la conjunción de un motor de videojuego con una plataforma de desarrollo. Generalmente se usa para arquitectura, diseño de producto, videojuegos, software de entrenamiento y simuladores. Los datos y animaciones son importados de paquetes CAD tales como Maya, 3D Studio Max y AutoCAD, a Quest3D donde son utilizados para la creación de aplicaciones interactivas 3D en tiempo real. Quest3D es un producto desarrollado por Act-3D B.V. en Holanda. Su primera versión fue publicada en septiembre del 2001.
168.1.2 Orientación a objetos
168.1 Entorno de desarrollo
168.1.3 Editores
Una de las características más importantantes de Quest3D es la metodología de programación. De una forma totalmente diferente a la de los habituales lenguajes de programación, tales como el C++, el entorno de desarrollo de Quest3D es casi por completo visual. Otra característica destacable es el hecho de que el programador puede modificar la aplicación mientras esta se ejecuta. Esto significa que no existe compilación de código como en los entornos de programación habituales.
Quest3D ha evolucionado en su versión 4.0 y posteriores, permitiendo implementar aplicaciones siguiendo un paradigma de diseño orientado a objetos. Haciendo uso de su nuevo editor de interfaces y clases, permite de una manera bastante intuituva el encapsulamiento de subárboles de“channels”en“Objetos”, que contienen métodos y propiedades. Esta característica aumenta la potencia del entorno, permitiendo aplicaciones mucho más dinámicas.
El entorno de Quest3D consiste en diferentes editores especializados en la creación de la aplicación: Editor de "Árbol de Channels”, modificación de características de los objetos 3D (modelos 3D), animaciones, programación High Level Shading Language (HLSL) y programación LUA Script entre otros.
168.1.4 Publicación
Las aplicaciones finalizadas pueden ser publicadas en diferentes formatos, para permitir su visualización en diferentes medios: Fichero ejecutable “standalone”(plata168.1.1 Lógica de las aplicaciones forma Microsoft Windows) y visor WEB basado en control ActiveX. Los navegadores soportados en la actualiLas aplicaciones Quest3D se desarrollan conectando dad son Internet Explorer y FireFox. componentes funcionales (cajas negras), denominadas “Channels”. Los“Channels”vinculados componen una estructura de árbol, que representa la estructura del pro- 168.2 Requerimientos del sistema grama que se implementa. El árbol de cajas negras se ejecuta por completo una vez (al menos) por frame, invocanAlgunas funcionalidades del motor 3D requieren hardwado a cada“channel”. Lo que se obtiene como resultado re más específico. es una aplicación 3D en tiempo real. Como no hay fase de compilación, o interpretación de un lenguaje de scripting, ya que los “Channels”son cajas con su código precompilado (implementadas en Dynamic Link Libraries), el rendimiento de las aplicaciones es el mismo en fase de diseño que en ejecución, característica muy apreciada cuando se desarrollan aplicaciones en tiempo real. 315
• Windows 2000, Windows XP, Windows Vista (64 or 32 bit) y DirectX 9 • 256 MB RAM • Procesador de 1Ghz • Tarjeta gráfica compatible con DirectX
316 • 32 MB de memoria gráfica • 400MB de espacio en disco duro
168.3 Licencias Se pueden adquirir diferentes licencias para el uso tanto comercial como educacional.
168.4 Aplicaciones Realidad virtual, Videojuegos, visualización arquitectónica, “serious games”, simuladores, TV y cine.
168.5 Referencias • DevMaster.net Quest3D specifications • Gamasutra “Rapid gameplay iterations are crucial to me, so I use Quest3D for everything else.”, Dylan Fitterer in “The road to IGF”
168.6 Enlaces externos • Quest3D website
CAPÍTULO 168. QUEST3D
Capítulo 169
Quine (programa) En informática, un quine (pronunciado “kwain”) es un programa (un tipo de Metaprogramación) que produce su código fuente como su salida única. Para diversión, algunos hackers intentan desarrollar el quine más corto posible en cualquier lenguaje de programación.
args) { string s = “using System;{0}namespace quine{0}{2}{0}{1}class Program{0} {1}{2}{0}{1}{1}[STAThread]{0}{1}{1}static void Main(string[] args){0}{1}{1}{2}{0}{1}{1}{1} string s = {4}{6}{4};{0}{1}{1}{1}Console.Write(s, Environment.NewLine, {4}{5}t{4}, {4}{2} Nota: simplemente abriendo el archivo fuente del progra{4}, {4}{3}{4}, {4}{5}{4}{4}, {4}{5}{5}{4}, ma e imprimiendo el contenido se considera hacer trams);{0}{1}{1}{3}{0}{1}{3}{0}{3}"; Console.Write(s, pa. Environment.NewLine, "\t”, "{", "}", "\"", "\\", s); } } } Los quines se llaman así por Willard Van Orman Quine, que hizo un estudio extensivo de autoreferencia indirecta y sugirió un caso famoso de paradoja sin autoreferencia 169.1.3 Scheme directa:“Da como resultado un enunciado falso si es precedido por su cita”da como resultado un enunciado falso ((lambda (x) (list x (list (quote quote) x))) (quote (lambda si es precedido por su cita. (x) (list x (list (quote quote) x)))))
169.1 Ejemplos
169.1.4
Common Lisp
169.1.1 C
(funcall (lambda (x) (append x (list (list 'quote x))))) '(funcall (lambda (x) (append x (list (list 'quote x)))))) #include char*i="\\#include",n='\n',q='"',*p= "%s%cchar*i=%c%c%s%c,n='%cn',q='%c',*p=%c%c%s%c,*m=%c%c%s%c%c;%s%c” ,*m=“int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}" 169.1.5 Ocaml ;int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);} (fun s -> Printf.printf "%s %S”s s) "(fun s -> Printf.printf Otro (este debe ser una sola línea, y supone que el compi- \"%s %S\" s s)" lador ejecuta en una máquina que usa el código ASCII): extern printf(char*,...);main(){char*a="extern 169.1.6 Python printf(char*,...); main(){char*a=%c%s%c;printf(a,34,a,34,10);}%c";printf(a,34,a,34,10);} a='a=%s;print a%%`a`';print a%`a` O aún más corto (aunque no es código C99 de ISO correcto): Otro: main(){char*a="main(){char*a=%c%s%c;printf(a,34,a,34);}";printf(a,34,a,34);} b='\\';g='"';p='%';s="b='%s%s';g='%s';p='%s';s=%s%s%s;print s%s(b,b,g,p,g,s,g,p)";print s%(b,b,g,p,g,s,g,p)
169.1.2 C#
Y otro que comparte los caracteres últimos con la anterior (solamente para mostrar que asignaciones múltiples Nota: Debe ser una sola línea. Los saltos de línea se agre- no salva mecanografía): garon para hacerlo más fácil de leer. b,g,p,s='\\','"','%',"b,g,p,s='%s%s','%s','%s',%s%s%s;print using gram
System; namespace quine { class Pro- s%s(b,b,g,p,g,s,g,p)";print s%(b,b,g,p,g,s,g,p) { [STAThread] static void Main(string[] 317
318
CAPÍTULO 169. QUINE (PROGRAMA)
169.1.7 JavaScript
169.1.11
Brainfuck
Nota: Debe ser una sola línea. Los cortes de línea se agreunescape(q="unescape(q=%22*%22).replace('*',q)").replace('*',q) garon para hacerlo más fácil de leer.
->+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+ +>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>+ 169.1.8 Perl >>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+ ++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>> $_=q{$_=q{Q};s/Q/$_/;print};s/Q/$_/;print ++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>> +>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>> El más corto conocido: >>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+> >>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>> open+0;print<0> [[->>+<<]]<+]+++++[>+++++++++<]>.[+]>>[<<+++++++[Y una combinación de Perl y script de shell: >+++++++++<]>.------------------->-[perl -le '$n=q{perl -le <.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[a$n=q{$x};($_=$n)=~s/\141/\47/g;s/\$x/$n/;printa};($_=$n)=~s/\141/\47/g;s/\$x/$n/;print' >+++++<]]>++++ ++++++++++<]>+++<]++++++[>+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<]
169.1.9 BASIC
169.1.12
10 LIST
Q
169.1.10
Pascal
const a='const a=';b='begin write(a,#39,a,#39#59#98#61#39,b,#39#59#10,b) end.'; begin write(a,#39,a,#39#59#98#61#39,b,#39#59#10,b) end.
169.1.13
HQ9+
DOS Batch
@echo off %1 %2 call %0 goto e %% call %0 goto e %%3 echo.%%4 echo :f goto f :e echo.%4@echo off echo.%4%31 %32 echo.%4call %30 goto e %3%3 echo.%4call %30 goto e %3%33 echo.%3%34 echo.%4echo :f echo.%4goto f echo.%4:e :f
Comentario 1: En el caso de una implementación DOS de Pascal, la salida de la pantalla puede parecer bastante desorientadora. En ese caso, sería apropiado sustituir 169.1.14 PHP ambas instancias de "#10”con "#13#10”e insertar un $a='chr(60).chr(63).chr(10).chr(36).chr(97).chr(61).chr(39).$a.chr(39). CR antes del LF al fin de la primera línea. $a;".chr(10).chr(63).chr(62)'; echo Comentario 2: El programa se puede hace todavía más chr(60).chr(63).chr(10).chr(36).chr(97).chr(61).chr(39).$a.chr(39).chr(59) corto porque ambas instancias de ") end.”se pueden sus$a;".chr(10).chr(63).chr(62); ?> $a=' $a=2; echo tituir con ")end.”(aunque le hace difícil de leer). Se puede str_replace(1+1,chr(39).$a.chr(39),$a); ?>'; echo acortar más por borrar ambas instancias de "#10”y escristr_replace(1+1,chr(39).$a.chr(39),$a); ?> biendo el programa en una sola línea en vez de dos líneas. Después de los cambios, el programa parecerá como sigue: const a='const a=';b='begin wri- 169.1.15 PL/I te(a,#39,a,#39#59#98#61#39,b,#39#59,b)end.';begin write(a,#39,a,#39#59#98#61#39,b,#39#59,b)end. Nota: Este es el quine de PL/I más pequeño posible que compila usando el compilador OS PL/I V2.3.0, pero reOtro (Borland Pascal and Free Pascal): quiere un margen izquierdo de 1 y la opción COMPILE const a='const a=;begin wri- para parar una cantidad significativo de errores): te(copy(a,1,8),#39,a,#39,copy(a,9,99)) end.';begin %dcl z%z='put edit';proc options(main;q=''''put list(m;do write(copy(a,1,8),#39,a,#39,copy(a,9,99)) end. i=1,2;z(q)skip;do j= 1to 78c=substr(m(i),j;if c=q Otro (Borland Pascal and Free Pascal): z(c;z(c;end;z(q',';dcl(c,q)char,m(2)char(99)init( '%dcl const a:string='const a:string=;begin in- z%z=''put edit'';proc options(main;q=''''''''put list(m;do sert(#39+a+#39,a,16);write(a) end.';begin in- i=1,2;z(q)skip;do j=', '1to 78c=substr(m(i),j;if c=q sert(#39+a+#39,a,16);write(a) end. z(c;z(c;end;z(q'','';dcl(c,q)char,m(2)char(99)init(',
169.2. ENLACES EXTERNOS
169.1.16
PostScript
(dup == {dup cvx exec} pop 8 12 getinterval =) dup cvx exec
169.1.17
Visual FoxPro
CLEAR SET TALK OFF SET TEXTMERGE ON \CLEAR \SET TALK OFF \SET TEXTMERGE ON
169.2 Enlaces externos • La página de los quines (por Gary P. Thompson) • Los programas quine al wiki del Portland Pattern Repository • Una página sobre los quines • Unos participantes en un concurso de hacer quines en JavaScript • Un quine HTML con uso de CSS apegado a la norma, incluyendo resaltado de la sintaxis • “Palíndromo quine": una página web que es lo mismo que su código fuente, lo mismo de izquierda a derecha que de derecha a izquierda, los mismo de arriba para abajo que de abajo para arriba.
319
Capítulo 170
Rebanamiento estático El rebanamiento estático es una técnica en el área de programación de computadoras conocida como mantenimiento de software. Es usada para identificar todo el código de programa que puede afectar de algún modo el valor de una variable dada. Una descripción breve de su cálculo es el siguiente: Basado en la definición original de Mark Weiser una rebanada estática de programa (S) consiste de todas las sentencias en un programa P que pueden afectar el valor de la variable v en algún punto p. La rebanada es definida por un criterio de rebanamiento C=(x,V), donde x es una sentencia en un programa P y V es un subconjunto de variables en P. Una rebanada estática incluye todas las sentencias que afectan la variable v para un conjunto de todos los posibles inputs en el punto de interés. Las rebanadas estáticas son computadas encontrando conjuntos consecutivos de sentencias indirectamente relevantes, de acuerdo a los datos y dependencias de control.
170.3 Referencias • Meilir Page-Jones, "The Practical Guide to Structured Systems Design", Yourdon Press,1980, ISBN 0917072-17-0
170.4 Enlaces externos
170.1 Ejemplo int i; int suma = 0; int producto = 1; for(i = 0; i < N; ++i) { suma = suma + i; producto = producto * i; } write(suma); write(producto); El siguiente programa es un rebanamiento válido del anterior, respecto al criterio (write(suma),{suma}): int i; int suma = 0; for(i = 0; i < N; ++i) { suma = suma + i; } write(suma); De hecho, la mayoría de técnicas de rebanamiento estático, incluida la propia técnica de Weiser, tampoco incluirían la sentencia write(suma), ya que en la sentencia write(suma), el valor de suma no es afectado por la sentencia en sí.
170.2 Véase también • Software • CMM 320
• Tufts University: Ensayo sobre Mantenimiento como parte del Ciclo de Vida del Software (en inglés)
Capítulo 171
Recolector de basura • Compactar espacios de memoria libres y consecutivos entre sí. • Llevar cuenta de qué espacios están libres y cuáles no. Generalmente, el programador dispone de una biblioteca de código que se encarga de estas tareas. No obstante, el propio programador es responsable de utilizar adecuadamente esta biblioteca. Esto tiene la ventaja de que se hace un uso eficiente de la memoria, es decir, los espacios de memoria quedan libres cuando ya no son necesarios. No obstante, este mecanismo explícito de gestión de memoria es propenso a errores. Por ejemplo, un programador puede olvidar liberar la memoria de manera que, tarde o temprano, no quede memoria disponible, abortando la ejecución del programa.
Recolección de basura informática. El espacio de memoria se va llenando con diferentes “objetos”(representados con colores), también pueden destruirse algunos de ellos, dejando “huecos” en el espacio de memoria. Cuando ya no queda espacio disponible, o cuando lo decide la rutina de recolección de basura, la memoria es“compactada”, colocando todos los“objetos”que se están usando al principio, y consolidando todos los “huecos” de memoria al final, quedando así una gran área de memoria Como alternativa es necesaria una gestión implícita de disponible para la futura creación de objetos.
memoria, con lo que el programador no es consciente de Un recolector de basura (del inglés garbage collector) es la reserva y liberación de memoria. Esto es obligado en un mecanismo implícito de gestión de memoria imple- algunos lenguajes de programación en los que no se mamentado en algunos lenguajes de programación de tipo neja el concepto de memoria. Por ejemplo, en lenguajes declarativos como Lisp o Prolog. interpretado o semiinterpretado.
171.1 Breve reseña histórica
171.3 Cómo funciona
El concepto de recolección de basura fue inventado por Cuando un lenguaje dispone de recolección de basura, el John McCarthy en 1958 para evitar la gestión manual de programador no tiene que invocar a una subrutina para memoria en el lenguaje Lisp. liberar memoria. La reserva de memoria también es más o menos automática sin la intervención del programador. Por ejemplo:
171.2 Contexto
Cualquier programa informático hace uso de una cierta cantidad de memoria de trabajo puesta a su disposición por el sistema operativo. Esta memoria tiene que ser gestionada por el propio programa para: • Reservar espacios de memoria para su uso. • Liberar espacios de memoria previamente reservados. 321
• En los lenguajes orientados a objetos: se reserva memoria cada vez que el programador crea un objeto, pero éste no tiene que saber cuánta memoria se reserva ni cómo se hace esto. • En los lenguajes declarativos: cada vez que se construye una expresión se reserva memoria (de una manera inteligente), pero el programador no es consciente de ello.
322
CAPÍTULO 171. RECOLECTOR DE BASURA
Cuando se compila el programa, automáticamente se in- 171.5 Cómo se implementa cluye en éste una subrutina correspondiente al recolector de basura. Esta subrutina también es invocada periódica- Existe la posibilidad de implementar la recolección de bamente sin la intervención del programador. sura como una biblioteca de código más, pero por norma El recolector de basura es informado de todas las reservas general no es así. El propio diseño de ciertos lenguajes de de memoria que se producen en el programa. Además, el programación hace necesaria la existencia del recolector compilador colabora para que sea posible llevar una cuen- de basura. Para poder implementar estos lenguajes se reta de todas las referencias que existen a un determinado quieren dos actuaciones: espacio de memoria reservado. • Que el compilador proporcione la información neCuando se invoca el recolector de basura, recorre la lista cesaria para el recolector de basura (el contador de de espacios reservados observando el contador de refereferencias). rencias de cada espacio. Si un contador ha llegado a cero significa que ese espacio de memoria ya no se usa y, por tanto, puede ser liberado. Naturalmente, este proceso consume un cierto tiempo en el que no se hace nada verdaderamente útil para el propósito del programa. Por tanto, no puede ser invocado con demasiada frecuencia. En consecuencia, el único inconveniente a este mecanismo es determinar cuándo se tiene que ejecutar el recolector de basura. Existen varios algoritmos para hacerlo, pero el más eficiente es el primero de ellos:
• Que el entorno de ejecución o máquina virtual implemente la subrutina del recolector de basura.
171.6 Ejemplos de lenguajes con recolector de basura 171.7 Véase también • Conteo de referencias
• Esperar a que no quede memoria libre, y entonces, ejecutar el recolector de basura. • Fijar un umbral de ocupación de la memoria libre y ejecutar el recolector de basura cuando se supere dicho umbral. • Ejecutar el recolector de basura a intervalos regulares (no siempre es posible). • Ejecutar el recolector de basura justo antes de cada reserva de memoria. • Permitir al programador que invoque explícitamente al recolector de basura cuando quiera.
171.4 Ventajas y desventajas Las ventajas y desventajas de este mecanismo de gestión de memoria son las opuestas al mecanismo explícito: • El programador no puede cometer errores y queda liberado de la tediosa tarea de gestionar la memoria. • La memoria permanece retenida durante más tiempo del estrictamente necesario. • El recolector de basura tarda cierto tiempo en hacer su tarea y produce pausas que pueden hacer la técnica incompatible con sistemas de tiempo real.
• Fuga de memoria
171.8 Enlaces externos • The Memory Management Reference (en inglés) • Recolector de basura para C y C++ (en inglés)
Capítulo 172
Recursión
Imagen recursiva formada por un triángulo. Cada triángulo está compuesto de otros más pequeños, compuestos a su vez de la misma estructura recursiva.
Para que se entienda mejor a continuación se exponen algunos ejemplos: • Factorial: Se desea calcular n! (el factorial de n , que se define como el producto de todos los enteros positivos de 1 a n ). Se puede definir el problema de forma recurrente como n(n−1)! ; como (n−1)! es menor que n! podemos aplicar inducción por lo que disponemos del resultado. El caso base es 0! que es 1 .
Anuncio de cacao con una imagen recursiva. La mujer muestra un paquete idéntico al del propio anuncio, conteniendo así a otra mujer que muestra otro paquete más pequeño, de forma recursiva.
• Algoritmo de ordenación por fusión: Sea v un vector de n elementos, podemos separar el vector en dos mitades. Estas dos mitades tienen tamaño n/2 por lo que por inducción podemos aplicar la ordenación en estos dos subproblemas. Una vez tenemos ambas mitades ordenadas simplemente debemos fusionarlas. El caso base es ordenar un vector de cero o un elemento, que está trivialmente ordenado y no hay que hacer nada.
Recurrencia, recursión o recursividad es la forma en la cual se especifica un proceso basado en su propia definición. Siendo un poco más precisos, y para evitar el aparente círculo sin fin en esta definición: Un problema que pueda ser definido en función de su tamaño, sea este N, pueda ser dividido en instancias más pequeñas (< N) del mismo problema y se conozca la solución explícita a las instancias más simples, lo que se conoce como casos base, se puede aplicar inducción sobre las llamadas más pequeñas y suponer que estas quedan resueltas.
En estos ejemplos podemos observar como un problema se divide en varias (una o más) instancias del mismo problema, pero de tamaño menor gracias a lo cual se puede aplicar inducción, llegando a un punto donde se conoce el resultado (el caso base).
323
324
CAPÍTULO 172. RECURSIÓN
Nota: aunque los términos“recursión”y“recursividad” 172.1.3 Constantes son ampliamente empleados en el campo de la informática, el término correcto en castellano es recurrencia * [cita La razón áurea se puede definir como sigue: ϕ = 1+ ϕ1 = 1 requerida]. Sin embargo este último término es algo más 1 + , como una fracción continua en que todos 1 1+ 1+ 1 específico. Véase relación de recurrencia. 1+... los números son unos. √ x−1 √ da lugar De forma similar, la identidad x = 1 + 1+ x 172.1 Recursión en matemáticas a una definición como fracción continua de cualquier raíz x−1 √ cuadrada:* [3] x = 1 + x−1 172.1.1 Conjuntos definidos de forma re2+ x−1 currente 2+ . 2 + .. Un ejemplo de conjunto definido de forma recurrente es el de los números naturales, es decir, el conjunto de los números enteros no negativos:* [1]
172.1.4 Resolución de problemas
1. 0 pertenece a ℕ. 2. Si n pertenece a ℕ, entonces n + 1 pertenece a ℕ. 3. Si x verifica las anteriores condiciones, entonces x está incluido en ℕ * [cita requerida].
172.1.2
Resolución de ecuaciones homogéneas de primer grado, segundo orden: a) Se pasan al primer miembro los términos an , an−1 , an−2 , los cuales también podrían figurar como an+2 , an+1 , an 2
Funciones definidas de forma re- b) Se reemplaza an por r , an−1 por r y an−2 por 1 , quedando una ecuación de segundo grado con raíces currente reales y distintas r1 y r2 .
Aquellas funciones cuyo dominio es un conjunto a lo más c) Se plantea a = u r1 n + v r2 n enumerable * [2] pueden ser definidas de forma recurren- d) Debemos tener como dato los valores de los dos prite. meros términos de la sucesión: A0 = k y A1 = k ′ . Un ejemplo conocido es la definición recurrente de la fun- Utilizando estos datos ordenamos el sistema de 2x2: ción factorial n!: { n! =
si n = 0 ⇒ 1 si n ≥ 1 ⇒ n (n − 1)!
{ u+v =k u r1 + u r2 = k ′
Veamos cómo se usa esta definición para hallar el valor La resolución de este sistema nos da como resultado los valores u0 y v0 , que son números reales conocidos. del factorial de 3: e) La solución general es: 3! = 3 · (3 − 1)! = 3 · 2! = 3 · 2 · (2 − 1)! = 3 · 2 · 1! = 3 · 2 · 1 · (1 − 1)! = 3 · 2 · 1 · 0! =3·2·1·1
an = u0 r1 n + v0 r2 n
172.2 Recursión en informática
En programación, un método usual de simplificación de un problema complejo es la división de este en subproblemas del mismo tipo. Esta técnica de programación se Otros ejemplos de funciones y sucesiones matemáticas conoce como divide y vencerás y es el núcleo en el didefinidas de forma recursiva son: seño de numerosos algoritmos de gran importancia, así • Sucesión de Fibonacci ̶f(0)= 1, f(1) = 1; f(n) = como también es parte fundamental de la programación dinámica. f(n−1) + f(n−2) para n ≥ 2. =6
• Números de Catalan ̶C(2n, n)/(n+1) • Función de Ackermann
El ejemplo del cálculo recursivo del factorial de un número llevado al campo de la programación, en este ejemplo C++:
172.5. REFERENCIAS int factorial(int x) { if (x > −1 && x < 2) return 1; // Cuando −1 < x < 2 devolvemos 1 puesto que 0! = 1 y 1! = 1 else if (x < 0) return 0; // Error no existe factorial de números negativos return x * factorial(x - 1); // Si x >= 2 devolvemos el producto de x por el factorial de x - 1 } Este ejemplo está basado en el lenguaje de programación Pascal: Proc Factorial(x:Entero):Entero Si (x > −1 Y x < 2) Devolver 1 ' Cuando x sea mayor que −1 y menor que 2 Devolver 1. Si (x < 0) Devolver 0 ' Cuando x sea menor a 0, devolver 0 Devolver x * Factorial(x - 1) ' Si x igual o mayor que 2 devolvemos el producto de x por el factorial de x - 1 FinProc El seguimiento de la recursividad programada es casi exactamente igual al ejemplo antes dado, para intentar ayudar a que se entienda mejor se ha acompañado con muchas explicaciones y con colores que diferencia los distintos sub-procesos de la recursividad. X = 3 //Queremos 3!, por lo tanto X inicial es 3 X >= 2 -> return 3*factorial(2); X = 2 //Ahora estamos solicitando el factorial de 2 X >= 2 -> return 2*factorial(1); X = 1 // Ahora estamos solicitando el factorial de 1 X < 2 -> return 1; [En este punto tenemos el factorial de 1 por lo que volvemos marcha atrás resolviendo todos los resultados] return 2 [es decir: return 2*1 = return 2*factorial(1)] return 6 [es decir: return 3*2 = return 3*factorial(2)*factorial(1)] // El resultado devuelto es 6
325 • Algoritmo recursivo • Fractal • Sistema-L • Torres de Hanói • Relación de recurrencia
172.5 Referencias [1] Algunos autores consideran que los números naturales son los números enteros positivos, es decir, excluyen el 0 de este conjunto. En ese caso, basta sustituir la línea que dice « 0 pertenece a ℕ» por « 1 pertenece a ℕ». [2] «Nociones de espacios normados» , Cotlar y Cignoli, Eudeba, Buenos Aires [3] Ben Thurston,“Estimating square roots, generalized continued fraction expression for every square root”, The Ben Paul Thurston Blog [4] Hunter, David (2011). Essentials of Discrete Mathematics. Jones and Bartlett. p. 494. [5] Daniel Rodríguez Herrera (29 de julio de 2009). «¿Qué es la recursividad? ¿Qué es la recursividad? ¿Qué es la recursividad?...». Libertad Digital. Consultado el 20 de enero de 2013.
Algoritmo implementado en el lenguaje Prolog: fact(0,1):-!. fact(N,F):-N1 is N-1,fact(N1,F1),F is N*F1.
172.6 Enlaces externos • Ejemplo de curvas recursivas fractales
172.3 Humor recursivo La recursividad se emplea a menudo de forma humorística en textos informáticos, filosóficos o matemáticos. No es raro que un libro de texto de estas disciplinas incluya en su glosario una entrada similar a esta: Recursividad, véase Recursividad.* [4] En el buscador Google, al buscar «recursion», el sitio sugiere «Quizá quisiste decir: recursion».* [5] Un chiste informático dice así: «Para entender la recursividad, debes entender la recursividad».* [4] En la informática también es común la elección de acrónimos recursivos. PHP son las iniciales de PHP Hypertext Preprocessor (Preprocesador de Hipertexto PHP), WINE son las de WINE Is Not an Emulator (WINE no es un emulador) y GNU significa GNU's Not Unix (GNU no es Unix).
172.4 Véase también • Recursión (ciencias de computación)
Capítulo 173
Refactorización La refactorización (del inglés refactoring) es una técnica de la ingeniería de software para reestructurar un código fuente, alterando su estructura interna sin cambiar su comportamiento externo.
nombre de una variable para que sea más significativo, como una sola letra 't' a 'tiempo'. Una refactorización más compleja es transformar el trozo dentro de un bloque en una subrutina. Una refactorización todavía más compleja es remplazar una sentencia condicional if por polimorfismo.
173.1 Refactorización de código
Aunque la limpieza de código se lleva realizando desde hace décadas, el factor clave de la refactorización es realizar de manera intencionada la limpieza separándola de la adición de funcionalidad nueva, usando un catálogo conocido de métodos útiles de refactorización, para después comprobar el código ejecutando las pruebas unitarias, sabiendo que cualquier cambio en el comportamiento significa que se ha introducido un error.
En ingeniería del software, el término refactorización se usa a menudo para describir la modificación del código fuente sin cambiar su comportamiento, lo que se conoce informalmente por limpiar el código. La refactorización se realiza a menudo como parte del proceso de desarrollo del software: los desarrolladores alternan la inserción de nuevas funcionalidades y casos de prueba con la refactorización del código para mejorar su consistencia interna y su claridad. Los tests aseguran que la refactorización no cambia el comportamiento del código.
La refactorización es un aspecto importante de la programación extrema. El libro de Martin Fowler Refactoring es la referencia clásica. Aunque la refactorización de código se ha llevado a cabo de manera informal durante años, la tesis doctoral de William F. Opdyke (1993) es el primer trabajo conocido que examina específicamente esta técnica. Todos estos recursos proporcionan un catálogo de métodos habituales de refactorización. Un método de refactorización tiene una descripción de cómo aplicar el método e indicaciones sobre cuándo debería (o no debería) aplicarse.
La refactorización es la parte del mantenimiento del código que no arregla errores ni añade funcionalidad. El objetivo, por el contrario, es mejorar la facilidad de comprensión del código o cambiar su estructura y diseño y eliminar código muerto, para facilitar el mantenimiento en el futuro. Añadir nuevo comportamiento a un programa puede ser difícil con la estructura dada del programa, así que un desarrollador puede refactorizarlo primero pa- La refactorización es un concepto tan importante que ha ra facilitar esta tarea y luego añadir el nuevo comporta- sido identificado por David A. Wheeler como «una de miento. las más importantes innovaciones en el campo del softEl término se creó como analogía con la factorización de ware».* [1] números y polinomios. Por ejemplo, x2 −1 puede ser factorizado como (x + 1)(x − 1) , revelando una estructura interna que no era visible previamente (como las dos raí173.2 Refactorización de otros texces en −1 y +1). De manera similar, en la refactorización del software, el cambio en la estructura visible puede fretos cuentemente revelar la estructura interna “oculta”del código original. El término refactorización se originó en el ámbito de la La refactorización debe ser realizada como un paso separado, para poder comprobar con mayor facilidad que no se han introducido errores al llevarla a cabo. Al final de la refactorización, cualquier cambio en el comportamiento es claramente un bug y puede ser arreglado de manera separada a la depuración de la nueva funcionalidad.
programación de ordenadores, pero el concepto se ha aplicado a la modificación de cualquier texto.
En los sitios Wiki, la refactorización se refiere al proceso de reescribir y reorganizar el texto para abreviarlo preservando su contenido. Se aplica en especial en las discusiones, que de esta manera pueden ser hechas accesibles para Un ejemplo de una refactorización trivial es cambiar el personas que están interesadas en los argumentos ofreci326
173.5. ENLACES EXTERNOS dos en la discusión y en la información que se obtiene de ella, más que en la propia historia de la discusión. Puede ser difícil refactorizar de tal manera que estén de acuerdo todos los participantes de la discusión.
173.3 Etimología El primer uso conocido del término refactorización en la literatura publicada se encuentra en el artículo Refactoring: An Aid in Designing Application Frameworks and Evolving Object-Oriented Systems, Proceedings of the Symposium on Object Oriented Programming Emphasizing Practical Applications (SOOPPA) September, 1990, ACM por William F. Opdyke y Ralph E. Johnson.* [2] La tesis doctoral de William Opdyke titulada “Refactoring Object-Oriented Framework”(Universidad de Illinois) se publicó en 1992.* [3] Tanto el término refactorización como la técnica que define se usaban ya con toda seguridad antes.
173.4 Referencias [1] [2] [3]
173.5 Enlaces externos • Libro de Martin Fowler' sobre refactorización
327
Capítulo 174
Reflexión (informática) En informática, reflexión (o reflexión computacional) es la capacidad que tiene un programa para observar y opcionalmente modificar su estructura de alto nivel.
174.2 Ejemplos 174.2.1
Python
Normalmente, la reflexión es dinámica o en tiempo de ejecución, aunque algunos lenguajes de programación # sin reflexión Foo().bar() # usando reflexión. gepermiten reflexión estática o en tiempo de compilación. tattr(globals()['Foo'](), 'bar')() Es más común en lenguajes de programación de alto nivel ejecutándose sobre una máquina virtual, como Smalltalk o Java, y menos común en lenguajes como C.
174.2.2
C#
En un sentido más amplio, la reflexión es una actividad computacional que razona sobre su propia computación. // Con reflexión // Usando GetType para obtener Cuando el código fuente de un programa se compila, nor- información del tipo: int i = 24; System.Type tipo malmente se pierde la información sobre la estructura = i.GetType(); System.Console.WriteLine(tipo); El del programa conforme se genera el código de bajo nivel resultado sería: System.Int32 (normalmente lenguaje ensamblador). Si un sistema permite reflexión, se preserva la estructura como metadatos en el código generado. Dependiendo de la implementación, el código con reflexión tiende a ser más lento que el 174.3 Véase también que no lo tiene. En los lenguajes que no distinguen entre tiempo de ejecución y tiempo de compilación (como las distintas variantes de Lisp), no hay diferencia entre compilación o interpretación de código y reflexión.
174.1 Implementación Un lenguaje con reflexión proporciona un conjunto de características disponibles en tiempo de ejecución que, de otro modo, serían muy difícilmente realizables en un lenguaje de más bajo nivel. Algunas de estas características son las habilidades para: • Descubrir y modificar construcciones de código fuente (tales como bloques de código, clases, métodos, protocolos, etc.) como objetos de“categoría superior”en tiempo de ejecución. • Convertir una cadena que corresponde al nombre simbólico de una clase o función en una referencia o invocación a esa clase o función. • Evaluar una cadena como si fuera una sentencia de código fuente en tiempo de ejecución. 328
• Lenguajes de programación con tipos dinámicos • Metaprogramación
Capítulo 175
Relación de compresión (informática) En la compresión digital, la relación de compresión (RC) indica en qué proporción ha sido reducida la información. Por ejemplo, un RC de 10:1 indica que por cada 10 bits del archivo informático original solamente tenemos 1 bit en el fichero comprimido, es decir, el tamaño del fichero se habrá reducido en 10 veces.
175.0.1
Véase también
• Compresor digital
329
Capítulo 176
Resolución de problemas de programación La resolución de un problema mediante un ordenador periencia del experto del dominio para entender el probleconsiste en el proceso que a partir de la descripción de un ma. Al final, si se quiere llegar a una solución satisfactoria problema, expresado habitualmente en lenguaje natural y es necesario que: en términos propios del dominio del problema, permite desarrollar un programa que resuelva dicho problema. • El problema esté bien definido con el máximo deEste proceso exige los siguientes pasos: talle • Las especificaciones de las entradas y salidas del problema, deben ser descritas también en detalle:
• Análisis del problema. • Diseño o desarrollo de un algoritmo. • Transformación del algoritmo en un programa (codificación).
• ¿Qué datos son necesarios para resolver el problema?
• Ejecución y validación del programa.
• ¿Qué información debe proporcionar la resolución del problema?
Los dos primeros pasos son los más difíciles del proceso. Una vez analizado el problema y obtenido un algoritmo que lo resuelva, su transformación a un programa de ordenador es una tarea de mera traducción al lenguaje de programación deseado.
176.1 Análisis del problema informático
176.2 Diseño del algoritmo Un algoritmo consiste en una especificación clara y concisa de los pasos necesarios para resolver un determinado problema, pero para poder diseñar algoritmos es necesario disponer de una notación, que llamaremosʻnotación algorítmicaʼ, que permita:
Cuando un usuario plantea a un programador un problema que resolver mediante su ordenador, por lo general ese usuario tendrá conocimientos más o menos amplios sobre el dominio del problema, pero no es habitual que tenga conocimientos de informática. Por ejemplo, un contable que necesita un programa para llevar la contabilidad de una empresa será un experto en contabilidad (dominio del problema), pero no tiene por qué ser experto en programación. Del mismo modo, el informático que va a resolver un determinado problema puede ser un experto programador, pero en principio no tiene por qué conocer el dominio del problema; siguiendo el ejemplo anterior, el informático que hace un programa no tiene por qué ser un experto en contabilidad.
• Describir las operaciones puestas en juego (acciones, instrucciones, comandos,...) • Describir los objetos manipulados por el algoritmo (datos/informaciones) • Controlar la realización de las acciones descritas, indicando la forma en que estas se organizan en el tiempo
Para poder describir cualquier tipo de acción de las que intervienen en un algoritmo, diversos autores proponen el uso de un conjunto de construcciones lógicas (secuencia, decisión e iteración) con las que es posible escribir cualquier programa. Lo que sigue a continuación es la desPor ello, al abordar un problema que se quiere resolver cripción de las diferentes construcciones disponibles para mediante un ordenador, el programador necesita de la ex- el diseño de algoritmos. 330
176.2. DISEÑO DEL ALGORITMO
176.2.1
Acciones elementales
331
176.2.5 Composición condicional múltiple
Se entiende por acciones elementales aquellas que el or- También es posible que a la hora de especificar la ejecución de una acción haya que escoger ésta entre varias denador es capaz de realizar y que serán de dos tipos: dependiendo del valor de una determinada variable (o indicador). Este caso se expresa del siguiente modo: • Aritmético – lógicas: Operaciones que, a partir de unos determinados datos, realizan un cálculo arit- Según Indicador Hacer Caso Valor 1: Acción 1; Caso mético (suma, resta, multiplicación,...) o un cálculo Valor 2: Acción 2; ... Caso Valor n: Acción n; [De Otro lógico (mayor que, menor que, igual que,...).Las pri- Modo: Acción X;] FinSegun meras devuelven un valor numérico (4, −5.67,...) y En esta construcción Indicador debe tener un determilas segundas un valor lógico (verdadero o falso). nado valor que en caso de coincidir con alguno de los n valores provocará la ejecución de la acción asociada a • De entrada – salida: Acciones que permiten cap- dicho valor. Si el valor del Indicador no coincidiera con turar datos para su posterior tratamiento (las de en- ninguno de los especificados se ejecutará la Acción X. No trada) y guardar los resultados de dicho tratamiento tiene por qué haber una Acción X para cuando el Indicador' no coincida con ninguno de los n valores; en ese (las de salida). caso, si el Indicador' no coincide con ningún valor no se ejecutaría ninguna acción.
176.2.2
Secuencia de acciones elementales
Al igual que en los casos anteriores, todas las acciones que aparecen en esta estructura (Acción 1, Acción 2,..., Acción Cuando en un algoritmo se deben ejecutar varias accio- n y Acción X) pueden referirse a una única acción o a un nes sucesivamente, éstas se describen una detrás de otra conjunto de ellas. según el orden en que deban ejecutarse. Si se desea se puede emplear algún tipo de símbolo para separar dos acciones consecutivas. En el siguiente ejemplo se muestra 176.2.6 Composición iterativa o bucle la descripción de n acciones separadas por punto y coma (símbolo que habitualmente se emplea como separador). Cuando una acción o conjunto de acciones debe ejecutarse varias veces se recurre a una estructura iterativa o Acción 1; Acción 2; ... Acción n; bucle. En este tipo de estructuras se necesita una condición que determine cuando terminan las iteraciones. Dependiendo de si esa condición se evalúa al principio o al final de la estructura y de si la condición para que las ite176.2.3 Composición condicional raciones continúen debe ser verdadera o falsa, se pueden Cuando en un algoritmo se quiere indicar que cierta ac- definir cuatro construcciones iterativas distintas: ción solo se debe ejecutar bajo cierta condición se indica Sobre las cuatro construcciones que se acaban de presendel siguiente modo: tar cabe hacer las siguientes observaciones: Si Condición Entonces Acción; FinSi Solo si la Condición (operación lógica) es verdadera se ejecutará la Acción. En este caso, la Acción puede referirse tanto a una acción elemental como a un conjunto de ellas.
176.2.4
Composición condicional doble (alternativa)
En ocasiones, se deben ejecutar unas acciones u otras dependiendo de la ocurrencia de una determinada condición. Esta especificación se realiza del siguiente modo: Si Condición Entonces Acción A; SiNo Acción B; FinSi Dependiendo de si la Condición es verdadera o falsa se ejecutará la Acción A o la Acción B respectivamente. De forma análoga a como ocurría en el caso anterior, tanto la Acción A como la Acción B pueden referirse a una acción elemental o a un conjunto de ellas.
• Si en las estructuras 1 y 2, cuando se evalúa laʻCondiciónʼ, ésta toma por primera vez un valor tal que no permita ejecutar laʻAcciónʼ(FALSO en la 1 y VERDADERO en la 2), ésta no se ejecutará ninguna vez. Es decir, puede ocurrir que la ʻAcciónʼ, en las estructuras 1 y 2, no se ejecute nunca. • En las estructuras 3 y 4, al estar laʻCondiciónʼde terminación al final, laʻAcciónʼse ejecutará antes de que la condición se evalúe por primera vez, por lo que aunque laʻCondiciónʼtome un valor tal que no se permita realizar más iteraciones, la ʻAcciónʼ se ejecutará al menos una vez. • Si las ʻCondicionesʼde las estructuras 1 y 2 son complementarias, es decir, que siempre que una es verdadera la otra es falsa y viceversa (ejemplo: [a > b] y [a ≤ b] son condiciones complementarias), entonces ambas estructuras son equivalentes ya que en ambas laʻAcciónʼse ejecutará el mismo número de veces.
332
CAPÍTULO 176. RESOLUCIÓN DE PROBLEMAS DE PROGRAMACIÓN
• De forma análoga, si las ʻCondicionesʼde las estructuras 3 y 4 son complementarias también ambas estructuras serán equivalentes. Existe una construcción especial para indicar una repetición de acciones que se suele emplear cuando se quiere que dicha repetición se realice un número determinado de veces: Para i = 1 Hasta n Hacer Acción; FinPara En este caso laʻAcciónʼse repetirá n veces eʻiʼserá una variable que tomará todos los valores entre 1 y n (ambos inclusive) en cada una de las sucesivas repeticiones. Esta construcción, aunque de apariencia diferente a las anteriores, se podría expresar como un caso particular de la estructura 1 del siguiente modo: i = 1; Mientras i <= n Hacer Acción; i = i + 1; FinMientras En este caso la condición de finalización del bucle es que la variableʻiʼsea mayor queʻnʼy siempre, al finalizar la ejecución de laʻAcciónʼ,ʻiʼse incrementa en una unidad antes de volver a evaluar la ʻCondiciónʼpara el nuevo valor de ʻiʼ.
176.3 Véase también • Algoritmo • Programación • Pseudocódigo • Diagrama de flujo • Estructuras de control • Bucle (programación) • Bucle for • Bucle while • Bucle repetir • Bucle infinito • Programación estructurada • Lenguaje de programación • Resolución de problemas
Capítulo 177
Instancia (programación) En el paradigma de la orientación a objetos, una instan- se (puede hacerlo para permitir ejecuciones concurrencia se refiere a una realización específica de una clase o tes de distintas versiones de una clase)* [Nota 1] entonces prototipo determinados. las clases serán representadas utilizando un Singleton. En En general, cuando se ejecuta un programa en un compu- Java, por ejemplo, si tenemos una clase definida como: tador, se dice que éste se instancia. En lenguajes que crean objetos a partir de clases, un objeto es una instancia de una clase. Esto es, es un miembro de una clase que tiene atributos en lugar de variables. En un contexto del mundo real, podríamos pensar en “Perro”como una clase y en un perro conreto en una instancia de esta clase.* [1]
177.1 Programación basada en clases En este apartado hablaremos de la programación orientada a objetos basada en clases, que es la que implementa la mayoría de lenguajes de programación orientados a objetos. En el modelo basado en prototipos, que es el de lenguajes como JavaScript, los términos que se refieren a clases han de sustituirse por los prototipos de los objetos, pero por lo demás, son de aplicación similar.
public class Perro {} Podremos acceder a la instancia que representa la clase (y es una instancia de la clase java.lang.Class), en un programa principal de clase Main, del siguiente modo: public class Main { public static void main(String... args) { Class> perroClass = Perro.class; System.out.println(perroClass); } }
177.2 Programación prototipos
En este modelo, un objeto tiene una referencia a la clase a la que pertenece y, por tanto, puede llamar a los métodos de instancia que hayan sido declarados como de instancia, así como a todos aquellos que hayan sido heredados por la jerarquía de herencia estática entre clases.
basada
en
En el estilo de programación orientada a objetos basada en prototipos las instancias son los objetos creados a partir de los prototipos. En general, los prototipos también son objetos creados a partir de otros prototipos, con lo que las propiedades y métodos se heredan en la profundidad Ciertos lenguajes de programación permiten utilizar clacompleta del árbol de herencia de prototipado. ses mixin, que permiten además realizar asociaciones entre instancias de objetos para establecer relaciones simi- En el caso particular de JavaScript, aunque no se puede cambiar el prototipo de un objeto una vez instanciado, sí lares a la herencia en tiempo de ejecución. se pueden cambiar las propiedades y métodos que tiene el prototipo, afectando a todas las instancias (en profundidad) de ese prototipo. En el caso particular de este len177.1.1 Clases como objetos guaje, en el que todos los objetos son instancias de ObMultitud de lenguajes de programación basados en cla- ject, modificar o añadir métodos a Object tendrá como ses proporcionan mecanismos de reflexión o introspec- consecuencia la modificación de esos métodos u objetos ción, esto es, permiten que el programa pueda observar en todos los demás objetos que no los hayan redefinido (e incluso modificar) su propia estructura de alto nivel. Si posteriormente, incluyendo los ya instanciados. Este es estos mecanismos siguen el paradigma de orientación a el mecanismo que utilizan algunas bibliotecas de JavaSobjetos también, entonces las clases serán representadas cript* [Nota 2] para proporcionar funciones que no hayan también como instancias de objetos. En particular, si el implementado ciertos motores a ciertos objetos del lenlenguaje no permite dos definiciones de una misma cla- guaje. 333
334
177.3 Notas [1] Erlang, por ejemplo, permite la ejecución concurrente de varias versiones de un mismo programa, véase [server.html#Module:code change-3 http://www.erlang. org/doc/man/gen server.html#Module:code change-3], y CLOS. [2] http://augmentjs.com, por ejemplo, proporciona métodos al objeto Array.prototype, cambiando todos los Array del programa.
177.4 Referencias [1] http://whatis.techtarget.com/definition/instance (en inglés)
CAPÍTULO 177. INSTANCIA (PROGRAMACIÓN)
Capítulo 178
Anexo:Scan code Son los códigos que envía el teclado al ordenador para indicar la tecla pulsada o soltada. Su valor no depende de la tecla, sino de su posición, así se consigue que sea independiente del idioma del teclado. Para el teclado QWERTY (PS/2) y códigos ASCII los scan codes son:
335
Capítulo 179
scanf En C, la función scanf() (scan-format, analizar con formato), en realidad representa a una familia de funciones que analizan una entrada de datos con formato y cargan el resultado en los argumentos que se pasan por referencia a dicha función o funciones: • La función scanf() lee los datos de entrada en el stdin (flujo de entrada estándar).
ll (codo-codo) - Especifica que especificador una d, un i, un o, un u, un x, de una conversión siguiente de X, o de n se aplica a un argumento con el tipo indicador a largo largo largo o sin firmar largo. j - Especifica que especificador una d, un i, un o, un u, un x, de una conversión siguiente de X, o de n se aplica a un argumento con el tipo indicador al intmax_t o al uintmax_t.
• La función fscanf() (file-scanf) lee en un flujo de entrada dado, por lo general un fichero (file) abierto para lectura. • La función sscanf() (string-scanf) obtiene la entrada que se va a analizar de una cadena de caracteres dada (string).
z - Especifica que especificador una d, un i, un o, un u, un x, de una conversión siguiente de X, o de n se aplica a un argumento con el tipo indicador al size_t o al tipo correspondiente del entero con signo.
Todas ellas leen caracteres, los interpretan según un formato, y almacenan los resultados en sus argumentos. Cada uno cuenta con varios argumentos: por un lado, un formato de la secuencia del control (se describe más abajo), por otro, un sistema de argumentos del indicador que señala dónde la entrada convertida debe ser almacenada. El resultado es indefinido si hay escasos argumentos para dar formato. Si se agota el formato mientras que sigue habiendo las argumentos, los argumentos sobrantes son evaluados pero no procesados de ninguna otra manera.
179.0.1
mento con el tipo indicador al doble; o que una c siguiente, s, o [el especificador de la conversión se aplica a una argumento con el tipo indicador al wchar_t.
t - Especifica que especificador una d, un i, un o, un u, un x, de una conversión siguiente de X, o de n se aplica a un argumento con el tipo indicador al ptrdiff_t o al tipo sin firmar correspondiente. L - Especifica que una a siguiente, A, e, E, f, F, g, o especificador de la conversión de G se aplica a un argumento con el tipo indicador al doble largo. Si un modificante de la longitud aparece con cualquier especificador de la conversión con excepción de según lo especificado arriba, el comportamiento es indefinido.
Modificantes de longitud
Los modificantes de la longitud y sus significados son:
Los especificadores siguientes de la conversión que son válidos
hh - Específica que especificador una d, un i, un o, un u, un x, de una conversión siguiente de X, o de n se aplica d - Empareja un número entero decimal opcionalmente a un argumento con el tipo indicador al carbón firmado o con signo, que formato es igual según lo esperado para la al carbón sin firmar. secuencia sujeta del strtol() con el valor 10 para el arguh - Específica que especificador una d, un i, un o, un u, mento bajo. En ausencia de un modificante del tamaño, un x, de una conversión siguiente de X, o de n se aplica a el uso se asegurará de que el argumento correspondiente un argumento con el tipo indicador al cortocircuito corto sea un indicador a interno. o sin firmar.
i - Empareja un entero con signo opcionalmente, que formato es igual según lo esperado para la secuencia sujeta del strtol() con 0 para el argumento bajo. En ausencia de un modificante del tamaño, el uso se asegurará de que el argumento correspondiente sea un indicador a interno.
l (codo) - Específica que especificador una d, un i, un o, un u, un x, de una conversión siguiente de X, o de n se aplica a un argumento con el tipo indicador para desear o largo sin firmar; que una a siguiente, A, e, E, f, F, g, o especificador de la conversión de G se aplica a una argu- o - Empareja un número entero octal opcionalmente con 336
337 signo, que formato es igual según lo esperado para la secuencia sujeta del strtoul() con el valor 8 para el argumento bajo. En ausencia de un modificante del tamaño, el uso se asegurará de que el argumento correspondiente sea un indicador a sin firmar. u - Empareja un número entero decimal opcionalmente con signo, que formato es igual según lo esperado para la secuencia sujeta del strtoul() con el valor 10 para el argumento bajo. En ausencia de un modificante del tamaño, el uso se asegurará de que el argumento correspondiente sea un indicador a sin firmar. x - Empareja un número entero hexadecimal opcionalmente con signo, que formato es igual según lo esperado para la secuencia sujeta del strtoul() con el valor 16 para el argumento bajo. En ausencia de un modificante del tamaño, el uso se asegurará de que el argumento correspondiente sea un indicador a sin firmar. a, e, f, g - Empareja un número, un infinito, o un NaN floating-point opcionalmente con signo, que formato es igual según lo esperado para la secuencia sujeta del strtod (). En ausencia de un modificante del tamaño, el uso se asegurará de que el argumento correspondiente sea un indicador a flotar. >>>Si la familia del fprintf() de funciones genera las representaciones de la cadena de caracteres para el infinito y NaN (una entidad simbólica codificada en formato floating-point) para apoyar IEEE Std 754-1985, la familia del fscanf () de funciones las reconocerá como entrada. s - Empareja una secuencia de los octetos que no son caracteres del blanco-espacio. El uso se asegurará de que el argumento correspondiente sea un indicador al octeto inicial de un arsenal del carbón, del carbón firmado, o del carbón sin firmar bastante grande aceptar la secuencia y un código de carácter nulo que termina, que serán agregados automáticamente.
>>>Si un l (codo) calificador está presente, la entrada es una secuencia de caracteres que comienza en el estado inicial de la cambio. Cada carácter en la secuencia será convertido a un carácter ancho como si por una llamada a la función del mbrtowc (), con el estado de la conversión descrito por un objeto del mbstate_t inicializado a cero antes del primer carácter sea convertido. El uso se asegurará de que el argumento correspondiente sea un indicador a un arsenal de wchar_t bastante grande para aceptar la secuencia y el carácter ancho nulo que termina, que serán agregados automáticamente. >>>La especificación de la conversión incluye todos los octetos subsecuentes en la secuencia del formato hasta e incluir el corchete derecho que empareja (“]”). Los octetos entre los corchetes (el scanlist) abarcan el scanset, a menos que el octeto después de que el corchete izquierdo sea un circunflejo (“^”), en este caso el scanset contiene todos los octetos que no aparezcan en el scanlist entre el circunflejo y el corchete derecho. Si la especificación de la conversión comienza con”[] “o”[^] “, el corchete derecho se incluye en el scanlist y el corchete derecho siguiente es el corchete derecho que empareja que termina la especificación de la conversión; si no, el primer corchete derecho es el que termina la especificación de la conversión. Si “-”es en el scanlist y no es el primer carácter, ni el segundo donde está un“^”, ni el carácter el primer carácter pasado, puesta en práctica-se define el comportamiento.
c - Empareja una secuencia de los octetos del número especificado por la anchura del campo (1 si no hay anchura del campo presente en la especificación de la conversión). El uso se asegurará de que el argumento correspondiente sea un indicador al octeto inicial de un arsenal del carbón, del carbón firmado, o del carbón sin firmar bastante grande aceptar la secuencia. No se agrega ningún octeto nulo. Los caracteres excesivos del blanco-espacio del >>>Si un l (codo) calificador está presente, la entrada es salto normal serán suprimidos en este caso. una secuencia de caracteres que comienza en el estado >>>Si un l (codo) calificador está presente, la entrada seinicial de la cambio. Cada carácter será convertido a un rá una secuencia de caracteres que comienza en el estado carácter ancho como si por una llamada a la función del inicial de la cambio. Cada carácter en la secuencia se conmbrtowc (), con el estado de la conversión descrito por vierte a un carácter ancho como si por una llamada a la un objeto del mbstate_t inicializado a cero antes del pri- función del mbrtowc (), con el estado de la conversión mer carácter sea convertido. El uso se asegurará de que el descrito por un objeto del mbstate_t inicializado a cero argumento correspondiente sea un indicador a un arsenal antes del primer carácter sea convertido. El uso se asegude wchar_t bastante grande para aceptar la secuencia y rará de que el argumento correspondiente sea un indicael carácter ancho nulo que termina, que serán agregados dor a un arsenal de wchar_t bastante grande para aceptar automáticamente. la secuencia que resulta de caracteres anchos. No se agre[ - Empareja una secuencia no vacía de octetos de un sis- ga ningún carácter ancho nulo. tema de los octetos previstos (el scanset). Los caracteres s - Indica que es una cadena de caracteres (string). La enexcesivos del blanco-espacio del salto normal serán supri- trada se termina con un espacio en blanco y un caracter midos en este caso. El uso se asegurará de que el argu- null es guardado al final de la cadena de caracteres. Esto mento correspondiente sea un indicador al octeto inicial significa que el buffer utilizado debe ser por lo menos un de un arsenal del carbón, del carbón firmado, o del car- caracter más grande que la longitud de entrada especificabón sin firmar bastante grande aceptar la secuencia y un da. De no ser así podría darse el caso que se sobrescriban octeto nulo que termina, que serán agregados automáti- porciones de memorias adyacentes, generando resultados camente. inesperados.
338 /*Posibles resultados no deseados al leer un solo caracter*/ char a; scanf("%s”,&a); /*Una forma non-sancta de evitarlo usando arreglos el caracter quedaría en a[0] */ char a[2]; scanf("%s”,a);
CAPÍTULO 179. SCANF introducidos por teclado, de tipos int, float y char //Si se introduce un dato erróneo se interrumpe la lectura del resto. int validos; printf(“Introduce un entero, un real, y un caracter:"); validos=scanf("%i%f%c”,&a,&b,&c); //Entrada: 5 1.2 J | Salida: 3 //Lectura de una cadenas de caracteres printf(“Introduce una palabra: "); scanf("%10s”,cad); // lee máximo 10 caracteres y le concatena el caracter cero.
p - Empareja un sistema puesta en práctica-definido de las secuencias, que serán iguales que el sistema de secuencias que es producido por la especificación de la conversión de %p de las funciones correspondientes del fprintf (). El uso se asegurará de que el argumento correspondiente sea un indicador a un indicador a anular. La interpretación del artículo de la entrada puesta en práctica-se define. Si el artículo de la entrada es un valor convertido anterior 179.3 Funciones derivadas durante la misma ejecución de programa, el indicador que los resultados compararán el igual a ese valor; si no, el comportamiento de la especificación de la conversión de 179.3.1 fscanf %p es indefinido. La función fscanf lee datos de entrada desde un fichero, n - No se consume ninguna entrada. El uso se asegurará en lugar de utilizar la entrada estándar. de que el argumento correspondiente sea un indicador al número entero en el cual será escrito el número de los oc- (C o C++) tetos leídos en la entrada hasta ahora por esta llamada a int fscanf (FILE *file, const char *format,...); las funciones del fscanf (). La ejecución de una especificación de la conversión de %n no incrementará la cuenta (PHP) de la asignación vuelta en la terminación de la ejecución int fscanf (resource file, const string format [, mixed de la función. No se convertirá ningún argumento, pero args...]); una será consumido. Si la especificación de la conversión incluye un carácter asignación-que suprime o una anchu- fscanf trabaja igual que la función scanf original; las entradas una vez leídas no serán leídas otra vez hasta que el ra del campo, el comportamiento es indefinido. archivo sea cerrado y abierto de nuevo.
179.1 Sintaxis valor_devuelto=scanf(tipo, &var);
179.3.2 sscanf La función sscanf lee datos de entrada desde un buffer, en lugar de utilizar la entrada estándar.
• valor_devuelto: representa el número datos leídos Sus prototipos son los siguientes: correctamente. Devuelve distinto de 0 si lee al(C o C++) guno.[Opcional] • tipo: Tipo de dato a almacenar
int sscanf (char *buffer, const char *format,...);
Retorna la cantidad de datos que pudo leer. • ampersand (&) se utiliza para indicar una dirección de memoria de la variable donde se almacenará el Recuerda que los parámetros después de *format deben dato. Cuando se guardan de cadenas de caracteres, ser punteros a variables donde la función dejará lo que lee. Estas variables deben tener el espacio suficiente. al tratarse de un array de tipo char, el & se omite. • var: variable para almacenar el dato.
179.4 Véase también 179.2 Ejemplo // Este ejemplo guarda un número en n. #include int n; printf(“Introduce un numero: "); scanf("%d”,&n); // Este ejemplo guarda en una variable en num. char num; printf(“Introduce un caracter: "); scanf("%c”,&num); // Este ejemplo guarda una cadena de caracteres (solamente una palabra) en cad. // Notese la ausencia de & char cad[20]; printf(“Introduce una palabra: "); scanf("%s”,cad); //Lectura de varios datos
• scanf_s • printf • stdio.h • Lenguaje de programación C • PHP
179.5. ENLACES EXTERNOS
179.5 Enlaces externos • scanf(3): conversión de la entrada con formato – Subrutinas en el Manual de Debian
339
Capítulo 180
SCons SCons es una herramienta de código abierto para la construcción e instalación de software a través de scripts hechos en Python, para los sistemas operativos basados en Unix. Su objetivo es ser una variante al método de compilación tradicional de fuentes. Entre sus ventajas se encuentra el análisis de dependencias. Scons utiliza el lenguaje de programación Python de propósitos generales como fundación, para que todas las de proyectos de configuraciones software y construcción de procesos implementarios sean los scripts de Python.
180.1 Véase también • Make • Autoconf
180.2 Enlaces externos Página oficial de SCons
340
Capítulo 181
Screen scraping Screen scraping es el nombre en inglés de una técnica de programación que consiste en tomar una presentación de una información (normalmente texto, aunque puede incluir información gráfica) para, mediante ingeniería inversa, extraer los datos que dieron lugar a esa presentación. Por ejemplo: • Extraer de la página web de un diario el tiempo meteorológico previsto. • Extraer los datos originales a partir de la imagen de una gráfica elaborada. • Hacer una consulta automática a la página de gestión de nuestro banco para verificar si el saldo es inferior a un umbral. • Extraer los datos de un informe en PDF para verterlos en una hoja de cálculo. En general, hay que destacar que los sistemas de los que se extrae la información no están diseñados para extraer dicha información (en algunos casos, es al contrario, como en los sistemas de captcha). La traducción aproximada de screen scraping es raspado de pantalla.
181.1 Véase también • Web scraping
341
Capítulo 182
Sección crítica Se denomina sección crítica, en programación concurrente, a la porción de código de un programa de ordenador en la que se accede a un recurso compartido (estructura de datos o dispositivo) que no debe ser accedido por más de un proceso o hilo en ejecución. La sección crítica por lo general termina en un tiempo determinado y el hilo, proceso o tarea sólo tendrá que esperar un período determinado de tiempo para entrar. Se necesita un mecanismo de sincronización en la entrada y salida de la sección crítica para asegurar la utilización en exclusiva del recurso, por ejemplo un semáforo. El acceso concurrente se controla teniendo cuidado de las variables que se modifican dentro y fuera de la sección crítica. La sección crítica se utiliza por lo general cuando un programa multihilo actualiza múltiples variables sin un hilo de ejecución separado que lleve los cambios conflictivos a esos datos. Una situación similar, la sección crítica puede ser utilizada para asegurarse de que un recurso compartido, por ejemplo, una impresora, pueda ser accedida por un solo proceso a la vez. La manera en cómo se implementan las secciones puede variar dependiendo de los diversos sistemas operativos. Sólo un proceso puede estar en una sección crítica a la vez. El método más común para evitar que dos procesos accedan al mismo tiempo a un recurso es el de la exclusión mutua.
182.1 Véase también • Cierre de exclusión mutua
342
Capítulo 183
Serialización En ciencias de la computación, la serialización (o mars- 183.3 Enlaces externos halling en inglés) consiste en un proceso de codificación de un objeto en un medio de almacenamiento (como pue- Para Java: de ser un archivo, o un buffer de memoria) con el fin de transmitirlo a través de una conexión en red como una • XML Data Binding serie de bytes o en un formato humanamente más legible como XML o JSON, entre otros. La serie de bytes o • Generar el serialVersionUID de una clase el formato pueden ser usados para crear un nuevo objeto que es idéntico en todo al original, incluido su estado inPara C#: terno (por tanto, el nuevo objeto es un clon del original). La serialización es un mecanismo ampliamente usado • Serialización XML de objetos en .net con C# (en para transportar objetos a través de una red, para hacer español) persistente un objeto en un archivo o base de datos, o para distribuir objetos idénticos a varias aplicaciones o localizaciones.
183.1 Usos Serialización tiene una serie de ventajas: • Un método de persistencia de objetos que es más conveniente que escribir sus propiedades a un archivo de texto en disco. • Un método de emisión de llamadas a procedimiento remoto, por ejemplo, como en SOAP. • Un método para la distribución de objetos, especialmente en los componentes software, tales como COM, CORBA, etc. • Un método para detectar cambios en variables en el tiempo.
183.2 Soporte en los lenguajes de programación Varios lenguajes de programación orientados a objeto soportan la serialización de forma directa. Algunos de ellos son Objective-C, Java, Delphi, C#, Visual Basic .NET, ColdFusion, Ocaml, Perl, Python, PHP y Ruby 343
Capítulo 184
Sigil En programación y sistemas de información, un sigil (pronunciado/ˈsɪdʒəl/ o /ˈsɪɡəl/; plural sigilia o sigiles) o sigilo es un símbolo agregado al nombre de una variable, especificando el tipo o alcance de la misma. Este término, basado en la palabra inglesa para sello mágico, fue usado por Philip Gwyn en 1999 “para designar el extraño carácter inicial en el nombre de una variable de Perl".
344
Capítulo 185
Signatura (informática) La signatura o firma de un método o una función define su entrada y su salida. Incluye por lo menos el nombre de la función o método y el número de sus parámetros. En algunos lenguajes de programación, puede incluir el tipo que devuelve la función o el tipo de sus parámetros. En el caso de un tipo de dato abstracto (TDA), se define signatura como los tipos que utiliza junto con los nombres y perfiles de las operaciones. Por ejemplo, para especificar el TDA de los booleanos se utiliza la siguiente signatura: 1. tipos bool 2. operaciones 3. verdadero : bool 4. falso : bool 5. And : bool x bool -> bool 6. Or : bool x bool -> bool 7. Not : bool -> bool
345
Capítulo 186
Signum Framework Signum Framework es un framework ORM Open Source creado por una empresa española en C# orientado al desarrollo de aplicaciones sobre la tecnología .Net de Microsoft, con un visión centrada en las entidades, de manera que es el modelo de datos el que determina el esquema de la base de datos. Como base de datos sólo está soportado MS SQL Server. Signum Framework se distribuye bajo licencia LGPL.
186.1 Características 186.1.1
de otros frameworks, la base de datos se genera a partir del código y no a la inversa. Dada la importancia que se concede a las entidades como núcleo de las aplicaciones, Signum Framework provee un pequeño grupo de clases base y primitivas que permiten modelar los objetos de una manera modular y reusable, evitando la redundancia y asegurando la integridad de los objetos, tanto en lógica como una vez persistidos en base de datos. Esto mismo (al tener que heredar las entidades desde alguna de estas clases base) hace que Signum Framework no soporte POCO (Plain Old C# Object).
Elementos de Signum Framework
Signum Framework está compuesto por los siguientes ensamblados:
186.1.3 Generación del esquema
La base de datos relacional se genera automáticamente a partir de las entidades utilizando un mapeado 1 a 1 des• Signum.Entities - Las clases base necesarias para gede las entidades a las tablas, de manera que cada entidad nerar las entidades de datos. independiente tiene su propia tabla y cada campo de la • Signum.Engine - El motor ORM con un proveedor entidad su propia columna. Las entidades que son embebidas (EmbeddedEntity) no tienen una tabla propia, sino LINQ completo. que sus campos se guardan como columnas en la tabla de • Signum.Utilities - Conjunto de utilidades y herra- la entidad a la que pertenecen. Se utilizan tablas relacionales para las colecciones, lo que permite las relaciones mientas. N a N. • Signum.Services - Interfaces base del servicio WCF Para permitir realizar modificaciones sobre los datos sin • Signum.Windows - Controles base para manipular tener que regenerar la base de datos cada vez, se puede realizar una sincronización entre las entidades y la base entidades de datos existente, en la que el motor generará un archivo de script SQL con las modificaciones necesarias para actualizar el esquema. 186.1.2 Entidades primero La filosofía centrada en las entidades propicia que el esquema de datos se genere automáticamente a partir de los objetos de código, evitando mapear los campos entre la base de datos y las entidades a través de archivos de configuración. De esta manera se trata de que se detecten las posibles incidencias en tiempo de compilación para todas las clases (tanto de datos como de lógica).
186.1.4 Herencia de entidades
Aunque Signum Framework utiliza un sistema de“tabla por clase concreta”, en el que se crea una tabla una por cada uno de los tipos concretos, permite implementar el Por otro lado, esto mismo impide que Signum Framework concepto de herencia utilizando relaciones polimórficas, se adapte bien a proyectos en los que existe una base de que cuentan con una clave externa que admite valores nudatos anterior que se debe preservar, ya que, a diferencia los por cada posible implementación. 346
186.2. HISTORIA
186.1.5
Interfaz de usuario y WCF
Signum.Windows ofrece controles WPF básicos que aprovechan la homogeneidad de las entidades para implementar un comportamiento automático. Estos controles simplifican el desarrollo de las vistas de las entidades de una aplicación. Para la comunicación entre los clientes y el servidor se utilizan contratos WCF que permiten la compartición de tipos. Esto facilita reutilizar las reglas de validación de las entidades en el cliente, eliminando la redundancia. La utilización de objetos Lazy permite trabajar con“huellas”de una entidad, conociendo su ToString y su identificador, pero sin recuperar la entidad completa hasta que sea necesario, minimizando así la carga de trabajo y la transferencia de datos, aumentando considerablemente el rendimiento de las aplicaciones.
186.1.6
LINQ
Signum Framework tiene un proveedor LINQ completo, de manera que todas las operaciones se ejecutan en LINQ, e internamente el motor las traduce a SQL. Algunas de las características del proveedor de LINQ son las siguientes:
347
186.2 Historia • 2004 - Primera versión de un motor ORM basado en los principios de reutilización y centrado en entidades. • 2007 - Segunda versión del motor ORM, incluyendo el Gestor de Operaciones y Procesos. • 2008 - Signum Framework 1.0 Beta 1, incluyendo las funcionalidades de ORM, WPF y LINQ. • 2009 - Release de Signum Framework 1.0 en Codeplex. • 2010 - Signum Framework 2.0 Beta 1, con soporte para .Net Framework 4 y ASP.Net MVC 2.0 (versión interna). • 2011 - Signum Framework 2.0 Beta 2, con soporte para ASP.Net MVC 3.0 (versión interna). • 2011 - Release de Signum Framework 2.0, incluyendo soporte para .Net Framework 4 y ASP.Net MVC 3.0
186.3 Enlaces externos
• Soporta joins.
• Página oficial de Signum Framework.
• Soporta valores booleanos en cualquier parte de la consulta.
• Código fuente de Signum Framework.
• Soporta GroupJoin y DefaultIfEmpty. • Soporta Group By en C# y VB.NET con agregados múltiples. • Soporta el uso de let en las consultas. • Maneja la construcción de objetos en memoria dentro de consultas, así como llamadas a métodos en memoria. • Soporta tipos nulables y conversiones implícitas. • Ofrece emulación nativa de funciones SQL. • Soporta operaciones de tipo SelectMany. Debido a algunas de las funcionalidades que soporta (en concreto las funciones CROSS APPLY / OUTER APPLY), actualmente las bases de datos soportadas por Signum Framework se limitan a SQL Server 2005 y SQL Server 2008 (tanto en las versiones Express como en las versiones de pago). La principal diferencia entre el proveedor de LINQ de Signum Framework y otros proveedores es que no depende de un contexto explícito que depende del esquema actual de la base de datos, lo que permite escribir lógica de negocio reutilizable.
• Canal de Youtube con tutoriales sobre Signum Framework. • Sitio web de Signum Software.
Capítulo 187
Simple Network Library Simple Network Library (SNL) es una biblioteca in- 187.2 Desarrollo formática desarrollada con el lenguaje C que proporciona funciones para realizar operaciones de comunicación en El sistema de control de versiones usado en el desarrollo red. La primera versión de esta biblioteca fue acabada el de SNL es Darcs por ser distribuido y no depender sus 5 de abril de 2009. repositorios de un servidor. El repositorio oficial es acceProporciona herramientas para el desarrollo de sible desde internet y los parches son enviados al mantevideojuegos y cualquier otra aplicación que necesi- nedor por correo electrónico para ser aplicados al reposite comunicación a través de una red informática. Una torio oficial. Todo aquel que quiere colaborar en el desade sus grandes virtudes es el tratarse de una biblioteca rrollo de SNL únicamente tiene que obtener una copia de multiplataforma, soportando oficialmente los sistemas trabajo desde el repositorio oficial y realizar los cambios GNU/Linux y OpenSolaris, además de otras arquitectu- que desee, enviando después los parches resultantes para ras/sistemas como windows, MacOS, etc. Las siglas le que puedan ser aplicados al repositorio oficial. vienen de Simple Network Library que se traduce como En la página web oficial de SNL se indica la localización biblioteca de red simple. Desarrollada inicialmente por del repositorio oficial así como documentación que pueJesús Hernández Gormaz. den consultar todos aquellos que quieran participar en el Soporta los protocolos de IP tanto de IPv4 como de IPv6 hacking de SNL y no conozcan el uso de Darcs. además de los protocolos de comunicación TCP y UDP. La biblioteca se distribuye bajo la licencia GPL.
187.3 Véase también • Simple DirectMedia Layer
187.4 Referencias 187.1 Origen del nombre
187.5 Bibliografía
El origen del nombre, Simple Network Library, puede 187.5.1 Documentación de SNL considerarse como un guiño a la biblioteca Simple DirectMedia Layer, SDL, ya que como se puede observar • Jesús Hernández Gormaz (2009). Documentacion de las siglas solo varían de una D, SDL, a una N, SNL. Esto SNL (1). p. 2. es debido a que al igual que SDL es ampliamente usada para el desarrollo de videojuegos, especialmente de videojuegos que sean software libre, SNL se creó con la 187.6 Enlaces externos intención de facilitar el desarrollo y programación de videojuegos multijugador en red aún más de lo que pueda • www.snl.ya.st - Página oficial de SNL (en esperanto, facilitarlo otras bibliotecas como SDL Net, de forma que español e ingles). el trabajo de el programador con los sockets y la labor de conseguir Multiplexación, para que un servidor pueda atender a varios clientes de forma no bloqueante, sea lo suficientemente sencillo para que el programador no pierda tiempo en la comunicación que podría invertir en el juego en si. 348
Capítulo 188
Smarty Smarty es un motor de plantillas para PHP, es decir, separa el código PHP, como lógica de negocios, del código HTML, como lógica de presentación, y genera contenidos web mediante la colocación de etiquetas Smarty en un documento. Se encuentra bajo la Licencia Pública General Reducida de GNU.
medida van surgiendo sistemas de separación en capas que intentan disciplinar un poco las metodologías de programación envueltas en el desarrollo con PHP, pero que no hacen otra cosa que acercarse más y más a otras herramientas ya existentes en otros entornos de desarrollo más complejos y pensados desde sus orígenes para proyectos más grandes, como pueden ser J2EE (Java), .NET (C#) Es común que en grandes proyectos el rol de diseñador gráfico y el de programador sean cubiertos por personas o Django (Python). distintas, sin embargo la programación en PHP tiene la tendencia de combinar estas dos labores en una persona y dentro del mismo código, lo que trae consigo grandes 188.3 Ejemplo dificultades a la hora de cambiar alguna parte del diseño de la página, pues se tiene que escarbar entre los scripts index.php para modificar la presentación del contenido, Smarty tiene como objetivo solucionar este problema. require_once(“smarty/Smarty.class.php”); // Instanciar la clase de Smarty $smarty = new Smarty(); // Configurar Smarty $smarty->template_dir = "./templates/"; $smarty->compile_dir = "./templates_c/"; $smarty188.1 Características >config_dir = "./configs/"; $smarty->cache_dir = "./cache/"; // Establecer variables que se usarán en la • Expresiones regulares plantilla $smarty->assign(“nombre”, “José Manuel Pardo Pérez”); $smarty->assign(“direccion”, “C/ • Bucles foreach, while Alpes, 992”); // Mostrar la plantilla $smarty->display( • Sentencias condicionales if, elseif, else “index.tpl”); • Modificadores de variables (por ejemplo: {$variable|nl2br})
index.tpl
• Funciones creadas por el usuario
tilla Información del Usuario Información del Usuario:
Nombre: {$nombre}
Dirección: {$direccion}
188.2 Críticas Existen más sistemas de plantillas para PHP, pero éste parece ser el más avanzado y con más frecuencia de desarrollo. También hay detractores de estas técnicas que alegan que las mismas hacen en cierta medida un grado más complejo el desarrollo web, por la necesidad de aprender un (pseudo) lenguaje más.
Salida HTML generada
Información del Usuario Información del Los detractores de esta idea se basan en el hecho de que, Usuario:
Nombre: José Manuel Pardo Pérez
Dirección: C/ Alpes, 992
rápido para hacer desarrollos web a pequeña escala. A 349
350
188.4 Referencias 188.5 Enlaces externos • Sitio web oficial • Documentación en español • Problemas con Smarty
CAPÍTULO 188. SMARTY
Capítulo 189
Snippet Snippet es un término del idioma inglés utilizado en programación para referirse a pequeñas partes reusables de código fuente, código binario o texto. Comúnmente son definidas como unidades o métodos funcionales que se pueden integrar fácilmente en módulos mucho más grandes, aportando funcionalidad. También se utiliza la palabra para referirse a la práctica de minimizar el uso de código repetido que es común en muchas funciones, por medio del uso de un solo método que pueda ser reutilizado. (No te repitas).
189.1
Rich snippets
Los rich snippets son etiquetas de código HTML utilizados por los programadores web para facilitar mayor información acerca del contenido de una web a los buscadores. La relación de etiquetas existentes en la actualidad, se puede encontrar en Schema.org.
189.2 Enlaces externos • Listado de tags o etiquetas enriquecidas o Rich Snippets
351
Capítulo 190
Stack Overflow Stack Overflow es un sitio web desarrollado por Jeff Att- 190.3 Moderación wood, este sitio web es utilizado por una comunidad de desarrolladores informáticos, en la cual otros desarrolla- Hasta enero del 2012, Stack Overflow tenía un registro de dores pueden encontrar soluciones a problemas de pro- 771.000 usuarios registrados, y 12 moderadores, en programación en diferentes lenguajes.* [2] medio, cada moderador tenía gestionar 64250 usuarios y sus actividades.
190.1 Funcionamiento de Stack Overflow 1. El usuario se suscribe al sitio web. 2. El usuario hace pública su pregunta. 3. El usuario recibe las respuestas. Las respuestas son publicadas por los miembros de una comunidad determinada o por otros usuarios con las mismas experiencias que encontraron solución al problema planteado. Todos los usuarios pueden votar por las preguntas y por sus respuestas, cuando se vota por una pregunta, el usuario puede calificarlas como más relevante o menos relevante; por otra parte, cuando se vota por las respuestas, éstas pueden ser más acertadas o menos acertadas.
190.2 Reputación Stack Overflow posee un aspecto interesante, la reputación, este término es destacado de acuerdo a la cantidad de votos que poseen las preguntas y las respuestas, a mayor cantidad de votos relevantes o aciertos, mayor es la reputación en el sitio web. De hecho, el número de votos es un indicador para muchos aspectos, entre estos tenemos: 1. Confianza de los usuarios.
El sistema de moderación está basado en la reputación. Los 12 moderadores iniciales son los moderadores generales del sitio web, pero todos los usuarios pueden alcanzar cierto poder de moderación en función de su reputación. Cuantos más puntos tenga el usuario, más cosas puede hacer. De esa manera se divide el coste de la moderación entre toda la comunidad: si cada uno modera un poco, entre todos moderan todo; pero siempre basado en la habilidad individual que permite ese privilegio.
190.4 Estadísticas Un estudio en 2013 encontró que el 77% de los usuarios sólo hacen una pregunta, el 65% solamente responden a una pregunta, y sólo el 8% de los usuarios responden a más de 5 preguntas.* [3] A partir de 2011, el 92% de las preguntas fueron contestadas en un tiempo medio de 11 minutos.* [4] Desde 2013, el software de red Stack Exchange elimina automáticamente las preguntas que cumplen con ciertos criterios, entre ellos el no tener respuestas en una cierta cantidad de tiempo.* [5] A partir de agosto de 2012, 443.000 de los 1,3 millones de usuarios registrados habían respondido al menos una pregunta, y de ellos, unos 6.000 (0,46% del número total de usuarios) se había ganado una puntuación de reputación superior a 5000.* [6]La Reputación se puede ganar más rápido contestando a preguntas relacionadas con las etiquetas con menor densidad de conocimientos, el hacerlo con prontitud (en particular, siendo la primera persona en contestar una pregunta), estar activo durante las horas de menor uso, y contribuyendo a diversas áreas.* [7]
2. Habilidades de comunicación. [1] «Stack Overflow ranking alexa.com».
3. Calidad y relevancia en preguntas y Respuestas.
[2] «Stack Overflow información sobre la compañía».
4. Manejo de los temas.
[3] “An Empirical Study on Developer Interactions in StackOverflow”
5. Nivel de experiencia y participación. 352
190.4. ESTADÍSTICAS
[4] Mamykina, Lena; Bella Manoim; Manas Mittal; George Hripcsak; Björn Hartmann (2011).“Design lessons from the fastest q&a site in the west” [5] “Turbocharging the Roomba: solutions for premature deletion”. stackexchange.com. [6] Bosu, Amiangshu; Christopher S. Corley; Dustin Heaton; Debarshi Chatterji; Jeffrey C. Carver; Nicholas A. Kraft (2013).“Building Reputation in StackOverflow: An Empirical Investigation” [7] What posts get deleted, and why?". Meta.StackOverflow. 10 June 2015.
353
Capítulo 191
StarBasic StarOffice Basic, también conocido como StarBasic, es un dialecto de Basic que Soporta Unicode, incluido en las Suites de Oficina OpenOffice.org y StarOffice.
191.1 Primer virus para OpenOffice El 30 de mayo de 2006 fue detectado el primer virus conceptual para OpenOffice. Fue desarrollado con el sólo objetivo de demostrar que es posible crear este tipo de software usando el lenguaje de macros de esta suite de aplicaciones libre. Escrito en StarBasic, el virus es capaz de infectar las versiones de OpenOffice y StarOffice en cualquier plataforma.
191.2 Enlaces externos • Más información
354
Capítulo 192
Stub Un stub es, en el contexto del testeo del software, un trozo de código usado como sustituto de alguna otra funcionalidad. Un stub puede simular el comportamiento de código existente (tal como un procedimiento en una máquina remota) o ser el sustituto temporal para un código aún no desarrollado. Los stubs son, por tanto, muy útiles para porting, computación distribuida así como en el desarrollo y pruebas de software en general. Un ejemplo de stub en pseudocódigo podría ser como éste: INICIO Temperatura = LeerTermometro(Afuera) SI Temperatura > 40 ENTONCES ESCRIBIR “Hace calor!" FIN SI FIN INICIO LeerTermometro(Fuente adentroOafuera) RETORNAR 28 FIN LeerTermometro El pseudocódigo de arriba utiliza la función LeerTermometro, que devuelve la temperatura. Aunque se pretende que LeerTermometro obtenga la temperatura de algún dispositivo, la función en este momento no contiene el código necesario. LeerTermometro, en esencia, no simula ningún proceso aunque devuelve un valor legal, permitiendo así probar aunque sea en parte el programa principal. Hay que notar también que aunque acepta un parámetro de tipo Fuente para determinar si se va a leer la temperatura externa o interna, éste no se usa. Un stub* [1] es una rutina que realmente no hace otra cosa que declararse a sí misma y a los parámetros que acepta y que devuelve un valor habitual dentro de los 'escenarios felices' del que llama al stub. Los stubs se usan habitualmente como sustitutos de la implementación aún no finalizada de una interfaz ya definida. El stub contendría sólo el código necesario para que compile y enlace con el resto del programa.
192.1 Referencias [1] http://www.webopedia.com/
192.2 Enlaces externos • A Stub Generation System For C++ (PDF) 355
• Stub/mock frameworks for Java Review and comparison of stub & mock frameworks for Java
Capítulo 193
Subalgoritmo Se llama subalgoritmo a cada una de las partes de un algoritmo más general que resuelve cada una de las tareas particulares necesarias para que dicho algoritmo general alcance el objetivo para el que fue diseñado, es decir resolver un problema. Este concepto está vinculado al diseño estructurado de algoritmos, en el cual un problema se divide en partes que posteriormente son resueltas por un módulo. Cada módulo coincidirá con un subalgoritmo.
nes en su funcionamiento. Este paso de argumentos se puede hacer por valor o por referencia. Ver Paso de argumentos en Argumento (Ciencias de la computación)'
193.4 Véase también • Programación estructurada
193.1 Tipos de subalgoritmos
• Programación modular
• Funciones: devuelven un valor.
• Subrutina
• Procedimientos: cambian un valor.
• Encapsulamiento (programación orientada a objetos) • Abstracción (programación orientada a objetos)
193.2 Ámbito de las variables
• Recursión y Algoritmo recursivo
Desde el punto de un subalgoritmo las variables pueden ser locales o globales: • Las variables locales se declaran dentro de un módulo o subalgoritmo y sólo tienen utilidad dentro de ese módulo, no se podrá acceder a ellas desde otros módulos. Pueden existir variables locales con el mismo nombre siempre que estén en módulos diferentes. • Las variables globales son declaradas de forma que puedan ser utilizadas (consultada y/o modificada) desde cualquiera de los módulos que forman el programa. En este caso, no puede haber dos variables globales con el mismo nombre, ya que esto produciría una ambigüedad que el compilador no podría resolver. En el diseño estructurado de algoritmos se desaconseja el uso de variables globales ya que este produciría acoplamiento común.
193.3 Paso de argumentos Cuando se hace una llamada a un subalgoritmo, se le pueden pasar argumentos para determinar ciertas condicio356
Capítulo 194
Tabla de saltos En programación, se denomina tabla de saltos a un mé- funciones por su número (el índice en la tabla) pueden todo eficiente de transferencia de control de programas ser útiles en ciertos programas. saltando a otra parte del código mediante una tabla de instrucciones de salto. Este sistema es utilizado normalmente en la programación en ensamblador aunque estas 194.1 Ejemplo tablas también pueden ser generadas por un compilador. Una tabla de saltos consiste en una lista de instrucciones de salto incondicional que se ejecutan utilizando un offset creado mediante la multiplicación de un índice secuencial por la longitud de la instrucción (los bytes que ocupa en memoria cada instrucción). Se basa en el hecho de que las instrucciones de salto en código máquina tienen una longitud fija y pueden ser ejecutadas de forma extremadamente eficiente por la mayoría del hardware, además de ser más útil cuando se trabaja con datos sin formato fácilmente convertibles a valores secuenciales de índice. Dados estos datos, una tabla de saltos suele ser bastante eficiente, siguiendo normalmente estos pasos: validación opcional de los datos de entrada, transformación de los mismos en un offset dentro de la tabla de saltos (esto suele necesitar multiplicarlos o desplazarlos para su longitud coincida con las instrucciones de salto) y salto a una dirección obtenida a partir de la base de la tabla y el offset generado (esta operación suele incluir la suma del offset al registro del contador de programa).
Un ejemplo simple del uso de tablas de saltos en ensamblador del microcontrolador PIC de 8 bits es:
Otro método de implementación de las tablas de saltos consiste en un array de direcciones desde las cuales es capturada la dirección necesaria para saltar. Este método suele implicar un menor tamaño del código y evita los saltos indirectos. Normalmente el método empleado para construir la tabla de saltos suele venir determinada por la arquitectura del procesador en el cual va a ser ejecutado el código.
194.2 Historia
Las tablas de saltos suelen usarse en el desarrollo de sistemas operativos. Tanto las llamadas al sistema como las funciones de biblioteca pueden ser referenciadas mediante un índice entero de una tabla de saltos. Con esto se consigue una mejora de la compatibilidad con las versiones siguientes: si el código de una función y la dirección de su destino de salto son modificados, solamente hará falta reajustar la instrucción de salto en la tabla, de este modo todas las aplicaciones compiladas utilizando código de la biblioteca y/o sistema operativo en cuestión no necesitan modificación alguna. Además, las llamadas a
movf INDEX, W ; mover el valor de índice al registro W (registro de trabajo) desde la dirección de memoria INDEX addwf PCL, F ; sumarlo al registro de contador de programa (PCL). Cada instrucción PIC ocupa 1 byte ; de modo que no es necesario realizar ninguna multiplicación. La mayoría de las arquitecturas transformarían ; el índice de alguna manera antes de sumarlo al contador de programa table ; esta etiqueta marca el comienzo de la tabla de salto goto index_zero ; cada una de estas instrucciones goto es un salto incondicional a diferentes secciones goto index_one ; del código goto index_two goto index_three index_zero ; en esta parte se añadiría el código necesario para realizar cualquier acción que requiera que el valor de INDEX sea igual a cero return index_one ...
El uso de las tablas de saltos y de la representación de los datos sin formato mediante índices era común en los inicios de la informática cuando las memorias eran caras y los procesadores lentos, siendo la representación compacta de los datos y la elección eficiente de las alternativas de almacenamiento dos factores importantes. También se ven con frecuencia en los sistemas empotrados modernos, donde suele hacer falta que el código quepa en espacios realmente mínimos y que a la vez opere de manera eficiente. La principal ventaja de tal conversión es que una vez que un valor ha sido convertido a un índice, puede ser utilizado para saltar o para recuperar algún dato de una tabla de búsqueda de forma eficiente y en cualquier momento sin necesidad de ser convertido de nuevo. Por ejemplo, se podría decir que, relativamente, hay pocos países en el mundo; de forma que éstos podrían ser representados de manera sencilla mediante un código de país
357
358 en lugar de por una cadena de texto. Esto evita almacenamientos masivos de datos y por consiguientes grandes tiempos de procesado. Las comparaciones numéricas son significativamente más rápidas que las de cadenas de texto, y las búsquedas indexadas son también notablemente más rápidas que las de cadenas. Sin embargo, entre las desventajas se incluye la aparición de un nivel más de indirección. Esto es de poca importancia para los ordenadores, pero supone mayor complejidad de código y de datos para el programador. Además, tal y como se pudo ver en el Efecto 2000, esta aproximación al problema puede llevar posteriormente a problemas si los requisitos de espacio para el índice o la representación superan a los reservados para la tarea.
194.3 Enlaces externos • HOWTO sobre la implementación de tablas de saltos en C
CAPÍTULO 194. TABLA DE SALTOS
Capítulo 195
Tabla de verdad Una tabla de verdad, o tabla de valores de verdad, Negación La negación es un operador que se ejecues una tabla que muestra el valor de verdad de una ta, sobre un único valor de verdad, devolviendo el valor proposición compuesta, para cada combinación de ver- contradictorio de la proposición considerada. dad que se pueda asignar.* [1] Fue desarrollada por Charles Sanders Peirce por los años 1880, pero el formato más popular es el que introdujo Ludwig Wittgenstein en su Tractatus logicophilosophicus, publicado en 1921.
A V F
∼A F V
Conjunción La conjunción es un operador que actúa dos valores de verdad, típicamente los valores de 195.1 Definiciones en el cálculo ló- sobre verdad de dos proposiciones, devolviendo el valor de vergico dad verdadero cuando ambas proposiciones son verdaderas, y falso en cualquier otro caso. Es decir es verdadera Para establecer un Sistema formal se establecen las defi- cuando ambas son verdaderas niciones de los operadores. Las definiciones se harán en La tabla de verdad de la conjunción es la siguiente: función del fin que se pretenda al construir el sistema que haga posible la formalización de argumentos: A B A∧B V V V • Como razonamientos deductivos lógico-lingüísticos V F F F V F • Como construcción de un sistema matemático puro F F F • Como una aplicación lógica en un Circuito de conQue se corresponde con la columna 8 del algoritmo funmutación. damental. en simbologia "^" hace referencia a el conector “y” Verdadero El valor verdadero se representa con la letra V; si se emplea notación numérica se expresa con un Disyunción La disyunción es un operador que actúa uno: 1; en un circuito eléctrico, el circuito está cerrado. sobre dos valores de verdad, típicamente los valores de verdad de dos proposiciones, devolviendo el valor de verFalso El valor falso se representa con la letra F; si se dad verdadero cuando una de las proposiciones es verdaemplea notación numérica se expresa con un cero: 0; en dera, o cuando ambas lo son, y falso cuando ambas son un circuito eléctrico, el circuito está abierto. falsas. La tabla de verdad de la disyunción es la siguiente: Variable Para una variable lógica A, B, C, ... que pueden ser verdaderas V, o falsas F, los operadores fundamentales se definen así:
A V F
A V F
A V V F F
B V F V F
A∨B V V V F
Que se corresponde con la columna 2 del algoritmo fundamental. 359
360
CAPÍTULO 195. TABLA DE VERDAD
Implicación o Condicional El condicional material es un operador que actúa sobre dos valores de verdad, típicamente los valores de verdad de dos proposiciones, devolviendo el valor de falso sólo cuando la primera proposición es verdadera y la segunda falsa, y verdadero en cualquier otro caso. La tabla de verdad del condicional material es la siguiente:
A V V F F
B V F V F
A⇒B V F V V
n 0 1 2 3 4 5 ... n
Nc 1 2 4 8 16 32 ... 2n
Si consideramos que un sistema combinacional de n variables binarias, puede presentar un resultado verdadero: V, o falso: F, para cada una de las posibles combinaciones de entrada tenemos que se pueden construir Cp circuitos posibles con n variables de entrada, donde:
Que se corresponde con la columna 5 del algoritmo fundamental. n
Cp = 22 Equivalencia, doble implicación o Bicondicional El bicondicional o doble implicación es un operador que funciona sobre dos valores de verdad, típicamente los valores de verdad de dos proposiciones, devolviendo el valor de verdad verdadero cuando ambas proposiciones tienen el mismo valor de verdad, y falso cuando sus valores de verdad son diferentes. La tabla de verdad del bicondicional es la siguiente:
A V V F F
B V F V F
A⇔B V F F V
Que da como resultado la siguiente tabla:
n 0 1 2 3 4 5 ... n
Cp 2 4 16 256 65. 536 4. 294.967.296 ... n 22
Para componer una tabla de verdad, pondremos las n variables en una línea horizontal, debajo de estas variables desarrollamos las distintas combinaciones que se pueden formar con V y F, dando lugar a la distintas Nc, número de combinaciones. Normalmente solo se representa la Que se corresponde con la columna 7 del algoritmo fun- función para la que se confecciona la tabla de verdad, y en damental. todo caso funciones parciales que ayuden en su cálculo, en la figura, se pueden ver todas las combinaciones posibles Cp, que pueden darse para el número de variables dado.
195.2 Número de combinaciones
n
Partiendo de un número n de variables, cada una de las cuales puede tomar el valor verdadero: V, o falso: F, por Combinatoria, podemos saber que el número total de combinaciones: Nc, que se pueden presentar es:
N c = 2n el número de combinaciones que se pueden dar con n variable, cada una de las cuales puede tomar uno entre dos valores lógicos es de dos elevado a n, esto es, el número de combinaciones: Nc, tiene crecimiento exponencial respecto al número de variable n:
Nc
C
A B
1 2 3 4 5 6 7
V V F F
V V V V
V F V F
V V V F
V V F V
V V F F
V F V V
V F V F
V F F V
195.3. TABLAS DE VERDAD Así podemos ver que para dos variables binarias: A y B, n= 2 , que pueden tomar los valores V y F, se pueden desarrollar cuatro combinaciones: Nc= 4, con estos valores se pueden definir dieciséis resultados distintos, Cp= 16, cada una de las cuales seria una función de dos variables binarias. Para otro número de variables se obtendrán los resultados correspondientes, dado el crecimiento exponencial de Nc, cuando n toma valores mayores de cuatro o cinco, la representación en un cuadro resulta compleja, y si se quiere representar las combinaciones posibles Cp, resulta ya complejo para n= 3.
361 Considérese además a "·" como una operación o función lógica que realiza una función de verdad al tomar los valores de verdad de A y de B, y devolver un único valor de verdad. Entonces, existen 16 funciones distintas posibles, y es fácil construir una tabla que muestre qué devuelve cada función frente a las distintas combinaciones de valores de verdad de A y de B.
Las dos primeras columnas de la tabla muestran las cuatro combinaciones posibles de valores de verdad de A y de B. Hay por lo tanto 4 líneas, y las 16 columnas despliegan 195.2.1 Para cero variables todos los posibles valores que puede devolver una función Un circuito sin variables, puede presentar una combina- "·". ción posible: Nc=1, con dos circuitos posibles: Cp=2. De esta forma podemos conocer mecánicamente, meQue serían el circuito cerrado permanentemente, y el cir- diante algoritmo, los posibles valores de verdad de cualcuito abierto permanentemente. quier conexión lógica interpretada como función, siempre y cuando definamos los valores que devuelva la función. Se hace necesario, pues, definir las funciones que se utilizan en la confección de un sistema lógico. En este caso se puede ver que no interviene ninguna vaDe especial relevancia se consideran las definiciones para riable. el Cálculo de deducción natural y las puertas lógicas Cada uno de estos circuitos admite una única posición y en los circuitos electrónicos. hay dos circuitos posibles.
195.2.2
Para una variable
195.3 Tablas de verdad
El caso de una variable binaria, que puede presentar dos Las tablas nos manifiestan los posibles valores de verdad combinaciones posibles: Nc=2, con 4 circuitos posibles: de cualquier proposición molecular, así como el análisis de la misma en función de las proposicíones que la inteCp=4. gran, encontrándonos con los siguientes casos:
195.3.1 Verdad Indeterminada o Contin-
Los casos 1 y 4 coinciden con los de cero variables, el gencia caso 2 la salida es la de la variable y el caso 3 la negación de la variable. Se entiende por verdad contingente, o verdad de hecho, aquella proposición que puede ser verdadera o falsa, según los valores de las proposiciones que la integran. Sea 195.2.3 Para dos variables el caso: A ∧ (B ∨ C) . Considérese dos variables proposicionales A y B.* [2] Cada una puede tomar uno de dos valores de verdad: o V (verdadero), o F (falso). Por lo tanto, los valores de verdad de A y de B pueden combinarse de cuatro maneras distintas: o ambas son verdaderas; o A es verdadera y B falsa, o A es falsa y B verdadera, o ambas son falsas. Esto puede expresarse con una tabla simple:
Su tabla de verdad se construye de la siguiente manera: Ocho filas que responden a los casos posibles que pueden darse según el valor V o F de cada una de las proposiciones A, B, C. (Columnas 1, 2, 3) Una columna (Columna 4) en la que se establecen los valores de B ∨ C aplicando la definición del disyuntor a los valores de B y de C en cada una de las filas.(Columnas 2,3 → 4)
A V V F F
B V F V F
Una columna (columna 5) en la que se establecen los valores resultantes de aplicar la definición de la conjunción entre los valores de A (columna 1) y valores de la columna B ∨ C , (columna 4) que representarán los valores de la proposición completa A ∧ (B ∨ C) , cuyo valor de ver-
362
CAPÍTULO 195. TABLA DE VERDAD
dad es V o F según la fila de los valores de A, B, y C que No obstante la sencillez del algoritmo, aparecen dos dificonsideremos. (Columnas 1,4 → 5) cultades. Donde podemos comprobar cuándo y por qué la proposición A ∧ (B ∨ C) es V y cuándo es F.
195.3.2
Contradicción
• La gran cantidad de operaciones que hay que hacer para una proposición con más de 4 variables. Esta dificultad ha sido magníficamente superada por la rapidez de los ordenadores, y no presenta dificultad alguna.
Se entiende por proposición contradictoria, o contradic• Que únicamente será aplicable a un esquema de inción, aquella proposición que en todos los casos posibles ferencia, o argumento cuando la proposición condide su tabla de verdad su valor siempre es F. Dicho de otra cionada, como conclusión, sea previamente conociforma, su valor F no depende de los valores de verdad de da, al menos como hipótesis, hasta comprobar que las proposiciones que la forman, sino de la forma en que su tabla de verdad manifiesta una tautología. están establecidas las relaciones sintácticas de unas con otras. Sea el caso: Por ello se construye un cálculo mediante cadenas deductivas: Las proposiciones que constituyen el antecedente del esquema de inferencia, se toman como premisas de un arProcederemos de manera similar al caso anterior. Par- gumento. tiendo de la variable A y su contradicción, la conjunción Se establecen como reglas de cálculo algunas tautologías de ambos siempre es falso, dado que si A es verdad su como tales leyes lógicas, (pues garantizan, por su carácter contradicción es falsa, y si A es falsa su contradicción es tautológico, el valor V). verdad, la conjunción de ambas da falso en todos los caSe permite la aplicación de dichas reglas como reglas de sos. sustitución de fórmulas bien formadas en las relaciones que puedan establecerse entre dichas premisas. A∧ ∼ A
195.3.3
Tautologías
Deduciendo mediante su aplicación, como teoremas, todas las conclusiones posibles que haya contenidas en las Se entiende por proposición tautológica, o tautología, premisas. aquella proposición que en todos los casos posibles de su tabla de verdad su valor siempre es V. Dicho de otra for- Cuando en un cálculo se establecen algunas leyes como ma, su valor V no depende de los valores de verdad de principios o axiomas, el cálculo se dice que es axiomático. las proposiciones que la forman, sino de la forma en que El cálculo lógico así puede utilizarse como demostración están establecidas las relaciones sintácticas de unas con argumentativa. otras. Sea el caso:
A∨ ∼ A Siguiendo la mecánica algorítmica de la tabla anterior construiremos su tabla de verdad, tenemos la variable A en disyunción con su contradicción, si A es verdad, su negación es falsa y si A es falsa su negación es verdad, en cualquier caso una de las dos alternativas es cierta, y su disyunción es cierta en todos los casos.
195.5 Aplicaciones 195.5.1 Cálculo lógico La aplicación fundamental se hace cuando se construye un sistema lógico que modeliza el lenguaje natural sometiéndolo a unas reglas de formalización del lenguaje. Su aplicación puede verse en el cálculo lógico.
195.4 Tablas de verdad, proposi- 195.5.2 Lógica de circuitos ciones lógicas y argumentos Una aplicación importante de las tablas de verdad procede del hecho de que, interpretando los valores lógicos de deductivos verdad como 1 y 0 (lógica positiva) en el sentido que En realidad toda la lógica está contenida en las tablas de verdad, en ellas se nos manifesta todo lo que implican las relaciones sintácticas entre las diversas proposiciones.
• valor “1”permite el paso de corriente eléctrica; y • valor “0”corta el paso de dicha corriente.
195.5. APLICACIONES
363 El primer caso en una función lógica que para todas las posibles combinaciones de A y B, el resultado siempre es verdadero, es un caso de tautología, su implementación en un circuito es una conexión fija.
V • Caso 2
Puertas lógicas para circuitos eléctricos
En este segundo caso el resultado solo es falso si A y B son falsos, si una de las dos variables es verdad el resultado es verdad. La función seria:
Los valores de entrada o no entrada de corriente a través de un diodo pueden producir una salida 0 ó 1 según las condiciones definidas como función según las tablas A ∨ B mostradas anteriormente. • Caso 3 Así se establecen las algunas funciones básicas: AND, NAND, OR, NOR, XOR, XNOR (o NXOR), que se coEn el tercer caso es verdad si A es verdad y cuando A y rresponden con las funciones definidas en las columnas 8, B son falsos el resultado también es verdad. 9, 2, 15, 10 y 7 respectivamente, y la función NOT. Su función seria: En lugar de variables proposicionales, considerando las posibles entradas como EA y EB, podemos armar una tabla análoga de 16 funciones como la presentada arriba, A∨ ∼ B con sus equivalentes en lógica de circuitos. Esta aplicación hace posible la construcción de aparatos • Caso 4 capaces de realizar estas computaciones a alta velocidad, y la construcción de circuitos que utilizan este tipo de En el cuarto caso la función es cierta si A es cierta, los análisis se hace por medio de puertas lógicas. posibles valores de B no influyen en el resultado. La Tabla de la verdad es una herramienta imprescindible La función solo depende de A: en la recuperación de datos en las bases de datos como Internet con los motores de búsqueda o en una biblioteca con sus ficheros informatizados. Así mismo se utilizan para programar simulaciones lógicas de inteligencia arti- A ficial con lenguajes propios. También en modelos mate• Caso 5 máticos predictores: meteorología, marketing y otros muchos. En el quinto caso si A es falso el resultado es verdadero, y si A y B son verdaderos el resultado también es verdadero, puede verse que este caso es idéntico al tercero 195.5.3 Desarrollo del algoritmo funda- permutando A por B.
mental en lógica de circuitos La definición de la tabla de verdad corresponde a funciones concretas, en cada caso, así como a implementaciones en cada una de las tecnologías que pueden representar funciones lógicas en binario, como las puertas lógicas o los circuitos de conmutación. Se entenderá como verdad la conexión que da paso a la corriente; en caso contrario se entenderá como falso. Veamos la presentación de los dieciséis casos que se presentan con dos variables binarias A y B: • Caso 1
Y si función es:
∼A∨B =A⇒B • Caso 6 En el sexto caso la función es cierta si B es cierta, los valores de A no influyen en el resultado. La función solo depende de B:
B
364 • Caso 7
CAPÍTULO 195. TABLA DE VERDAD • Caso 13
El séptimo caso corresponde a la relación bicondicional En el caso decimotercero podemos ver que el resultado entre A y B, el resultado solo es verdad si A y B son ambos es el opuesto de A, independientemente del valor de B: verdad o si A y B son ambos falsos.
(A ∧ B) ∨ (∼ A∧ ∼ B) = A ⇔ B • Caso 8
∼A • Caso 14
En el octavo caso el resultado es verdad si A y B son verdad, en el resto de los valores de A y B el resultado es falso, corresponde a la conjunción de A y B, equivalente a un circuito en serie.
Caso decimocuarto, el resultado de la función solo es verdad si A es falso y B verdadero, luego es equivalente a un circuito en serie de A en conexión inversa y de B en conexión directa.
A∧B
∼A∧B
• Caso 9
• Caso 15
En el noveno caso el resultado solo es falso si A y B son En el caso decimoquinto, el resultado solo es verdad si A verdad, en el resto de los valores de A y B el resultado es y B son falsos, Luego es necesario que tanto A como B verdadero, corresponde a la disyunción de la negación A y sean falsos para que el resultado sea verdadero. de B, equivalente a un circuito en paralelo de conexiones inversas. ∼ A∧ ∼ B ∼ A∨ ∼ B
• Caso 16
• Caso 10
Por último en el caso decimosexto, tenemos que el resultado siempre es falso independientemente de los valores Podemos ver que el décimo caso es lo opuesto a la bide A o de B. condicional, solo es verdad si A y B discrepan, si A y B son diferentes el valor es verdad, si A y B son iguales el resultado es falso. F (A∧ ∼ B) ∨ (∼ A ∧ B) • Caso 11 En este caso podemos ver que cuando B es verdad el resultado es falso y que cuando B es falso el resultado es verdadero, independientemente del valor de A, luego la función solo depende de B, en sentido inverso.
195.6 Véase también • Operador lógico • Anexo:Tabla de símbolos matemáticos • Lenguaje formalizado • Álgebra de Boole
∼B • Caso 12 En el caso doce, vemos que solo hay un combinación de A y B con resultado verdadero, que es A y la negación de B.
• Cálculo lógico • Lógica binaria • Lógica proposicional • Puerta lógica • Función lógica
A∧ ∼ B
• Función de verdad
195.8. ENLACES EXTERNOS
195.7 Notas y referencias [1] «truth table» (en inglés), The Concise Oxford Dictionary of Mathematics, Oxford University Press, http://www.oxfordreference.com/views/ENTRY.html? subview=Main&entry=t82.e2895, consultado el 8 de octubre de 2009 [2] Las letras A y B son metavariables, es decir pertenecen a un metalenguaje respecto a un lenguaje-objeto; por ello simbolizan cualquier proposición, atómica o no, del lenguaje de la lógica proposicional.
195.8 Enlaces externos • TABLAS DE VERDAD • Tablas De Verdad • Tablas de Verdad • Lógica matemática
365
Capítulo 196
Thunk Thunk es un término usado en la jerga del desarrollo de software que designa la llamada o invocación a un código que pertenece a otra plataforma o a otro Framework. En el paso de 16 a 32 bit por ejemplo, los sistemas operativos (OS/2, Windows NT etc.) podían resolver código de 16 bit a través de la transformación de los parámetros de llamadas y direcciones, de modo tal que fue posible seguir utilizando los programas de 16 bit.
public ref class CManagedClass { private: System::Int32 m_i; public: void SetValue( int i ) { m_i = i; // Implementación del tipo de datos } };
Las clases nativas C++ en un proyecto C++/CLI. Aquí se puede ver que también el camino inverso es posible, es decir, instanciar el código gestionado dentro de una clase no gestionada. La condición es, sin embargo, que se trate de un proyecto C++/CLI, de modo tal que el compilador En el desarrollo de software moderno, un thunk es la lla- comprenda la correspondiente sintaxis. El thunk ya apamada del código nativo desde el código gestionado y vi- rece en la instrucción «gcnew», ya que aquí se invoca al ceversa (véase por ejemplo Java Native Access o .NET constructor de la clase gestionada: P/Invoke). Es decir, se trata de una plataforma de tran- public class CNativeClass { public: void Foo() { int i = sición, en la que las convenciones y/o parámetros de in- 42; CManagedClass^ pManagedClass = gcnew CManavocación tienen que transformarse correspondientemente gedClass(); pManagedClass->SetValue( i ); } }; (Marshalling). El lenguaje de programación C++/CLI del .NET-Framework de Microsoft fue concebido especialmente para posibilitar tales thunks en ambas direcciones:
196.3 Bibliografía
196.1 Invocación por «gestionada» a «no gestionada» Sea dada una clase nativa en C++, por ejemplo un proyecto C++ o como parte integrante de un proyecto C++/CLI, que se utilizará más abajo en código gestionado: public class CNativeClass { private: int m_i; public: void SetValue( int i ) { m_i = i; } }; La clase gestionada C++/CLI (que en esta forma puede ser directamente instanciada, por ejemplo, en C#), la cual utiliza la clase nativa mostrada anteriormente: public ref class CManagedClass { public: CManagedClass() { System::Int32 i = 42; CNativeClass* pNativeClass = new CNativeClass(); pNativeClass->SetValue( i ); // Implementación del tipo de datos delete pNativeClass; } };
196.2 Invocación por «no gestionada» a «gestionada» La clase gestionada C++/CLI : 366
• Marcus Heege: Expert C++/CLI. Apress Verlag, Berkeley 2007, ISBN 978-1-59059-756-9, Capítulo 9, p. 203 y siguientes.
Capítulo 197
Tipo de dato elemental Se llama tipo primitivo o tipo elemental a los tipos de datos originales de un lenguaje de programación, esto es, aquellos que nos proporciona el lenguaje y con los que podemos (en ocasiones) construir tipos de datos abstractos y estructuras de datos. Generalmente ejemplos de tipos primitivos son: • Char (Carácter) • Int (Entero) • Float (Real - Coma flotante) Otros tipos de datos que pueden ser considerados primitivos ya que la mayoría de lenguajes de programación así los proporcionan (aunque no todos) son: • Booleano (Lógico: Verdadero, Falso) • String (Cadena de caracteres) • Puntero (Dirección de memoria - Int)
367
Capítulo 198
Triángulo de Floyd El Triángulo de Floyd, llamado así en honor a Robert Floyd, es un triángulo rectángulo formado con números naturales. Para crear un triángulo de Floyd, se comienza con un 1 en la esquina superior izquierda, y se continúa escribiendo la secuencia de los números naturales de manera que cada línea contenga un número más que la anterior:
198.3 Referencias
Una de los ejercicios más comunes en los cursos de introducción a la programación de ordenadores consiste en escribir un pequeño programa que produzca este triángulo.* [1]* [2] El triángulo de Floyd tiene varias propiedades matemáticas interesantes. Los números del cateto de la parte izquierda forman la secuencia de los números poligonales centrales, mientras que los de la hipotenusa nos dan el conjunto de los números triangulares. La suma de los números de la línea n equivale a n(n2 + 1)/2 (sucesión A006003 en OEIS).
198.1 Algoritmo computacional En PSeInt es: Definir TAMANIO Como Entero; TAMANIO <- 10; Definir i, j, t Como Enteros; t <- 1; Escribir “Triángulo Floyd"; Para i <- 1 Hasta TAMANIO Con Paso 1 Hacer Para j <- t Hasta t + i - 1 Con Paso 1 Hacer Escribir j, " " Sin Bajar; FinPara Escribir ""; t <- t + i; FinPara FinProceso En Java es: public class TrianguloFloyd { public static void main(String[] args) { final int TAMANO = 10; int t = 1; System.out.println("\nTriángulo Floyd\n”); for (int i = 1; i <= TAMANO; ++i) { for (int j = t; j <= t + i - 1; ++j) { System.out.print(j + "\t”); } System.out.println("\n” ); t += i; } } }
198.2 Véase también • Triángulo de Pascal 368
[1] Keller, Arthur M. (1982), A first course in computer programming using PASCAL, McGraw-Hill, p. 39. [2] Peters, James F. (1986), Pascal with program design, Holt, Rinehart and Winston, pp. 137, 154.
Capítulo 199
Tubería (informática)
|¦
La comunicación por medio de tuberías se basa en la interacción productor/consumidor, los procesos productores (aquellos que envían datos) se comunican con los procesos consumidores (que reciben datos) siguiendo un orden FIFO. Una vez que el proceso consumidor recibe un dato, éste se elimina de la tubería.
Las tuberías (pipes) están implementadas en forma muy eficiente en los sistemas operativos multitarea, iniciando todos los procesos al mismo tiempo, y atendiendo automáticamente los requerimientos de lectura de datos para cada proceso cuando los datos son escritos por el proceso anterior. De esta manera el planificador de corto plazo va a dar el uso de la CPU a cada proceso a medida que pueda ejecutarse minimizando los tiempos muertos. Para mejorar el rendimiento, la mayoría de los sistemas operativos implementan las tuberías usando buffers, lo que permite al proceso proveedor generar más datos que lo que el proceso consumidor puede atender inmediatamente. Podemos distinguir dos tipos de tuberías: Tubería sin nombre Las tuberías sin nombre tienen asociado un fichero en memoria principal, por lo tanto, son temporales y se eliminan cuando no están siendo usados ni por productores ni por consumidores. Permiten la comunicación entre el proceso que crea un cauce y procesos hijos tras la creación de la tubería. Tubería con nombre Su diferencia respecto a las tuberías sin nombre radica en que el cauce se crea en el sistema de archivos, y por lo tanto no tienen carácter temporal. Se manejan mediante llamadas al sistema (open, close, read y write) como el resto de ficheros del sistema. Permiten la comunicación entre los procesos que usen dicha tubería, aunque no exista una conexión jerárquica entre ellos.
Tubería y barra partida.
En informática, una tubería (pipe, cauce o '|') consiste en una cadena de procesos conectados de forma tal que la salida de cada elemento de la cadena es la entrada del próximo. Permiten la comunicación y sincronización entre procesos. Es común el uso de buffer de datos entre elementos consecutivos.
199.1 Véase también
369
• Arquitectura en pipeline (informática) • Tubería (Unix)
370
CAPÍTULO 199. TUBERÍA (INFORMÁTICA)
• Pleca •
Wikcionario tiene definiciones y otra información sobre tubería (informática).Wikcionario
Capítulo 200
Violación de acceso Se define como violación de acceso (violación del segmento o access violation y segmentation fault en Inglés) al intento fallido de acceso a información o a programas a los que no se tiene autorización para ver o modificar. Este mensaje puede ser causado por la configuración de software, por los programadores o por falla de hardware, siendo los más comunes los 2 primeros. Con los sistemas operativos actuales, cada proceso tiene uno o más segmentos de la memoria del sistema donde puede almacenar y recuperar la información. Cada proceso puede solicitar más o menos memoria (según lo necesitado), y la petición será reconocida por el sistema operativo y comparada con la sección de memoria concedida para el proceso. Generalmente, el proceso que solicitó la memoria es el único que puede leerla o modificarla. Una violación de acceso ocurre cuando un proceso trata de acceder a una parte de la memoria asignada a otra aplicación, o a una área no usada de la memoria, no teniendo los permisos para hacerlo. Normalmente se produce como resultado de un error de programación, por ejemplo, un puntero descarriado. Otra forma en que podría producirse un“segmentation fault”es con una memoria dañada físicamente, puesto que algún programa escribirá en la memoria, luego intentará acceder a esos datos, pero al tener una falla la memoria, es posible que los datos se hayan borrado, por ende el programa considerará esa dirección de memoria como vacía, o sea no usada, con lo que arrojará el error.
200.1 Véase también • Error de software. • Agujero de seguridad.
371
Capítulo 201
Waf Waf es una herramienta que ayuda a configurar automáticamente la compilación y la instalación de otros programas o bibliotecas (build).
• Información en pantalla colorida y barra de progreso. • Los scripts son módulos de Python.
201.1 Funciones
• Esquema modular de configuración con análisis personalizable en línea de comandos.
General
• Modo demonio para el historial de recompilación.
• Es portable a sistemas Unix y no-Unix. • Es ligero.
• Busca archivos fuente de forma inteligente para facilitar el mantenimiento del script .
• Ofrece un lenguaje de programación real (similar a SCons).
• Soporta caché de objetos global para evitar compilaciones innecesarias.
• Soporta objetivos estándar: configurar, compilar, limpiar, instalar y desinstalar.
• Soporta la ejecución de pruebas(test) en los programas al final de la compilación.
Requerimientos • No requiere instalación: el script WAF (menos de 201.2 Historia 100KB) puede ser distribuido y utilizado directamente. Era alrededor del año 2005, el proyecto KDE usó durante mucho tiempo el Autotools como su principal sistema • Sólo necesita a Python como dependencia externa. de construcción. Autotools tiene una arquitectura que es difícil de comprender, y ha sido apodado“auto-infierno” • No requiere sh (a diferencia de GNU Autotools). .,* [1] en KDE estaban considerando la posibilidad de pa• No requiere de conocimientos acerca de M4 (a di- sar de Autotools a SCons. ferencia de GNU Autotools). Thomas Nagy había creado una herramienta de construcción automatizada llamada BKsys que fue diseñada para Soporte de lenguajes: colocarse encima de SCons, proporcionando mayor nivel de funcionalidad similar a la de autotools. Cuando Thomas Nagy decide que los problemas fundamentales de • Preprocesador de dependencias C/C++. SCons (sobre todo la mala escalabilidad) eran demasia• Soporte para programas híbridos en OCaml, en pro- do complejos y requerían mucho tiempo para arreglarse, gramas de GNOME. comienza una reescritura completa llamada “Waf”. • Soporte para el lenguaje de programación D (tanto Waf fue objeto de un poco de atención cuando el proyecto en KDE decidieron utilizar BKsys (y más tarde WAF) GDC y dmd son compatibles). como su principal sistema de construcción, aunque más • Proyectos escritos en vala son soportados ( como tarde, esa decisión fue revocada en favor de CMake porVal(a)IDE ). que BKsys no pudo resolver los problemas de SCons, y Waf todavía estaba en una fase muy temprana de desaOtros: rrollo (pre-alfa) en ese momento.* [1] 372
201.6. ENLACES EXTERNOS
201.3 Ejemplo Waf archivo A continuación se muestra una wscript muy simple, que incluirá una fuente llamada “hola-mundo.c”usando el compilador C por defecto. top = '.' out = 'build' def set_options(opt): opt.tool_options('compiler_cc') def configure(conf): conf.check_tool('compiler_cc') def build(bld): bld(source = 'hello-world.c', target = 'hello-world', features = 'cc cprogram') El proyecto se construye con el siguiente comando: waf configure build
201.4 Véase también • CMake • GNU build system • SCons
201.5 Referencias [1] ¿Por qué el proyecto KDE cambió a CMake(ingles)
201.6 Enlaces externos • Waf página de inicio • GNOME, usado WAF? • Proyectos de Uso Waf
373
Capítulo 202
Win32 Thread Information Block En computación, el Win32 Thread Information Block (TIB) es una estructura de datos en los sistemas Win32, específicamente en la arquitectura x86, que almacena información acerca del hilo que se está ejecutando. También es conocido como el Thread Environment Block (TEB).* [1]
Ejemplos en C inlined-assembly para x86 de 32 bits:
// gcc (AT&T-style inline assembly). void *getTIB() { void *pTib; __asm__(“movl %%fs:0x18, %0”: "=r” (pTib) : : ); return pTib; } // Microsoft C void *getTib() { void *pTib; __asm { mov EAX, FS:[18h] mov [pTib], EAX } return pTib; } El TIB no está documentado oficialmente para Windows // Usando intrinsics de Microsoft en vez de inline 9x. El DDK de la familia Windows NT incluye una es- assembly void *getTib() { void *pTib = ( void * ) tructura NT_TIB en winnt.h que documenta la parte in- __readfsdword( 0x18 ); return pTib; } dependiente de subsistema. El emulador Wine incluye declaraciones para el TIB extendido (una parte especifica del subsistema). Todavía muchos programas de Win32 usan estos campos no documentados que son en efecto 202.3 Enlaces externos una parte de la API. El primer campo, en particular, está directamente referenciado por el código producido por el • Under The Hood - MSJ, May 1996 propio compilador de Microsoft.* [1] • Wine HQ El TIB puede ser usado para obtener una buena cantidad de información sobre el proceso sin tener que llamar a ninguna API de Win32 (por ejemplo, emulaciones de GetLastError() , GetVersion() ). A través del puntero al PEB se puede obtener acceso a las tablas de importación (IAT), los argumentos de inicio pasados al proceso, nombre de la imagen, etc.
202.1 Contenido del TIB FS conduce a un TIB que está incorporado en un bloque de datos conocido como el TDB (Thread Data Base). El TIB contiene la cadena de manejo de excepciones específico a cada hilo y punteros al TLS (Thread Local Storage). El TLS no es lo mismo que el C local storage.
202.2 Acceso al TIB El TIB se puede acceder como un desplazamiento del segmento de registro FS. No es común acceder a campos del TIB por medio de un desplazamiento desde FS:[0], sino que primero se obtiene un puntero de auto-referencia lineal a éste, almacenado en FS:[0x18]. Este puntero se puede usar con aritmética de punteros o se puede transformar a un puntero struct. 374
[1]
Capítulo 203
Wrapper •
Wikcionario tiene definiciones y otra información sobre wrapper.Wikcionario
Wrapper (en castellano empaquetador), es un término inglés que generalmente se refiere a un tipo de embalaje, tal como una hoja plana de papel, celofán o plástico para envolver un objeto.
203.1 Computación • Función wrapper, una función cuyo principal propósito es llamar a otra función. • Biblioteca wrapper • Driver wrapper, software que funciona como un adaptador entre un sistema operativo y un driver. • Patrón Wrapper, donde algunos códigos de programación permiten que ciertas clases trabajen juntas, lo que no sería posible de otra forma. • Clase wrapper, término de computación que se refiere a una clase Java en programación orientada a objetos. • TCP Wrapper, software usado para filtrar el acceso a la red. • Wrapper (Minería de datos), técnica usada en la minería de datos.
203.2 Véase también • Framework
203.3 Referencias • Esta obra deriva de la traducción parcial de Wrapper de Wikipedia en inglés, concretamente de esta versión del 15 de mayo de 2014, publicada por sus editores bajo la Licencia de documentación libre de 375
GNU y la Licencia Creative Commons AtribuciónCompartirIgual 3.0 Unported. • Esta obra deriva de la traducción parcial de Wrapper de Wikipedia en portugués, publicada por sus editores bajo la Licencia de documentación libre de GNU y la Licencia Creative Commons AtribuciónCompartirIgual 3.0 Unported.
Capítulo 204
XAML XAML (acrónimo pronunciado xammel del inglés eXtensible Application Markup Language, Lenguaje Extensible de Formato para Aplicaciones en español) es el lenguaje de formato para la interfaz de usuario para la Base de Presentación de Windows (WPF por sus siglas en inglés) y Silverlight(wpf/e), el cual es uno de los“pilares” de la interfaz de programación de aplicaciones .NET en su versión 3.0 (conocida con anterioridad con el nombre clave WinFX).
como un recurso en un ensamblado de Framework .NET. En el momento de ejecución, el motor del Framework extrae el archivo .baml de los recursos del ensamblado, se analiza sintácticamente, y crea el correspondiente árbol visual WPF o Workflow.
En su uso típico, los archivos tipo XAML serían producidos por una herramienta de diseño visual, como Microsoft Visual Studio o Microsoft Blend. El XML resultante es interpretado en forma instantánea por un subsistema de despliegue de Windows que reemplaza al GDI de las versiones anteriores de Windows. Los elementos de XAML se interconectan con objetos del Entorno Común de Ejecución para Lenguajes. Los atributos se conectan con propiedades o eventos de esos objetos.
de workflow es todavía XOML. [4][5]
Cuando se use en Windows Presentation Foundation, XAML es usado para describir interfaces visuales para usuarios. WPF permite la definición de objetos en 2D y 3D, rotaciones, animaciones y otra variedad de caracteXAML es un lenguaje declarativo basado en XML, opti- rísticas y efectos. mizado para describir gráficamente interfaces de usuarios Cuando es usado en el contexto de Windows Workflow visuales ricas desde el punto de vista gráfico, tales co- Foundation, XAML es usado para describir lógica demo las creadas por medio de Adobe Flash. XUL y UIML clarativa potencialmente larga (potentially long-running son otros ejemplos de lenguajes de interfaz basados en declarative logic), como aquellos creados en el proceso XML. SVG es un estándar de la organización W3C, el de sistemas de modelado y herramientas. El formato de cual soporta gráficos, animaciones, audio y video inte- serialización para WorkFlows había sido llamado previagrados, eventos y comportamiento descrito por medio de mente XOML, para diferenciarlo de su uso en IU de los escritura y puede ser utilizado como lenguaje de interfaz XAML, pero esa diferenciación ya no existe. Sin embarbasado en XML. go las extensiones de los archivos que contienen marcado
XAML fue diseñado para soportar las clases y métodos de la plataforma de desarrollo .NET que tienen relación con la interacción con el usuario, en especial el despliegue en pantalla. El acrónimo XAML originalmente significaba Extensible Avalon Markup Language, Lenguaje Extensible de Formato de Avalon; habiendo sido Avalon el nombre clave original de la Base de Presentación de Windows, nombre que engloba a este grupo de clases de .NET.
204.2 Ejemplos Este ejemplo en XAML muestra un texto“Hola Mundo!" dentro de un contenedor del tipo Canvas.
204.3 Véase también • Microsoft Expression Blend (Herramienta de Microsoft que utiliza XAML)
204.1 Tecnología Un archivo XAML puede ser compilado para obtener un archivo binario XAML .baml, el cual puede ser insertado 376
• Adobe Flex • JavaFX
204.5. ENLACES EXTERNOS • OpenLaszlo • XUL • ZUL
204.4 Referencias 204.5 Enlaces externos • Microsoft Expression • Blog del Equipo de Silverlight (español) • Blog del Equipo de Expression(español) • Información general sobre XAML • United XAML Initiative - Alternativas a XAML de código libre. • Editor XAML gratuito - Aurora
377
Capítulo 205
Zenphp 205.1 ¿Qué es zenphp? zenphp es un completo framework con código fuente, comentarios y documentación en español. Hace las tareas de creación de aplicaciones, no sólo para la web, más sencillas gracias al patrón MVC modificado, y una jerarquía que conecta los componentes de forma que cada parte es accesible mediante variables "$padre”. Está desarrollado en PHP 4 y 5, de forma que es compatible con la mayor parte de los servidores web. Ha sido probado en numerosos proyectos reales. Es posible usarlo para conectar con sistemas gestores de bases de datos como MySQL, PostgreSQL, Oracle o Microsoft SQL Server. Se puede ejecutar por tanto en plataformas *nix (Unix, Linux, etc.) como en plataformas Windows. Hace uso de varios lenguajes de programación:HTML, XHTML, CSS, JavaScript, PERL(CGI), AJAX, PHP, Gtk y XML Se llama zen PHP porque no sólo “simplifica”mucho el código sino que es llevado con la máxima concentración y poco a poco, cada vez más lejos, en cada versión,automáticamente, instantáneamente se van generando nuevas líneas de trabajo...
205.2 ¿Qué ventajas zenphp?
ofrece
• Separación de las capas de información en 3 fases bien distinguidas: diseño de la aplicación, comunicación con el sistema y resultados visibles. • Sencillez y“luminosidad”del código, comprensible de un vistazo y simple. • Realización de tareas complejas,pretratamiento de datos de entrada/salida,etc. • Posibilidad de automatización para AJAX • Generadores de código, formularios, plantillas, consultas,etc.
378
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
379
205.3 Origen del texto y las imágenes, colaboradores y licencias 205.3.1
Texto
• Programación Fuente: https://es.wikipedia.org/wiki/Programaci%C3%B3n?oldid=87243057 Colaboradores: Youssefsan, EL Willy, Soniautn, Sabbut, Moriel, Josmanbernal, Sauron, ManuelGR, Sanbec, Javier Carro, Dodo, Ejmeza, Fortran~eswiki, Ascánder, Rsg, Tostadora, Tano4595, Fernandomirandamuro, Jecanre, Pablomdo, Cinabrium, Porao, Elsenyor, Renabot, Richy, FAR, Mejiad, Mendocino, Digigalos, Sicarul, Airunp, Edub, Emijrp, Magister Mathematicae, Viko~eswiki, Guanxito, Murven, Unf, Mikel Gómez, Dromero, Yrbot, Vitamine, BOTijo, Ivancp, GermanX, Jyon, Gaijin, Quiron, The Photographer, Lucascr, Jesuja, Tigerfenix, Eduardo Lima, Götz, Morza, Ciencia Al Poder, Cheveri, Chlewbot, Tomatejc, Zanaqo, Rbonvall, Electrican MV, Jstitch, BOTpolicia, Qwertyytrewqqwerty, CEM-bot, Jorgelrm, Krli2s, Laura Fiorucci, Chabacano, X.Cyclop, Retama, Rosarinagazo, Antur, Dorieo, Thijs!bot, Esoya, Alvaro qc, Jonpagecr, RoyFocker, Isha, Rrmsjp, JAnDbot, Jugones55, Cmontero, Kved, Pmisiones, Mansoncc, Bboccioz, NaBUru38, Humberto, Netito777, Xsm34, Marvelshine, Nioger, Chabbot, Pólux, Biasoli, AchedDamiman, Snakeyes, Technopat, Matdrodes, Autonomia, Fernando Estel, Elabra sanchez, Lic. Armando, BlackBeast, Shooke, Lucien leGrey, Sdfk, Dinopmi, Gerakibot, SieBot, Ctrl Z, Cousteau, Ortellado, Manwë, Correogsk, 3xxx, Mafores, Yonseca, Tirithel, Jarisleif, Javierito92, Amorde2, Eduardosalg, Leonpolanco, Botito777, Petruss, Aliuk, Moucaisius, JMDC, UA31, SergioN, AVBOT, David0811, Diegusjaimes, IATG, Jjflorescueto, CarsracBot, HerculeBot, Arjuno3, Andreasmperu, Luckas-bot, Jaromero, Cata11, Roinpa, Bifus, Jotterbot, Vitucho3005, ArthurBot, SuperBraulio13, Xqbot, Jkbw, NeoTommy, Serolillo, Pedrovicenterosero, Voetius, Chester269, Albertochoa, Torrente, Botarel, BenzolBot, Stuffy, MauritsBot, TigreVMMM, MAfotBOT, Gusbelluwiki, Linux65, RedBot, KamikazeBot, Slashcsc, Dinamik-bot, Angelito7, Ripchip Bot, Tarawa1943, GrouchoBot, EmausBot, Savh, HRoestBot, Sergio Andres Segovia, Fabian Rod, Rubpe19, Jcaraballo, ChuispastonBot, Merryt, Waka Waka, WikitanvirBot, Upc, RobotEducativo, Renly, Communities, AvicBot, Sebrev, Travelour, Acratta, Brainup, LlamaAl, EnzaiBot, Helmy oved, DavidUlquiorra, MaKiNeoH, Ovallesoft, Xx.the.samuel.xx, Ivanretro, Addbot, Balles2601, Advarg, Tenganmemiedo, Qwerty asdfg zxcvb, Eliazibh Bojorquez, MrCharro, Jarould, Eurodyne, Sapristi1000, Castillo.melanii y Anónimos: 437 • Portal:Programación Fuente: https://es.wikipedia.org/wiki/Portal%3AProgramaci%C3%B3n?oldid=68731535 Colaboradores: Emijrp, Jesuja, Bienchido, AchedDamiman, VolkovBot, Shooke, PaintBot, KLBot2, MetroBot, Addbot y Anónimos: 1 • & Fuente: https://es.wikipedia.org/wiki/%26?oldid=87472056 Colaboradores: Josemoya, Rosarino, Cookie, Tano4595, Rodrigouf, M3c4n0, Edupedro, Jo-Con-El, Taichi, Emijrp, LP, Kenedhor, Orgullobot~eswiki, RobotQuistnix, Platonides, Caiserbot, Amadís, BOTSuperzerocool, YurikBot, Martingala, Armin76, KnightRider, Kazahana, No sé qué nick poner, Ephraim33, DivByZ, Faelomx, Futbolero, Cerato, SaulPerdomo, Qwertyytrewqqwerty, Nethac DIU, CEM-bot, Jorgelrm, Al2, Corbu, Araltor, Penquista, Rastrojo, Antur, D.o, Thijs!bot, Zigurat, JAnDbot, Mansoncc, TXiKiBoT, Aalvarez12, Humberto, Guillermo D.~eswiki, Rei-bot, Chabbot, Pólux, Bucephala, Aibot, Vicdesan, Technopat, Lahi, DRMProd, Matdrodes, RandomJambo, Muro Bot, Edmenb, SieBot, Bigsus-bot, BOTarate, Ceat 700, Greek, Tirithel, Farisori, Eduardosalg, TronaBot, Petruss, Osado, Purbo T, Abajo estaba el pez, AVBOT, LucienBOT, Marifernan, Lampsako, Luckas-bot, 67wkii, Almabot, Jkbw, Cally Berry, TobeBot, Alph Bot, GrouchoBot, AVIADOR, WikitanvirBot, Serlack, KLBot2, Bibliofilotranstornado, Stramin, Ralgisbot, Thegastiinthedark, Jarould, ~Expresses life y Anónimos: 68 • Acoplamiento secuencial Fuente: https://es.wikipedia.org/wiki/Acoplamiento_secuencial?oldid=65390358 Colaboradores: Kavanagh, Héctor Guido Calvo, Invadibot, Dalbela y Addbot • Adobe Director Fuente: https://es.wikipedia.org/wiki/Adobe_Director?oldid=79460596 Colaboradores: BOT-Superzerocool, BOTijo, FedericoMP, Sinopsis, Boja, Faelomx, BOTpolicia, Mampato, CEM-bot, Laura Fiorucci, Muro de Aguas, JoseA, Rei-bot, Pólux, VolkovBot, Muro Bot, SieBot, Pedro Felipe, Ivgarci, Mit3d, Alecs.bot, Alexbot, Orgullo Illustrator, Spider pig, BotSottile, AVBOT, Diegusjaimes, MelancholieBot, Luckas-bot, Wikisilki, Dangelin5, Ortisa, AstaBOTh15, EmausBot, Grillitus, Rufflos, MerlIwBot, KLBot2, Elvisor, Helmy oved, Ralgisbot, Digmin3 y Anónimos: 19 • Anidamiento (informática) Fuente: https://es.wikipedia.org/wiki/Anidamiento_(inform%C3%A1tica)?oldid=72430597 Colaboradores: Muro Bot, Poco a poco, Dangelin5, MaxBech1975, Patafisik, EmausBot, KLBot2, Ginés90, Harpagornis y Anónimos: 3 • Antipatrón de diseño Fuente: https://es.wikipedia.org/wiki/Antipatr%C3%B3n_de_dise%C3%B1o?oldid=87450852 Colaboradores: Pacoqueen, Vanbasten 23, Rosarino, Fortran~eswiki, Ascánder, Tostadora, Porao, Benjavalero, Renabot, RobotQuistnix, YurikBot, GermanX, KnightRider, Dmlambea~eswiki, Cad, Zoid, CEM-bot, Davius, Thijs!bot, Yeza, Kavanagh, Gitano.canalla, Pvent, Kijote, PJTraill, VolkovBot, Jarm.yo, Technopat, Lauramcastro, SieBot, Ozewi, Pablo323, BetoCG, Zeliq, BotSottile, Diegusjaimes, Amirobot, Ptbotgourou, Vic Fede, Xqbot, Silvioq, AstaBOTh15, Enrique Cordero, ArwinJ, Xiidarkevil, EmausBot, ZéroBot, WikitanvirBot, MovGP0, KLBot2, MetroBot, Addbot y Anónimos: 44 • Archivo de cabecera Fuente: https://es.wikipedia.org/wiki/Archivo_de_cabecera?oldid=84684202 Colaboradores: Sabbut, Basquetteur, CEM-bot, BlackSalamander, Cratón, Isha, JAnDbot, TXiKiBoT, Phirosiberia, Muro Bot, MaSt, Poco a poco, Kroji, MastiBot, Angel GN, DumZiBoT, Luckas-bot, Marioxcc, SuperBraulio13, Xqbot, Jkbw, Panderine!, KamikazeBot, Mr.Ajedrez, Sergio Andres Segovia, Grillitus, Hoo man, MerlIwBot, Elvisor, Addbot y Anónimos: 15 • Aserción (informática) Fuente: https://es.wikipedia.org/wiki/Aserci%C3%B3n_(inform%C3%A1tica)?oldid=87499440 Colaboradores: Robbot, BOT-Superzerocool, GermanX, Escarbot, Fabeirojorge, Carmin, Poco a poco, MystBot, Alph Bot, Waeswaes, EmausBot, ZéroBot, KLBot2, Bibliofilotranstornado, Elvisor y Anónimos: 5 • Automatización de tareas Fuente: https://es.wikipedia.org/wiki/Automatizaci%C3%B3n_de_tareas?oldid=74686365 Colaboradores: CF, Walking Mind, Technopat, BlackBeast, PaintBot, M S, Farisori, Diegusjaimes, DiegoFb, Victor carmonag, Jkbw, Khavas, RodolfoLay y Anónimos: 5 • Base de código Fuente: https://es.wikipedia.org/wiki/Base_de_c%C3%B3digo?oldid=86838733 Colaboradores: GermanX, CEM-bot y KLBot2 • Bean Fuente: https://es.wikipedia.org/wiki/Bean?oldid=84356720 Colaboradores: Pilaf, Sunsinron, Robotico, Soulreaper, Taichi, FlaBot, Rosarinagazo, Desert69, Kved, VolkovBot, Carmin, Umondri, PatruBOT, Canyq, Goica, Dark Bane, HRoestBot, ChuispastonBot, Addbot y Anónimos: 26 • Beta tester Fuente: https://es.wikipedia.org/wiki/Beta_tester?oldid=77021285 Colaboradores: SimónK, Digigalos, FlaBot, Varano, Vitamine, GermanX, Smrolando, Nethac DIU, CEM-bot, Marianov, Madoks, JAnDbot, TXiKiBoT, Krun00, Mstreet linux, Muro Bot, Fadesga, UA31, AVBOT, MastiBot, Ezarate, Arjuno3, Hoenheim, SuperBraulio13, Jkbw, Ignasi Gorina, Irak Gaitán, Addbot, BOTito y Anónimos: 10
380
CAPÍTULO 205. ZENPHP
• Bifurcación (sistema operativo) Fuente: https://es.wikipedia.org/wiki/Bifurcaci%C3%B3n_(sistema_operativo)?oldid=83423061 Colaboradores: Yearofthedragon, Niqueco, Chobot, FlaBot, Qwertyytrewqqwerty, TXiKiBoT, VolkovBot, Shooke, PaintBot, Diegusjaimes, Ptbotgourou, DiegoFb, Kizar, ZéroBot, ChessBOT, MerlIwBot, KLBot2, Martin Ariel Ramirez, Porrasporrasporras y Anónimos: 11 • Binding Fuente: https://es.wikipedia.org/wiki/Binding?oldid=79485676 Colaboradores: Robbot, Loco085, Airunp, Genba, Yrbot, Beto29, CEM-bot, Thijs!bot, Gusgus, Segedano, Aika~eswiki, Synthebot, Muro Bot, Farisori, Jerowiki, Diamondland, MerlIwBot, KLBot2, Elvisor, Addbot, Hipocamp15 y Anónimos: 8 • Bloqueo mutuo Fuente: https://es.wikipedia.org/wiki/Bloqueo_mutuo?oldid=74685861 Colaboradores: Sabbut, Moriel, Sauron, Vanbasten 23, Dodo, Sms, Niqueco, Hari Seldon, Rembiapo pohyiete (bot), RobotQuistnix, Francosrodriguez, Superzerocool, Caiserbot, Yucon, Yrbot, BOT-Superzerocool, Martincarr, YurikBot, GermanX, Gothmog, Tigerfenix, Eskimbot, CEM-bot, Isha, Dogor, JAnDbot, TXiKiBoT, Rei-bot, NaSz, VolkovBot, Matdrodes, Estirabot, Leonpolanco, Alexbot, BotSottile, AVBOT, Luckas-bot, Amirobot, Jkbw, AstaBOTh15, D'ohBot, PatruBOT, Waeswaes, EmausBot, ZéroBot, Elvisor, Legobot, Ideator 2.0 y Anónimos: 21 • Bodyshopping Fuente: https://es.wikipedia.org/wiki/Bodyshopping?oldid=80659893 Colaboradores: SimónK, Yrbot, Varano, Olea, CEM-bot, Tortillovsky, Isha, Phirosiberia, Rolloqui, Muro Bot, Diegusjaimes, Marcomogollon, Caritdf, Grillitus, Johnbot, Elvisor y Anónimos: 12 • BrookGPU Fuente: https://es.wikipedia.org/wiki/BrookGPU?oldid=68993723 Colaboradores: Boticario, CEM-bot, Montgomery, Filiprino, VolkovBot, Alexbot, Krysthyan, AVBOT, Bethan 182, InflaBOT, MerlIwBot, KLBot2, Elvisor, EduLeo y Anónimos: 3 • Caja blanca (sistemas) Fuente: https://es.wikipedia.org/wiki/Caja_blanca_(sistemas)?oldid=85453584 Colaboradores: Carutsu, Xexito, Cinevoro, Robertorp, Espilas, Nicop, Farisori, VkN, UA31, AVBOT, Angel GN, KLBot, MerlIwBot, KLBot2, YeltFlor y Anónimos: 11 • Caja negra (sistemas) Fuente: https://es.wikipedia.org/wiki/Caja_negra_(sistemas)?oldid=85423326 Colaboradores: Oblongo, Jesuja, Davius, Tortillovsky, Amire80, JAnDbot, VolkovBot, Synthebot, Muro Bot, Feministo, Loveless, David.Horat, XalD, Cyborg ar, Alejandro Lodes, UA31, AVBOT, Diegusjaimes, CarsracBot, Luckas-bot, Ptbotgourou, DiegoFb, Botarel, MondalorBot, PatruBOT, Dinamik-bot, Angelito7, Foundling, Wikiléptico, EmausBot, HRoestBot, WikitanvirBot, MerlIwBot, KLBot2, TeleMania, Elvisor, MahdiBot, AS-W, BOTito, Jarould, Crystallizedcarbon y Anónimos: 33 • CamelCase Fuente: https://es.wikipedia.org/wiki/CamelCase?oldid=80299007 Colaboradores: Robbot, Miuler, Ascánder, Fernandomirandamuro, Fleam, Emijrp, Rembiapo pohyiete (bot), Aadrover, RobotQuistnix, Maquiavelo, Yrbot, Baifito, BOT-Superzerocool, FlaBot, BOTijo, Eskimbot, Floppy3, Rei-bot, Biasoli, VolkovBot, Technopat, Chechurisk, Muro Bot, SieBot, Loveless, Mrfoxtalbot, Jaontiveros, Alexbot, MastiBot, Luckas-bot, MystBot, Marioxcc, Vivaelcelta, Invelg, Yago AB, EmausBot, David camelo, Grillitus, Albertojuanse, WikitanvirBot, KLBot2, Allan Aguilar, Makecat-bot, Addbot y Anónimos: 28 • Caml Fuente: https://es.wikipedia.org/wiki/Caml?oldid=86731214 Colaboradores: UAwiki y Brivadeneira • Cierre de exclusión mutua Fuente: https://es.wikipedia.org/wiki/Cierre_de_exclusi%C3%B3n_mutua?oldid=77602139 Colaboradores: Periku, Boticario, Yrbot, Martincarr, YurikBot, GermanX, CEM-bot, Thijs!bot, Dogor, CommonsDelinker, VolkovBot, Muro Bot, Racso, STBot~eswiki, Luckas-bot, Amirobot, Diogeneselcinico42, EmausBot, WikitanvirBot, Dexbot, Legobot y Anónimos: 3 • Clase utilidad Fuente: https://es.wikipedia.org/wiki/Clase_utilidad?oldid=22946124 Colaboradores: Matiasmoreno, Muro Bot, Gizbot y Anónimos: 1 • Clear.gif Fuente: https://es.wikipedia.org/wiki/Clear.gif?oldid=35650490 Colaboradores: Eloy, CEM-bot, Beaire1 y Anónimos: 1 • CMake Fuente: https://es.wikipedia.org/wiki/CMake?oldid=87507838 Colaboradores: Emijrp, Anonimato1990, El Pantera, Menthalo, UA31, Billinghurst, Monkey.libre, Paroga, KLBot2, Conopo, Silentter y Anónimos: 8 • Codecademy Fuente: https://es.wikipedia.org/wiki/Codecademy?oldid=85518557 Colaboradores: Eloy, CEM-bot, CommonsDelinker, Fremen, TheDarkFear, EmausBot, Grillitus, Invadibot, Flashlack, Harry Canyon, Quethzel, Jaod98 y Anónimos: 4 • Código cerrado Fuente: https://es.wikipedia.org/wiki/C%C3%B3digo_cerrado?oldid=85015301 Colaboradores: Pino, Joseaperez, Dodo, Ejrrjs, Ascánder, Sms, Yakoo, JCCO, Digigalos, Hari Seldon, RobotQuistnix, FlaBot, Usrwp, AtilaElHuno, Gabriel Acquistapace, Thijs!bot, JAnDbot, TXiKiBoT, Rei-bot, AlnoktaBOT, Shooke, Muro Bot, SieBot, PaintBot, Javierito92, Marcecoro, UA31, X-DNA-X, DiegoFb, MerlIwBot, Addbot, Balles2601 y Anónimos: 12 • Código compilado Fuente: https://es.wikipedia.org/wiki/C%C3%B3digo_compilado?oldid=83041666 Colaboradores: CEM-bot, Netito777, AchedDamiman, Muro Bot, PaintBot, Farisori, DiegoFb, Jarould, Ivan santillo y Anónimos: 1 • Código mutante Fuente: https://es.wikipedia.org/wiki/C%C3%B3digo_mutante?oldid=65069407 Colaboradores: Hari Seldon, Tomatejc, Sirpuppet, AchedDamiman, VolkovBot, Muro Bot, PaintBot, BOTarate, Farisori, DiegoFb, Jorge c2010, Addbot y Anónimos: 2 • Código objeto Fuente: https://es.wikipedia.org/wiki/C%C3%B3digo_objeto?oldid=84835561 Colaboradores: Oblongo, Moriel, ManuelGR, Sms, Rsg, Rembiapo pohyiete (bot), RobotQuistnix, Yrbot, Baifito, Icvav, GermanX, Jesuja, Aleator, Chabacano, Escarlati, Thijs!bot, TXiKiBoT, Gacq, Rei-bot, Biasoli, Shooke, AlleborgoBot, Muro Bot, Loveless, BOTarate, Marodok, AVBOT, Arjuno3, Luckasbot, Kender00, RedBot, PatruBOT, KamikazeBot, GrouchoBot, EmausBot, Grillitus, ChuispastonBot, Legobot, DarkBlueZV, Jarould y Anónimos: 21 • Ofuscación Fuente: https://es.wikipedia.org/wiki/Ofuscaci%C3%B3n?oldid=86976670 Colaboradores: JMPerez, Nuen, Thijs!bot, Matdrodes, Alejandroadan, BenzolBot, Gusbelluwiki, Acastiello, Elvisor, Addbot, Comnetgt y Anónimos: 14 • ColdFusion Fuente: https://es.wikipedia.org/wiki/ColdFusion?oldid=84655763 Colaboradores: Pino, Tostadora, Benjavalero, Boticario, Yrithinnd, Taichi, RobotQuistnix, Yrbot, FlaBot, GermanX, The Photographer, Aladiah, FedericoMP, Kekkyojin, Mrpollo, Faelomx, CEM-bot, Thijs!bot, Ernesto r., JAnDbot, C4rlitoz, Tuliopa, Spa karmona, TXiKiBoT, AlnoktaBOT, Shinji14, AlleborgoBot, Muro Bot, Bucho, Rrrafa, BotMultichill, SieBot, Loveless, Abrenoite, WikiBotas, Alexbot, LucienBOT, Emiliot11, HerculeBot, Nallimbot, Cristianpark, Ptbotgourou, Xqbot, TiriBOT, Alph Bot, EmausBot, KLBot2, LlamaAl, Elvisor, Legobot y Anónimos: 23 • Coloreado de sintaxis Fuente: https://es.wikipedia.org/wiki/Coloreado_de_sintaxis?oldid=77127817 Colaboradores: Oblongo, Murphy era un optimista, Barcex, Ictlogist, RobotQuistnix, Icvav, Eloy, Antur, Diosa, Isha, JAnDbot, Humberto, Biasoli, Dusan, VolkovBot, AlleborgoBot, Muro Bot, SieBot, Pan con queso, MenoBot, Heallo, AVBOT, MastiBot, Luckas-bot, WikiDreamer Bot, Xqbot, Josemiguel93, Adryitan, EmausBot, Guarddon, Grillitus, Diego Moya, Gcosta87, Draug, Legobot y Anónimos: 16
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
381
• Comentario (informática) Fuente: https://es.wikipedia.org/wiki/Comentario_(inform%C3%A1tica)?oldid=86674487 Colaboradores: Joseaperez, Corso, Jachguate, Emijrp, Adrruiz, Götz, Faelomx, CEM-bot, Isha, Gaius iulius caesar, Xosema, Netito777, VolkovBot, Matdrodes, Drinibot, BOTarate, Eduardosalg, Poco a poco, Ucevista, LucienBOT, MastiBot, TheDarkFear, Diegusjaimes, MelancholieBot, Luckas-bot, Gperaltascura, SuperBraulio13, Jkbw, Kyng, Rubinbot, Desiben, Waeswaes, Edslov, EmausBot, Adri128, Grillitus, WikitanvirBot, Metrónomo, KLBot2, Invadibot, Elvisor, DarkBlueZV y Anónimos: 15 • Compatibilidad (informática) Fuente: https://es.wikipedia.org/wiki/Compatibilidad_(inform%C3%A1tica)?oldid=85054771 Colaboradores: Elwikipedista, Emijrp, Yrbot, BOTijo, Gejotape, Dmitri Lytov, Isha, Pólux, AchedDamiman, Technopat, Elabra sanchez, Shooke, Muro Bot, Fadesga, Farisori, Botito777, Jcaraballo, MerlIwBot, Elvisor, Addbot y Anónimos: 12 • Competición Internacional Universitaria ACM de Programación Fuente: https://es.wikipedia.org/wiki/Competici%C3%B3n_ Internacional_Universitaria_ACM_de_Programaci%C3%B3n?oldid=87462212 Colaboradores: Sabbut, Sanbec, Boticario, BOTSuperzerocool, Jgaray, Banderas, CEM-bot, Ingenioso Hidalgo, Xxim, Xavigivax, Pólux, Atomic 007, AlleborgoBot, Loblesa, BOTarate, Botito777, MastiBot, Diegusjaimes, Luckas-bot, MystBot, Xqbot, TobeBot, ZéroBot, Elvisor, ShersonLazaro, Legobot, Cbretana, LucasMCG y Anónimos: 31 • Computación parasitaria Fuente: https://es.wikipedia.org/wiki/Computaci%C3%B3n_parasitaria?oldid=65029794 Colaboradores: Aeveraal, CEM-bot, Argaldo, Muro Bot, KLBot2 y Anónimos: 1 • Conectiva lógica Fuente: https://es.wikipedia.org/wiki/Conectiva_l%C3%B3gica?oldid=87466604 Colaboradores: Niceforo, Dodo, Ascánder, Julian Colina, Xenoforme, Superzerocool, Caiserbot, Memiux, Yrbot, GermanX, JAGT, Jesuja, Er Komandante, Rdds, Ivan romero, CEM-bot, Damifb, Davius, Julian Mendez, Zufs, TXiKiBoT, MONIMINO, Snakeyes, Matdrodes, Elabra sanchez, Mary dream, Edmenb, SieBot, Francisco Mochis, Drinibot, Jarisleif, Dnu72, Alejandrocaro35, AVBOT, Cegik, Diegusjaimes, Davidgutierrezalvarez, Arjuno3, Dangelin5, Equiman, Luis Felipe Schenone, ArthurBot, SuperBraulio13, Xqbot, Jkbw, GNM, Danke7, Igna, Foundling, Grillitus, Gusama Romero, Acratta, Addbot, Anderper, Jarould, TheGamerSexy y Anónimos: 64 • Configuración regional Fuente: https://es.wikipedia.org/wiki/Configuraci%C3%B3n_regional?oldid=77882164 Colaboradores: Faelomx, Thijs!bot, Biasoli, Fadesga, Nallimbot, ArthurBot, Xqbot, Born2bgratis, Dinamik-bot, EmausBot, Grillitus, JackieBot, WikitanvirBot, Makecat-bot y Addbot • Conteo de referencias Fuente: https://es.wikipedia.org/wiki/Conteo_de_referencias?oldid=65063546 Colaboradores: Niqueco, Pinar~eswiki, Thijs!bot, Muro Bot, SieBot, Luckas-bot, DiegoFb, Hoenheim, D'ohBot, Hprmedina, Dinamik-bot, EmausBot y KLBot2 • Convención de Nombres (Programación) Fuente: https://es.wikipedia.org/wiki/Convenci%C3%B3n_de_Nombres_(Programaci%C3% B3n)?oldid=87413749 Colaboradores: BOT-Superzerocool, Bngs, FrescoBot, Grillitus, KLBot2, MetroBot, Elvisor, Omixam, JSuarezB, BenjaBot y Anónimos: 4 • Cracking (software) Fuente: https://es.wikipedia.org/wiki/Cracking_(software)?oldid=73824018 Colaboradores: Robbot, Alakasam, JAnDbot, ARNT, TXiKiBoT, ColdWind, Xvazquez, Biasoli, Poco a poco, MystBot, Jotterbot, Xqbot, Kizar, Sermed, Alph Bot, ChessBOT, Grillitus, WikitanvirBot, KLBot2 y Damianiencowiki • Cuaderno de carga Fuente: https://es.wikipedia.org/wiki/Cuaderno_de_carga?oldid=66426276 Colaboradores: Tomatejc, Boja, CEMbot, Montgomery, Resped, Muro Bot, HUB y Anónimos: 3 • Currificación Fuente: https://es.wikipedia.org/wiki/Currificaci%C3%B3n?oldid=86841892 Colaboradores: Rbonvall, Rosarinagazo, SITOMON, Nolaiz, VolkovBot, Loveless, BOTarate, Poco a poco, OMFGROFLMAO, Angelito7, ChuispastonBot, Elvisor, Addbot y Anónimos: 1 • Código enhebrado Fuente: https://es.wikipedia.org/wiki/C%C3%B3digo_enhebrado?oldid=87343406 Colaboradores: GermanX, Cinevoro, Shooke, Muro Bot, ZéroBot, Elvisor, Addbot y Anónimos: 1 • Código inalcanzable Fuente: https://es.wikipedia.org/wiki/C%C3%B3digo_inalcanzable?oldid=79130740 Colaboradores: CEM-bot, Cinevoro, Waeswaes, Grillitus, Invadibot, Rotlink y Addbot • Código muerto Fuente: https://es.wikipedia.org/wiki/C%C3%B3digo_muerto?oldid=80068437 Colaboradores: Sabbut, GermanX, CEMbot, Angelito7, Waeswaes, Invadibot, Addbot y Anónimos: 1 • Código redundante Fuente: https://es.wikipedia.org/wiki/C%C3%B3digo_redundante?oldid=79134303 Colaboradores: CEM-bot, Waeswaes, Grillitus, Invadibot y Addbot • Dato Fuente: https://es.wikipedia.org/wiki/Dato?oldid=87217423 Colaboradores: PACO, Moriel, Sauron, JorgeGG, Pilaf, Angus, Wiki Wikardo~eswiki, Bigsus, Interwiki, Cookie, Tano4595, Robotito, Dianai, Jpodjarny, Porao, Alphabravotango, Digigalos, Soulreaper, Hispa, Airunp, Taichi, Emijrp, RobotQuistnix, Alhen, Chobot, Yrbot, Baifito, Vitamine, .Sergio, YurikBot, Icvav, KnightRider, The Photographer, Jesuja, Maldoror, Er Komandante, Filipo, Siabef, Alexquendi, Locutus Borg, BOTpolicia, Klondike, Damifb, Laura Fiorucci, -jem-, Davius, Antur, Montgomery, Escarbot, CED, RoyFocker, IrwinSantos, Isha, Egaida, Dogor, Gusgus, JAnDbot, Ana wiki, TXiKiBoT, Humberto, Idioma-bot, Pólux, Biasoli, AchedDamiman, Cinevoro, VolkovBot, Technopat, Mr. Benq, Matdrodes, Lucien leGrey, Edmenb, Racso, Dodecaedro, SieBot, Manwë, Correogsk, Aleposta, Tirithel, Jarisleif, Javierito92, Marcecoro, HUB, Nicop, Farisori, Eduardosalg, Leonpolanco, Alejandrocaro35, Furti, Açipni-Lovrij, UA31, AVBOT, David0811, Alejandro bera, MastiBot, MarcoAurelio, NjardarBot, Diegusjaimes, CarsracBot, HerculeBot, Arjuno3, Andreasmperu, Luckas-bot, SuperBraulio13, Jkbw, Igna, Botarel, SUL, MondalorBot, TobeBot, Vubo, Leugim1972, PatruBOT, Dinamik-bot, Duuk-Tsarith, Tarawa1943, Foundling, Edslov, EmausBot, Savh, AVIADOR, MercurioMT, Jcaraballo, Waka Waka, WikitanvirBot, Richardedu, Rezabot, MerlIwBot, JABO, Laencilclopedialibre, Deivis, Travelour, Vichock, Gusama Romero, Hcurti, Acratta, Mega-buses, Érico, Santga, Helmy oved, Syum90, Faustinogay, Addbot, Balles2601, Chivogay, Edergay, Rancho gudy, JacobRodrigues, CamiloBer04, Joyaso123, Jarould, Matiia, Raelth, Fearinghealer, Gaby Medina Murillo, JuanCalamidad, Ariel0345, Losperritos, Fernando2812l y Anónimos: 286 • Depuración de programas Fuente: https://es.wikipedia.org/wiki/Depuraci%C3%B3n_de_programas?oldid=81463985 Colaboradores: Kristobal, Ejrrjs, Sms, Rsg, Felipealvarez, Renabot, Rembiapo pohyiete (bot), Wastingmytime, OMenda, Orgullobot~eswiki, Chobot, Yrbot, Baifito, YurikBot, GermanX, KnightRider, CEM-bot, ARHEKI, Thijs!bot, JAnDbot, Gsrdzl, Guirrohl, Biasoli, Gmarinp, Muro Bot, J.M.Domingo, SieBot, PaintBot, Djblack!, Facucario, Alejandrocaro35, Pedromanchon, Diegusjaimes, Luckas-bot, Amirobot, Xqbot, Jkbw, Rocafort8, BOTirithel, Kizar, Waeswaes, EmausBot, HRoestBot, Grillitus, WikitanvirBot, Lexinerus, MerlIwBot, Erick Capslock, Legobot, Addbot, Jarould, Gregory serrata y Anónimos: 23
382
CAPÍTULO 205. ZENPHP
• Desarrollador de software Fuente: https://es.wikipedia.org/wiki/Desarrollador_de_software?oldid=86789961 Colaboradores: SimónK, Herenvardo, Vitamine, BOTijo, CEM-bot, Thijs!bot, JAnDbot, Antipatico, TXiKiBoT, Rei-bot, VolkovBot, Shooke, Lucien leGrey, BotMultichill, Loveless, Marcecoro, DragonBot, BetoCG, Nallimbot, DiegoFb, ArthurBot, Xqbot, AnselmiJuan, PatruBOT, EmausBot, CocuBot, MerlIwBot, KLBot2, Wrotetool, Legobot, Hazel.rojas96, Jarould y Anónimos: 11 • Desarrollo en cascada Fuente: https://es.wikipedia.org/wiki/Desarrollo_en_cascada?oldid=87023744 Colaboradores: Ejmeza, Ejrrjs, Richy, FAR, Edub, Yrithinnd, Orgullobot~eswiki, Penyaskito, Unf, Alhen, Superzerocool, Yrbot, Vitamine, Icvav, GermanX, JRGL, Kepler Oort, Axxgreazz, CEM-bot, Osepu, Fsd141, Thijs!bot, Jonpagecr, Mahadeva, Isha, Ppedrodom, Infovoro, TXiKiBoT, Humberto, Decorrea, Pólux, VolkovBot, WarddrBOT, Technopat, Jose figueredo, Matdrodes, DJ Nietzsche, SieBot, Irtusb, Greek, Jossue130987, Marcecoro, Feperozpo, Nicop, UA31, AVBOT, SpBot, Diegusjaimes, Bethan 182, MelancholieBot, Luckas Blade, Tremal Naik, Arjuno3, Luckas-bot, Nallimbot, Roinpa, Markoszarrate, Barteik, Gacpro, ArthurBot, SuperBraulio13, Jkbw, Torrente, Jesua3005, PatruBOT, Tarawa1943, GrouchoBot, EmausBot, Africanus, Grillitus, Almogo, Alexandermark, WikitanvirBot, Lcsrns, MerlIwBot, Ayaita, Renciw, Adribeex, Harpagornis, Elvisor, Asqueladd, Bolivarista, Rotlink, Legobot, Melgar22, Bordierrez, Jedijor14, Julianromera, IsaacReal, Jonxa22, Ikeri122 y Anónimos: 206 • Desarrollo en espiral Fuente: https://es.wikipedia.org/wiki/Desarrollo_en_espiral?oldid=85593490 Colaboradores: PACO, Vanbasten 23, Sanbec, Dodo, Rikaaii, Cookie, Murphy era un optimista, Msxgopr, Cinabrium, Balderai, Kordas, Taragui, Pezezin~eswiki, Airunp, Rembiapo pohyiete (bot), Orgullobot~eswiki, RobotQuistnix, LarA, Caiserbot, Yrbot, Oscar ., BOTijo, Martingala, GermanX, The Photographer, Galle, Siabef, Tamorlan, CEM-bot, Meltryth, Ignacio Icke, Rafa sanz, GuiXu, Retama, Osepu, EcLiB, Thijs!bot, Escarbot, RoyFocker, Isha, Kved, Yamaneko, Infovoro, Muro de Aguas, Netito777, Xsm34, Pólux, Javierxar, VolkovBot, Technopat, Jose figueredo, Matdrodes, Shooke, Muro Bot, Bucho, Jmvgpartner, SieBot, PaintBot, Gospelepsog, Cumanacr, Leonpolanco, Caucas, SergioN, AVBOT, Adelpine, Diegusjaimes, Arjuno3, Kmilovc, Xqbot, Jkbw, Botarel, Ereguero, ErikvanB, Jorge c2010, Savh, Grillitus, Bpk, MerlIwBot, Thehelpfulbot, Ginés90, Adribeex, Johnbot, MarioCar88, Legobot, Nito18, Thawk101, Jarould y Anónimos: 142 • Desarrollo iterativo y creciente Fuente: https://es.wikipedia.org/wiki/Desarrollo_iterativo_y_creciente?oldid=81974918 Colaboradores: Vanbasten 23, Yrbot, Varano, Martingala, CEM-bot, Osepu, Isha, Corvocativo, LeinaD natipaC, Redjhawk, Technopat, Jose figueredo, BlackBeast, Muro Bot, Botito777, UA31, Diegusjaimes, Bloomy, DixonDBot, Foundling, Grillitus, Davidarturo21, MerlIwBot, AvicBot, Addbot, Farnhey, Nathy2893, Dominic1593, LinkYanela, Elnico2787, Gustavosanais y Anónimos: 28 • Detección dinámica de invariantes Fuente: https://es.wikipedia.org/wiki/Detecci%C3%B3n_din%C3%A1mica_de_invariantes?oldid= 50060317 Colaboradores: El Pantera • Diagrama de colaboración Fuente: https://es.wikipedia.org/wiki/Diagrama_de_colaboraci%C3%B3n?oldid=85275446 Colaboradores: Tano4595, Santiperez, Er Komandante, Dhidalgo, PaintBot, Tirithel, Mutari, Javierito92, Kikobot, Alejandro Lodes, AVBOT, Ialad, DiegoFb, Wikante, Hoenheim, Botarel, Allforrous, EduLeo y Anónimos: 38 • Diagrama de flujo Fuente: https://es.wikipedia.org/wiki/Diagrama_de_flujo?oldid=87525997 Colaboradores: JIPumarino, JorgeGG, Wesisnay, Angus, Comae, Rosarino, Dodo, SimónK, Rsg, Cookie, Tostadora, Julian Colina, Barcex, DanielCardaci, Gengiskanhg, Porao, Schummy, Fmariluis, Chewie, FAR, Digigalos, Boticario, Soulreaper, Petronas, Hispa, Airunp, JMPerez, Edub, Taichi, LeCire, Magister Mathematicae, Dem, Murven, RobotQuistnix, Unf, Alhen, Akhram, Ryavara, Jomra, Caiserbot, Yrbot, Amadís, BOT-Superzerocool, Vitamine, BOTijo, .Sergio, Mortadelo2005, Beto29, Armin76, Quiron, The Photographer, Jesuja, Santiperez, Banfield, Jmencisom, Morza, Er Komandante, Tomatejc, Filipo, The worst user, Rbonvall, Faelomx, Kn, Aleator, BOTpolicia, CEM-bot, Jorgelrm, Cantero, Laura Fiorucci, Ignacio Icke, Xexito, Baiji, Rastrojo, Antur, Dorieo, Montgomery, Resped, Thijs!bot, Alvaro qc, Tortillovsky, Hygiliak, Carlos t, Diosa, Olaf Emmanuel Vargas Ramírez, RoyFocker, Gabrielmt, IrwinSantos, Ninovolador, Cratón, Isha, Gusgus, Góngora, Mpeinadopa, Niko guti2006, Jurgens~eswiki, JAnDbot, Ncespedes, Maria angelica, Mansoncc, Muro de Aguas, Zufs, Gsrdzl, Hidoy kukyo, Elisardojm, Humberto, Netito777, Jvlivs, Pólux, Rovnet, Manuel Trujillo Berges, Bucephala, AlnoktaBOT, Cipión, Cinevoro, Aibot, VolkovBot, Technopat, Jose figueredo, Galandil, Queninosta, Erfil, Matdrodes, Fernando Estel, Synthebot, BlackBeast, Lucien leGrey, Luis1970, Vatelys, Muro Bot, J.M.Domingo, Numbo3, Comu nacho, YonaBot, Sealight, Jmvgpartner, SieBot, Mushii, Carmin, Dars666, Cyberkender, Gurgut, OboeCrack, Manwë, Greek, BuenaGente, Belb, Mafores, PipepBot, Ivanics, Xqno, Tirithel, XalD, HUB, Antón Francho, Nicop, Farisori, Eduardosalg, Leonpolanco, Pan con queso, Alejandrocaro35, TronaBot, Petruss, Víctor Barbero, BetoCG, PetrohsW, Toolserver, Açipni-Lovrij, Osado, Camilo, UA31, CRISPIS, AVBOT, Elliniká, JAQG, David0811, Yoprideone, LucienBOT, Juanjo.it.ab, MastiBot, Angel GN, MarcoAurelio, Speedplus, Ezarate, Diegusjaimes, Davidgutierrezalvarez, DumZiBoT, Arjuno3, Lampsako, Luckas-bot, SpiritBlack-Wikipedista, M411045, Vic Fede, Dangelin5, Kevinprado, Nixón, MaBy25, ArthurBot, SuperBraulio13, Xqbot, Jkbw, Rubinbot, Dreitmen, Plasmoid, AssassinR15, Annabrinn, NONYTO P8a, FrescoBot, Ricardogpn, Janiyi, Xalox~eswiki, Igna, Botarel, Hprmedina, Guillermo Axel, TobeBot, Halfdrag, RedBot, Alonsosm, Abece, Leugim1972, Elchelemanda, PatruBOT, KamikazeBot, Angelito7, Zpu,portaynach, Tarawa1943, Foundling, Miss Manzana, Axvolution, Edslov, EmausBot, Savh, AVIADOR, Edgarga, ZéroBot, HRoestBot, Allforrous, Sergio Andres Segovia, Africanus, J. A. Gélvez, SAMTODOPODEROSO, Rubpe19, Emiduronte, MadriCR, Fjmejor, Waka Waka, Banck, Movses-bot, Wednom, Antonorsi, MerlIwBot, KLBot2, TeleMania, Firewalldefender, Vagobot, AvocatoBot, Travelour, Ginés90, Jhóselings, Carliitaeliza, Vetranio, LlamaAl, Érico, Elvisor, DanielithoMoya, AGEchacky, Jlurbe, Flashlack, Armonizador, Juanitorreslp, 2rombos, Lfe-2, Leitoxx, Oscar.gasca7, Lautaro 97, Tushu89, Richard Lyon, Sanperni, Jean70000, Addbot, Balles2601, Kamarori, Zamaconas, Omelgarejo, Luiggypozo7, Henrikhwolf, Jarould, Matiia, Egis57, Crystallizedcarbon, Berruguin, Rodsg, Sfr570, Fernando2812l, Axel froylan, Pikamas y Anónimos: 993 • Diagrama Nassi-Shneiderman Fuente: https://es.wikipedia.org/wiki/Diagrama_Nassi-Shneiderman?oldid=85505196 Colaboradores: Magister Mathematicae, Jesuja, Folkvanger, VolkovBot, Urdangaray, DJ Nietzsche, Muro Bot, Anoryat, Ezarate, Arjuno3, Luckas-bot, Ortisa, Xqbot, Jkbw, D'ohBot, MAfotBOT, PatruBOT, EmausBot, ZéroBot, Iwèr, KLBot2, Rotlink, Addbot, Marcelita torres y Anónimos: 14 • Diff Fuente: https://es.wikipedia.org/wiki/Diff?oldid=87086482 Colaboradores: Ascánder, FlaBot, The Photographer, Camima, Jarke, CEM-bot, Penquista, Rastrojo, TXiKiBoT, Mercenario97, Muro Bot, PaintBot, Brayan Habid, Bigsus-bot, BOTarate, Desmond, Botellín, AVBOT, David0811, LucienBOT, Luckas-bot, Xqbot, EmausBot, ZéroBot, Hiperfelix, Kasirbot, MetroBot, Invadibot, Ninrouter, Dexbot, Zerabat, Addbot, Jarould y Anónimos: 6 • Dirección de retorno Fuente: https://es.wikipedia.org/wiki/Direcci%C3%B3n_de_retorno?oldid=65083372 Colaboradores: GermanX, Resped, AchedDamiman, Farisori, DiegoFb y Addbot • Diseño estructurado Fuente: https://es.wikipedia.org/wiki/Dise%C3%B1o_estructurado?oldid=85114290 Colaboradores: GermanX, Jesuja, CEM-bot, Jorgelrm, Developer, Jkarretero, David.rgh, Farisori, AVBOT, Andreasmperu, SuperBraulio13, Jarould y Anónimos: 24
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
383
• Distancia de Damerau-Levenshtein Fuente: https://es.wikipedia.org/wiki/Distancia_de_Damerau-Levenshtein?oldid=86009827 Colaboradores: Sabbut, RobotQuistnix, Pinar~eswiki, Muro de Aguas, Rapid2k1, VolkovBot, Cibi3d, CiaPan, Luckas-bot, Ptbotgourou, DiegoFb, Addbot, Fivestarts y Anónimos: 2 • Distancia de Levenshtein Fuente: https://es.wikipedia.org/wiki/Distancia_de_Levenshtein?oldid=87168183 Colaboradores: Sabbut, Dodo, Chewie, LeonardoRob0t, Orgullobot~eswiki, RobotQuistnix, Yrbot, FlaBot, YurikBot, Gaeddal, KnightRider, Tamorlan, Pinar~eswiki, Davius, RoyFocker, Rei-bot, Dante Alighieri 1975, AlleborgoBot, Luigli, Oncina, DragonBot, Amsantosr, Botito777, DumZiBoT, Luckasbot, ArthurBot, Sharop, Halfdrag, Tomasdev, Sigifredo89, MerlIwBot, Elvisor, Addbot, Juankmx y Anónimos: 44 • DLO Fuente: https://es.wikipedia.org/wiki/DLO?oldid=85277666 Colaboradores: BOTijo, Gusgus, Anna Montull~eswiki, Elvisor y Addbot • Driver Chain Manager Fuente: https://es.wikipedia.org/wiki/Driver_Chain_Manager?oldid=77766026 Colaboradores: BOTSuperzerocool, CEM-bot, Shooke, LucienBOT, Abece y Siwel • Dublin Core Fuente: https://es.wikipedia.org/wiki/Dublin_Core?oldid=85005569 Colaboradores: RGLago, JosebaAbaitua, Ecemaml, Niqueco, Wikier~eswiki, RobotQuistnix, Chobot, Yrbot, FlaBot, BOTijo, Fariel, CEM-bot, Laura Fiorucci, Rosarinagazo, Thijs!bot, Esenabre, Gusgus, Humberto, Rei-bot, Amisadai, Anna Montull~eswiki, Zesar88, SieBot, Francisco Mochis, Wekeland, DragonBot, Alejandrocaro35, Webposible, Luckas-bot, Gallega61, Abece, Jorge c2010, Kasirbot, Senator2029, MetroBot, Legobot, Ramonjeria y Anónimos: 21 • EAthena Fuente: https://es.wikipedia.org/wiki/EAthena?oldid=86400364 Colaboradores: Joseaperez, Taichi, Lord cradet, Rastrojo, Kamen~eswiki, Muro Bot, PaintBot, BOTarate, Manwë, Revealer, Lockalbot, Remember the dot, DumZiBoT, Streiker~eswiki, Diego Plaza, 0scar0nOjeda, MetroBot, Elvisor, Addbot y Anónimos: 10 • Efecto Hover Fuente: https://es.wikipedia.org/wiki/Efecto_Hover?oldid=85911552 Colaboradores: Akhram, Muro Bot, FBaena, Botellín, Fidelbotquegua, DiegoFb, Marsal20, Elvisor y Anónimos: 2 • Emtp Fuente: https://es.wikipedia.org/wiki/Emtp?oldid=65129941 Colaboradores: Akhram, FlaBot, CEM-bot, Ernesto Genis, Muro Bot, Bigsus-bot, DoN vErDuGo, DiegoFb, Addbot y Anónimos: 3 • Enlace dinámico Fuente: https://es.wikipedia.org/wiki/Enlace_din%C3%A1mico?oldid=67606875 Colaboradores: Ecemaml, Digigalos, Genba, GermanX, Lobillo, CEM-bot, Shooke, Muro Bot, PaintBot y Anónimos: 3 • Enlace estático Fuente: https://es.wikipedia.org/wiki/Enlace_est%C3%A1tico?oldid=60295530 Colaboradores: Digigalos, Yrbot, GermanX, Jesuja, CEM-bot, Technopat, Shooke, Muro Bot, PaintBot, Omegakent y Anónimos: 3 • Enlazado Fuente: https://es.wikipedia.org/wiki/Enlazado?oldid=57226529 Colaboradores: Zuirdj, Digigalos, Zeioth, Platonides, Caiserbot, ¡EL WIKIPEDIA ES COMUNISMO!, Yrbot, GermanX, Lobillo, X.Cyclop, Muro Bot, PaintBot, Leonpolanco, AVBOT, PatruBOT y Anónimos: 2 • Entrada chapuza Fuente: https://es.wikipedia.org/wiki/Entrada_chapuza?oldid=65375984 Colaboradores: Kavanagh, Waeswaes, Dalbela, Addbot y Anónimos: 1 • Error de software Fuente: https://es.wikipedia.org/wiki/Error_de_software?oldid=87138345 Colaboradores: 4lex, Neodraco, Moriel, Sauron, Wiki Wikardo~eswiki, Comae, Stoni, Sms, Robotito, Sonett72~eswiki, Carnendil, Edub, Rembiapo pohyiete (bot), OMenda, Orgullobot~eswiki, RobotQuistnix, Adept~eswiki, Superzerocool, Yrbot, Baifito, Vitamine, YurikBot, GermanX, Quiron, Eskimbot, Kuanto, Sking, Linus~eswiki, CEM-bot, CF, Thijs!bot, Bark~eswiki, Escarbot, Hanjin, JAnDbot, Jugones55, Cuate77, Zyder, AchedDamiman, Aibot, Technopat, Matdrodes, ElVaka, DJ Nietzsche, BlackBeast, Gmarinp, Muro Bot, Gerakibot, SieBot, Wilfreddehelm, Bigsus-bot, Xqno, Helenio, Poco a poco, UA31, AVBOT, MastiBot, Joaferna2008, Diegusjaimes, DumZiBoT, Eldelgas, Arjuno3, Luckas-bot, Nallimbot, Markoszarrate, Yuri Grille Orce, Feedehh, Obersachsebot, Xqbot, Jkbw, Rubinbot, Josemiguel93, ChenzwBot, Igna, BenzolBot, Alfre204, TobeBot, RedBot, PatruBOT, Alph Bot, Waeswaes, EmausBot, ZéroBot, JackieBot, ChuispastonBot, Albertojuanse, HarrySanti, VR0, MetroBot, Invadibot, Lfgg2608, LSonico2012, Bibliofilotranstornado, Minsbot, Salvador85, Elvisor, Rotlink, Legobot, Addbot, Roger de Lauria, JacobRodrigues, DarkBlueZV, Das MiMaMi, Pololo gibby, Eschweiler-1964, Jarould, GTX-TTT, GanksLocos y Anónimos: 76 • Estilo de programación Fuente: https://es.wikipedia.org/wiki/Estilo_de_programaci%C3%B3n?oldid=87423753 Colaboradores: Grstain~eswiki, GermanX, CEM-bot, Thijs!bot, Alvaro qc, JAnDbot, TXiKiBoT, Barri, SieBot, Jpereza, AVBOT, Luckas-bot, ArthurBot, Jkbw, EmausBot, ChuispastonBot, WikitanvirBot, Bibliofilotranstornado, Elvisor, Addbot y Anónimos: 14 • Eventos del ratón Fuente: https://es.wikipedia.org/wiki/Eventos_del_rat%C3%B3n?oldid=83714919 Colaboradores: Pino, Pertile, GermanX, Manolo456, No sé qué nick poner, Guialven, Dani26, Filipo, CEM-bot, NickelSpider, Educhip, Satin, Muro de Aguas, Gustronico, PaintBot, Marcecoro, Machucho2007, AVBOT, DiegoFb, Elvisor, Jarould, Aramiza y Anónimos: 7 • Exclusión mutua (informática) Fuente: https://es.wikipedia.org/wiki/Exclusi%C3%B3n_mutua_(inform%C3%A1tica)?oldid= 72980957 Colaboradores: PACO, Pantulis, Ascánder, Robotito, Niqueco, Emijrp, RobotQuistnix, Yrbot, Martincarr, GermanX, KnightRider, Chlewbot, Xibranc, CEM-bot, AugustoIturri, Thijs!bot, Dogor, JAnDbot, Pólux, VolkovBot, Muro Bot, SieBot, Mcapdevila, Almabot, Rubinbot, EmausBot, ChuispastonBot, WikitanvirBot, BendelacBOT, Addbot y Anónimos: 9 • Expresión regular Fuente: https://es.wikipedia.org/wiki/Expresi%C3%B3n_regular?oldid=87549861 Colaboradores: Moriel, JorgeGG, Pilaf, SpeedyGonzalez, ManuelGR, Diegojc, Bigsus, Dodo, Crescent Moon, Triku, Ascánder, Sms, Tano4595, SantiagoGala, Periku, Toto~eswiki, Digigalos, Boticario, Hari Seldon, Silvestre, Korg, Viko~eswiki, Murven, RobotQuistnix, Caiserbot, Yrbot, GermanX, M4r10c354r, George McFinnigan, Maldoror, Er Komandante, Chlewbot, UberKaeL, CEM-bot, 333, Rbrena, Damifb, Laura Fiorucci, Alexav8, Exos, Lcmarzulli, Resped, Cfvergara, TXiKi, JoaquinFerrero, Botones, JAnDbot, Muro de Aguas, Erwin, TXiKiBoT, Luis junco, ColdWind, Humberto, Luisgulo, Rlizarralde, Vector Mike Bravo Sierra, NaSz, Fixertool, Nioger, Mcanto, Feandir, Technopat, Alvlin, Matdrodes, Muro Bot, SieBot, Loveless, BOTarate, Macarse, Cristhiangr, Arafael, MetsBot~eswiki, Borja Sánchez, Eduardosalg, Leonpolanco, Alecs.bot, Hernaldo, SilvonenBot, AVBOT, Antolingarcia, Dermot, LucienBOT, Vituzzu, Diegusjaimes, CarsracBot, Andreasmperu, Luckas-bot, QuBote, Nixón, ArthurBot, Eññe, 0xff~eswiki, Xqbot, Igna, Botarel, Joaquin medina, Jomabeal, Foundling, GrouchoBot, Savh, ChuispastonBot, Albertojuanse, Waka Waka, Hiperfelix, KLBot2, Angelgonzg, John plaut, Óscar Becerril, Bibliofilotranstornado, Elvisor, Legobot, Francisco2289, Addbot, Paconaranjo, Jarould, Matiia, Egis57, Enxaneta y Anónimos: 147 • Flag Fuente: https://es.wikipedia.org/wiki/Flag?oldid=72869566 Colaboradores: Sabbut, BOT-Superzerocool, GermanX, VolkovBot, Aleposta, Ptbotgourou, Rubinbot, Puck2099, ZéroBot, Grillitus, KLBot2, Addbot, JacobRodrigues, Giliofelix y Anónimos: 3
384
CAPÍTULO 205. ZENPHP
• Front-end y back-end Fuente: https://es.wikipedia.org/wiki/Front-end_y_back-end?oldid=87272243 Colaboradores: Sabbut, Robbot, Dodo, Sms, Julgon, Elwikipedista, Armonth, Periku, MatiasBellone, Morgul~eswiki, Soulreaper, Edub, Emijrp, AlexGalisteo, RobotQuistnix, Caiserbot, Sotomayor, Yrbot, Baifito, FlaBot, BOTijo, YurikBot, LoquBot, C-3POrao, Götz, CEM-bot, Damifb, Thijs!bot, VARGUX, Crates, ColdWind, Carlesius~eswiki, VolkovBot, Technopat, BlackBeast, Shooke, SieBot, Pablo323, LordT, Yorulito 89, Hoenheim, Bot0811, Hprmedina, Born2bgratis, PatruBOT, Waeswaes, Grillitus, Ser malvado, MerlIwBot, Invadibot, MadonnaFan, Legobot, Deimagjas, Addbot, Lagoset, BenjaBot y Anónimos: 35 • Fuga de memoria Fuente: https://es.wikipedia.org/wiki/Fuga_de_memoria?oldid=87116558 Colaboradores: Pino, Moriel, Sauron, ManuelGR, Triku, Niqueco, Rembiapo pohyiete (bot), Further (bot), RobotQuistnix, Chobot, Baifito, FlaBot, YurikBot, GermanX, CEM-bot, Tute, Ignacio Icke, Thijs!bot, Botones, JAnDbot, ColdWind, Galaxy4, AlnoktaBOT, Gmarinp, Muro Bot, YonaBot, BotMultichill, Alexbot, Luckas-bot, Amirobot, Wikante, Hprmedina, Ripchip Bot, Waeswaes, EmausBot, Grillitus, WikitanvirBot, MetroBot, Elvisor, Legobot y Anónimos: 7 • Generación de código Fuente: https://es.wikipedia.org/wiki/Generaci%C3%B3n_de_c%C3%B3digo?oldid=64767313 Colaboradores: Edub, Superzerocool, GermanX, Equi, Lobillo, Gabriel.arias, Eduardo Lima, CEM-bot, Joseanquiles, VolkovBot, PaintBot, Loveless, Leonpolanco, Luckas-bot, DiegoFb, Xqbot, GrouchoBot, Legobot y Anónimos: 4 • Generador de números aleatorios Fuente: https://es.wikipedia.org/wiki/Generador_de_n%C3%BAmeros_aleatorios?oldid=84075873 Colaboradores: Pino, Joseaperez, Th3j0ker, Julian Colina, Anv, Pati, Airunp, Orgullobot~eswiki, LuchoX, GermanX, JRGL, Emilio.carrizosa, Siabef, Qwertyytrewqqwerty, CEM-bot, Thanos, Alexav8, Pevica, FrancoGG, TXiKiBoT, Aibot, Muro Bot, Pacomegia, Pascow, Kalverseihn, LordT, Juan Mayordomo, Raulshc, MystBot, Billinghurst, ArthurBot, Xqbot, Jkbw, Hprmedina, Ganímedes, EmausBot, ZéroBot, Esaintpierre, ChuispastonBot, Ricardo IV, Bibliofilotranstornado, JYBot, Legobot, Wilson Pinto Romero, Ncomputersorg y Anónimos: 20 • Gledplay Fuente: https://es.wikipedia.org/wiki/Gledplay?oldid=86942139 Colaboradores: Superzerocool, BOT-Superzerocool, Gaeddal, JorSol, CEM-bot, Sergio.fierens~eswiki, Mahadeva, Matias.saguir, Pólux, Zyder, Botellín, LucienBOT, KLBot2, Elvisor y Anónimos: 5 • GPGPU Fuente: https://es.wikipedia.org/wiki/GPGPU?oldid=70422721 Colaboradores: Riviera, Rondador, Yrithinnd, RobotQuistnix, Yrbot, GermanX, CEM-bot, Thijs!bot, CommonsDelinker, TXiKiBoT, Filiprino, VolkovBot, PolarBot, Alexaltea, DragonBot, Alexbot, LucienBOT, Cibi3d, Luckas-bot, MKDrDre, Xqbot, SassoBot, Mctpyt, ZéroBot, Alecm88, KLBot2, Elvisor, Legobot, ScotXW y Anónimos: 10 • Hackathon Fuente: https://es.wikipedia.org/wiki/Hackathon?oldid=86943923 Colaboradores: Luisrull, Itnas19, Graciela Caldeiro, El Pantera, Luckas-bot, MystBot, MartinDM, Xqbot, EmausBot, ZéroBot, HRoestBot, Sergio Andres Segovia, Grillitus, WikitanvirBot, KLBot2, ShakMR, Cleibenzon y Anónimos: 10 • Hacker Fuente: https://es.wikipedia.org/wiki/Hacker?oldid=87426282 Colaboradores: Sabbut, Lourdes Cardenal, Gmagno, SimónK, Petronas, Patricio.lorente, Superzerocool, Vitamine, Olea, Baronti, The Photographer, Er Komandante, Fercufer, CEM-bot, Laura Fiorucci, IvanStepaniuk, Montgomery, Resped, PabloCastellano, RoyFocker, JoaquinFerrero, Alakasam, Isha, JAnDbot, Mansoncc, Tucto, Cristianuz12, L0biz0n, Gustronico, Humberto, Nioger, Biasoli, Technopat, BlackBeast, Muro Bot, El Pantera, Loveless, Bigsus-bot, Marcelo, Pascow, McOil, Tirithel, Javierito92, Leonpolanco, Pan con queso, PetrohsW, Rαge, Frei sein, Osado, UA31, AVBOT, DayL6, TheDarkFear, Diegusjaimes, Davidgutierrezalvarez, Malacitano, Arjuno3, Gacpro, Bloomy, Nixón, Jkbw, Rubinbot, Cybermaniac, FrescoBot, Surfaz, Igna, BenzolBot, AstaBOTh15, RubiksMaster110, Panderine!, Jakeukalane, Halfdrag, Omerta-ve, AnselmiJuan, Lustar, PatruBOT, Ganímedes, ArwinJ, Hack txus, Isi viki, Tarawa1943, Nachosan, Foundling, Edslov, EmausBot, Savh, AVIADOR, ChessBOT, Internetsinacoso, Mescaicedo, Grillitus, FL0per, Waka Waka, Warairarepano&Guaicaipuro, EdgarFabiano, Metrónomo, MerlIwBot, KLBot2, TeleMania, Luisllamas, UAwiki, Damianiencowiki, Frank sin Otra, Allan Aguilar, Nernix1, LlamaAl, Elvisor, Santga, ElGatoSaez, Syum90, Leitoxx, Alberto Elvira, NeftaliYagua, Chmarkine, Balles2601, Romuant, Paolaricaurte, Saectar, 19Tarrestnom65, Henrikhwolf, Laberinto16, Juancastellar1, Gonzalo.villarreal, Majlis99, Shernandezrg, ComaHermosa, PabloYglesias, Joeldavid rodriguez hernandez, Jarould, Otup, FedeNab PB, SAHIBORFIRE001, Lioemiliorodriguez, MoonLeech, Hacker1234567890123, Randomediterhahatroll, Hola ke azse, Rulax Nada, Andrea.merelo, Condoruser, Daniel Justiniani, Cristiantamara1999, Vladernn, Nada Nada01, YerayJackson, Juliana colorado, Hackersjorge, Alquimista Kvothe, Ana Lucia-es genial y Anónimos: 219 • Heisenbug Fuente: https://es.wikipedia.org/wiki/Heisenbug?oldid=83785803 Colaboradores: JKD, Yeza, Invadibot, BenjaBot y Cecetaca • Hoja de estilo Fuente: https://es.wikipedia.org/wiki/Hoja_de_estilo?oldid=86504408 Colaboradores: Pilaf, Daniel G., JosebaAbaitua, Kokoo, Tomatejc, Alexquendi, Gizmo II, Especiales, Locovich, Gaius iulius caesar, Osado, Linfocito B, Jkbw, PatruBOT, Semensoy, Diamondland, Johnbot, Elvisor, Addbot, Jarould y Anónimos: 15 • Hola mundo Fuente: https://es.wikipedia.org/wiki/Hola_mundo?oldid=87221037 Colaboradores: Sabbut, Pilaf, Angus, Zwobot, Comae, Janus~eswiki, Dodo, Sms, Rsg, Opinador, Robotito, Jag2k4, Xenoforme, Jecanre, Hildergarn, Porao, Ivan.Romero, Steve-o, Robotico, Adrianbs, Kordas, Niqueco, FAR, Lmsilva, Digigalos, Quemasda~eswiki, Soulreaper, RobotJcb, JMPerez, Edub, Yrithinnd, Emijrp, Rembiapo pohyiete (bot), Johnbojaen, Ppfk~eswiki, Orgullobot~eswiki, RobotQuistnix, Platonides, Unf, Superzerocool, BillGatos, Chobot, Warmize, Yrbot, Amadís, BOT-Superzerocool, Oscar ., Davidsevilla, Vitamine, Laban~eswiki, Gaeddal, Museo8bits, Icvav, Martingala, Zelkova~eswiki, Unaiaia, KnightRider, Acalpixca, Banfield, Kenshin 85, Aenima~eswiki, Götz, Skirmish~eswiki, Er Komandante, Leonardocaballero, Touareg, Spc, Tomatejc, EOZyo, Siabef, Bernethe, BOTpolicia, CEM-bot, Guzman622, Voragine, Efegé, Xexito, Davius, Antur, Yuanga, Programador, Thijs!bot, Nabrozidhs, Alvaro qc, RoyFocker, JoaquinFerrero, Locovich, Ninovolador, Egaida, Gusgus, JAnDbot, Mansoncc, Muro de Aguas, Iulius1973, TXiKiBoT, Humberto, Infjms00, Sirpuppet, Pólux, Snakefang, Developer, Swicher, Wutores, Garaizar, VolkovBot, Technopat, Zurtitto, Mstreet linux, Matdrodes, Elabra sanchez, Synthebot, ElVaka, BlackBeast, Lucien leGrey, Will.ruiz, Muro Bot, Srbanana, BotMultichill, Zydeco, Gmol, Gerakibot, SieBot, Tucapl, Nachet70, Cousteau, Jjcc, Manwë, Dmontero7, Joelperez, Tomyleeswf, PipepBot, Tirithel, Javierito92, Beby.akselrad, Socram8888, Minterior, Nicop, PixelBot, Leonpolanco, Sunopen, TuEresTu, Gxlalesca, LordT, Alexbot, Manco Capac, Darkicebot, Miguelusque, Osado, Jofegibo, Mr freeze360, SilvonenBot, Camilo, AVBOT, Louperibot, NicolasAlejandro, Carlitos.dll, Diegusjaimes, Fguillen, Amirobot, Nallimbot, Diádoco, Ptbotgourou, Jotterbot, LyingB, Cplusplus~eswiki, Byrito, Barteik, Yonidebot, Edutecno, Hytac, Ezarate73, DSisyphBot, Clablues, SuperBraulio13, Xqbot, Jkbw, Es carva, Dreitmen, Helloworldextremadura, Ferbrunnen, Adryitan, Botarel, TiriBOT, Hprmedina, Halfdrag, Edgardo C, PatruBOT, KamikazeBot, TheOrlSan, EmausBot, Sergio Andres Segovia, Bazookao, ChuispastonBot, Jereees, Antonorsi, MerlIwBot, KLBot2, AvocatoBot, MetroBot, Rafael.Todresak, Fontedoso, Lautaro 97, Coins, Jarould, Pedrov857 y Anónimos: 395 • Homebrew Fuente: https://es.wikipedia.org/wiki/Homebrew?oldid=87338482 Colaboradores: Aloriel, FlaBot, Eloy, Elrond 3, CEM-bot, Laura Fiorucci, Twisen, Mapep, Bernard, JAnDbot, Rtalaman, TXiKiBoT, Wikiangeld, Biasoli, Technopat, AlleborgoBot, SieBot, PaintBot, Ensada, Bigsus-bot, El bot de la dieta, Javierito92, Eduardosalg, Sidcc, Alexbot, AVBOT, SpBot, Vic Fede, DSisyphBot, Xqbot, Irbian,
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
385
Doble, BOTirithel, Kizar, Ravmn, PatruBOT, Sergi70, Nanopulga, Gerda Arendt, ASTUR2000, EmausBot, Yayolas, KLBot2, Gusama Romero, Elvisor, Daltreck, BenjaBot y Anónimos: 62 • ICONIX Fuente: https://es.wikipedia.org/wiki/ICONIX?oldid=86024206 Colaboradores: BOT-Superzerocool, CEM-bot, CommonsDelinker, Technopat, Rwheimle, Ortisa, Marsal20, PatruBOT, Angelito7, KLBot2, Invadibot, Arvelo592, Jarould y Anónimos: 12 • Anexo:Implementaciones de Smalltalk Fuente: https://es.wikipedia.org/wiki/Anexo%3AImplementaciones_de_Smalltalk?oldid= 70775907 Colaboradores: Sabbut, Tano4595, Dusan, Stickel, Shooke, Muro Bot, Carmin, MiguelAngelCaballero, Alelapenya, Lividiniski, Elvisor y Anónimos: 1 • Anexo:Implementaciones para algoritmo de rut Fuente: https://es.wikipedia.org/wiki/Anexo%3AImplementaciones_para_algoritmo_ de_rut?oldid=87166683 Colaboradores: Josemoya, Isha, Terinchu y Anónimos: 1 • Inanición (informática) Fuente: https://es.wikipedia.org/wiki/Inanici%C3%B3n_(inform%C3%A1tica)?oldid=79794169 Colaboradores: Sabbut, GermanX, Thijs!bot, Mcapdevila, Angelito7, Ripchip Bot, EmausBot, KLBot2, Nejnadusho, Angeldefuego22 y Anónimos: 2 • Indirección Fuente: https://es.wikipedia.org/wiki/Indirecci%C3%B3n?oldid=77015655 Colaboradores: DMG, Glia, Muro de Aguas, Biasoli, Elabra sanchez, Xqbot, KLBot2, Lizbeth Melissa Appleton Tavarez y Sociologiaipa • Infraestructura de lenguaje común Fuente: https://es.wikipedia.org/wiki/Infraestructura_de_lenguaje_com%C3%BAn?oldid= 70047167 Colaboradores: Pino, Wikier~eswiki, Yrbot, BOTijo, Dangertn, Biasoli, Muro Bot, Bcnbits.com, XalD, Leonpolanco, Luckas-bot, SuperBraulio13, Canyq, Waeswaes, EmausBot, Javiermarinros, MerlIwBot, KLBot2, Dexbot y Anónimos: 6 • Ingeniería de software Fuente: https://es.wikipedia.org/wiki/Ingenier%C3%ADa_de_software?oldid=87347378 Colaboradores: Zeno Gantner, 4lex, Caligari~eswiki, Soniautn, Sabbut, Moriel, Sauron, JorgeGG, Lourdes Cardenal, ManuelGR, Head, Lsanabria, Rosarino, Dodo, Jonik, Jynus, Ascánder, Sms, Rsg, Cookie, Tano4595, Robotito, JavierCantero, Amana, Ograma, Rodrigouf, Cinabrium, Porao, Loco085, Jabernal, Renabot, Richy, Robotkarel, Chlewey, Soulreaper, Petronas, Airunp, JMPerez, Edub, Taichi, Emijrp, Rembiapo pohyiete (bot), Magister Mathematicae, RobotQuistnix, Platonides, Chobot, Afpineda, Yrbot, Baifito, BOT-Superzerocool, Adrruiz, Mortadelo2005, Martingala, GermanX, The Photographer, Tigerfenix, Ppja, Maldoror, Covi, BOTpolicia, CEM-bot, Jorgelrm, Laura Fiorucci, Eneaslabra, Ignacio Icke, Osepu, Dou1985, Davius, Govelamo, Antur, Juan.palacio, Julian Mendez, Gafotas, Genaro Rafael, Fsd141, Jonpagecr, Diosa, Bot que revierte, Eidansoft, Ninovolador, Botones, Isha, Arcibel, Migp~eswiki, JAnDbot, Jugones55, Antipatico, Xavigivax, Gsrdzl, Fugarte, Humberto, Netito777, Fixertool, Nioger, Pólux, Developer, Manuel Trujillo Berges, Biasoli, Bucephala, VolkovBot, Drever, Technopat, Jose figueredo, Galandil, Queninosta, Raystorm, MasterNoX, Belgrano, Matdrodes, Autonomia, Gmarinp, Muro Bot, Jmvgpartner, SieBot, Ctrl Z, Carmin, Hompis, Bigsus-bot, Alben9586, Switcher6746, Navarroaxel, Greek, BuenaGente, Mafores, Fadesga, Arnombela, Tirithel, Javierito92, Marcecoro, Antón Francho, Nicop, Brayan Jaimes, Eduardosalg, Qwertymith, Graimito, Leonpolanco, Pan con queso, Alejandrocaro35, LordT, Furti, Poco a poco, Rαge, Camilo, UA31, SergioN, Climens, Andres romeroc, AVBOT, Flakinho, Diegusjaimes, Davidgutierrezalvarez, CarsracBot, Arjuno3, Saloca, Andreasmperu, Luckas-bot, Jaromero, Nallimbot, Sergiportero, Vic Fede, Dangelin5, ArthurBot, Usuwiki, Txangu22, Jefrcast, Angelux3000, SuperBraulio13, Xqbot, Jkbw, FrescoBot, Josemariasaldana, Igna, Botarel, Kraixx, Ochonueve98, Yabama, BOTirithel, Maria.Jose.Garcia.UEM, Brian26, Luysys, RedBot, Fidelleandro, Abece, Leugim1972, PatruBOT, Dinamik-bot, Jpussacq, Axvolution, EmausBot, Burny~eswiki, Savh, ZéroBot, Joinsolutions, Hdavila1, Grillitus, Cris Dav CDVS, Kasirbot, MerlIwBot, JABO, KLBot2, Ayaita, Thehelpfulbot, Iranvaur, AvocatoBot, Sebrev, MetroBot, Diegosangz, TQLEOFULL, Raes123, Aine Takarai, Elvisor, Felener, Makecat-bot, Ralgisbot, Withsell, Legobot, Ssamuel, Addbot, Balles2601, MarielCB, Guilberth, Ricardo concepcion, DianaJMZr18, Isaacjuc, Bryanro, Franklin.ayarza, Starmird, FlareXIII, Abdiel Williams, LisleidysDominguez, Joseline Jaramillo, Neogeo02, RicardoFong, Albert-507, Joxeph18, Javrro, Alecjz, Jarould, Lomejordejr, Miranda23~eswiki, BenjaBot, José Tomás reyes rodriguez, FidiasX y Anónimos: 403 • Instancia (informática) Fuente: https://es.wikipedia.org/wiki/Instancia_(inform%C3%A1tica)?oldid=86236359 Colaboradores: Carlos Castañeda Girón, Ascánder, BOT-Superzerocool, Varano, CEM-bot, Laura Fiorucci, Santhy, Nightwish, Isha, Netito777, Technopat, Carmin, Javierito92, Poco a poco, AVBOT, Msanguino, David0811, Diegusjaimes, Bethan 182, Boto a Boto, SuperBraulio13, Jkbw, FrescoBot, Botarel, Grillitus, Balles2601, Jarould, Unmanitito y Anónimos: 28 • Instrucción (informática) Fuente: https://es.wikipedia.org/wiki/Instrucci%C3%B3n_(inform%C3%A1tica)?oldid=84858207 Colaboradores: Vanbasten 23, Dodo, Airunp, RobotQuistnix, Joanfusan, Yrbot, Amadís, BOT-Superzerocool, GermanX, Jesuja, Maldoror, Cheveri, Folkvanger, Feiri25, BOTpolicia, CEM-bot, Rastrojo, Fsd141, Tortillovsky, Ángel Luis Alfaro, Dogor, JAnDbot, Netito777, Bedwyr, Biasoli, Cinevoro, Rmarcel, Muro Bot, SieBot, PaintBot, Loveless, LordT, Al Lemos, Juan Mayordomo, Diegusjaimes, DumZiBoT, Arjuno3, Kavor, Txangu22, Ortisa, Jkbw, Botarel, Pablotol, AnselmiJuan, Grillitus, Elías, MerlIwBot, JABO, Matiia y Anónimos: 34 • Interfaz binaria de aplicaciones Fuente: https://es.wikipedia.org/wiki/Interfaz_binaria_de_aplicaciones?oldid=83104096 Colaboradores: JKD, Lobillo, Hprmedina, Invadibot y Korislife • Interfaz fluida Fuente: https://es.wikipedia.org/wiki/Interfaz_fluida?oldid=64499560 Colaboradores: GermanX, TXiKiBoT, Shooke, LucienBOT, Luckas-bot, ZéroBot, KLBot2 y Anónimos: 1 • Invariante (informática) Fuente: https://es.wikipedia.org/wiki/Invariante_(inform%C3%A1tica)?oldid=64502259 Colaboradores: Poco a poco, Waeswaes, EmausBot y KLBot2 • Jframe Fuente: https://es.wikipedia.org/wiki/Jframe?oldid=77831062 Colaboradores: Ivordro UV • Usuario discusión:Juliasocorro Fuente: https://es.wikipedia.org/wiki/Usuario_discusi%C3%B3n%3AJuliasocorro?oldid=80551923 Colaboradores: Frank sin Otra • Kanban (desarrollo) Fuente: https://es.wikipedia.org/wiki/Kanban_(desarrollo)?oldid=87051531 Colaboradores: Lourdes Cardenal, Invadibot, Elvisor, Marco.fiunno, Jarould, Bossarro, Galo Jerez y Anónimos: 9 • Kit de desarrollo de software Fuente: https://es.wikipedia.org/wiki/Kit_de_desarrollo_de_software?oldid=87227842 Colaboradores: Aleator, Laura Fiorucci, Bryant1410, TXiKiBoT, Humberto, Biasoli, Shooke, Marcecoro, Quijav, LucienBOT, MastiBot, Ambil, Diegusjaimes, MystBot, Gua-naiko-che, SuperBraulio13, Xqbot, Rubinbot, RedBot, MarioGL, PatruBOT, Cifz, EmausBot, ZéroBot, ChuispastonBot, Cybelmar, KLBot2, Minsbot, Elvisor, Javier casas sevilla, BOTito y Anónimos: 18 • Kommander Fuente: https://es.wikipedia.org/wiki/Kommander?oldid=64677101 Colaboradores: CEM-bot, Phirosiberia, Moises.coronado, Loveless, StarBOT, KLBot2 y Anónimos: 3
386
CAPÍTULO 205. ZENPHP
• Last Error (informática) Fuente: https://es.wikipedia.org/wiki/Last_Error_(inform%C3%A1tica)?oldid=71687590 Colaboradores: CEM-bot, Muro de Aguas, Dangelin5, Yuri Grille Orce, Mister Roboto, Waeswaes, Grillitus, Fle3tw00d, Mastervick18 y Anónimos: 2 • Línea de código fuente Fuente: https://es.wikipedia.org/wiki/L%C3%ADnea_de_c%C3%B3digo_fuente?oldid=87548009 Colaboradores: Pieter, Mnts, Boticario, Yrithinnd, Rembiapo pohyiete (bot), Johnbojaen, Magnus Colossus, Yrbot, YurikBot, GermanX, Lucascr, Götz, CEM-bot, Jorgelrm, Thijs!bot, Isha, Muro de Aguas, ColdWind, Biasoli, VolkovBot, Elabra sanchez, BlackBeast, Shooke, Muro Bot, PaintBot, Drinibot, Ignacio javier igjav, Bigsus-bot, Marcecoro, Poco a poco, Juan Mayordomo, BotSottile, MastiBot, Luckas-bot, Boto a Boto, DiegoFb, Vivaelcelta, Mr. Geek, Locobot, Jkbw, Bodigami, GrouchoBot, Adri128, Grillitus, MerlIwBot, Invadibot, Acratta, Elvisor, Rotlink, Legobot, BenjaBot y Anónimos: 18 • Macintosh Toolbox Fuente: https://es.wikipedia.org/wiki/Macintosh_Toolbox?oldid=75150746 Colaboradores: Banfield, Jago84, ZéroBot, Grillitus y KLBot2 • Macro Fuente: https://es.wikipedia.org/wiki/Macro?oldid=86728967 Colaboradores: Aloriel, Rosarino, Dodo, Richy, Pati, Petronas, Airunp, Taichi, Rembiapo pohyiete (bot), NekroByte, Magister Mathematicae, RobotQuistnix, Javialacarga, Pla, YurikBot, GermanX, Gaijin, SidV, C-3POrao, Lasneyx, BOTpolicia, CEM-bot, Alexav8, Retama, FrancoGG, Thijs!bot, Srengel, Jorgebarrios, Will vm, Isha, Kved, Mansoncc, Muro de Aguas, TXiKiBoT, Aalvarez12, Humberto, Netito777, Biasoli, AlnoktaBOT, Technopat, Queninosta, Matdrodes, DJ Nietzsche, BlackBeast, 3coma14, SieBot, Mushii, Hispalis, Loveless, Carmin, BOTarate, Manwë, Ugly, BuenaGente, Fadesga, Pla y Grande Covián, Jarisleif, Nicop, Eduardosalg, Leonpolanco, Drlogo, Açipni-Lovrij, UA31, AVBOT, David0811, NicolasAlejandro, Diegusjaimes, Arjuno3, Andreasmperu, Luckas-bot, Macrorosario, Billinghurst, Wikiwikifan, Nixón, Billyrobshaw, SuperBraulio13, Manuelt15, Xqbot, Jkbw, Ricardogpn, Igna, BOTirithel, Hprmedina, Xlsexcel, Oxilium, Ferrnandosantosf, Lungo, PatruBOT, AldanaN, Dinamik-bot, Foundling, Edslov, EmausBot, Savh, AVIADOR, ZéroBot, HRoestBot, Grillitus, JackieBot, FL0per, Waka Waka, WikitanvirBot, Antonorsi, Maquedasahag, Helmy oved, FMQ, Addbot, DJ WARMIN, Marcrodos, Jarould, Fenadez24 y Anónimos: 204 • Malla de triángulos 3D Fuente: https://es.wikipedia.org/wiki/Malla_de_tri%C3%A1ngulos_3D?oldid=85348681 Colaboradores: Sabbut, Banfield, Tomatejc, Folkvanger, CommonsDelinker, BlackBeast, Mafores, Ravave, Martabosch, KLBot2, Elvisor y Balles2601 • Mapeo objeto-relacional Fuente: https://es.wikipedia.org/wiki/Mapeo_objeto-relacional?oldid=85517312 Colaboradores: Dapasa, Niqueco, Petronas, Magister Mathematicae, BOT-Superzerocool, Cad, CEM-bot, Pete~eswiki, Thijs!bot, RoyFocker, Zufs, Hidoy kukyo, Rei-bot, Manuel Trujillo Berges, Muro Bot, Globalpegasus, Loveless, Abel.orian, SPZ, Broda Noel, Robertmacias, Estirabot, Adelpine, DumZiBoT, Trimax, Mrbaltus, DiegoFb, ArthurBot, Denniscm20, Xqbot, Jkbw, Ppazos, Davidmarco, Silvioq, HoLiC, TiriBOT, LoliBot, Rro4785, Diego.sarmentero, GrouchoBot, ElTeq, WikitanvirBot, KLBot2, Thehelpfulbot, AvocatoBot, HiW-Bot, Makecat-bot y Anónimos: 38 • Máquina de estados Fuente: https://es.wikipedia.org/wiki/M%C3%A1quina_de_estados?oldid=83627948 Colaboradores: Mikelo, Orgullomoore, Airunp, BOT-Superzerocool, GermanX, Beto29, JRGL, Andrés Djordjalian, Isarmien, Muro Bot, PaintBot, Cegik, Jagp0004, Balles2601, Guapote69rafa y Anónimos: 10 • Máquina desnuda Fuente: https://es.wikipedia.org/wiki/M%C3%A1quina_desnuda?oldid=26913093 Colaboradores: Tano4595, Sebastiancruz, Tortillovsky, Délawen, Shooke, Muro Bot, PaintBot y Anónimos: 1 • MCML Fuente: https://es.wikipedia.org/wiki/MCML?oldid=65805016 Colaboradores: Murven, FlaBot, Jjvaca, Muro Bot, PaintBot, LucienBOT, DiegoFb, EmausBot y Anónimos: 2 • Metaprogramación Fuente: https://es.wikipedia.org/wiki/Metaprogramaci%C3%B3n?oldid=78306463 Colaboradores: Triku, Dianai, YurikBot, Jgaray, KnightRider, Gothmog, Eskimbot, CEM-bot, TXiKiBoT, VolkovBot, Shooke, Muro Bot, SieBot, LordT, Alexbot, Luckas-bot, Codename, EmausBot, Invadibot, Legobot y Anónimos: 7 • Microformatos Dublin Core Fuente: https://es.wikipedia.org/wiki/Microformatos_Dublin_Core?oldid=22604847 Colaboradores: Muro Bot, Mutari, HUB y Webposible • Modelo de prototipos Fuente: https://es.wikipedia.org/wiki/Modelo_de_prototipos?oldid=84552079 Colaboradores: Taichi, Rakela, BOTijo, Filipo, Alfredobi, Rosarinagazo, Hanjin, Netito777, Scap2000, Pólux, Alexhd, Jose figueredo, Matdrodes, Racso, Manwë, Javierito92, David.rgh, Caucas, Diegusjaimes, Jkbw, PatruBOT, Foundling, Alexandermark, Adribeex, BenjaBot y Anónimos: 58 • Modificador Fuente: https://es.wikipedia.org/wiki/Modificador?oldid=84562935 Colaboradores: CEM-bot, Ismaelivan, Gusgus, Jatrobat, Technopat, Galandil, Queninosta, Leonpolanco, AVBOT, Angel GN, DiegoFb, SuperBraulio13, Jkbw, Pitufo.Budista, Wikielwikingo, Rubpe19, Elvisor, Osiris, Jarould y Anónimos: 11 • Modularidad Fuente: https://es.wikipedia.org/wiki/Modularidad?oldid=70539491 Colaboradores: Jesuja, Davius, Lauranrg, Millars, Developer, VolkovBot, Matdrodes, SieBot, BOTarate, Poco a poco, SergioN, AVBOT, J.delanoy, Luckas-bot, FariBOT, SuperBraulio13, Jkbw, Jorge c2010, Albertojuanse, WikitanvirBot, KLBot2 y Anónimos: 12 • Módulo (informática) Fuente: https://es.wikipedia.org/wiki/M%C3%B3dulo_(inform%C3%A1tica)?oldid=86721547 Colaboradores: Jesuja, Mpeinadopa, Cinevoro, Elabra sanchez, Muro Bot, Poco a poco, SergioN, AVBOT, Arjuno3, Jkbw, Googolplanck, Angelito7, Jarould y Anónimos: 12 • Monitor (concurrencia) Fuente: https://es.wikipedia.org/wiki/Monitor_(concurrencia)?oldid=85923415 Colaboradores: Dianai, Chobot, Yrbot, Martincarr, BOTijo, YurikBot, GermanX, Tomatejc, Jorgechp, BOTpolicia, CEM-bot, Thijs!bot, Bryant1410, Dogor, JAnDbot, CommonsDelinker, Netito777, BOTarate, Danilindo, AVBOT, DumZiBoT, Luckas-bot, Nixón, SuperBraulio13, Xqbot, NewBlood7, Diegodm, BOTirithel, Hprmedina, MaschioAlfonso, Daniville7, Grillitus, Dr Doofenshmirtz, MerlIwBot, JABO, Sebrev, Invadibot, Helmy oved, Legobot, Jarould y Anónimos: 40 • Anexo:Motores de persistencia Fuente: https://es.wikipedia.org/wiki/Anexo%3AMotores_de_persistencia?oldid=81100261 Colaboradores: JMPerez, Filipo, Cad, CEM-bot, Mercenario97, 3coma14, Hu12, Luckas-bot, DiegoFb, Mangel2050, AldanaN, Khiari, Elvisor, Addbot y Anónimos: 4 • Método de depuración del patito de goma Fuente: https://es.wikipedia.org/wiki/M%C3%A9todo_de_depuraci%C3%B3n_del_patito_ de_goma?oldid=86909428 Colaboradores: Sabbut, Poramo, Marcelo, Sergio Andres Segovia, Grillitus, Invadibot, Tuareg50 y Anónimos: 1 • Net Yaroze Fuente: https://es.wikipedia.org/wiki/Net_Yaroze?oldid=87149619 Colaboradores: Sabbut, CEM-bot, Diablo Cris, CommonsDelinker, FrescoBot, KLBot2, Invadibot, Elvisor, Helmy oved, Excalibra, Victoria216 y Anónimos: 4
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
387
• Nodo (informática) Fuente: https://es.wikipedia.org/wiki/Nodo_(inform%C3%A1tica)?oldid=86760466 Colaboradores: Rosarino, Magister Mathematicae, Echani, Jesuja, Götz, Tomatejc, Nihilo, CEM-bot, Jorgelrm, Antur, Ggenellina, Alvaro qc, Technopat, Lucien leGrey, Farisori, Alejandrocaro35, Gomariles, AVBOT, Diegusjaimes, Arjuno3, DiegoFb, SuperBraulio13, Jkbw, Botarel, PatruBOT, EmausBot, Waka Waka, Hiperfelix, Bibliofilotranstornado, Helmy oved, Jean70000, Addbot, The$oul, Jarould, Matiia y Anónimos: 44 • Notación Reddick Fuente: https://es.wikipedia.org/wiki/Notaci%C3%B3n_Reddick?oldid=21138085 Colaboradores: Vanbasten 23, Airunp, Vitamine, Jesuja, Folkvanger, CEM-bot, StarBOT, LordT y Anónimos: 3 • Notación húngara Fuente: https://es.wikipedia.org/wiki/Notaci%C3%B3n_h%C3%BAngara?oldid=75873474 Colaboradores: Pjimenez, Moriel, Pablo.cl, Sauron, SpeedyGonzalez, Angus, Elwikipedista, Airunp, Rembiapo pohyiete (bot), RobotQuistnix, Mortadelo, Yrbot, BOTijo, YurikBot, Beto29, CEM-bot, Thijs!bot, Knocte~eswiki, Snakefang, Aibot, Loveless, BOTarate, Locos epraix, Reyiyo, Luckasbot, MerlIwBot, Ni.cero, Elvisor, Ralgisbot, Addbot y Anónimos: 21 • Null Fuente: https://es.wikipedia.org/wiki/Null?oldid=85452031 Colaboradores: Moriel, Pilaf, Sms, B1mbo, Tano4595, Renabot, Orgullobot~eswiki, RobotQuistnix, Superzerocool, Chobot, Caiserbot, Yrbot, FlaBot, YurikBot, Qwertyytrewqqwerty, CEM-bot, Thijs!bot, JAnDbot, Camahuetos, Muro de Aguas, Pólux, VolkovBot, Technopat, José Daniel, Matdrodes, Carcediano, Gabo rage, Cebrianm, Nullsound, SilvonenBot, CarsracBot, LyingB, Secdio, Manuelt15, Xqbot, Rubinbot, PatruBOT, Dinamik-bot, EmausBot, MerlIwBot, BendelacBOT, Elvisor, Addbot, Jarould y Anónimos: 23 • NWNScript Fuente: https://es.wikipedia.org/wiki/NWNScript?oldid=75144330 Colaboradores: Emijrp, Muro Bot, PaintBot, Akhran, Mctpyt, Grillitus y Anónimos: 1 • Objeto todopoderoso Fuente: https://es.wikipedia.org/wiki/Objeto_todopoderoso?oldid=86476755 Colaboradores: CEM-bot, Poco a poco, Luckas-bot, MartinDM, TiriBOT, EmausBot, KLBot2, Igorov87, AxVirus, Addbot, Jarould y Anónimos: 1 • Oday Fuente: https://es.wikipedia.org/wiki/Oday?oldid=69581302 Colaboradores: CF, Gusgus y Cinevoro • Offset (informática) Fuente: https://es.wikipedia.org/wiki/Offset_(inform%C3%A1tica)?oldid=84332849 Colaboradores: El Moska, Digigalos, Deividmeil, GermanX, Eskimbot, Calsbert, CEM-bot, Thijs!bot, TXiKiBoT, Jmvgpartner, PaintBot, Loveless, El bot de la dieta, Marcecoro, Jost Riedel, MystBot, DiegoFb, ArthurBot, SuperBraulio13, Xqbot, Isseu, Vascodecai, EmausBot, Grillitus, Addbot y Anónimos: 11 • OGNL Fuente: https://es.wikipedia.org/wiki/OGNL?oldid=86821108 Colaboradores: Cinabrium, Benjavalero, Isha, DragonBot, UA31, Luckas-bot, Rodamaker, EmausBot, KLBot2, MetroBot, Elvisor, Addbot y Anónimos: 3 • OpenACS Fuente: https://es.wikipedia.org/wiki/OpenACS?oldid=78499694 Colaboradores: Barcex, Dianai, Halcón, GermanX, Lobillo, KnightRider, Davidam, Ca in, Thijs!bot, Cinevoro, Matdrodes, Muro Bot, Obelix83, Mcordova, Cjervis, PixelBot, LordboT, Salva84, Javiertoledos, Chemaur, Legobot, Ashaverus y Anónimos: 6 • Operaciones con archivos (informática) Fuente: https://es.wikipedia.org/wiki/Operaciones_con_archivos_(inform%C3%A1tica) ?oldid=85017788 Colaboradores: Jesuja, CEM-bot, PaintBot, Poco a poco, DiegoFb, LordboT, Jkbw, Grillitus, Elías, Érico y Anónimos: 2 • Operador Fuente: https://es.wikipedia.org/wiki/Operador?oldid=87368515 Colaboradores: 4lex, Yrbot, Jesuja, Götz, ManuelMore, Marianov, Mister, Davius, Julian Mendez, Ingenioso Hidalgo, Thijs!bot, IrwinSantos, Isha, JAnDbot, Gaius iulius caesar, MONIMINO, Nioger, Jmvkrecords, VolkovBot, Matdrodes, 3coma14, Ctrl Z, Mel 23, Greek, Mafores, Farisori, ElMeBot, Alejandrocaro35, Juan Mayordomo, Raulshc, SilvonenBot, AVBOT, Diegusjaimes, Luckas-bot, LordboT, CayoMarcio, ArthurBot, SuperBraulio13, Jkbw, Botarel, Adriana03, PatruBOT, KamikazeBot, Jorge c2010, EmausBot, TuHan-Bot, Rubpe19, Kallikanzarid, Rezabot, Abián, Travelour, Acratta, Fer13413, Legobot, Balles2601, Jarould, Lectorina y Anónimos: 73 • Operando Fuente: https://es.wikipedia.org/wiki/Operando?oldid=86610212 Colaboradores: Götz, JAnDbot, VolkovBot, Muro Bot, SieBot, Eduardosalg, Poco a poco, AVBOT, LucienBOT, Luckas-bot, Xqbot, PatruBOT, Foundling, EmausBot, HRoestBot, JackieBot, MerlIwBot, Acratta, Elvisor, Dexbot, Addbot y Anónimos: 11 • Paquetes en PL/SQL Fuente: https://es.wikipedia.org/wiki/Paquetes_en_PL/SQL?oldid=86909034 Colaboradores: Sabbut, Vanbasten 23, Dodo, Platonides, Baifito, GermanX, Lobillo, Nicop, Botito777, LordT, PatruBOT y Anónimos: 6 • Pascal Casing Fuente: https://es.wikipedia.org/wiki/Pascal_Casing?oldid=60127173 Colaboradores: BOT-Superzerocool, Galandil, Ezarate y Anónimos: 2 • Patch (Unix) Fuente: https://es.wikipedia.org/wiki/Patch_(Unix)?oldid=86042448 Colaboradores: Alejandrocaro35, UA31, Esceptic0, JackieBot, KLBot2, Elvisor, Zerabat y Anónimos: 1 • Phrogram Fuente: https://es.wikipedia.org/wiki/Phrogram?oldid=87258582 Colaboradores: Airunp, GermanX, Suomi 1973, CEM-bot, Rastrojo, Hymake, STBot~eswiki, Botito777, Boto a Boto, PatruBOT, TONYKRAZY, KLBot2, Elvisor y Anónimos: 12 • Plataforma de desarrollo Fuente: https://es.wikipedia.org/wiki/Plataforma_de_desarrollo?oldid=82814138 Colaboradores: Digigalos, Airunp, Murven, Gustronico, Shooke, Muro Bot, PaintBot, Marcecoro y Anónimos: 4 • Plataforma virtual didáctica Fuente: https://es.wikipedia.org/wiki/Plataforma_virtual_did%C3%A1ctica?oldid=86908914 Colaboradores: Sabbut, FAR, Airunp, Taichi, Lestaire~eswiki, CEM-bot, Rosarinagazo, Damelac, Netito777, Amanuense, Matdrodes, Bigsus-bot, Eduardosalg, BetoCG, UA31, AVBOT, David0811, Diegusjaimes, Arjuno3, Mindsociety, Andreasmperu, SuperBraulio13, Jkbw, Figaronline, Ganímedes, Savh, Waka Waka, Palissy, Invadibot, Nescalab, Elvisor, Helmy oved, Josgarfel, Jean70000, JuanG83, Jarould, Worldwriter3, Kintsugi, Oaxaco3293 y Anónimos: 65 • Polling Fuente: https://es.wikipedia.org/wiki/Polling?oldid=64497459 Colaboradores: Zyder, VolkovBot, FBaena, Eried, Alexbot, LucienBOT, DumZiBoT, Ykhwong, KLBot2 y Anónimos: 10 • Poltergeist (informática) Fuente: https://es.wikipedia.org/wiki/Poltergeist_(inform%C3%A1tica)?oldid=65390382 Colaboradores: Kavanagh, Héctor Guido Calvo, ZéroBot, Dalbela y Addbot • Portabilidad Fuente: https://es.wikipedia.org/wiki/Portabilidad?oldid=70481568 Colaboradores: Joseaperez, Dodo, Cookie, Daniel G., Jag2k4, Renabot, Digigalos, Taichi, Rembiapo pohyiete (bot), RobotQuistnix, Yrbot, YurikBot, Glia, GermanX, KnightRider, Eskimbot, Siabef, CEM-bot, Spazer, Sir Magician, Karshan, Thijs!bot, Mapep, JAnDbot, TXiKiBoT, Aibot, VolkovBot, Oxigenia, SieBot, Armando.Mejia, Ugly, Jkbw, Marsal20, PatruBOT, ErikvanB, Jef.smets, KLBot2, Leojd88 y Anónimos: 23
388
CAPÍTULO 205. ZENPHP
• Postcondición Fuente: https://es.wikipedia.org/wiki/Postcondici%C3%B3n?oldid=75146898 Colaboradores: Fabeirojorge, Carmin, Nano412, Waeswaes, ZéroBot, Grillitus y KLBot2 • Pragma Fuente: https://es.wikipedia.org/wiki/Pragma?oldid=78457101 Colaboradores: SimónK, Airunp, Equi, Martinmartin, Resped, Xoneca, Fitmoos, Biasoli, VolkovBot, Muro Bot, Loveless, Farisori, PixelBot, Botito777, Luis Felipe Schenone, Roberto Parrillas, Xqbot, Igna, Pragma~eswiki, KLBot2 y Anónimos: 2 • Precondición Fuente: https://es.wikipedia.org/wiki/Precondici%C3%B3n?oldid=74642503 Colaboradores: Ricpelo, Yardcock, Dianai, Yrbot, Lobillo, Chlewbot, Muro Bot, DSisyphBot, Waeswaes, Sfvier, HRoestBot, Grillitus, KLBot2, Bibliofilotranstornado y Anónimos: 1 • Primitiva de sincronización rendezvous Fuente: https://es.wikipedia.org/wiki/Primitiva_de_sincronizaci%C3%B3n_rendezvous?oldid= 54347703 Colaboradores: Sabbut, Ascánder, Dianai, Lobillo, Botito777, MarcoAurelio, Marsal20 y Anónimos: 3 • Proceso (informática) Fuente: https://es.wikipedia.org/wiki/Proceso_(inform%C3%A1tica)?oldid=86704547 Colaboradores: Lourdes Cardenal, ManuelGR, Robbot, Ecelan, Triku, Renacimiento, Jsanchezes, Yakoo, Rodrigouf, Emijrp, Magister Mathematicae, Afpineda, Yrbot, Martincarr, Wewe, Mriosriquelme, Tomatejc, BOTpolicia, CEM-bot, GoyoToscano, Thijs!bot, RoyFocker, Isha, Dogor, Gusgus, JAnDbot, Jugones55, Achata, CommonsDelinker, Humberto, Idioma-bot, Sebado, Biasoli, Cipión, Cinevoro, VolkovBot, Technopat, Raystorm, Matdrodes, Elabra sanchez, Shooke, Muro Bot, SieBot, Furado, Tirithel, Jarisleif, Javierito92, MetsBot~eswiki, Lyonn, Aleix87, PixelBot, Leonpolanco, Netito, VanBot, UA31, AVBOT, Hemingway10, Diegusjaimes, Whibla, Andreasmperu, Luckas-bot, Servando rivera, SuperBraulio13, Jkbw, S3rg10p3l1gr0, Ricardogpn, Botarel, BOTirithel, Lanreload, EmausBot, Savh, Ebrambot, Jcaraballo, WikitanvirBot, Movses-bot, Heradiom, MerlIwBot, Gohst~eswiki, Acratta, Creosota, Rauletemunoz, Legobot, Hans Topo1993, Oscawilma, Jarould, Kperdomo1 y Anónimos: 145 • Proceso para el desarrollo de software Fuente: https://es.wikipedia.org/wiki/Proceso_para_el_desarrollo_de_software?oldid=87352718 Colaboradores: Sabbut, CEM-bot, Osepu, Jgomo3, JAnDbot, Cmontero, Nioger, Leonpolanco, Poco a poco, Greenny, Arjuno3, Jkbw, FrescoBot, TiriBOT, PatruBOT, Waeswaes, ChuispastonBot, MerlIwBot, Travelour, Invadibot, Acratta, Vetranio, Elvisor, 2rombos, Addbot, ARLIAM, Arisneth, Jyee16, Gys21, Cesarh19, Lagr.0494, Crystallizedcarbon y Anónimos: 40 • Programa informático Fuente: https://es.wikipedia.org/wiki/Programa_inform%C3%A1tico?oldid=87352611 Colaboradores: Ejmeza, Taichi, Magister Mathematicae, Chobot, Vitamine, GermanX, Gaijin, The Photographer, Banfield, CEM-bot, Jorgelrm, Nagul, Baiji, Jgomo3, Dorieo, Escarbot, RoyFocker, Cratón, Isha, JAnDbot, Jugones55, Gsrdzl, CommonsDelinker, Vsuarezp, Gacq, Humberto, Amanuense, Idioma-bot, Pólux, Biasoli, Cinevoro, VolkovBot, Technopat, Queninosta, Matdrodes, Elabra sanchez, Shooke, Lucien leGrey, Gerakibot, SieBot, PaintBot, Rigenea, Bigsus-bot, BOTarate, Mel 23, Tirithel, Javierito92, Marcecoro, HUB, Estirabot, Eduardosalg, Botellín, Leonpolanco, Alejandrocaro35, Botito777, Petruss, Açipni-Lovrij, UA31, SergioN, MARC912374, AVBOT, David0811, Angel GN, SubSevenMoRpHeEuS, MarcoAurelio, NjardarBot, Diegusjaimes, Mikiguti, CarsracBot, Arjuno3, Saloca, Luckas-bot, Spirit-BlackWikipedista, Roinpa, Dangelin5, Axel.axel, Nixón, ArthurBot, SuperBraulio13, Xqbot, Jkbw, Igna, Botarel, D'ohBot, BOTirithel, Vubo, AnselmiJuan, PatruBOT, KamikazeBot, Rudol0075, Foundling, EmausBot, Bachi 2805, Savh, ZéroBot, HRoestBot, Grillitus, Rubpe19, Jcaraballo, MadriCR, AStarBot, MerlIwBot, Vagobot, MetroBot, BiTAlejandro, Elvisor, Helmy oved, Makecat-bot, Addbot, Balles2601, Amautita12, AVIADOR-bot, Jarould, Kevin15jdr, Beromawiki y Anónimos: 180 • Programa interactivo Fuente: https://es.wikipedia.org/wiki/Programa_interactivo?oldid=76595564 Colaboradores: BOT-Superzerocool, Ombresaco, Ignacio Icke, Miik Ezdanitofff, Elvisor y Anónimos: 8 • Programación lineal paramétrica Fuente: https://es.wikipedia.org/wiki/Programaci%C3%B3n_lineal_param%C3%A9trica?oldid= 76695344 Colaboradores: Dangelin5, Paolahlopez, Nibb10 y Anónimos: 1 • Programación visual Fuente: https://es.wikipedia.org/wiki/Programaci%C3%B3n_visual?oldid=82252981 Colaboradores: Vanbasten 23, Airunp, TXiKiBoT, VolkovBot, Matdrodes, Shooke, Muro Bot, NapoliAzzurro, Rgimenez, PipepBot, Eduardosalg, Botito777, LordT, Açipni-Lovrij, Elliniká, Luckas-bot, Amirobot, DiegoFb, DirlBot, Jkbw, DSP-user, EmausBot, ChuispastonBot, KLBot2, Baute2010, Jarould y Anónimos: 21 • Programador Fuente: https://es.wikipedia.org/wiki/Programador?oldid=86535702 Colaboradores: Moriel, Vanbasten 23, Robbot, Comae, Rbidegain, Avm, SimónK, Tostadora, Elwikipedista, Mig29x, Edmont, Rapomon, Petronas, Edub, Emijrp, Rembiapo pohyiete (bot), Magister Mathematicae, Alhen, Chobot, Afpineda, Yrbot, Baifito, BOT-Superzerocool, Vitamine, Jhony192, GermanX, KnightRider, Tomatejc, Zalovitch, CEM-bot, Marianov, Roberpl, Mister, Alvaro qc, Tyrannosaurusreflex, Srengel, Un Mercenario, RoyFocker, Isha, Imakuni, Jugones55, LogC, Netito777, NaSz, Pólux, Developer, NpR.Soft, VolkovBot, Queninosta, Matdrodes, Elabra sanchez, Vladimir138, 3coma14, Muro Bot, Dinopmi, SieBot, Manwë, Edans, Jsainz, Tirithel, Marcecoro, HUB, MetsBot~eswiki, Craneorojo, Mawitolope, Chococob, Petto, Poco a poco, Toolserver, UA31, SergioN, AVBOT, David0811, Mizukane203, Quique24, Juanpablovelezlopez, Luckas-bot, Jaka14, ChristianH, Xqbot, Jkbw, Dreitmen, D'ohBot, Betomorales, Halfdrag, PatruBOT, Humbefa, Guikipedia, Dark Bane, GrouchoBot, EmausBot, AVIADOR, Sergio Andres Segovia, Mecamático, Solde9, Iannabir, EmiOk, Waka Waka, WikitanvirBot, MerlIwBot, KLBot2, Thehelpfulbot, LlamaAl, Carlosierra96, Addbot, Masterchief12345678, MarioFinale y Anónimos: 114 • Pseudocódigo Fuente: https://es.wikipedia.org/wiki/Pseudoc%C3%B3digo?oldid=87176241 Colaboradores: Pino, JorgeGG, Lourdes Cardenal, Julie, Rumpelstiltskin, Bigsus, Jynus, Elwikipedista, Lanjoe9, Robotico, Skiel85, Soulreaper, Petronas, Airunp, Edub, Taichi, Emijrp, RobotQuistnix, Yrbot, Amadís, BOTijo, YurikBot, Gaeddal, GermanX, Beto29, Jesuja, Santiperez, Maldoror, Er Komandante, Chlewbot, Transon, Tomatejc, Siabef, Rbonvall, Kn, BOTpolicia, CEM-bot, Jorgelrm, Baiji, Antur, Gafotas, Roslopez, FrancoGG, Fsd141, Thijs!bot, Leandroidecba, Isha, JAnDbot, Muro de Aguas, Iulius1973, Xavigivax, Netito777, Rei-bot, Nioger, Pólux, Jatrobat, Manuel Trujillo Berges, Almendro, AchedDamiman, VolkovBot, Snakeyes, Technopat, Raystorm, Matdrodes, DJ Nietzsche, BlackBeast, Carmel2007, Muro Bot, BotMultichill, Ctrl Z, Loveless, Housjdhfjk, Cousteau, Dark, BOTarate, BuenaGente, EdoS, Tirithel, Dnu72, HUB, Rolochafi, Estirabot, Eduardosalg, Leonpolanco, Pan con queso, Alejandrocaro35, BetoCG, Açipni-Lovrij, Osado, UA31, AVBOT, MastiBot, Speedplus, Enramos, Diegusjaimes, Davidgutierrezalvarez, MelancholieBot, Arjuno3, Luckas-bot, Eduenas, Luzbelito92, WikiIgnacioJavier, Nixón, ArthurBot, SuperBraulio13, ChristianH, Manuelt15, Xqbot, Jkbw, Jjuanchojp, Igna, Botarel, Panderine!, Manito777, E404, BOTirithel, Hprmedina, PatruBOT, Ganímedes, Mr.Ajedrez, Tarawa1943, Waeswaes, Sakura 3, Miss Manzana, Edslov, Derrypr, Savh, AVIADOR, Sergio Andres Segovia, Africanus, Grillitus, MercurioMT, Mecamático, Emiduronte, Obeyjuan, MA LópezMolina, Bien claro, Antonorsi, KLBot2, Ginés90, Kepnesro, Henry bedon, Vetranio, Mowgli.solis, Elvisor, Badgov, Helmy oved, VanesaQuintero', Oscar.gasca7, Ndz17, BOTito, Chico raul, Jarould, Matiia, Ehhhmaincraa, Fernando2812l y Anónimos: 369 • Puente de aplicación Fuente: https://es.wikipedia.org/wiki/Puente_de_aplicaci%C3%B3n?oldid=74642668 Colaboradores: Pilaf, Dianai, Baifito, GermanX, Lobillo, -jem-, Especiales, Muro Bot, PaintBot, LucienBOT, Grillitus, Beherith y Anónimos: 4 • Puntero inteligente Fuente: https://es.wikipedia.org/wiki/Puntero_inteligente?oldid=87179431 Colaboradores: CEM-bot, JoseTomasTocino, El Pantera, Luckas-bot, MystBot, Pepe3r, EmausBot, Josemarente, KLBot2, Johnbot, Elvisor y Anónimos: 1
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
389
• Pure data Fuente: https://es.wikipedia.org/wiki/Pure_data?oldid=87336476 Colaboradores: Aloriel, Dodo, Ejmeza, Jarfil, Cinabrium, Mescalier, Edub, Taichi, Orgullobot~eswiki, Jose.zapata, Yucon, Dibujon, Deprieto, Yrbot, Acracia, FlaBot, YurikBot, GermanX, Marb, Ál, Gizmo II, CEM-bot, DifferentSmoke~eswiki, Mpeinadopa, Sergeeo, VolkovBot, Jarm.yo, Shooke, Muro Bot, Dinopmi, Loveless, Drinibot, Botellín, LordT, LucienBOT, Angel GN, Luckas-bot, MystBot, Angelalg, DanielrocaES, ArthurBot, KLBot, KLBot2, El erno, DerProspekt, Elvisor y Anónimos: 27 • QuadTIN Fuente: https://es.wikipedia.org/wiki/QuadTIN?oldid=22507224 Colaboradores: Lobillo, Alex15090, Tito HX, PaintBot y DiegoFb • Query string Fuente: https://es.wikipedia.org/wiki/Query_string?oldid=81380457 Colaboradores: Taichi, Rembiapo pohyiete (bot), Varano, GermanX, Lobillo, The Photographer, CEM-bot, Resped, PaintBot, BOTarate, Ortellado, MystBot, DiegoFb, Xqbot, D'ohBot, KLBot2, Vichock, Ytotrip, Elvisor y Anónimos: 5 • Quest3D Fuente: https://es.wikipedia.org/wiki/Quest3D?oldid=83296729 Colaboradores: Vanbasten 23, Benjavalero, BOTijo, GermanX, Thijs!bot, Calapito, Biasoli, Loveless, Tirithel, Alexaltea, Kroji, MastiBot, Sbarrera, MystBot, KLBot2 y Anónimos: 3 • Quine (programa) Fuente: https://es.wikipedia.org/wiki/Quine_(programa)?oldid=78055735 Colaboradores: Pieter, Robbot, Zwobot, Renabot, OMenda, RobotQuistnix, Chobot, Yrbot, BOTijo, YurikBot, YoungSpinoza, C-3POrao, Eskimbot, Spc, BOTpolicia, CEM-bot, JoaquinFerrero, Ajavier, Rulo86, Dusan, Matdrodes, Elabra sanchez, Valenluis, Armando.Mejia, El bot de la dieta, Amoceann~eswiki, MastiBot, Luckas-bot, Kizar, Abece, KamikazeBot, GrouchoBot, Addbot y Anónimos: 11 • Rebanamiento estático Fuente: https://es.wikipedia.org/wiki/Rebanamiento_est%C3%A1tico?oldid=77066202 Colaboradores: Kiekvogel, Airunp, Orgullobot~eswiki, Yrbot, Baifito, Lobillo, SieBot, BOTarate, Obersachsebot, BenzolBot, Angelito7, Ll0l00l, KLBot2 y Anónimos: 2 • Recolector de basura Fuente: https://es.wikipedia.org/wiki/Recolector_de_basura?oldid=87391272 Colaboradores: Comae, Dodo, Opinador, Niqueco, LeonardoRob0t, Gelo71, Yrithinnd, Emijrp, Rembiapo pohyiete (bot), Orgullobot~eswiki, Unf, Afpineda, Yrbot, FlaBot, YurikBot, GermanX, Beto29, KnightRider, Banfield, BOTpolicia, Qwertyytrewqqwerty, Chfiguer, CEM-bot, Thijs!bot, Ñuño Martínez, JAnDbot, ColdWind, Rei-bot, Biasoli, AlnoktaBOT, Technopat, AlleborgoBot, SieBot, Loveless, Mutari, XalD, Rizziac, Louperibot, MastiBot, Diegusjaimes, Victormoz, Luckas-bot, Nallimbot, Xqbot, Hprmedina, RedBot, PatruBOT, TjBot, GrouchoBot, EmausBot, Savh, WikitanvirBot, MerlIwBot, Elvisor, Addbot y Anónimos: 33 • Recursión Fuente: https://es.wikipedia.org/wiki/Recursi%C3%B3n?oldid=82777675 Colaboradores: Sabbut, Pablo.cl, JorgeGG, Cdlfd, Zwobot, Triku, Sms, Pabloa, Rembiapo pohyiete (bot), Magister Mathematicae, Orgullobot~eswiki, RobotQuistnix, Yrbot, Baifito, Dagavi, BOTijo, Equi, CarCar, Jesuja, Banfield, José., Jarke, Paintman, Calsbert, CEM-bot, -jem-, Davius, Ingenioso Hidalgo, Escarbot, JAnDbot, Soulbot, Kakico, TXiKiBoT, HiTe, Humberto, Netito777, Amanuense, Miguelmrm, Matdrodes, Amitie 10g, Peregring-lk, Ensada, Daniel Ajoy, Farisori, Eduardosalg, Alejandrocaro35, Poco a poco, BodhisattvaBot, Raulshc, AVBOT, Diegusjaimes, MelancholieBot, CarsracBot, Arjuno3, Luckas-bot, Fabiocalde, ArthurBot, Secdio, Xqbot, Bitarray, Ricardogpn, Carlospretelt, TiriBOT, KamikazeBot, EmausBot, MerlIwBot, Jnjnjn, Acratta, Addbot, DarkBlueZV, BenjaBot, Joseph.skater y Anónimos: 62 • Refactorización Fuente: https://es.wikipedia.org/wiki/Refactorizaci%C3%B3n?oldid=76830519 Colaboradores: Sabbut, Pilaf, Rsg, Wikier~eswiki, LeonardoRob0t, Guille.hoardings, Taichi, RobotQuistnix, Platonides, Yrbot, YurikBot, Wiki-Bot, GermanX, Eskimbot, Calsbert, JAnDbot, TXiKiBoT, Rei-bot, Idioma-bot, Aibot, VolkovBot, Muro Bot, BotMultichill, El bot de la dieta, PipepBot, Amischol, Alecs.bot, UA31, MastiBot, ArthurBot, SuperBraulio13, Xqbot, Kismalac, EmausBot, ZéroBot, ChuispastonBot, KLBot2 y Anónimos: 4 • Reflexión (informática) Fuente: https://es.wikipedia.org/wiki/Reflexi%C3%B3n_(inform%C3%A1tica)?oldid=75475919 Colaboradores: Fibonacci, Pilaf, Yrithinnd, Chobot, GermanX, KnightRider, Moiwiki, CEM-bot, Santhy, Thijs!bot, JoaquinFerrero, Gusgus, Biasoli, Dusan, VolkovBot, Elabra sanchez, Gerakibot, SieBot, Asclepios~eswiki, Arjuno3, Felipe Raimann, Francisco.cifuentes, JackieBot, KLBot2, Makecat-bot y Anónimos: 11 • Relación de compresión (informática) Fuente: https://es.wikipedia.org/wiki/Relaci%C3%B3n_de_compresi%C3%B3n_(inform%C3% A1tica)?oldid=34972408 Colaboradores: Neurotronix • Resolución de problemas de programación Fuente: https://es.wikipedia.org/wiki/Resoluci%C3%B3n_de_problemas_de_programaci% C3%B3n?oldid=84827790 Colaboradores: Vivero, Jesuja, CEM-bot, LMLM, Queninosta, Edmenb, Alejandrocaro35, Botito777, Camilo, AVBOT, Angel GN, Botarel, AstaBOTh15, BOTirithel, Hprmedina, Iwèr, MercurioMT, Helmy oved, Jarould y Anónimos: 23 • Usuario:Santhy/En edición/Instancia (programación) Fuente: https://es.wikipedia.org/wiki/Usuario%3ASanthy/En_edici%C3%B3n/ Instancia_(programaci%C3%B3n)?oldid=67398481 Colaboradores: Santhy • Anexo:Scan code Fuente: https://es.wikipedia.org/wiki/Anexo%3AScan_code?oldid=64546479 Colaboradores: Murphy era un optimista, Rembiapo pohyiete (bot), GermanX, Ciencia Al Poder, CEM-bot, R2D2!, Snakeyes, Muro Bot, Xqbot, EmausBot, WikitanvirBot, Addbot y Anónimos: 2 • Scanf Fuente: https://es.wikipedia.org/wiki/Scanf?oldid=87399727 Colaboradores: Dodo, Ascánder, Jesuja, Faelomx, Nelson.cruz, CEMbot, Jorgelrm, RoyFocker, Hameryko, VolkovBot, Shooke, Muro Bot, Loveless, MacaBot, AntonCampos, Botito777, AVBOT, Luckas-bot, Kurt86, Eññe, Dreitmen, WikitanvirBot, KLBot2, Pccoronado, JacobRodrigues, Monty programador y Anónimos: 22 • SCons Fuente: https://es.wikipedia.org/wiki/SCons?oldid=77306026 Colaboradores: Hari Seldon, Lin linao, Paintman, Anonimato1990, Dalacost, Thijs!bot, Muro Bot, LordT, UA31, Amirobot, Nallimbot, Xqbot, D'ohBot, KLBot, FranKapranos, KLBot2, Invadibot, Osorambolo y Anónimos: 1 • Screen scraping Fuente: https://es.wikipedia.org/wiki/Screen_scraping?oldid=77149450 Colaboradores: RobotQuistnix, Cacique500, Teufelskerl, VolkovBot, Rapto, Leonpolanco, Alecs.bot, UA31, DiegoFb, Ortisa, Grillitus, Mentibot, KLBot2, Bibliofilotranstornado, ProfesorFavalli y Anónimos: 1 • Sección crítica Fuente: https://es.wikipedia.org/wiki/Secci%C3%B3n_cr%C3%ADtica?oldid=78884564 Colaboradores: ManuelGR, Comae, Dodo, Robotito, Rembiapo pohyiete (bot), Orgullobot~eswiki, RobotQuistnix, Francosrodriguez, Toxickore, Martincarr, GermanX, Lobillo, CEM-bot, Dogor, Hameryko, JAnDbot, Antipatico, Aibot, VolkovBot, Muro Bot, BotMultichill, SieBot, PaintBot, Loveless, Cousteau, Alexbot, MastiBot, MelancholieBot, Luckas-bot, Xqbot, WikitanvirBot, Elvisor, Addbot y Anónimos: 8 • Serialización Fuente: https://es.wikipedia.org/wiki/Serializaci%C3%B3n?oldid=87539851 Colaboradores: Angus, Boticario, Rembiapo pohyiete (bot), Viko~eswiki, RobotQuistnix, Yrbot, YurikBot, GermanX, The Photographer, Banfield, Cad, Qwertyytrewqqwerty, Chfiguer, CEM-bot, Byzs, BotMultichill, SieBot, Inuyasha1111, R.factorial, HUB, AVBOT, Luckas-bot, Jackie, Almabot, Jkbw, MauritsBot, BOTirithel, JackieBot, KLBot2, Victorvic1 y Anónimos: 20
390
CAPÍTULO 205. ZENPHP
• Sigil Fuente: https://es.wikipedia.org/wiki/Sigil?oldid=75149926 Colaboradores: Sabbut, Mr. Moonlight, JoaquinFerrero, Technopat, Waeswaes, Grillitus, KLBot2 y Anónimos: 1 • Signatura (informática) Fuente: https://es.wikipedia.org/wiki/Signatura_(inform%C3%A1tica)?oldid=79576682 Colaboradores: Beagle~eswiki, Alejolp, Humberto, Muro Bot, Hoenheim, KLBot2, ElGatoSaez, SteenthIWbot y Anónimos: 2 • Signum Framework Fuente: https://es.wikipedia.org/wiki/Signum_Framework?oldid=64829284 Colaboradores: Sabbut, JMPerez, Cad, Grillitus, KLBot2 y Anónimos: 1 • Simple Network Library Fuente: https://es.wikipedia.org/wiki/Simple_Network_Library?oldid=85753665 Colaboradores: CEM-bot, Shooke, Barri, Muro Bot, Antón Francho, Lacabra25, Rαge, KLBot, MerlIwBot y Anónimos: 10 • Smarty Fuente: https://es.wikipedia.org/wiki/Smarty?oldid=77195456 Colaboradores: Comae, Levhita, Sms, Cinabrium, Boticario, Petronas, Orgullomoore, Rembiapo pohyiete (bot), RobotQuistnix, Superzerocool, Caiserbot, Yrbot, YurikBot, Gpayo, Peperoni, Tomatejc, Nethac DIU, CEM-bot, Thijs!bot, Escarbot, Botones, VolkovBot, Chusete, Muro Bot, FBaena, Loveless, Obelix83, BOTarate, Machucho2007, Artistadelpecado, PixelBot, Oriol Jimenez, Alexbot, DumZiBoT, Luckas-bot, LordboT, Wikiniel, Crisanto82, XZeroBot, Lalo0002, Xqbot, Adryitan, Apgew, Addbot, BOTito y Anónimos: 23 • Snippet Fuente: https://es.wikipedia.org/wiki/Snippet?oldid=85722369 Colaboradores: Wolkmx, GermanX, Covi, Drinibot, Louperibot, Ezarate, Billinghurst, HRoestBot, Albertojuanse, KLBot2, Elvisor, Barkfox y Anónimos: 5 • Stack Overflow Fuente: https://es.wikipedia.org/wiki/Stack_Overflow?oldid=87516998 Colaboradores: Erik Streb, Djcandido, MastiBot, Grillitus, Kasirbot, MerlIwBot, KLBot2, UAwiki, SantyXDz, Invadibot, Gaaplex, Jarould, Davilajhon98 y Anónimos: 8 • StarBasic Fuente: https://es.wikipedia.org/wiki/StarBasic?oldid=85575218 Colaboradores: Yrithinnd, FlaBot, Equi, Lobillo, PaintBot, DiegoFb, KLBot2, Invadibot, Elvisor y Anónimos: 2 • Stub Fuente: https://es.wikipedia.org/wiki/Stub?oldid=77522196 Colaboradores: Sunsinron, Dasoman, KLBot2, Ni.cero, Harpagornis y Anónimos: 2 • Subalgoritmo Fuente: https://es.wikipedia.org/wiki/Subalgoritmo?oldid=75146615 Colaboradores: Jesuja, Pinar~eswiki, Biasoli, Fran Ara, Technopat, Grillitus y Anónimos: 2 • Tabla de saltos Fuente: https://es.wikipedia.org/wiki/Tabla_de_saltos?oldid=64505443 Colaboradores: CEM-bot, Fabeirojorge, Muro Bot, Mafores, KLBot2, Elvisor y Anónimos: 1 • Tabla de verdad Fuente: https://es.wikipedia.org/wiki/Tabla_de_verdad?oldid=87508038 Colaboradores: Sabbut, Vivero, Dodo, Julian Colina, Robotje, Melocoton, Dianai, Xenoforme, Elsenyor, FAR, LeonardoRob0t, Xuankar, Yrithinnd, Taichi, Rembiapo pohyiete (bot), Caiser, Gabri-gr-es, Magister Mathematicae, Kokoo, Orgullobot~eswiki, RobotQuistnix, JKD, Caiserbot, FlaBot, Vitamine, .Sergio, YurikBot, GermanX, The Photographer, No sé qué nick poner, Banfield, Chlewbot, Filipo, Lagarto, BOTpolicia, CEM-bot, Laura Fiorucci, Arctosouros, -jem-, L30nc1t0, Davius, Antur, Lauranrg, Mario modesto, Isha, JAnDbot, Mansoncc, Muro de Aguas, Gsrdzl, Alephcero~eswiki, Amdkde, Pabloallo, MONIMINO, VolkovBot, Technopat, C'est moi, Matdrodes, AlleborgoBot, Muro Bot, Edmenb, SieBot, Loveless, Drinibot, Mel 23, Belb, Fortefranco, Tirithel, XalD, Jarisleif, Dnu72, Nicop, Farisori, Eduardosalg, Dansanti, Leonpolanco, Alejandrocaro35, BetoCG, Cebrianm, Angel verde, Açipni-Lovrij, Camilo, UA31, AVBOT, Elliniká, Xenocrates, MastiBot, Diegusjaimes, Luckas-bot, Nallimbot, Dangelin5, Luis Felipe Schenone, ArthurBot, SuperBraulio13, Xqbot, Jkbw, GNM, Kevinar12, Ricardogpn, Bot0811, Kismalac, Igna, MAfotBOT, Hprmedina, Danie1996, Omerta-ve, PatruBOT, Ripchip Bot, Tarawa1943, Wikiléptico, Miss Manzana, Edslov, Jhon97, ZéroBot, MercurioMT, Mecamático, ChuispastonBot, MadriCR, Desdeluego, Waka Waka, Antonorsi, Acratta, Elvisor, JYBot, Helmy oved, Addbot, Balles2601, Juan paul toledo rivera, Veloniel, Lopenovi, XVRT, Joanmiguel1998, Jarould, Kenia Marcela y Anónimos: 342 • Thunk Fuente: https://es.wikipedia.org/wiki/Thunk?oldid=64588015 Colaboradores: Mar del Sur, KLBot2 y Anónimos: 1 • Tipo de dato elemental Fuente: https://es.wikipedia.org/wiki/Tipo_de_dato_elemental?oldid=77059484 Colaboradores: Emijrp, Jesuja, Asocall, Loveless, Juan Mayordomo, Waeswaes, Grillitus, MerlIwBot, Addbot y DarkBlueZV • Triángulo de Floyd Fuente: https://es.wikipedia.org/wiki/Tri%C3%A1ngulo_de_Floyd?oldid=73932861 Colaboradores: Urdangaray, Koldito, Drinibot, Alejandrocaro35, Raulshc, LucienBOT, WikitanvirBot, KLBot2, Invadibot y Anónimos: 1 • Tubería (informática) Fuente: https://es.wikipedia.org/wiki/Tuber%C3%ADa_(inform%C3%A1tica)?oldid=80896342 Colaboradores: 4lex, Elwikipedista, FlaBot, GermanX, Nihilo, Jorgechp, CEM-bot, Dogor, JAnDbot, NaBUru38, Penarc, PaintBot, Piware, LordT, Arjuno3, DiegoFb, Vivaelcelta, EmausBot, ZéroBot, Mentibot, Bibliofilotranstornado, Elvisor, Xbosch, Ralgisbot, Addbot y Anónimos: 4 • Violación de acceso Fuente: https://es.wikipedia.org/wiki/Violaci%C3%B3n_de_acceso?oldid=72535485 Colaboradores: LeCire, RobotQuistnix, Chobot, Yrbot, YurikBot, Siabef, Raulul, Electrican MV, Thijs!bot, TXiKiBoT, PetrohsW, MastiBot, TobeBot, Waeswaes, GrouchoBot, Grillitus, KLBot2 y Anónimos: 8 • Waf Fuente: https://es.wikipedia.org/wiki/Waf?oldid=87092956 Colaboradores: Jcarlos77, Anonimato1990, Muro Bot, LordT, UA31, Luckas-bot, MystBot, AstaBOTh15, ZéroBot, MerlIwBot, KLBot2, NyappyBOT, Elvisor y Anónimos: 1 • Win32 Thread Information Block Fuente: https://es.wikipedia.org/wiki/Win32_Thread_Information_Block?oldid=67493984 Colaboradores: CEM-bot, Especiales, Luiswtc73, LucienBOT, Mizukane203, Yuri Grille Orce, TiriBOT, DarAR92 y Addbot • Wrapper Fuente: https://es.wikipedia.org/wiki/Wrapper?oldid=75067340 Colaboradores: Kirtash006, Totemkin, VictorPines y Niniahormona • XAML Fuente: https://es.wikipedia.org/wiki/XAML?oldid=87128772 Colaboradores: Zwobot, Sampler, Wikier~eswiki, Aliman5040, Viko~eswiki, Murven, RobotQuistnix, Yrbot, BOTijo, GermanX, KnightRider, Jesuja, Edanielc, CEM-bot, Jjvaca, Thijs!bot, Locovich, Nahog, Rei-bot, Jarm.yo, Muro Bot, SieBot, PaintBot, Rv53705, BenjaminZepeda, OssDev~eswiki, Jmmuguerza, DragonBot, Pablo323, Alexbot, UA31, AVBOT, LucienBOT, Whibla, Bethan 182, Linfocito B, DiegoFb, ArthurBot, Abcpaem, Xqbot, EmausBot, WikitanvirBot, Diamondland, KLBot2, Elvisor y Anónimos: 20 • Zenphp Fuente: https://es.wikipedia.org/wiki/Zenphp?oldid=77226374 Colaboradores: Muro Bot, Poco a poco, UA31, Juaxix, LordboT, Jllopezpino, FrescoBot, MerlIwBot, Elvisor, BOTito y Anónimos: 2
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
205.3.2
391
Imágenes
• Archivo:Actual_DEC_UNIX_License_Plate_DSC_0317.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/c/c0/Actual_ DEC_UNIX_License_Plate_DSC_0317.jpg Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Armandops • Archivo:Ada_Lovelace_1838.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/2e/Ada_Lovelace_1838.jpg Licencia: Public domain Colaboradores: From The Ada Picture Gallery. Evelyn Silva scanned this from a picture she found “in the trash”in Louisiana, USA, and submitted it to the Ada Picture Gallery in October 2000. She wrote: On the bottom of the picture it says “LONDON PUBLISHED NOV 1 1838 FOR THE PROPRIETORS, No 18 & 19 SOUTHAMPTON PLACE, EUSTON SQUARE, NEW ROAD”. In the lower left corner it says “Printered by Mc Queen”. On the lower right of the picture its “Engraved By W. H. Mote”. On the left “Drawn by A.E. Chaton R.A.”. There was also a page with a bio on it. This was not in a book when I found it, it was loose along with some other Ladies of the Queens court. So I don't have any other info on it. It is an original print from its time, not a reproduction. Artista original: William Henry Mote • Archivo:Adobe_Director_v11_icon.png Fuente: https://upload.wikimedia.org/wikipedia/commons/e/ee/Adobe_Director_v11_icon. png Licencia: Public domain Colaboradores: This image is from roaringapps.com/app:413 (Direct link) It matches the smaller sized one available on adobe.com at [1] and [2]; therefore, it is believed to be the genuine icon. Artista original: Adobe Systems • Archivo:Ampersand.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/1/1b/Ampersand.svg Licencia: CC-BY-SA-3.0 Colaboradores: ? Artista original: ? • Archivo:Bang.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/e/e6/Bang.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:Begriffsschrift_connective1.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/6/67/Begriffsschrift_connective1. svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Guus Hoekman • Archivo:Blackbox3D.png Fuente: https://upload.wikimedia.org/wikipedia/commons/4/44/Blackbox3D.png Licencia: CC BY-SA 4.0 Colaboradores: Trabajo propio Artista original: Krauss • Archivo:Blueduck.png Fuente: https://upload.wikimedia.org/wikipedia/commons/c/c8/Blueduck.png Licencia: CC BY-SA 3.0 Colaboradores: http://willnicholes.com/duck/screenshots.htm Artista original: Will Nicholes • Archivo:Broom_icon.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/2c/Broom_icon.svg Licencia: GPL Colaboradores: http://www.kde-look.org/content/show.php?content=29699 Artista original: gg3po (Tony Tony), SVG version by User:Booyabazooka • Archivo:CamelCase_sign.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/6/6d/CamelCase_sign.jpg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Camera_web.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/f/f4/Camera_web.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:Check_mark.png Fuente: https://upload.wikimedia.org/wikipedia/commons/f/f0/Check_mark.png Licencia: CC BY-SA 3.0 Colaboradores: Wikipedia Artista original: Wikipedia • Archivo:Ciclo_mientras.png Fuente: https://upload.wikimedia.org/wikipedia/commons/a/a1/Ciclo_mientras.png Licencia: CC-BY-SA3.0 Colaboradores: Trabajo propio (Hecho con OpenOffice.org Draw) Artista original: kn • Archivo:Cmake.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/1/13/Cmake.svg Licencia: CC BY 2.0 Colaboradores: File:Cmake.jpg Artista original: Cmake team. The original uploader was Francesco Betti Sorbelli de Wikipedia en italiano. Vectorized by Magasjukur2 • Archivo:CodeCmmt002.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/7/75/CodeCmmt002.svg Licencia: CC BY 2.5 Colaboradores: Transferido desde en.wikipedia a Commons.28041964 Artista original: The original uploader was Dreftymac de Wikipedia en inglés • Archivo:Commons-emblem-copyedit.svg Fuente: Commons-emblem-copyedit.svg Licencia: CC BY-SA 3.0 Colaboradores:
https://upload.wikimedia.org/wikipedia/commons/e/e8/
• File:Gnome-emblem-important.svg Artista original: GNOME icon artists, Fitoschido • Archivo:Commons-emblem-disambig-notice.svg Fuente: Commons-emblem-disambig-notice.svg Licencia: GPL Colaboradores:
https://upload.wikimedia.org/wikipedia/commons/5/58/
• Commons-emblem-notice.svg Artista original: GNOME icon artists, Fitoschido • Archivo:Commons-emblem-issue.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/b/bc/Commons-emblem-issue.svg Licencia: GPL Colaboradores: File:Gnome-emblem-important.svg Artista original: GNOME icon artists and User:ViperSnake151 • Archivo:Commons-emblem-merge.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/8/8b/Commons-emblem-merge.svg Licencia: CC BY-SA 3.0 Colaboradores: • File:Gnome-emblem-important.svg Artista original: GNOME icon artists, Fitoschido • Archivo:Commons-emblem-question_book_orange.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/1/1f/ Commons-emblem-question_book_orange.svg Licencia: CC BY-SA 3.0 Colaboradores:
+
Artista original: GNOME icon artists, Jorge 2701
392
CAPÍTULO 205. ZENPHP
• Archivo:Commons-emblem-question_book_yellow.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/d/dd/ Commons-emblem-question_book_yellow.svg Licencia: CC BY-SA 3.0 Colaboradores:
+
Artista original: GNOME icon artists, Linfocito B • Archivo:Commons-logo.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/4/4a/Commons-logo.svg Licencia: Public domain Colaboradores: This version created by Pumbaa, using a proper partial circle and SVG geometry features. (Former versions used to be slightly warped.) Artista original: SVG version was created by User:Grunt and cleaned up by 3247, based on the earlier PNG version, created by Reidab. • Archivo:Computer-aj_aj_ashton_01.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/d/d7/Desktop_computer_clipart_ -_Yellow_theme.svg Licencia: CC0 Colaboradores: https://openclipart.org/detail/105871/computeraj-aj-ashton-01 Artista original: AJ from openclipart.org • Archivo:Condicional.png Fuente: https://upload.wikimedia.org/wikipedia/commons/0/0e/Condicional.png Licencia: CC-BY-SA-3.0 Colaboradores: Trabajo propio (Hecho con OpenOffice.org Draw) Artista original: kn • Archivo:Condicional1.png Fuente: https://upload.wikimedia.org/wikipedia/commons/f/f8/Condicional1.png Licencia: CC-BY-SA-3.0 Colaboradores: Trabajo propio Artista original: Jesuja • Archivo:Crystal_Clear_action_edit_add.png Fuente: https://upload.wikimedia.org/wikipedia/commons/e/e2/Crystal_Clear_action_ edit_add.png Licencia: LGPL Colaboradores: All Crystal Clear icons were posted by the author as LGPL on kde-look; Artista original: Everaldo Coelho and YellowIcon; • Archivo:Crystal_Clear_app_kcoloredit.png Fuente: https://upload.wikimedia.org/wikipedia/commons/7/70/Crystal_Clear_app_ kcoloredit.png Licencia: LGPL Colaboradores: All Crystal Clear icons were posted by the author as LGPL on kde-look; Artista original: Everaldo Coelho and YellowIcon; • Archivo:Cscr-featured.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/e/e7/Cscr-featured.svg Licencia: LGPL Colaboradores: Wikipedia until June, 2006 Artista original: Wikimedia users ClockworkSoul, CyberSkull, Optimager, White Cat, Erina, AzaToth, Pbroks13. • Archivo:Cuadro_de_ventajas_y_desventajas_del_uso_del_Paradigma_tradicional.JPG Fuente: https://upload.wikimedia.org/ wikipedia/commons/2/21/Cuadro_de_ventajas_y_desventajas_del_uso_del_Paradigma_tradicional.JPG Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Arisneth Chanapi • Archivo:DeadlockGraph.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/9/99/DeadlockGraph.svg Licencia: CC0 Colaboradores: Trabajo propio Artista original: Niqueco • Archivo:Dg-nova3.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/9/99/Dg-nova3.jpg Licencia: Copyrighted free use Colaboradores: Photograph taken by Qu1j0t3. Artista original: User Qu1j0t3 on en.wikipedia • Archivo:DiagramaFlujoLampara.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/7/76/DiagramaFlujoLampara.svg Licencia: CC-BY-SA-3.0 Colaboradores: versión en español de w:Image:LampFlowchart.svg Artista original: svg en español por Jipumarino • Archivo:Distrains.png Fuente: https://upload.wikimedia.org/wikipedia/commons/0/05/Distrains.png Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:Droste.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/6/62/Droste.jpg Licencia: Public domain Colaboradores: [4] [5] Artista original: Jan (Johannes) Misset? • Archivo:Ejemplo_de_JFrame.png Fuente: https://upload.wikimedia.org/wikipedia/commons/5/5e/Ejemplo_de_JFrame.png Licencia: CC BY-SA 4.0 Colaboradores: Trabajo propio Artista original: Ivordro UV • Archivo:El_modelo_de_desarrollo_en_cascada.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/2e/El_modelo_de_ desarrollo_en_cascada.svg Licencia: CC BY 3.0 Colaboradores: http://en.wikipedia.org/wiki/File:Waterfall_model_%281%29.svg Artista original: Paulsmith99 • Archivo:Esoteric_Taijitu.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/21/Esoteric_Taijitu.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Kenny Shen • Archivo:Esperluette.png Fuente: https://upload.wikimedia.org/wikipedia/commons/8/8f/Esperluette.png Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:For-loop-diagram.png Fuente: https://upload.wikimedia.org/wikipedia/commons/0/06/For-loop-diagram.png Licencia: CC BY-SA 2.5 Colaboradores: No machine-readable source provided. Own work assumed (based on copyright claims). Artista original: No machine-readable author provided. Faxe assumed (based on copyright claims). • Archivo:Fuente.png Fuente: https://upload.wikimedia.org/wikipedia/commons/e/e2/Fuente.png Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Garbage_collection.gif Fuente: https://upload.wikimedia.org/wikipedia/commons/3/3b/Garbage_collection.gif Licencia: Public domain Colaboradores: Trabajo propio Artista original: German • Archivo:Glider.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/4/45/Glider.svg Licencia: Public domain Colaboradores: Hacker Emblem Artista original: Eric S. Raymond
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
393
• Archivo:Gnome-globe.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/f/f3/Gnome-globe.svg Licencia: LGPL Colaboradores: http://ftp.gnome.org/pub/GNOME/sources/gnome-themes-extras/0.9/gnome-themes-extras-0.9.0.tar.gz Artista original: David Vignoni • Archivo:Grid.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/4/47/Grid.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:H96566k.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/8/8a/H96566k.jpg Licencia: Public domain Colaboradores: U.S. Naval Historical Center Online Library Photograph NH 96566-KN Artista original: Courtesy of the Naval Surface Warfare Center, Dahlgren, VA., 1988. • Archivo:HappyHackingBicicleta.png Fuente: https://upload.wikimedia.org/wikipedia/commons/5/59/HappyHackingBicicleta.png Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Omerta-ve • Archivo:Heckert_GNU_white.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/22/Heckert_GNU_white.svg Licencia: CC BY-SA 2.0 Colaboradores: gnu.org Artista original: Aurelio A. Heckert • Archivo:Historical_ampersand_evolution.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/1/1c/Historical_ampersand_ evolution.svg Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Alatius • Archivo:History.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/d/d2/History.svg Licencia: CC BY-SA 3.0 Colaboradores: http://darkobra.deviantart.com/art/Tango-History-Icon-163719409 Artista original: ~DarKobra at Deviantart • Archivo:Hola_Mundo_AppleScript.png Fuente: https://upload.wikimedia.org/wikipedia/commons/3/3b/Hola_Mundo_AppleScript. png Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Jaimemf • Archivo:Html-source-code3.png Fuente: https://upload.wikimedia.org/wikipedia/commons/3/3d/Html-source-code3.png Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Icon_tools.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/8/8e/Icon_tools.svg Licencia: CC BY 2.5 Colaboradores: File:Icon tools.png: http://www.icon-king.com/projects/nuvola/ Artista original: David Vignoni, STyx • Archivo:Indireccion.gif Fuente: https://upload.wikimedia.org/wikipedia/commons/7/7b/Indireccion.gif Licencia: Public domain Colaboradores: No machine-readable source provided. Own work assumed (based on copyright claims). Artista original: No machine-readable author provided. Glioma assumed (based on copyright claims). • Archivo:Linux_API_and_Linux_ABI.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/b/bb/Linux_API_and_Linux_ ABI.svg Licencia: CC BY-SA 4.0 Colaboradores: Trabajo propio Artista original: ScotXW • Archivo:Linux_kernel_interfaces.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/6/68/Linux_kernel_interfaces.svg Licencia: CC BY-SA 3.0 Colaboradores: Esta imagen incluye elementos que han sido tomados o adaptados de esta:
Tux-shaded.svg. Artista original: ScotXW • Archivo:Logical_connectives_Hasse_diagram.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/3e/Logical_ connectives_Hasse_diagram.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Watchduck (a.k.a. Tilman Piesk)
• Archivo:Mergefrom.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/0/0f/Mergefrom.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Metro_pd.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/a/a8/Metro_pd.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:ModeloEspiral.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/39/ModeloEspiral.svg Licencia: Public domain Colaboradores: ? Artista original: Chabacano • Archivo:Multiple_Branching.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/e/ef/Multiple_Branching.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Ben Honan • Archivo:NewTux.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/b/b0/NewTux.svg Licencia: Attribution Colaboradores: Based on original image by Larry Ewing, created using Sodipodi Artista original: gg3po (kde-look.org source) • Archivo:Nuvola_apps_edu_science.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/5/59/Nuvola_apps_edu_science.svg Licencia: LGPL Colaboradores: http://ftp.gnome.org/pub/GNOME/sources/gnome-themes-extras/0.9/gnome-themes-extras-0.9.0.tar.gz Artista original: David Vignoni / ICON KING • Archivo:Nuvola_apps_konsole.png Fuente: https://upload.wikimedia.org/wikipedia/commons/2/24/Nuvola_apps_konsole.png Licencia: LGPL Colaboradores: http://icon-king.com Artista original: David Vignoni / ICON KING • Archivo:Nuvola_devices_cdrom_unmount.png Fuente: https://upload.wikimedia.org/wikipedia/commons/9/9d/Nuvola_devices_ cdrom_unmount.png Licencia: LGPL Colaboradores: http://icon-king.com Artista original: David Vignoni / ICON KING • Archivo:Nuvola_mimetypes_template_source.png Fuente: https://upload.wikimedia.org/wikipedia/commons/1/1c/Nuvola_ mimetypes_template_source.png Licencia: LGPL Colaboradores: http://icon-king.com Artista original: David Vignoni / ICON KING • Archivo:Object-Oriented-Programming-Methods-And-Classes-with-Inheritance.png Fuente: wikipedia/commons/3/37/Object-Oriented-Programming-Methods-And-Classes-with-Inheritance.png Colaboradores: Taking a screenshot, then editing using Paint.NET Artista original: Carrot Lord
https://upload.wikimedia.org/ Licencia: CC BY-SA 3.0
• Archivo:Objetos.png Fuente: https://upload.wikimedia.org/wikipedia/commons/8/8f/Objetos.png Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:Osc.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/36/Osc.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg
394
CAPÍTULO 205. ZENPHP
• Archivo:Oscilador.png Fuente: https://upload.wikimedia.org/wikipedia/commons/5/51/Oscilador.png Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:Overview_of_the_Common_Language_Infrastructure.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/8/85/ Overview_of_the_Common_Language_Infrastructure.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Jarkko Piiroinen • Archivo:Phonebloks_open.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/6/6a/Phonebloks_open.jpg Licencia: CC BYSA 3.0 Colaboradores: Provided by email Artista original: Dave Hakkens • Archivo:Pipe_and_broken_bar.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/6/6f/Pipe_and_broken_bar.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: GJo • Archivo:PlusMinusTimesDivide.png Fuente: https://upload.wikimedia.org/wikipedia/commons/5/59/PlusMinusTimesDivide.png Licencia: Public domain Colaboradores: Trabajo propio Artista original: Theodoric Stier • Archivo:ProcesamientoDatos.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/e/e6/ProcesamientoDatos.svg Licencia: Public domain Colaboradores: • ProcesamientoDatos.png Artista original: ProcesamientoDatos.png: Moriel • Archivo:Puertas_lógicas_de_circuitos.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/5/5a/Puertas_l%C3%B3gicas_ de_circuitos.jpg Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: MONIMINO • Archivo:Pure_data_screen_capture.png Fuente: https://upload.wikimedia.org/wikipedia/commons/e/ed/Pure_data_screen_capture. png Licencia: CC-BY-SA-3.0 Colaboradores: ? Artista original: ? • Archivo:Rubber_duck_assisting_with_debugging.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/d/d5/Rubber_duck_ assisting_with_debugging.jpg Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Tom Morris • Archivo:SNL_Logo.png Fuente: https://upload.wikimedia.org/wikipedia/commons/4/4b/SNL_Logo.png Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Lacabra25 • Archivo:SO_Home_Page.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/e/e7/SO_Home_Page.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: George Edison • Archivo:Sciences_humaines.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/3f/Sciences_humaines.svg Licencia: LGPL Colaboradores: eriollsdesigns - Lanthys Icon Set (for KDE) Artista original: Adrien Facélina • Archivo:Select-object_Pure_Data.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/c/cf/Select-object_Pure_Data.svg Licencia: BSD Colaboradores: SVG converted from the PostScript output of the software Artista original: Miller-Puckette • Archivo:SierpinskiTriangle.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/8/80/SierpinskiTriangle.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: PiAndWhippedCream • Archivo:Spanish_Language_Wiki.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/2a/Spanish_Language_Wiki.svg Licencia: CC BY-SA 3.0 Colaboradores: Derived from Wiki puzzle.svg by user:Kimbar Artista original: James.mcd.nz • Archivo:Spanish_Wikiquote.SVG Fuente: https://upload.wikimedia.org/wikipedia/commons/1/13/Spanish_Wikiquote.SVG Licencia: CC BY-SA 3.0 Colaboradores: derived from Wikiquote-logo.svg Artista original: James.mcd.nz • Archivo:Sports_icon.png Fuente: https://upload.wikimedia.org/wikipedia/commons/9/95/Sports_icon.png Licencia: Public domain Colaboradores: made by myself Artista original: Pepetps • Archivo:Start_pd.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/a/a1/Start_pd.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:Steven_Levy_(1).jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/a/ac/Steven_Levy_%281%29.jpg Licencia: CC BY 2.0 Colaboradores: http://www.flickr.com/photos/joi/2939357516/sizes/o/in/photostream/ Artista original: Joi • Archivo:Subpatch.jpg Fuente: https://upload.wikimedia.org/wikipedia/commons/9/98/Subpatch.jpg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:TE_Conex_00.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/3c/TE_Conex_00.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Conex_05.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/8/81/TE_Conex_05.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Conex_09.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/a/ae/TE_Conex_09.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Conex_10.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/5/51/TE_Conex_10.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Conex_12.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/4/4b/TE_Conex_12.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Conex_14.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/9/92/TE_Conex_14.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_05.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/c/cd/TE_Interu_05.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_06.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/e/e3/TE_Interu_06.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_07.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/5/5d/TE_Interu_07.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_08.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/0/0a/TE_Interu_08.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72
205.3. ORIGEN DEL TEXTO Y LAS IMÁGENES, COLABORADORES Y LICENCIAS
395
• Archivo:TE_Interu_1A.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/6/6c/TE_Interu_1A.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_1B.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/7/72/TE_Interu_1B.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_1C.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/a/aa/TE_Interu_1C.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_2A.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/f/f1/TE_Interu_2A.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_2B.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/28/TE_Interu_2B.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_3A.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/0/02/TE_Interu_3A.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_3B.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/f/f0/TE_Interu_3B.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:TE_Interu_4B.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/a/ae/TE_Interu_4B.svg Licencia: GFDL Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:Tabla_de_verdad.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/6/60/Tabla_de_verdad.svg Licencia: CC BYSA 3.0 Colaboradores: Trabajo propio Artista original: Dnu72 • Archivo:Tecno-rueda.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/1/1f/Tecno-rueda.svg Licencia: CC BY-SA 2.5 Colaboradores:
The Tango! Desktop Project. Artista original: The people from the Tango! project. • Archivo:Test_pd.png Fuente: https://upload.wikimedia.org/wikipedia/commons/c/c2/Test_pd.png Licencia: Public domain Colaboradores: Trabajo propio Artista original: Angelalg • Archivo:Translation_arrow.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/2a/Translation_arrow.svg Licencia: CCBY-SA-3.0 Colaboradores: gráfico vectorial con Inkscape. Artista original: Jesse Burgheimer • Archivo:Two_red_dice_01.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/36/Two_red_dice_01.svg Licencia: CC0 Colaboradores: Open Clip Art Library Artista original: Stephen Silver • Archivo:USB_flash_drive.JPG Fuente: https://upload.wikimedia.org/wikipedia/commons/2/2c/USB_flash_drive.JPG Licencia: CCBY-SA-3.0 Colaboradores: ? Artista original: ? • Archivo:Venn00.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/5/5c/Venn00.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Lipedia • Archivo:Venn0001.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/9/99/Venn0001.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn0011.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/7/76/Venn0011.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn01.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/0/06/Venn01.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Lipedia • Archivo:Venn0101.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/1/10/Venn0101.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn0110.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/4/46/Venn0110.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn0111.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/30/Venn0111.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn10.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/7/73/Venn10.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Watchduck (a.k.a. Tilman Piesk) • Archivo:Venn1000.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/3c/Venn1000.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn1001.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/4/47/Venn1001.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn1011.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/1/1e/Venn1011.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn11.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/3f/Venn11.svg Licencia: Public domain Colaboradores: Trabajo propio Artista original: Lipedia • Archivo:Venn1101.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/3/35/Venn1101.svg Licencia: Public domain Colaboradores: ? Artista original: ? • Archivo:Venn1110.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/c/cb/Venn1110.svg Licencia: Public domain Colaboradores: ? Artista original: ?
396
CAPÍTULO 205. ZENPHP
• Archivo:Waterfall_model.png Fuente: https://upload.wikimedia.org/wikipedia/commons/5/51/Waterfall_model.png Licencia: CC BYSA 2.5 Colaboradores: Transferido desde en.wikipedia a Commons. Artista original: The original uploader was PaulHoadley de Wikipedia en inglés • Archivo:Wikibooks-logo.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/f/fa/Wikibooks-logo.svg Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: User:Bastique, User:Ramac et al. • Archivo:Wikinews-logo.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/2/24/Wikinews-logo.svg Licencia: CC BY-SA 3.0 Colaboradores: This is a cropped version of Image:Wikinews-logo-en.png. Artista original: Vectorized by Simon 01:05, 2 August 2006 (UTC) Updated by Time3000 17 April 2007 to use official Wikinews colours and appear correctly on dark backgrounds. Originally uploaded by Simon. • Archivo:Wikiversity-logo-Snorky.svg Fuente: https://upload.wikimedia.org/wikipedia/commons/1/1b/Wikiversity-logo-en.svg Licencia: CC BY-SA 3.0 Colaboradores: Trabajo propio Artista original: Snorky • Archivo:Wiktionary-logo-es.png Fuente: https://upload.wikimedia.org/wikipedia/commons/0/06/Wiktionary-logo-es.png Licencia: CC BY-SA 3.0 Colaboradores: originally uploaded there by author, self-made by author Artista original: es:Usuario:Pybalo
205.3.3
Licencia del contenido
• Creative Commons Attribution-Share Alike 3.0