Co zrobili programiści przed zmiennym zakresem, gdzie wszystko jest globalne?

40

Tak więc mam do czynienia z pozornie archaicznym językiem (zwanym PowerOn), w którym mam główną metodę, kilka typów danych do definiowania zmiennych i mam możliwość posiadania podprocedur (zasadniczo nieważnych metod), które nie zwracają typu ani nie przyjmuje żadnych argumentów. Problem w tym, że WSZYSTKO ma charakter globalny. Czytałem o tego rodzaju językach, ale większość książek przyjmuje podejście „Ok, używamy koni i powozów, ale teraz oto samochód, więc nauczmy się, jak nad tym pracować!” NIGDY nie przeżyjemy tych dni ponownie . Muszę przyznać, że umysł stara się myśleć poza zasięgiem i zakresem .

Cóż, oto jestem. Próbuję wymyślić, jak najlepiej zarządzać tylko zmiennymi globalnymi za pomocą kilku otwartych metod. Tak, nawet iteratory dla forpętli muszą być zdefiniowane globalnie, co wydaje mi się recyklingiem w różnych częściach mojego kodu.

Moje pytanie: w jaki sposób programiści poradzili sobie z dużą liczbą zmiennych na globalnym polu gry? Czuję, że to właśnie stała się sztuczką żonglerki, ale chciałbym wiedzieć, czy są jakieś znane podejścia.

Chad Harrison
źródło
71
Dużo się modlili.
Robert Harvey
15
Mogę sobie wyobrazić wiele szalonych nazw zmiennych o przybliżonym zasięgu - bob_dog_fur_colouritd., Aby spróbować zmniejszyć szansę na trafienie tych samych nazw.
Latty
12
Napisali programy o mniejszym zakresie i zawierają wiele błędów.
Charles E. Grant
12
@Lattyware, w rzeczywistości w dawnych czasach byłeś bardzo ograniczony, jak opisowo możesz tworzyć nazwy zmiennych. Niektóre języki dopuszczały tylko nazwy zmiennych o 1 lub 2 znakach, inne pozwalały na aż 8. Pozwoliło to kompilatorowi wcisnąć się w ograniczoną ilość pamięci.
Charles E. Grant
17
wymyślili lepsze języki programowania ...
wim

Odpowiedzi:

44

Będziesz potrzebować jakiegoś rodzaju mentalnych sztuczek księgowych (konwencje nazewnictwa itp.), Aby zachować prostotę. Ponadto dokument, dokument, dokument. Ponieważ wszystkie zmienne są globalne, w miarę możliwości miej jeden dokument z wszystkimi na liście.

Staraj się mieć niewielką liczbę zmiennych, których zawsze używasz do tymczasowości, i pamiętaj, że ONI SĄ TYMCZASOWI. Dzięki ciągłemu ponownemu wykorzystywaniu tych samych nawyków będziesz miał zwyczaj sprawdzania, czy są one ważne, czy nie.

Ponadto chcesz przejrzeć dokumentację i upewnić się, jak długie mogą być nazwy zmiennych i ile znaków jest faktycznie unikatowych. Nie znam NIC o PowerOn, ale jeśli jest wystarczająco archaiczny, aby mieć zasięg globalny, to możliwe, że ma ograniczoną długość unikatowości w identyfikatorach.

Widziałem już rzeczy z długimi identyfikatorami, ale których identyfikatory były unikalne tylko w pierwszych 8 znakach. Więc możesz mieć RonnyRayGun i RonnyRayBlaster i są one w rzeczywistości zmienną SAME. W takich przypadkach zalecam utrzymywanie nazw zmiennych poniżej „unikalnego” limitu, aby uniknąć przypadkowego zderzenia.

Michael Kohne
źródło
4
+1: Pisząc asembler zwykle napotykam na te same problemy, że jeśli nazywam rejestry, nazwy są globalne (napotykam dodatkowy problem, że nawet jeśli utworzę więcej nazw, nie dostanę więcej rejestrów, ale to jest nie dotyczy tutaj). Posiadanie kilku rejestrów dedykowanych dla wartości tymczasowych naprawdę pomaga utrzymać liczbę utworzonych zmiennych, co ułatwia trzymanie wszystkiego w głowie. Dokumentowanie zmiennych, których będzie używać każda funkcja (najważniejsze jest to, które zmodyfikuje) pomaga uzyskać właściwy obraz globalny.
Leo
53

Słownik danych.

W centralnym repozytorium (zwykle biurze głównego programisty) znajdował się luźny segregator, który zawierał jedną stronę dla każdej zmiennej globalnej. Strona podała nazwę, jej definicję, cel oraz to, jakie procedury ją ustawiły lub wykorzystały.

Wczesne systemy wbudowane z mikroskopową pamięcią RAM miały podobny problem i podobne rozwiązanie. Główny programista utrzymywał główną mapę RAM, aż do poszczególnych bajtów, pokazując, jaka pamięć RAM była używana przez które moduły do ​​jakich celów. Programiści, którzy potrzebowali dedykowanego przydziału pamięci RAM, udali się do głównego programisty, który po omówieniu sprawy dokonał odpowiedniego wpisu w notatniku i dał facetowi swoją pamięć RAM. (Nie chciałeś być w roli programisty, który wziął bajt pamięci RAM bez wyczyszczenia go za pomocą głównego programisty. Zaufaj mi w tym.)

Ten problem pojawił się również, gdy programiści musieli budować duże systemy we wczesnych wersjach BASIC. Okazało się to dla mnie osobiście podczas korzystania z bardzo prymitywnego menedżera „bazy danych” o nazwie Info (produkt Henco, Inc. z New Jersey - NADZIEI już dawno nie ma!). Oba te języki miały bardzo ograniczone słownictwo dotyczące zmiennych nazw.

John R. Strohm
źródło
Znajduję się w bardzo podobnej sytuacji, ponieważ jest bardziej menedżerem „bazy danych”, w którym język bezpośrednio łączy się z bazą danych, podobnie jak niektóre funkcje programowania. Jest to bardzo pomocne
Chad Harrison
1
To przypomina mi przeszłość, kiedy uczyłem się języka BASIC, a zmienne nie mogły mieć nazw dłuższych niż dwa znaki i śledzić je w sporym programie ...
Kevin Rubin
@KevinRubin, nie przypominaj mi. Ach, poczuj ból, jak mawiał Bill Clinton ...
John R. Strohm,
8

Pojawienie się języków programowania o zakresie blokowym zbiegło się w czasie z pojawieniem się szybszych, większych maszyn, i to nie przypadek. Wczesne komputery miały pamięć RAM mierzoną w MB, kB, a nawet w bajtach; po prostu nie było możliwości posiadania tak wielu zmiennych, że byłyby one mylone, gdy program stał się duży, ponieważ programy nigdy nie były tak duże . Postępów w językach programowania zwykle dokonywano, gdy ludzie zdawali sobie sprawę, że ich stare nawyki programowe nie rosły, gdy arena stała się znacznie większa; blok zakres został wynaleziony jako mechanizm obrony dla programistów przed ich własną ograniczoną pamięcią.

Komputery były również znacznie rzadszym i bardziej egzotycznym zajęciem, gdy komputery były fantastycznie drogie, i może być tak, że tylko szczególnie skłonni matematycznie i pomysłowi ludzie zostali programistami (chociaż takie porównania są niepraktyczne do przetestowania, a na pewno politycznie podpalające). Na początku oprogramowanie było zwykle dostarczane bezpłatnie z komputerem, aby przede wszystkim przekonać ludzi do zakupu; myśl, że użytkownicy instytucjonalni będą nawet próbować pisać własne programy, na początku była nieznana.

Kilian Foth
źródło
Jak daleko ty mówisz. Osobiście widziałem kilka minikomputerów z początku lat 80-tych, które miały „pulę danych” (tj. Listę zmiennych globalnych) zawierającą ponad 60 000 etykiet.
Evan Plaice
-1: Na początku nie tylko płaciłeś miesięczny czynsz za dostęp do komputera, ale płaciłeś za cykle procesora i pamięć używaną przez twój program. Oprogramowanie było dalekie od darmowego, a jeszcze gorzej.
mattnz
1
@mattnz: Jakiś czas temu oprogramowanie było często dołączane, co nieco różni się od darmowego. Zazwyczaj przedsiębiorstwo, które potrzebuje komputera, kupuje lub wynajmuje komputer, a nie płaci za uruchomienie komputera, chociaż za to często płacą indywidualni użytkownicy. Zastanawia mnie również twierdzenie OP, że ludzie nie mieli pisać własnego oprogramowania, ponieważ z pewnością nie było to moje doświadczenie. Jeśli stać cię na komputer, możesz sobie pozwolić na programistów, a naprawdę nie ma tam zbyt wielu programów w puszkach.
David Thornley
Problemy z programowaniem jednozakresowym zostały wykryte dość wcześnie, na długo zanim komputery miały wiele megabajtów pamięci. ALGOL, pierwszy język o zakresie leksykalnym, pojawił się w 1958 roku.
kevin cline
4

Mój Boże, to jest wiele lat temu (bąbelki wspomnień :)).

Nie znam języka, o którym mówisz, ale ogólnie dostosowaliśmy się do tego, co mieliśmy. To nie był naprawdę duży problem. Trzeba było zwracać większą uwagę na nazwy var, które często zawierały (w skrócie, w tamtych czasach liczba bajtów była cenna) odniesienie do podrzędnej lub funkcji, tak jak mIORead1gdybyś miał moduł obsługi do odczytu danych z pliku 1 lub miałeś różne kontr-zmienne, takie jak i, j, k itd., które według własnego systemu wiedziałeś, do czego służą, jeśli można je ponownie wykorzystać i tak dalej. To było bardziej hardcorowe (wtedy nie było kasków ani rękawiczek) :-)

epistemex
źródło
3

Jest to dość podobne do programowania PLC, chociaż nowoczesne sterowniki PLC pozwalają teraz na posiadanie „znaczników” (czyli zmiennych), które są lokalne dla programu. Mimo to wiele osób po prostu programuje przy użyciu wszystkich globalnych tagów.

Odkryłem, że jeśli chcesz to zrobić, musisz użyć konwencji nazewnictwa strukturalnego. Na przykład: Motor1_DriveContactor_Run. Jeśli język dzieje konstrukcji wsporczych (czasami znane jako typy zdefiniowane przez użytkownika), a następnie można również użyć do stworzenia tych strukturze hierarchii danych, takich jak: Motor[1].DriveContactor.Run.

Dzięki temu wszystko jest uporządkowane, a inteligencja zwykle wystarcza, aby ci pomóc.

Scott Whitlock
źródło
2

Właściwie nauczyłem się programować w języku o nazwie Authorware, gdzie wszystko było globalne. Na szczęście miał tablice i po pewnym czasie coś o nazwie Listy, które były podobne do ogólnych obiektów.

Program Authorware faktycznie miał strukturę fizyczną (Authorware opierał się na metaforze schematu blokowego), a jego język skryptowy był oparty na starym stylu Pascala. To, co zrobiliśmy, polegało na powiązaniu struktury fizycznej ze wskaźnikami w tablicy, a często wskaźniki zawierały listy, które traktowalibyśmy jako lokalny obiekt dla używanego przez nas elementu fizycznego.

Oprogramowanie autorskie zostało zaprojektowane dla eLearningu, więc jedną z naszych ikon była strona. Strony zostaną dołączone do frameworka. Tak więc, dla strony 1, sprawdzilibyśmy tablicę w indeksie 1 (Autorware został zindeksowany 1) i wyciągnęliśmy dane dla tej strony, na której przechowywana byłaby lista, która działałaby jak pseudoobiektyw. Strona miałaby wtedy logikę, która wyciągałaby „właściwości” obiektu według nazwy. Jeśli nie masz czegoś takiego jak Przedmioty, ale masz Tablice, możesz po prostu mieć konwencję, jakie dane idą.

Nie różni się tak naprawdę od tego, co robimy, gdy pobieramy dane z bazy danych i wykonujemy wstrzykiwanie zależności, z wyjątkiem tego, że wszystko jest naprawdę globalne, a ty po prostu decydujesz się umieścić wszystko w małych pudełkach i patrzeć tylko na te, które Ty ”. ponownie się tym zajmuję.

W zależności od tego, co próbujesz zrobić i tego, co obsługuje Twój język, może to pomóc przynajmniej rozbić sprawy na łatwiejsze do zarządzania części.

Amy Blankenship
źródło
Pracowałem również z Macromedia Authorware, @ amy-blankenship. Nie pamiętam, jaka była wersja, kiedy ostatnio z nią pracowałem, może 3. Czy została zastąpiona przez Flash / Showckwave, czy nadal istnieje?
Tulains Córdova
To były różne rzeczy. Macromedia spowodowała wiele zamieszania w wersji 5 (obu), nazywając wszystko Shockwave, w tym Director, gdy jest zapakowane do Internetu. Adobe przestało tworzyć oprogramowanie autorskie po przejęciu, Flash nadal działa.
Amy Blankenship
1

Kiedy byłem na uniwersytecie, obszernie nauczono nas o „The Global Variable Problem” - zbiór błędów i problemów z utrzymaniem kodu spowodowanych przez wiele zmiennych globalnych.

Niektóre zmienne są bardziej niebezpieczne niż inne.

Bezpieczny : zmienne, które nie wpływają na przepływ kontroli, np. LastName

Niebezpieczne : Każda zmienna, która wpływa na przepływ kontroli programu, np. DeliveryStatus

Najpierw najbardziej niebezpieczne:

  • Status związku (tryb i pod-tryb)
  • Wartości złożone (ogółem, sumą częściową)
  • Pojedynczy status (tryb)
  • Pojedyncze wartości (liczba)

Aby uniknąć „problemu zmiennej globalnej”, musisz

  • Dokumentuj każdą zmienną i funkcję.
  • Trzymaj powiązane zmienne blisko siebie (z kodem, który ich używa) w tej samej sekcji kodu źródłowego.
  • Ukryj „niebezpieczne” zmienne, aby inni programiści nie wiedzieli o ich istnieniu. Unikaj ich bezpośredniego używania, szczególnie w innych sekcjach kodu.
  • Zapewniają funkcje, które odczytują / zapisują niebezpieczne zmienne (więc inni programiści nie muszą).

Aby ustrukturyzować kod , gdy żadna struktura nie jest dostępna w języku, użyj komentarzy i konwencji nazewnictwa:

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

źródło
0

Nie wiem jak to zrobili.

Ale myślę, że współczesne języki OOP miały bardzo podobny problem dotyczący kolizji nazw .

Rozwiązaniem jest przyjęcie przestrzeni nazw . Jest to koncepcja abstrakcyjna, ale powszechnie przyjęta przez kilka implementacji (pakiety Java, przestrzeń nazw .NET, moduły Python).

Jeśli używany język nie ma zbyt wąskich ograniczeń dotyczących długości nazewnictwa, możesz zastosować przestrzeń nazw do dobrego nazewnictwa zmiennych.

Zatem nazwa zmiennej reprezentuje również zakres zmiennej.

Spróbuj zdefiniować wzór nazewnictwa w ten sposób: order_detail_product_code, order_detail_product_unit_price. Lub w przypadku tymczasowych liczników lub swapów: tmp_i, tmp_swap.

Alberto De Caro
źródło
0

W językach, w których wszystkie zmienne są globalne (użyłem kilku), używaliśmy konwencji nazewnictwa zmiennych. Na przykład: jeśli naprawdę chciałbym użyć zmiennej jako globalnej, mógłbym użyć prefiksu „m_” lub „_”. Oczywiście nadal zależy to od twórców tej dyscypliny

bytedev
źródło