2.2.1 El modelo de nomenclatura
Es útil tener un modelo de cómo se asocian los nombres con objetos específicos. Un diseñador de sistemas crea un esquema de nomenclatura, que consta de tres elementos. El primer elemento es un espacio de nombres, que comprende un alfabeto de símbolos junto con reglas sintácticas que especifican qué nombres son aceptables. El segundo elemento es un algoritmo de asignación de nombres, que asocia algunos (no necesariamente todos) nombres del espacio de nombres con algunos (de nuevo, no necesariamente todos) valores en un universo de valores, que es el tercer y último elemento del esquema de nombres. Un valor puede ser un objeto, o puede ser otro nombre del espacio de nombres original o de un espacio de nombres diferente. Un mapeo de nombre a valor es un ejemplo de vinculación, y cuando tal mapeo existe, se dice que el nombre está vinculado al valor. La figura 2.10 lo ilustra.
En la mayoría de los sistemas, normalmente varios esquemas de nomenclatura distintos están en funcionamiento simultáneamente. Por ejemplo, un sistema puede utilizar un esquema de nomenclatura para los nombres de los buzones de correo electrónico, un segundo esquema de nomenclatura para los hosts de Internet, un tercero para los archivos y un cuarto para las direcciones de memoria virtual. Cuando el intérprete de un programa encuentra un nombre, debe saber qué esquema de nomenclatura debe invocar. El entorno que rodea el uso del nombre suele proporcionar suficiente información para identificar el esquema de nomenclatura. Por ejemplo, en un programa de aplicación, el autor de ese programa sabe que el programa debe esperar que los nombres de archivo sean interpretados sólo por el sistema de archivos y que los nombres de host de Internet sean interpretados sólo por algún servicio de red.
El intérprete que encuentra el nombre ejecuta el algoritmo de asignación de nombres del esquema de nombres apropiado. El algoritmo de mapeo de nombres resuelve el nombre, lo que significa que descubre y devuelve el valor asociado (por esta razón, el algoritmo de mapeo de nombres también se llama resolver). El algoritmo de asignación de nombres suele estar controlado por un parámetro adicional, conocido como contexto. Para un esquema de nomenclatura dado, puede haber muchos contextos diferentes, y un mismo nombre del espacio de nombres puede asignarse a diferentes valores cuando el resolvedor utiliza diferentes contextos. Por ejemplo, en el discurso ordinario, cuando una persona se refiere a los nombres “tú”, “aquí” o “Alicia”, el significado de cada uno de esos nombres depende del contexto en el que la persona lo pronuncia. En cambio, algunos esquemas de nomenclatura sólo tienen un contexto. Estos esquemas de nomenclatura proporcionan lo que se denomina espacios de nombres universales, y tienen la agradable propiedad de que un nombre siempre tiene el mismo significado dentro de ese esquema de nomenclatura, independientemente de quién lo utilice. Por ejemplo, en Estados Unidos, los números de la seguridad social, que identifican las cuentas de pensiones e impuestos del gobierno, constituyen un espacio de nombres universal. Cuando hay más de un contexto, el intérprete puede indicar al resolvedor cuál debe utilizar o el resolvedor puede utilizar un contexto por defecto.
Podemos resumir el modelo de nomenclatura definiendo la siguiente operación conceptual sobre los nombres:
valor ← resolver (nombre, contexto)
Cuando un intérprete encuentra un nombre en un objeto, primero averigua de qué esquema de nomenclatura se trata y, por tanto, qué versión de resolver debe invocar. Entonces identifica un contexto apropiado, resuelve el nombre en ese contexto, y reemplaza el nombre con el valor resuelto mientras continúa la interpretación. La variable context indica a resolve qué contexto debe utilizar. Esa variable contiene un nombre conocido como referencia de contexto.
En un procesador, los números de registro son nombres. En un procesador simple, el conjunto de nombres de registro, y los registros a los que esos nombres están ligados, son ambos fijos en el momento del diseño. En la mayoría de los otros sistemas que utilizan nombres (incluyendo el esquema de nomenclatura de registros de algunos procesadores de alto rendimiento), es posible crear nuevos enlaces y eliminar los antiguos, enumerar el espacio de nombres para obtener una lista de enlaces existentes, y comparar dos nombres. Para ello, definimos otras cuatro operaciones conceptuales:
estado ← bind (nombre, valor, contexto)
estado ← unbind (nombre, contexto)
lista ← enumerate (contexto)
resultado ← compare (nombre1, nombre2)
La primera operación cambia el contexto añadiendo un nuevo binding; el resultado del estado informa si el cambio tuvo éxito o no (puede fallar si el nombre propuesto viola las reglas sintácticas del espacio de nombres). Después de una llamada exitosa a bind, resolve devolverá el nuevo valor de name.*La segunda operación, unbind, elimina un enlace existente del contexto, con el estado de nuevo informando de éxito o fracaso (tal vez porque no había tal enlace existente). Después de una llamada exitosa a unbind, resolve ya no devolverá ese valor para name. Las operaciones bind y unbind permiten el uso de nombres para hacer conexiones entre objetos y cambiar esas conexiones más tarde. Un diseñador de un objeto puede, utilizando un nombre para referirse a un objeto componente, elegir el objeto al que está vinculado ese nombre, ya sea en ese momento o en un momento posterior, invocando bind, y eliminar una vinculación que ya no es apropiada invocando unbind, todo ello sin modificar el objeto que utiliza el nombre. Esta capacidad de retrasar y cambiar los enlaces es una poderosa herramienta utilizada en el diseño de casi todos los sistemas. Algunas implementaciones de nombres proporcionan una operación de enumeración, que devuelve una lista de todos los nombres que se pueden resolver en el contexto. Algunas implementaciones de enumerar también pueden devolver una lista de todos los valores actualmente vinculados en el contexto. Por último, la operación comparar informa (verdadero o falso) si nombre1 es o no el mismo que nombre2. El significado de “igual” es una cuestión interesante que se aborda en la Sección 2.2.5, y puede requerir el suministro de argumentos de contexto adicionales.
Diferentes esquemas de nomenclatura tienen diferentes reglas sobre la singularidad de las asignaciones de nombre a valor. Algunos esquemas de nomenclatura tienen una regla según la cual un nombre debe corresponder exactamente a un valor en un contexto dado y un valor debe tener sólo un nombre, mientras que en otros esquemas de nomenclatura un nombre puede corresponder a varios valores, o un valor puede tener varios nombres, incluso en el mismo contexto. Otro tipo de regla de unicidad es la de un espacio de nombres con un identificador único, que proporciona un conjunto de nombres que nunca se reutilizarán durante la vida del espacio de nombres y que, una vez vinculados, siempre permanecerán vinculados al mismo valor. Se dice que un nombre de este tipo tiene una vinculación estable. Si un espacio de nombres con identificadores únicos también tiene la regla de que un valor sólo puede tener un nombre, los nombres únicos resultan útiles para hacer un seguimiento de los objetos durante un largo periodo de tiempo, para comparar las referencias para ver si son del mismo objeto y para la coordinación de múltiples copias en sistemas donde los objetos se replican por rendimiento o fiabilidad. Por ejemplo, el número de cuenta del cliente de la mayoría de los sistemas de facturación constituye un espacio de nombres identificador único. El número de cuenta se referirá siempre a la misma cuenta de cliente mientras ésta exista, a pesar de los cambios en la dirección, el número de teléfono o incluso el nombre personal del cliente. Si se elimina la cuenta de un cliente, el número de cuenta de ese cliente no se reutilizará algún día para la cuenta de otro cliente. Los campos con nombre dentro de la cuenta, como el saldo adeudado, pueden cambiar de vez en cuando, pero el enlace entre el número de cuenta del cliente y la cuenta en sí es estable.
El algoritmo de asignación de nombres más un contexto único no necesariamente asignan todos los nombres del espacio de nombres a los valores. Por lo tanto, un posible resultado de realizar la resolución puede ser un resultado no encontrado, que la resolución puede comunicar a la persona que llama, ya sea como un valor reservado o como una excepción. Por otro lado, si el esquema de nomenclatura permite que un nombre se asigne a varios valores, un posible resultado puede ser una lista de valores. En ese caso, la operación de desvinculación puede requerir un argumento adicional que especifique qué valor debe desvincularse. Por último, algunos esquemas de nomenclatura proporcionan una búsqueda inversa, lo que significa que un llamador puede suministrar un valor como argumento al algoritmo de asignación de nombres, y averiguar qué nombre o nombres están vinculados a ese valor.
La figura 2.10 ilustra el modelo de nomenclatura, mostrando un espacio de nombres, el correspondiente universo de valores, un algoritmo de asignación de nombres, y un contexto que controla el algoritmo de asignación de nombres.
En la práctica, uno encuentra tres algoritmos de mapeo de nombres frecuentemente utilizados:
Búsqueda de tablas
■
Búsqueda recursiva
■
Búsqueda múltiple
La implementación más común de un contexto es una tabla de pares {nombre, valor}. Cuando la implementación de un contexto es una tabla, el algoritmo de asignación de nombres es sólo una búsqueda del nombre en esa tabla. La tabla en sí misma puede ser compleja, implicando hashing o B-trees, pero la idea básica sigue siendo la misma. Vincular un nuevo nombre a un valor consiste en añadir ese par {nombre, valor} a la tabla. La figura 2.11 ilustra esta implementación común del modelo de nomenclatura. Hay una tabla de este tipo para cada contexto, y diferentes contextos pueden contener diferentes enlaces para el mismo nombre.
Los ejemplos del mundo real tanto del modelo general de nomenclatura como de la implementación de la búsqueda de tablas abundan:
Una guía telefónica es un contexto de búsqueda de tablas que vincula nombres de personas y organizaciones a números de teléfono. Al igual que en el ejemplo de la red de comunicación de datos, los números de teléfono son en sí mismos nombres que la compañía telefónica resuelve en apariencias de líneas físicas, utilizando un algoritmo de mapeo de nombres que implica códigos de área, centrales y conmutadores físicos. Las guías telefónicas de Boston y de San Francisco son dos contextos del mismo esquema de nomenclatura; cualquier nombre particular puede aparecer en ambas guías telefónicas, pero si es así, probablemente esté vinculado a diferentes números de teléfono.
Los pequeños enteros nombran los registros de un procesador. El valor es el propio registro, y la asignación de nombre a valor se realiza mediante cableado.
Las celdas de memoria se nombran de forma similar con los números llamados direcciones, y la asignación de nombre a valor se realiza de nuevo mediante cableado. El capítulo 5 describe un mecanismo de renombramiento de direcciones conocido como memoria virtual, que vincula bloques de direcciones virtuales a bloques de celdas de memoria contiguas. Cuando un sistema implementa múltiples memorias virtuales, cada memoria virtual es un contexto distinto; una dirección dada puede referirse a una celda de memoria diferente en cada memoria virtual. Las celdas de memoria también pueden ser compartidas entre las memorias virtuales, en cuyo caso la misma celda de memoria puede tener las mismas (o diferentes) direcciones en diferentes memorias virtuales, según lo determinado por los enlaces.
Un típico sistema de archivos de computadora utiliza varias capas de nombres y contextos: los sectores de disco, las particiones de disco, los archivos y los directorios son todos objetos con nombre. Los directorios son ejemplos de contextos de búsqueda de tablas. Un nombre de archivo concreto puede aparecer en varios directorios diferentes, vinculados al mismo o a diferentes archivos. En la sección 2.5 se presenta un caso de estudio de la nomenclatura en el sistema de archivos unix.
Los ordenadores se conectan a las redes de comunicación de datos en lugares conocidos como puntos de conexión de red. Los puntos de conexión a la red se suelen nombrar con dos esquemas de nomenclatura distintos. El primero, utilizado dentro de la red, implica un espacio de nombres que consiste en números en un campo de longitud fija. Estos nombres están vinculados, a veces de forma permanente y a veces sólo brevemente, a puntos físicos de entrada y salida de la red. Un segundo esquema de nombres, utilizado por los clientes de la red, asigna un espacio de nombres universal de cadenas de caracteres más fácil de usar a los nombres del primer espacio de nombres. La sección 4.4 es un estudio de caso del Sistema de Nombres de Dominio, que proporciona una nomenclatura de puntos de conexión de fácil uso para Internet.
Un programador identifica las variables de procedimiento mediante nombres, y cada activación del procedimiento proporciona un contexto distinto en el que se resuelven la mayoría de dichos nombres. Algunos nombres, identificados como “estáticos” o “globales”, pueden en cambio resolverse en un contexto compartido entre activaciones o entre diferentes procedimientos. Cuando se compila un procedimiento, algunos de los nombres originales de las variables que son fáciles de usar pueden ser reemplazados por identificadores enteros que son más convenientes para que una máquina los manipule, pero el modelo de nomenclatura sigue siendo válido.
Un Localizador Uniforme de Recursos (URL) de la World Wide Web es mapeado a una página web específica por un algoritmo relativamente complicado que rompe la URL en varias partes constituyentes y resuelve las partes utilizando diferentes esquemas de nomenclatura; el resultado finalmente identifica una página web en particular. La sección 3.2 es un estudio de caso de este esquema de nomenclatura.
Un sistema de facturación de clientes suele mantener al menos dos tipos de nombres para cada cuenta de cliente. El número de cuenta nombra a la cuenta en un espacio de nombre de identificador único, pero también hay un espacio de nombre distinto de nombres personales que también se puede utilizar para identificar la cuenta. Ambos nombres suelen ser asignados a los registros de la cuenta por un sistema de base de datos, de modo que las cuentas pueden ser recuperadas por el número de cuenta o por el nombre personal.
Estos ejemplos también ponen de relieve una distinción entre “nombrar” y vincular. Algunos contextos, pero no todos, “nombran” cosas, en el sentido de que asignan un nombre a un objeto que comúnmente se considera que tiene ese nombre. Así, la guía telefónica no “nombra” ni a las personas ni a las líneas telefónicas. En otro lugar hay contextos que vinculan los nombres a las personas y que vinculan los números de teléfono a teléfonos físicos concretos. La guía telefónica vincula los nombres de las personas a los nombres de los teléfonos.