¿Qué hicieron los programadores antes del alcance variable, donde todo es global?

40

Por lo tanto, tengo que lidiar con un lenguaje aparentemente arcaico (llamado PowerOn) donde tengo un método principal, algunos tipos de datos con los que definir variables y tengo la capacidad de tener subprocedimientos (métodos esencialmente nulos) que no devuelven un tipo ni acepta ningún argumento. El problema aquí es que TODO es global. He leído sobre este tipo de idiomas, pero la mayoría de los libros adoptan el enfoque "Ok, solíamos usar un caballo y un carruaje, pero ahora, aquí hay un automóvil, ¡así que aprendamos a trabajar en ESO!" NUNCA reviviremos esos días " . Tengo que admitir que la mente está luchando para pensar fuera de alcance y alcance .

Pues aquí estoy. Estoy tratando de descubrir la mejor manera de administrar nada más que variables globales a través de varios métodos abiertos . Sí, incluso los iteradores para forbucles tienen que definirse globalmente, lo que me encuentro reciclando en diferentes partes de mi código.

Mi pregunta: para aquellos que tienen este tipo de experiencia, ¿cómo trataron los programadores con una gran cantidad de variables en un campo de juego global? Tengo la sensación de que se convirtió en un truco mental de malabarismo, pero me interesaría saber si hay algún enfoque conocido.

Chad Harrison
fuente
71
Rezaban mucho.
Robert Harvey
15
Puedo imaginar muchos nombres de variables insanos que tienen un alcance aproximado, bob_dog_fur_colouretc. para intentar reducir la posibilidad de tocar los mismos nombres.
Latty
12
Escribieron programas que tenían un alcance más pequeño, y tienen muchos errores.
Charles E. Grant
12
@Lattyware, en realidad, en los días anteriores, estabas muy limitado en cuanto a qué tan descriptivo puedes hacer tus nombres de variables. Algunos idiomas solo permitían nombres de variables de 1 o 2 caracteres, otros permitían hasta 8. Apestaba, pero no sabíamos cuánto apestaba en ese momento. Dejó que el compilador se metiera en una cantidad limitada de memoria.
Charles E. Grant
17
inventaron mejor lenguajes de programación ...
wim

Respuestas:

44

Necesitará algún tipo de trucos de contabilidad mental (convenciones de nombres, etc.) para mantenerlo en orden. Además, documento, documento, documento. Como todas las variables son globales, tenga un solo documento con todas ellas listadas, si puede.

Intente tener una pequeña cantidad de variables que siempre use para los temporales, y recuerde que SON TEMPORALES. Al reutilizar constantemente los mismos, tendrá el hábito de realizar un seguimiento de dónde son válidos o no.

Además, desea consultar la documentación y asegurarse de saber cuánto tiempo pueden ser los nombres de las variables y cuántos caracteres son realmente únicos. No sé nada sobre PowerOn, pero si es lo suficientemente arcaico como para tener solo alcance global, entonces es posible que tenga una longitud de unicidad limitada en los identificadores.

He visto cosas antes con identificadores largos, pero cuyos identificadores solo eran únicos en los primeros 8 caracteres. Entonces podría tener RonnyRayGun y RonnyRayBlaster y en realidad son la MISMA variable. En tales casos, recomiendo mantener los nombres de las variables por debajo del límite 'único' para que sea menos probable que choque accidentalmente.

Michael Kohne
fuente
44
+1: Al escribir el ensamblaje, generalmente enfrento algunos de los mismos problemas, ya que si nombro los registros, los nombres son globales (enfrento el problema agregado de que incluso si creo más nombres, no obtengo más registros, pero eso es no relevante aquí). Tener algunos registros dedicados a valores temporales realmente ayuda a mantener baja la cantidad de variables creadas, lo que facilita mantener todo en su cabeza. Documentar qué variables usará cada función (la más importante es cuál modificará) ayuda a obtener la imagen global correcta.
Leo
53

Diccionario de datos.

En un repositorio central (generalmente la oficina del programador principal), había una carpeta de hojas sueltas, que contenía una página para cada variable global. La página dio el nombre, su definición, su propósito y qué rutinas lo configuraron o usaron.

Los primeros sistemas integrados con RAM microscópica tenían un problema similar y una solución similar. El programador principal mantuvo el mapa de RAM maestro, hasta los bytes individuales, mostrando qué RAM fue utilizada por qué módulos para qué fines. Los programadores que necesitaban una asignación de RAM dedicada fueron al programador principal, quien, después de discutir el asunto, hizo la entrada apropiada en el cuaderno y le dio su RAM al chico. (No querías estar en el lugar del programador que tomó un byte RAM sin borrarlo con el programador principal. Confía en mí en esto).

Este problema también apareció cuando los programadores tuvieron que construir sistemas grandes en las primeras versiones de BASIC. Se me presentó personalmente mientras usaba un administrador de "base de datos" muy primitivo llamado Info (producto de Henco, Inc. de Nueva Jersey - ¡ESPERO, hace tiempo que desapareció!). Ambos idiomas tenían un vocabulario de nombres variables muy limitado.

John R. Strohm
fuente
Estoy en una situación muy similar, ya que es más un administrador de "base de datos" donde el lenguaje interactúa directamente con la base de datos, junto con algunas funciones como la programación. Esto es muy útil
Chad Harrison
1
Eso me recuerda a cuando estaba aprendiendo BASIC y las variables no podían tener nombres de más de dos caracteres, y hacer un seguimiento de ellas en un programa considerable ...
Kevin Rubin
@KevinRubin, no me lo recuerdes. Ah, siento mucho dolor, como solía decir Bill Clinton ...
John R. Strohm
8

El auge de los lenguajes de programación con alcance de bloque coincidió con la llegada de máquinas más grandes y rápidas, y eso no es una coincidencia. Las primeras computadoras tenían RAM medida en MB, kB o incluso en bytes; simplemente no había oportunidad de tener tantas variables que se confundirían cuando el programa creciera, porque los programas nunca llegaron a ser tan grandes . Los avances en los lenguajes de programación generalmente se hicieron cuando las personas reconocieron que sus viejos hábitos de programación no aumentaron cuando la arena se hizo mucho más grande; El alcance del bloque se inventó como un mecanismo de defensa para los programadores contra su propia memoria limitada.

La informática también era una actividad mucho más enrarecida y exótica cuando los ordenadores eran increíblemente caros, y puede ser que solo individuos particularmente matemáticos e ingeniosos se convirtieron en programadores (aunque tales comparaciones no son prácticas para probar, y ciertamente políticamente incendiarias). En los primeros días, el software generalmente se enviaba gratis con una computadora para convencer a la gente de comprarlo en primer lugar; Al principio, la idea de que los usuarios institucionales intentarían escribir sus propios programas era desconocida.

Kilian Foth
fuente
¿Qué tan atrás estás hablando? Personalmente, he visto un par de minicomputadoras de principios de los 80 que tenían un 'conjunto de datos' (es decir, un listado de variables globales) que contenía más de 60 mil etiquetas.
Evan Plaice
-1: En los primeros días, no solo pagaba un alquiler mensual para tener acceso a una computadora, sino que pagaba los ciclos de CPU y la memoria utilizada por su programa. El software estaba lejos de ser gratuito, y ejecutar el software aún menos.
mattnz
1
@mattnz: Hace algún tiempo, el software a menudo se incluía, lo que es algo diferente de lo gratuito. Por lo general, una empresa que necesitaba una computadora compraría o alquilaría una, y no pagaría por el funcionamiento de la máquina, aunque a los usuarios individuales a menudo se les cobraría por eso. También estoy desconcertado por la afirmación del OP de que no se esperaba que las personas escribieran su propio software, porque ciertamente esa no era mi experiencia. Si pudiera pagar una computadora, podría pagar un equipo de desarrollo, y realmente no había mucho software enlatado.
David Thornley
Los problemas con la programación de un solo alcance se reconocieron bastante temprano, mucho antes de que las computadoras tuvieran múltiples megabytes de memoria. ALGOL, el primer idioma con alcance léxico, apareció en 1958.
Kevin Cline
4

Dios mío, eso fue hace muchos años (recuerdos burbujeantes :)).

No sé el idioma al que te refieres, pero en general nos adaptamos a lo que teníamos. No fue realmente un gran problema. Necesitaba prestar más atención a los nombres de variables que a menudo contenían (en forma abreviada, en esos días, el número de bytes era precioso) referencia a sub o función, como mIORead1si tuviera un controlador para leer datos de un archivo 1, o si tuviera varios contrarrestar variables como i, j, k, etc., que según su propio sistema usted sabía para qué servían, si podían reutilizarse, etc. Fue más duro (sin cascos ni guantes en ese entonces) :-)

epistemex
fuente
3

Esto es bastante similar a la programación de PLC, aunque los PLC modernos ahora le permiten tener "etiquetas" (también conocidas como variables) que son locales para un programa. Aún así, mucha gente simplemente programa usando todas las etiquetas globales.

Descubrí que si vas a hacer eso, debes usar una convención de nomenclatura estructurada. Por ejemplo: Motor1_DriveContactor_Run. Si su idioma pasa a estructuras de soporte (a veces conocidos como tipos definidos por el usuario), entonces también puede usarlos para crear una jerarquía de datos estructurados, tales como: Motor[1].DriveContactor.Run.

Eso mantiene todo organizado, y generalmente el intellisense es lo suficientemente decente como para ayudarlo.

Scott Whitlock
fuente
2

De hecho, aprendí a programar en un lenguaje llamado Authorware, donde todo era global. Afortunadamente, tenía matrices y, después de cierto punto, algo llamado Listas, que eran similares a los objetos genéricos.

Un programa Authorware en realidad tenía una estructura física (Authorware se basaba en una metáfora de diagrama de flujo), y su lenguaje de secuencias de comandos se basaba en Pascal de estilo antiguo. Lo que hicimos fue relacionar la estructura física con los índices en una matriz, y a menudo los índices de la matriz contendrían listas que trataríamos como un objeto local para la pieza física que estábamos usando.

Authorware fue diseñado para eLearning, por lo que uno de los íconos que teníamos era una página. Las páginas se adjuntarían a un Marco. Entonces, para la Página 1, buscaríamos en algunos Array en el índice 1 (Authorware estaba indexado en 1) y extraeríamos los datos para esa página, que se almacenaría en una Lista que actuaría como un pseudoobjeto. La página tendría entonces una lógica que extraería las "propiedades" del objeto por su nombre. Si no tiene nada parecido a Objetos, pero tiene Arreglos, simplemente puede tener una convención de qué datos van a dónde.

Realmente no es tan diferente de lo que hacemos cuando recuperamos datos de una base de datos y realizamos una inyección de dependencia, excepto que todo es realmente global, y simplemente está eligiendo poner todo en pequeñas cajas y solo mirar las que usted ' Re preocupado en este momento.

Dependiendo de lo que intente hacer y de lo que admita su idioma, esto podría ayudarlo a dividir las cosas en partes más manejables.

Amy Blankenship
fuente
También trabajé con Macromedia Authorware, @ amy-blankenship. No recuerdo qué versión era la última vez que trabajé con él, tal vez 3. ¿Fue reemplazado por Flash / Showckwave o todavía existe?
Tulains Córdova
Eran cosas diferentes. Macromedia causó mucha confusión en la versión 5 (de ambas) al llamar a todo Shockwave, incluido Director, cuando se empaquetó para la web. Adobe suspendió el software de autor después de la adquisición, Flash todavía está funcionando.
Amy Blankenship
1

Cuando estaba en la universidad, nos enseñaron extensamente sobre "El problema de la variable global": una colección de errores y problemas de mantenimiento del código causados ​​por muchas variables globales.

Algunas variables son más peligrosas que otras.

Seguro : Variables que no afectan el flujo de control, por ejemplo, Apellido

Peligroso : cualquier variable que afecte el flujo de control del programa, por ejemplo, DeliveryStatus

Lo más peligroso primero:

  • Estado compuesto (modo y submodo)
  • Valores compuestos (total, subtotal)
  • Estado único (modo)
  • Valores individuales (recuento)

Para evitar el "problema de la variable global" necesita

  • Documente cada variable y función.
  • Mantenga las variables relacionadas muy juntas (con el código que las usa) en la misma sección del código fuente.
  • Oculta las variables "peligrosas" para que otros programadores no sepan de su existencia. Evite usarlos directamente, especialmente en otras secciones del código.
  • Proporcione funciones que lean / escriban variables peligrosas (para que otros programadores no lo necesiten).

Para estructurar su código , cuando no haya una estructura disponible en el idioma, use comentarios y convenciones de nomenclatura:

/* --------------------------- Program mode ------------------------ */

var Mode_Standard = 1;      // Normal operation (SubMode unused)
var Mode_Backup   = 2;      // Backup mode      (SubMode is backup device)

var BackupMode_Disk = 1;    // SubMode: Backup to disk
var BackupMode_Tape = 2;    // SubMode: Backup to tape

var MainMode = Mode_Standard;
var SubMode = 0;

function Mode_SetBackup(backupMode)
{
    MainMode = Mode_Backup;
    SubMode = backupMode;
}

function Mode_SetStandardMode()
{
    MainMode = Mode_Standard;
    SubMode  = 0;
}

function Mode_GetBackupMode()
{
    if (MainMode != Mode_Backup)
        return 0;

    return SubMode;
}

/* --------------------------- Stock Control ------------------------ */

var Stock_Total =  123;      // Total stock       (including RingFenced)
var Stock_RingFenced = 22;   // Ring-fenced stock (always less than total)

// Adds further ring-fenced stock 
function Stock_AddRingFenced(quantity)
{
    Stock_Total      += quantity;
    Stock_RingFenced += quantity;
}

/* ------------------------- Customers ----------------------- */

var Customer_FirstName = "Tony";
var Customer_LastName  = "Stark";

fuente
0

No sé cómo lo hicieron.

Pero creo que los lenguajes OOP modernos tenían un problema muy similar con respecto a la colisión de nombres .

La solución es adoptar un espacio de nombres . Es un concepto abstracto, pero ampliamente adoptado por varias implementaciones (paquetes Java, espacio de nombres .NET, módulos Python).

Si el idioma que está utilizando no tiene una limitación demasiado estrecha sobre la longitud de los nombres, puede aplicar el espacio de nombres a un buen nombre de variables.

Entonces el nombre de la variable también representa el alcance de la variable.

Intente definir un patrón de nomenclatura como este: order_detail_product_code, order_detail_product_unit_price. O para los contadores temporales o permutas: tmp_i, tmp_swap.

Alberto De Caro
fuente
0

En los idiomas donde todas las variables son globales (he usado un par) solíamos usar una convención de nomenclatura variable. Por ejemplo: si realmente quisiera usar una variable como global, podría usar el prefijo "m_" o "_". Por supuesto, esto todavía depende de que los desarrolladores tengan esta disciplina.

bytedev
fuente