Was haben Programmierer vor dem Variablenbereich gemacht, wo alles global ist?

40

Ich muss mich also mit einer scheinbar archaischen Sprache (PowerOn) auseinandersetzen, in der ich eine Hauptmethode, ein paar Datentypen zum Definieren von Variablen und die Möglichkeit habe, Unterprozeduren (im Wesentlichen ungültige Methoden) zu verwenden, die keinen Typ zurückgeben noch akzeptiert irgendwelche Argumente. Das Problem dabei ist, dass ALLES global ist. Ich habe diese Art von Sprachen gelesen, aber die meisten Bücher haben den Ansatz "Ok, wir benutzen ein Pferd und einen Wagen, aber jetzt ist hier ein Auto, also lass uns lernen, wie man daran arbeitet!" Wir werden diese Tage NIE wieder erleben. " Ich muss zugeben, der Verstand hat Mühe, außerhalb von Umfang und Umfang zu denken .

Also, hier bin ich. Ich versuche herauszufinden, wie man nichts als globale Variablen über mehrere offene Methoden am besten verwaltet . Ja, es müssen sogar Iteratoren für forSchleifen global definiert werden, die ich in verschiedenen Teilen meines Codes wiederverwerte.

Meine Frage: Wie haben Programmierer mit einer großen Anzahl von Variablen in einem globalen Spielfeld umgegangen? Ich habe das Gefühl, dass es nur ein mentaler Jongliertrick wurde, aber ich würde mich interessieren, ob es irgendwelche bekannten Ansätze gibt.

Chad Harrison
quelle
71
Sie haben viel gebetet.
Robert Harvey
15
Ich kann mir viele verrückte Variablennamen vorstellen, die ungefähr dem Umfang entsprachen - bob_dog_fur_colourusw., um zu versuchen, die Wahrscheinlichkeit zu verringern, dieselben Namen zu treffen.
Latty
12
Sie schrieben Programme, deren Umfang kleiner war, und sie hatten viele Fehler.
Charles E. Grant
12
@Lattyware, in früheren Zeiten waren Sie in Bezug auf die Beschreibung Ihrer Variablennamen sehr eingeschränkt. Einige Sprachen erlaubten nur Variablennamen mit 1 oder 2 Zeichen, andere erlaubten bis zu 8 Zeichen. Es hat gesaugt, aber wir wussten nicht, wie viel es damals gesaugt hat. Es hat den Compiler in eine begrenzte Menge an Speicher gedrückt.
Charles E. Grant
17
sie haben bessere programmiersprachen erfunden ...
wim 24.10.12

Antworten:

44

Sie benötigen eine Art von mentalen Buchhaltungstricks (Namenskonventionen usw.), um die Übersichtlichkeit zu wahren. Auch Dokument, Dokument, Dokument. Da alle Variablen globale Variablen sind, sollten Sie nach Möglichkeit ein einziges Dokument mit allen aufgeführten Variablen erstellen.

Versuchen Sie, eine kleine Anzahl von Variablen zu verwenden, die Sie immer für Provisorien verwenden, und denken Sie daran, dass SIE VORÜBERGEHEND SIND. Durch die ständige Wiederverwendung derselben werden Sie sich angewöhnen, den Überblick darüber zu behalten, wo sie gültig sind oder nicht.

Außerdem sollten Sie sich die Dokumentation ansehen und sicherstellen, dass Sie wissen, wie lang Variablennamen sein können und wie viele Zeichen tatsächlich eindeutig sind. Ich weiß NICHTS über PowerOn, aber wenn es archaisch genug ist, um nur globalen Geltungsbereich zu haben, ist es möglich, dass es eine begrenzte Eindeutigkeitslänge für Bezeichner hat.

Ich habe schon Dinge mit langen Bezeichnern gesehen, deren Bezeichner jedoch nur in den ersten 8 Zeichen eindeutig waren. Sie könnten also RonnyRayGun und RonnyRayBlaster haben und sie sind tatsächlich die GLEICHE Variable. In solchen Fällen empfehle ich, die Variablennamen unter der "eindeutigen" Grenze zu halten, damit Sie nicht versehentlich kollidieren.

Michael Kohne
quelle
4
+1: Beim Schreiben von Assemblys treten in der Regel die gleichen Probleme auf: Wenn ich die Register benenne, sind die Namen global (ich habe das zusätzliche Problem, dass ich, selbst wenn ich mehr Namen erstelle, keine weiteren Register erhalte, aber das ist es hier nicht relevant). Ein paar Register für temporäre Werte helfen wirklich dabei, die Anzahl der erstellten Variablen zu verringern, was es einfacher macht, alles im Kopf zu behalten. Wenn Sie dokumentieren, welche Variablen von jeder Funktion verwendet werden (am wichtigsten ist die Änderung), können Sie das Gesamtbild verbessern.
Leo
53

Datenwörterbuch.

In einem zentralen Repository (normalerweise im Büro des leitenden Programmierers) befand sich ein Loseblattordner, der für jede globale Variable eine Seite enthielt. Die Seite gab den Namen, die Definition, den Zweck und die Routinen an, die sie festgelegt oder verwendet haben.

Frühe eingebettete Systeme mit mikroskopischem RAM hatten ein ähnliches Problem und eine ähnliche Lösung. Der leitende Programmierer hat die Master-RAM-Karte bis auf die einzelnen Bytes gepflegt und angezeigt, welcher RAM von welchen Modulen für welche Zwecke verwendet wurde. Programmierer, die eine dedizierte RAM-Zuweisung benötigten, gingen zu dem leitenden Programmierer, der nach Erörterung der Angelegenheit den entsprechenden Notizbucheintrag machte und dem Typen seinen RAM gab. (Sie wollten nicht in der Rolle des Programmierers stehen, der ein RAM-Byte genommen hat, ohne es mit dem Hauptprogrammierer zu löschen. Vertrauen Sie mir.)

Dieses Problem trat auch auf, als Programmierer in frühen Versionen von BASIC große Systeme erstellen mussten. Es zeigte sich für mich persönlich, als ich einen sehr primitiven "Datenbank" -Manager namens Info benutzte (Produkt von Henco, Inc. aus New Jersey - HOFFNUNGSVOLL, jetzt schon lange weg!). Beide Sprachen hatten ein sehr begrenztes Vokabular für Variablennamen.

John R. Strohm
quelle
Ich bin in einer sehr ähnlichen Situation, da ich eher ein "Datenbank" -Manager bin, bei dem die Sprache direkt mit der Datenbank in Verbindung steht, zusammen mit einigen programmierähnlichen Funktionen. Dies ist sehr hilfreich
Chad Harrison
1
Das erinnert mich an damals, als ich BASIC lernte, und Variablen durften nicht länger als zwei Zeichen sein und sie in einem umfangreichen Programm nachverfolgen ...
Kevin Rubin,
@ Kevin Rubin, erinner mich nicht. Wie Bill Clinton immer sagte ...
John R. Strohm
8

Der Aufstieg der Programmiersprachen mit Blockumfang fiel mit dem Aufkommen schnellerer, größerer Maschinen zusammen, und das ist kein Zufall. Frühe Computer hatten RAM gemessen in MB, KB oder sogar in Bytes; es gab einfach keine Möglichkeit, selbst hat so viele Variablen , dass sie verwechselt werden würden , wenn das Programm großes bekam, weil Programme , die großen nie bekommen . Fortschritte in den Programmiersprachen wurden normalerweise gemacht, als die Leute erkannten, dass ihre alten Programmiergewohnheiten nicht größer wurden, als die Arena viel größer wurde. Block Scope wurde als Schutzmechanismus für Programmierer gegen ihren eigenen begrenzten Speicher entwickelt.

Computing war auch eine viel seltenere und exotischere Aktivität, als Comoputer fantastisch teuer waren, und es kann durchaus sein, dass nur besonders mathematisch veranlagte und geniale Personen Programmierer wurden (obwohl solche Vergleiche unpraktisch und mit Sicherheit politisch brandaktuell sind). Früher wurde Software normalerweise kostenlos mit einem Computer ausgeliefert, um die Leute davon zu überzeugen, sie überhaupt zu kaufen. Der Gedanke, dass institutionelle Benutzer sogar versuchen würden, ihre eigenen Programme zu schreiben, war zunächst unbekannt.

Kilian Foth
quelle
Von wie weit zurück sprichst du? Ich habe persönlich ein paar Minicomputer aus den frühen 80ern gesehen, die einen 'Datenpool' (dh eine globale Variablenliste) mit mehr als 60.000 Labels hatten.
Evan Plaice
-1: In den Anfängen haben Sie nicht nur eine monatliche Miete für den Zugang zu einem Computer bezahlt, sondern auch für die CPU-Zyklen und den von Ihrem Programm verwendeten Speicher. Software war alles andere als kostenlos und die Ausführung der Software noch weniger.
Mattnz
1
@mattnz: Vor einiger Zeit wurde oft Software gebündelt, was sich etwas von kostenlos unterscheidet. In der Regel würde ein Unternehmen, das einen Computer benötigt, einen Computer kaufen oder mieten und nicht für den Betrieb des Computers bezahlen, obwohl dies häufig einzelnen Benutzern in Rechnung gestellt wird. Ich bin auch verwirrt über die Behauptung des OP, dass von den Leuten nicht erwartet wurde, dass sie ihre eigene Software schreiben, denn das war sicherlich nicht meine Erfahrung. Wenn Sie sich einen Computer leisten könnten, könnten Sie sich ein Entwicklungspersonal leisten, und es gab wirklich nicht viel Dosen-Software.
David Thornley
Die Probleme mit der Single-Scope-Programmierung wurden sehr früh erkannt, lange bevor Computer über mehrere Megabyte Speicher verfügten. ALGOL, die erste Sprache mit lexikalischem Umfang, erschien 1958.
Kevin Cline
4

Meine Güte, das ist viele Jahre her (sprudelnde Erinnerungen :)).

Ich kenne die Sprache, auf die Sie sich beziehen, nicht, aber im Allgemeinen haben wir uns an das angepasst, was wir hatten. Es war nicht wirklich ein großes Problem. Sie mussten mehr auf var-Namen achten, die häufig (in Kurzform, in jenen Tagen war die Anzahl der Bytes kostbar) Verweise auf sub oder function enthielten, beispielsweise mIORead1wenn Sie einen Handler zum Lesen von Daten aus einer Datei 1 hatten oder verschiedene hatten Counter-Vars wie i, j, k usw., von denen Sie nach Ihrem eigenen System wussten, wofür sie bestimmt waren, wenn sie wiederverwendet werden konnten und so weiter. Es war mehr Hardcore (damals keine Helme oder Handschuhe) :-)

epistemex
quelle
3

Dies ist der SPS-Programmierung ziemlich ähnlich, obwohl Sie in modernen SPS jetzt "Tags" (auch als Variablen bezeichnet) haben können, die für ein Programm lokal sind. Trotzdem programmieren viele Leute nur mit allen globalen Tags.

Ich habe festgestellt, dass Sie dafür eine strukturierte Namenskonvention verwenden müssen. Zum Beispiel: Motor1_DriveContactor_Run. Wenn Ihre Sprache Strukturen unterstützt (manchmal als benutzerdefinierte Typen bezeichnet), können Sie diese auch zum Erstellen einer strukturierten Datenhierarchie verwenden, z Motor[1].DriveContactor.Run.

Das hält alles in Ordnung, und normalerweise ist der Intellisense anständig genug, um Ihnen weiterzuhelfen.

Scott Whitlock
quelle
2

Ich habe tatsächlich gelernt, in einer Sprache namens Authorware zu programmieren, in der alles global war. Zum Glück gab es Arrays und ab einem bestimmten Punkt so genannte Listen, die generischen Objekten ähnelten.

Ein Authorware-Programm hatte tatsächlich eine physische Struktur (Authorware basierte auf einer Flussdiagramm-Metapher), und seine Skriptsprache basierte auf Pascal im alten Stil. Wir haben die physische Struktur mit den Indizes in einem Array in Beziehung gesetzt, und häufig enthielten die Array-Indizes Listen, die wir als lokales Objekt für das von uns verwendete physische Teil behandeln würden.

Authorware wurde für eLearning entwickelt, eines der Symbole, die wir hatten, war eine Seite. Seiten würden an ein Framework angehängt. Für Seite 1 sehen wir uns also in einem Array Index 1 an (Authorware war 1-indiziert) und ziehen die Daten für diese Seite heraus, in der eine Liste gespeichert wird, die als Pseudoobjekt fungiert. Die Seite würde dann eine Logik haben, die die "Eigenschaften" des Objekts nach Namen aufruft. Wenn Sie keine Objekte, sondern Arrays haben, können Sie einfach festlegen, welche Daten wohin übertragen werden sollen.

Es unterscheidet sich nicht wirklich von dem, was wir tun, wenn wir Daten aus einer Datenbank abrufen und eine Abhängigkeitsinjektion durchführen, außer dass alles wirklich global ist. Ich beschäftige mich gerade mit.

Je nachdem, was Sie versuchen und was Ihre Sprache unterstützt, kann dies Ihnen helfen, die Dinge zumindest in handlichere Teile aufzuteilen.

Amy Blankenship
quelle
Ich habe auch mit Macromedia Authorware, @ amy-blankenship gearbeitet. Ich erinnere mich nicht, welche Version es war, als ich das letzte Mal damit gearbeitet habe, vielleicht 3. Wurde es durch Flash / Showckwave ersetzt oder existiert es noch?
Tulains Córdova
Es waren verschiedene Dinge. Macromedia hat in Version 5 (von beiden) viel Verwirrung gestiftet, indem es Shockwave, einschließlich Director, als Paket für das Web aufgerufen hat. Authorware wurde von Adobe nach der Übernahme eingestellt, Flash läuft noch.
Amy Blankenship
1

Als ich an der Universität war, wurde uns ausführlich "The Global Variable Problem" beigebracht - eine Sammlung von Fehlern und Problemen bei der Codewartung, die durch viele globale Variablen verursacht wurden.

Einige Variablen sind gefährlicher als andere.

Sicher : Variablen, die den Kontrollfluss nicht beeinflussen, z. B. Nachname

Gefährlich : Jede Variable, die den Steuerungsfluss des Programms beeinflusst, z. B. DeliveryStatus

Am gefährlichsten zuerst:

  • Verbindungsstatus (Modus und Untermodus)
  • Zusammengesetzte Werte (gesamt, Zwischensumme)
  • Einzelstatus (Modus)
  • Einzelwerte (Anzahl)

Um das "globale Variablenproblem" zu vermeiden, müssen Sie

  • Dokumentieren Sie jede Variable und Funktion.
  • Halten Sie zusammengehörige Variablen (mit dem Code, der sie verwendet) im selben Abschnitt des Quellcodes dicht beieinander.
  • Verstecken Sie die "gefährlichen" Variablen, damit andere Programmierer nichts von ihrer Existenz wissen. Vermeiden Sie die direkte Verwendung, insbesondere in anderen Codeabschnitten.
  • Stellen Sie Funktionen bereit, die gefährliche Variablen lesen / schreiben (andere Programmierer müssen dies nicht tun).

Verwenden Sie zum Strukturieren Ihres Codes , wenn in der Sprache keine Struktur verfügbar ist, Kommentare und Namenskonventionen:

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

quelle
0

Ich weiß nicht, wie sie es gemacht haben.

Aber ich denke, dass moderne OOP-Sprachen ein sehr ähnliches Problem in Bezug auf die Namenskollision hatten .

Die Lösung übernimmt Namespace . Es ist ein abstraktes Konzept, das jedoch von mehreren Implementierungen (Java-Pakete, .NET-Namespace, Python-Module) weitgehend übernommen wird.

Wenn die von Ihnen verwendete Sprache hinsichtlich der Benennungslänge keine zu enge Beschränkung aufweist, können Sie den Namespace auf eine gute Benennung von Variablen anwenden.

Der Variablenname repräsentiert also auch den Gültigkeitsbereich der Variablen.

Versuchen Sie, ein Namensmuster wie das folgende zu definieren: order_detail_product_code, order_detail_product_unit_price. Oder für die temporären Zähler oder Swaps: tmp_i, tmp_swap.

Alberto De Caro
quelle
0

In Sprachen, in denen alle Variablen global sind (ich habe ein paar verwendet), verwendeten wir eine Namenskonvention für Variablen. Zum Beispiel: Wenn ich tatsächlich eine Variable als global verwenden wollte, könnte ich das Präfix "m_" oder "_" verwenden. Natürlich hängt dies immer noch von den Entwicklern ab, die über diese Disziplin verfügen

bytedev
quelle