En informática , el alcance ( Scope English) de un identificador es el alcance en el que este identificador está vinculado. Este ámbito puede ser léxico o dinámico.
Un alcance léxico está definido por una parte del código fuente. Dentro de esta porción, el identificador tiene un solo enlace.
Un identificador global está vinculado a lo largo del código fuente (a veces solo después de su declaración o definición). En muchos lenguajes de programación, todas las funciones tienen un alcance global (ejemplo: C). Cuando un identificador con alcance global designa una variable, hablamos de variable global . Por lo general, se utilizan para almacenar datos de carga útil en varias ubicaciones del programa, siendo un caso especial los bloqueos.
Un identificador con alcance local se vincula solo dentro de una construcción sintáctica del lenguaje, generalmente aquella en la que se declara. Cuando un identificador con alcance local designa una variable, hablamos de una variable local . Además, en la mayoría de lenguajes, un identificador con alcance local oculta cualquier posible identificador del mismo nombre, pero de mayor alcance. Declarar el mismo identificador dos veces en el mismo ámbito puede considerarse un error o una re-declaración, según el idioma y el contexto.
Ejemplo en esquema :
REPL> (define foo 42) ; la variable globale foo contient la valeur 42 REPL> foo ; accès à la variable foo 42 REPL> (let ((foo -1)) ; ouverture d'une forme let où est définie une variable locale foo qui contient la valeur -1 foo) ; fin de la forme let, qui renvoie la valeur de la variable foo -1 REPL> foo ; accès à la variable foo 42El principio de alcance léxico se introdujo por primera vez en LISP 1.5. Se agregó a Algol 60, cuyos descendientes son típicamente solo pentagramas léxicos ( C , Pascal ). Scheme , que fue un promotor, es un dialecto Lisp que también tiene solo alcances léxicos. Common Lisp tiene ámbitos léxicos, importados de Scheme, y ámbitos dinámicos.
Un alcance dinámico se define en un alcance dinámico delimitado por un punto de entrada y un punto de salida durante el tiempo de ejecución. La vinculación de un identificador de ámbito dinámico oculta una vinculación anterior dentro del ámbito dinámico de la forma que crea esta nueva vinculación. Por lo tanto, una variable con alcance dinámico, llamada variable dinámica, se utiliza para propagar una modificación a un entorno en la pila de llamadas.
Ejemplo en Common Lisp:
CL-USER> (defvar *foo* 42) ; définition d'une variable à portée dynamique *foo* contenant la valeur 42 *FOO* CL-USER> (defun return-foo () ; définition d'une fonction renvoyant la valeur de *foo* *foo*) RETURN-FOO CL-USER> (return-foo) ; accès à la variable *foo* 42 CL-USER> (let ((*foo* -1)) ; ouverture d'une forme let re-liant *foo* à la valeur -1, (return-foo)) ; dont l'exécution constitue l'étendue dynamique de cette liaison -1 CL-USER> (return-foo) ; accès à la variable *foo* 42Y el mismo ejemplo en Scheme, sin alcance dinámico:
REPL> (define foo 42) REPL> (define (return-foo) foo) REPL> (return-foo) 42 REPL> (let ((foo -1)) (return-foo)) ; ici l'exécution de return-foo accèdera à la variable foo dans sa portée lexicale 42 REPL> (return-foo) 42Los lenguajes no funcionales también admiten el alcance dinámico, en particular los derivados de Forth (un lenguaje de pila), incluido PostScript . El método empleado es utilizar una segunda pila (independiente de la pila de parámetros o de la pila de retorno de funciones, siendo las dos pilas comunes a menudo) que contiene para cada posición apilada una referencia a un diccionario de variables. Si no se puede encontrar una variable en el primer diccionario al que se hace referencia en la parte superior de la pila, la búsqueda continúa en los diccionarios inferiores de la pila.
Cada diccionario de variables generalmente se modela mediante una tabla hash para obtener un tiempo de búsqueda óptimo dentro de cada diccionario (el tiempo de búsqueda se vuelve casi independiente del número de variables almacenadas en el diccionario). Para ello, el nombre de la variable se convierte en una clave de búsqueda numérica, todos los bits de información de los cuales se equidistribuyen mediante una función hash; esta clave numérica luego se reduce al intervalo del tamaño de la tabla hash, para obtener la ubicación donde se almacena la variable. Dado que las colisiones son posibles, la tabla hash contiene en cada posición utilizada una entrada para el nombre de la variable (para poder verificar por igualdad que la variable correcta está almacenada allí). Luego, existen diferentes estrategias para resolver la colisión de variables que comparten la misma clave calculada:
PostScript y Forth son únicos en el sentido de que todos los diccionarios (a los que se hace referencia en la pila de alcance) son en sí mismos variables que se pueden nombrar, que se pueden usar directamente o buscar por su nombre, también se buscan en la pila de personal, antes de obtener la referencia, que luego se pueden apilar en la pila de personal. Por lo tanto, no hay un nombre de variable reservado en estos lenguajes, todos los nombres de objeto predefinidos se referencian de hecho en una pila de alcance que nunca está vacía, pero al menos hace referencia a un primer diccionario de alcance del "sistema" que contiene su propia referencia y su propio nombre. Además, es posible eliminar selectivamente ciertas variables de todas las resoluciones de alcance posteriores, eliminando su referencia en uno de los diccionarios a los que se hace referencia en la pila de alcance (esto hace posible ocultar ciertas variables de un nivel de alcance dado para el uso posterior de la variable definido en un nivel de alcance inferior). También puede reemplazar una de las entradas por otra (la variable definida en el alcance inicial ya no es accesible allí pero será reemplazada por otra con el mismo nombre, pero posiblemente de un tipo diferente, pudiendo entonces hacer completamente inaccesible una variable de sistema que queremos ocultar).
Namescope no está reservado solo para idiomas para almacenar y hacer referencia a valores. También se encuentra en la mayoría de los sistemas de archivos jerárquicos para presentar diferentes vistas de nombres de archivos accesibles. Solo los sistemas de archivos más antiguos y muy simples, con solo un diccionario de nombres de archivo para todo el sistema (y todos los procesos alojados por el sistema), admiten solo un ámbito para los nombres de archivo (sin embargo, puede usarlos tal cual para ampliarlos, almacenando diccionarios de nombres como un archivo).