Que faisaient les programmeurs avant la portée variable, où tout est global?

40

Donc, je dois faire face à un langage apparemment archiac (appelé PowerOn) où j'ai une méthode principale, quelques types de données pour définir des variables, et qui a la possibilité d'avoir des sous-procédures (essentiellement des méthodes void) qui ne retournent pas de type ni accepte aucun argument. Le problème ici est que TOUT est global. J'ai lu ces types de langues, mais la plupart des livres adoptent l'approche "Ok, on utilisait un cheval et un chariot, mais maintenant, voici une voiture alors apprenons à travailler sur CELA!" Nous ne reverrons JAMAIS ces jours " . Je dois admettre que l'esprit a du mal à sortir des sentiers battus .

Bien je suis ici. J'essaie de comprendre comment gérer au mieux rien que des variables globales à travers plusieurs méthodes ouvertes . Oui, même les itérateurs de forboucles doivent être définis globalement, ce que je me retrouve à recycler dans différentes parties de mon code.

Ma question: pour ceux qui ont une telle expérience, comment les programmeurs ont-ils géré une grande quantité de variables sur un terrain de jeu mondial? J'ai le sentiment que cela est devenu une astuce mentale, mais j'aimerais savoir s'il y a des approches connues.

Chad Harrison
la source
71
Ils ont beaucoup prié.
Robert Harvey
15
Je peux imaginer beaucoup de noms de variables insensés qui ont une portée approximative - bob_dog_fur_colouretc.
Latty
12
Ils ont écrit des programmes de plus petite envergure, et ils ont beaucoup de bugs.
Charles E. Grant
12
@Lattyware, en fait, à l'époque des anciens, vous étiez très limité quant à la manière dont vous pouviez décrire les noms de variables. Certaines langues n'autorisaient que des noms de variable à 1 ou 2 caractères, d'autres vous en autorisaient jusqu'à 8. C'est nul, mais nous ne savions pas à quel point c'était variable à l'époque. Cela permettait au compilateur de puiser dans une quantité limitée de mémoire.
Charles E. Grant
17
ils ont inventé de meilleurs langages de programmation ...
wim

Réponses:

44

Vous aurez besoin de quelques astuces de tenue de livres mentales (conventions de nommage, etc.) afin de les garder droites. Aussi, document, document, document. Étant donné que toutes les variables sont globales, il est préférable d’avoir un seul document répertoriant toutes les variables.

Essayez d’avoir un petit nombre de variables que vous utilisez toujours pour les temporaires, et rappelez-vous qu’elles sont temporaires. En réutilisant constamment les mêmes, vous aurez l’habitude de garder une trace de leur validité ou non.

En outre, vous souhaitez consulter la documentation et vous assurer de savoir combien de temps les noms de variables peuvent être longs et combien de caractères sont réellement uniques. Je ne connais RIEN de PowerOn, mais s’il est assez archaïque de n’avoir qu’une portée globale, il est possible qu’il ait une longueur d’unicité limitée sur les identificateurs.

J'ai déjà vu des choses avec de longs identifiants, mais dont les identifiants n'étaient uniques que dans les 8 premiers caractères. Donc, vous pourriez avoir RonnyRayGun et RonnyRayBlaster et ils sont en fait la variable SAME. Dans de tels cas, je vous recommande de conserver les noms de variable sous la limite "unique" afin d'éviter les risques de collision accidentelle.

Michael Kohne
la source
4
+1: lors de la rédaction de l'assembly, je rencontre généralement les mêmes problèmes: si je nomme les registres, les noms sont globaux (je suis confronté au problème suivant: même si je crée plus de noms, je n'ai pas plus de registres, mais pas pertinent ici). Avoir quelques registres dédiés aux valeurs temporaires aide vraiment à réduire le nombre de variables créées, ce qui permet de tout garder plus facilement dans la tête. La documentation des variables que chaque fonction utilisera (la plus importante est celle qu’elle modifiera) permet d’obtenir une image globale juste.
Leo
53

Dictionnaire de données.

Dans un référentiel central (généralement le bureau du programmeur principal), il y avait un classeur à feuilles mobiles, qui contenait une page pour chaque variable globale. La page a donné le nom, sa définition, son but et les routines définies ou utilisées.

Les premiers systèmes embarqués avec RAM microscopique avaient un problème similaire et une solution similaire. Le programmeur principal a mis à jour la mappe de RAM principale, jusqu'aux octets individuels, indiquant quelle RAM était utilisée, par quels modules et à quelles fins. Les programmeurs qui avaient besoin d’une allocation de RAM dédiée se sont adressés au programmeur principal, qui, après avoir discuté de la question, a procédé à la saisie appropriée dans le cahier et a donné au gars sa RAM. (Vous ne voulez pas être à la place du programmeur qui a pris un octet de RAM sans le supprimer avec le programmeur principal. Faites-moi confiance à ce sujet.)

Ce problème est également apparu lorsque les programmeurs devaient créer de grands systèmes dans les premières versions de BASIC. Il s’est révélé personnellement pour moi en utilisant un gestionnaire de base de données très primitif appelé Info (produit de Henco, Inc. du New Jersey - HOPEFULLY, disparu depuis longtemps!). Le vocabulaire des noms de variables était très limité dans les deux langues.

John R. Strohm
la source
Je suis dans une situation très similaire, il s’agit plus d’un gestionnaire de "base de données" où le langage s’interface directement avec la base de données, ainsi que certaines fonctionnalités de programmation. Ceci est très utile
Chad Harrison
1
Cela me rappelle l'époque où j'apprenais BASIC et que les variables ne pouvaient pas avoir des noms plus longs que deux caractères, et les garder dans un programme
Kevin Rubin
@ KevinRubin, ne me rappelle pas. Ah, ressentez la douleur, comme disait Bill Clinton ...
John R. Strohm
8

L'essor des langages de programmation avec portée de bloc a coïncidé avec l'avènement de machines plus grandes et plus rapides, et ce n'est pas un hasard. Les premiers ordinateurs avaient une RAM mesurée en Mo, Ko ou même en octets; il n’était tout simplement pas possible d’ avoir autant de variables qu’elles seraient confondues lorsque le programme deviendrait grand, car les programmes n’étaient jamais aussi grands . Les progrès dans les langages de programmation ont généralement été réalisés lorsque les gens ont compris que leurs anciennes habitudes de programmation ne se développaient pas lorsque l'arène était devenue beaucoup plus vaste; block scope a été inventé en tant que mécanisme de défense des programmeurs contre leur propre mémoire limitée.

L’informatique était également une activité beaucoup plus rare et exotique lorsque les ordinateurs étaient extrêmement coûteux, et il se peut que seuls des individus particulièrement enclins à être mathématiquement et ingénieux soient devenus des programmeurs (bien que ces comparaisons soient difficiles à tester et certainement incendiaires sur le plan politique). Au début, les logiciels étaient généralement livrés gratuitement avec un ordinateur afin de convaincre les gens de l'acheter. L'idée que des utilisateurs institutionnels tentent même d'écrire leurs propres programmes était inconnue au début.

Kilian Foth
la source
Vous parlez de combien de temps en arrière. J'ai personnellement vu quelques mini-ordinateurs datant du début des années 80 dotés d'un "datapool" (une liste de variables globale) contenant plus de 60 000 étiquettes.
Evan Plaice
-1: Dans les premiers temps, vous avez non seulement payé un loyer mensuel pour avoir accès à un ordinateur, mais vous avez également payé les cycles de processeur et la mémoire utilisés par votre programme. Le logiciel était loin d'être gratuit et son utilisation encore moins.
mattnz
1
@mattnz: Il y a quelque temps, les logiciels étaient souvent fournis avec une solution intégrée, ce qui diffère quelque peu de la version gratuite. En règle générale, une entreprise qui avait besoin d'un ordinateur en achetait ou en louait un, et ne payait pas pour faire fonctionner la machine, bien que les utilisateurs individuels paient souvent pour cela. Je suis également intrigué par l'affirmation du PO selon laquelle les utilisateurs n'étaient pas censés écrire leur propre logiciel, car ce n'était certainement pas mon expérience. Si vous pouviez vous permettre un ordinateur, vous pourriez avoir un personnel de développement, et il n'y avait pas beaucoup de logiciels en conserve sur le marché.
David Thornley
Les problèmes liés à la programmation mono-portée ont été reconnus assez tôt, bien avant que les ordinateurs ne disposent de plusieurs mégaoctets de mémoire. ALGOL, la première langue à portée lexicale, est apparue en 1958.
kevin cline
4

Mon dieu, cela fait plusieurs années (souvenirs bouillonnants :)).

Je ne connais pas le langage auquel vous faites référence, mais en général nous nous sommes adaptés à ce que nous avions. Ce n'était pas vraiment un gros problème. Vous devez faire plus attention aux noms de variables qui contiennent souvent (sous forme abrégée, à cette époque le nombre d'octets était précieux), référence à sub ou function, comme mIORead1si vous aviez un gestionnaire pour lire les données d'un fichier 1, ou plusieurs. les compteurs comme i, j, k, etc. qui, par votre propre système, vous savaient à quoi ils étaient destinés, s’ils pouvaient être réutilisés et ainsi de suite. C'était plus hardcore (pas de casque ni de gants à l'époque) :-)

Epistemex
la source
3

Ceci est assez similaire à la programmation automate, bien que les automates modernes vous permettent maintenant d’avoir des "balises" (ou variables) locales à un programme. Pourtant, beaucoup de gens ne font que programmer en utilisant toutes les balises globales.

J'ai découvert que si vous voulez faire cela, vous devez utiliser une convention de dénomination structurée. Par exemple: Motor1_DriveContactor_Run. Si votre langue arrive à des structures de soutien (parfois appelés types définis par l' utilisateur), vous pouvez aussi les utiliser pour créer une hiérarchie de données structurées, telles que: Motor[1].DriveContactor.Run.

Cela permet de tout organiser et, généralement, intellisense est suffisamment décent pour vous aider.

Scott Whitlock
la source
2

J'ai en fait appris à programmer dans un langage appelé Authorware, où tout était global. Heureusement, il y avait des tableaux et après un certain point, quelque chose appelée Listes, similaires aux objets génériques.

Un programme Authorware avait en fait une structure physique (Authorware était basé sur une métaphore de diagramme de flux) et son langage de script était basé sur un Pascal de style ancien. Ce que nous avons fait était de relier la structure physique aux indices d'un tableau. Souvent, les index de tableau contenaient des listes que nous considérions comme un objet local pour l'élément physique que nous utilisions.

Authorware a été conçu pour l'eLearning, l'une des icônes que nous avions était donc une page. Les pages seraient attachées à un cadre. Ainsi, pour la page 1, nous examinerions un tableau à l'index 1 (Authorware était indexé 1) et extrairions les données de cette page, qui seraient stockées dans une liste pouvant agir en tant que pseudo-objet. La page aurait alors une logique qui extrairait les "propriétés" de l'objet par son nom. Si vous n'avez rien de comparable à Objects, mais que vous ayez des tableaux, vous pouvez simplement avoir une convention indiquant quelles données vont où.

Ce n'est pas si différent de ce que nous faisons lorsque nous récupérons des données d'une base de données et effectuons une injection de dépendance, sauf que tout est vraiment global et que vous choisissez simplement de tout mettre dans de petites cases et de ne regarder que celles qui vous intéressent. re concerné avec en ce moment.

Selon ce que vous essayez de faire et ce que votre langue prend en charge, cela peut vous aider au moins à diviser les choses en parties plus gérables.

Amy Blankenship
la source
J'ai également travaillé avec Macromedia Authorware, @ amy-blankenship. Je ne me souviens plus de la version précédente, peut-être 3. A-t-elle été remplacée par Flash / Showckwave ou existe-t-elle encore?
Tulains Córdova
C'étaient des choses différentes. Macromedia a causé beaucoup de confusion dans la version 5 (des deux) en appelant tout ce que Shockwave, y compris Director, était emballé pour le Web. Authorware ayant cessé l’utilisation de Adobe après l’acquisition, Flash continue de fonctionner.
Amy Blankenship
1

Quand j'étais à l'université, on nous avait beaucoup appris sur le «problème de variables globales» - un ensemble de bogues et de problèmes de maintenance du code causés par de nombreuses variables globales.

Certaines variables sont plus dangereuses que d'autres.

Coffre-fort : Variables qui n'affectent pas le flux de contrôle, par exemple LastName

Dangerous : toute variable qui affecte le contrôle du programme, par exemple DeliveryStatus

Le plus dangereux en premier:

  • Statut composé (mode et sous-mode)
  • Valeurs composées (total, sous-total)
  • Statut unique (mode)
  • Valeurs uniques (nombre)

Pour éviter le "problème de variable globale", vous devez

  • Documentez chaque variable et fonction.
  • Conservez les variables associées à proximité (avec le code qui les utilise) dans la même section du code source.
  • Cachez les variables "dangereuses" afin que les autres programmeurs ne sachent pas qu’elles existent. Évitez de les utiliser directement, en particulier dans d'autres sections du code.
  • Fournit des fonctions qui lisent / écrivent des variables dangereuses (les autres programmeurs n'en ont donc pas besoin).

Pour structurer votre code , utilisez les commentaires et les conventions d'appellation lorsque aucune structure n'est disponible dans le langage:

/* --------------------------- 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";

la source
0

Je ne sais pas comment ils ont fait.

Mais je pense que les langages POO modernes ont eu un problème très similaire concernant la collision de nommage .

La solution consiste à adopter un espace de noms . C'est un concept abstrait, mais largement adopté par plusieurs implémentations (packages Java, espaces de noms .NET, modules Python).

Si la langue que vous utilisez n’est pas trop limitée en termes de longueur de nom, vous pouvez appliquer l’espace de nom à un nom de variable correct.

Le nom de la variable représente donc également la portée de la variable.

Essayez de définir un modèle de nommage comme celui-ci: order_detail_product_code, order_detail_product_unit_price. Ou pour les compteurs temporaires ou les échanges: tmp_i, tmp_swap.

Alberto De Caro
la source
0

Dans les langues où toutes les variables sont globales (j'en ai utilisé quelques-unes), nous utilisions une convention de dénomination des variables. Par exemple: si je voulais réellement utiliser une variable globale, je pourrais utiliser le préfixe "m_" ou "_". Bien sûr, cela dépend toujours des développeurs pour avoir cette discipline

bytedev
la source