O que os programadores fizeram antes do escopo variável, onde tudo é global?

40

Portanto, estou tendo que lidar com uma linguagem aparentemente arquíaca (chamada PowerOn), onde tenho um método principal, alguns tipos de dados para definir variáveis ​​e tenho a capacidade de ter subprocedimentos (métodos essencialmente nulos) que não retornam um tipo nem aceita argumentos. O problema aqui é que TUDO é global. Eu já li esse tipo de linguagem, mas a maioria dos livros tem a abordagem "Ok, usamos um cavalo e uma carruagem, mas agora, aqui está um carro, então vamos aprender a trabalhar nisso!" NUNCA reviveremos esses dias " . Devo admitir que a mente está lutando para pensar fora do escopo e da extensão .

Bem, aqui estou eu. Estou tentando descobrir como gerenciar melhor nada além de variáveis ​​globais em vários métodos abertos . Sim, mesmo iteradores de forloops precisam ser definidos globalmente, o que eu me vejo reciclando em diferentes partes do meu código.

Minha pergunta: para aqueles que têm esse tipo de experiência, como os programadores lidaram com uma grande quantidade de variáveis ​​em um campo de atuação global? Sinto que acabou de se tornar um truque de malabarismo mental, mas gostaria de saber se existem abordagens conhecidas.

Chad Harrison
fonte
71
Eles oraram muito.
Robert Harvey
15
Eu posso imaginar muitos nomes de variáveis ​​insanos com escopo aproximado - bob_dog_fur_colouretc ... para tentar reduzir a chance de atingir os mesmos nomes.
Latty
12
Eles escreveram programas com escopo menor e muitos bugs.
Charles E. Grant
12
@ Lattyware, na verdade, antigamente, você era muito limitado quanto à descrição descritiva que poderia criar para os nomes das variáveis. Alguns idiomas permitiam apenas nomes de variáveis ​​de 1 ou 2 caracteres, outros permitiam até 8. Isso era péssimo, mas não sabíamos o quanto isso era ruim na época. Deixou o compilador compactar em uma quantidade limitada de memória.
Charles E. Grant
17
eles inventaram melhor linguagens de programação ...
wim

Respostas:

44

Você precisará de algum tipo de truque de contabilidade mental (convenções de nomenclatura etc.) para manter as coisas em ordem. Além disso, documento, documento, documento. Como todas as variáveis ​​são globais, tenha um único documento com todas elas listadas, se você puder.

Tente ter um pequeno número de variáveis ​​que você sempre usa para temporários e lembre-se de que são temporários. Ao reutilizar constantemente os mesmos, você adquirirá o hábito de acompanhar onde eles são válidos ou não.

Além disso, você deseja examinar a documentação e saber quanto tempo os nomes das variáveis ​​podem ter e quantos caracteres são realmente exclusivos. Não sei nada sobre o PowerOn, mas se é arcaico o suficiente para ter apenas escopo global, é possível que ele tenha um tamanho limitado de exclusividade nos identificadores.

Já vi coisas com identificadores longos, mas cujos identificadores eram únicos nos 8 primeiros caracteres. Então você poderia ter RonnyRayGun e RonnyRayBlaster e eles são realmente a mesma variável. Nesses casos, recomendo manter os nomes de variáveis ​​abaixo do limite "exclusivo" para que você tenha menos probabilidade de colidir acidentalmente.

Michael Kohne
fonte
4
+1: Ao escrever uma montagem, geralmente enfrento alguns dos mesmos problemas: se eu nomear os registros, os nomes serão globais (enfrento o problema adicional de que, mesmo que eu crie mais nomes, não recebo mais registros, mas é isso não relevante aqui). Ter alguns registros dedicados a valores temporários realmente ajuda a diminuir o número de variáveis ​​criadas, o que facilita manter tudo em sua cabeça. A documentação de quais variáveis ​​cada função utilizará (o mais importante é qual será a modificação) ajuda a acertar a imagem global.
24312 Leo
53

Dicionário de dados.

Em um repositório central (geralmente o escritório do programador principal), havia um fichário folgado, que continha uma página para cada variável global. A página forneceu o nome, sua definição, sua finalidade e quais rotinas a definiram ou usaram.

Os primeiros sistemas embarcados com RAM microscópica tinham um problema semelhante e uma solução semelhante. O programador líder manteve o mapa principal da RAM, até os bytes individuais, mostrando qual RAM foi usada por quais módulos para quais finalidades. Os programadores que precisavam de uma alocação de RAM dedicada foram ao programador líder, que, depois de discutir o assunto, fez a entrada apropriada no notebook e deu a ele a RAM. (Você não queria estar no lugar do programador que pegou um byte de RAM sem limpá-lo com o programador líder. Confie em mim.)

Esse problema também apareceu quando os programadores tiveram que criar grandes sistemas nas versões anteriores do BASIC. Apareceu para mim pessoalmente enquanto usava um gerenciador de "banco de dados" muito primitivo chamado Info (produto da Henco, Inc. de Nova Jersey - ESPERANÇA agora há muito tempo!). Ambos os idiomas tinham um vocabulário de nome de variável muito limitado.

John R. Strohm
fonte
Estou em uma situação muito semelhante, pois é mais um gerenciador de "banco de dados", onde a linguagem interage diretamente com o banco de dados, juntamente com algumas programações como funcionalidades. Isso é muito útil
Chad Harrison
11
Isso me lembra de quando eu estava aprendendo BASIC e variáveis não podia ter nomes de mais de dois personagens, e manter o controle deles em um programa considerável ...
Kevin Rubin
@KevinRubin, não me lembre. Ah sentir outrora dor, como Bill Clinton costumava dizer ...
John R. Strohm
8

O surgimento de linguagens de programação com escopo de bloco coincidiu com o advento de máquinas maiores e mais rápidas, e isso não é coincidência. Os computadores antigos tinham RAM medida em MB, kB ou mesmo em bytes; simplesmente não havia oportunidade de ter tantas variáveis ​​que elas ficariam confusas quando o programa aumentasse, porque os programas nunca aumentariam . Os avanços nas linguagens de programação geralmente eram feitos quando as pessoas reconheciam que seus antigos hábitos de programação não aumentavam quando a arena ficava muito maior; O escopo do bloco foi inventado como um mecanismo de defesa para programadores contra sua própria memória limitada.

A computação também era uma atividade muito mais rarefeita e exótica quando os passageiros eram extraordinariamente caros, e pode ser que apenas indivíduos particularmente inclinados e engenhosos matematicamente tenham se tornado programadores (embora essas comparações sejam impraticáveis ​​de testar e certamente politicamente incendiárias). Nos primeiros dias, o software era normalmente enviado gratuitamente com um computador para convencer as pessoas a comprá-lo em primeiro lugar; o pensamento de que os usuários institucionais tentariam escrever seus próprios programas era desconhecido a princípio.

Kilian Foth
fonte
A que distância você está falando? Eu pessoalmente vi alguns minicomputadores do início dos anos 80 que tinham um 'datapool' (ou seja, uma lista de variáveis ​​globais) contendo mais de 60 mil rótulos.
quer
-1: nos primeiros dias, você não pagava apenas um aluguel mensal para ter acesso a um computador, pagava pelos ciclos da CPU e pela memória usada pelo programa. O software estava longe de ser gratuito e rodava o software ainda menos.
mattnz
11
@mattnz: Há algum tempo atrás, o software era frequentemente incluído, o que é um pouco diferente do gratuito. Normalmente, uma empresa que precisava de um computador comprava ou alugava um, e não pagava pela operação da máquina, embora os usuários individuais frequentemente sejam cobrados por isso. Também estou intrigado com a alegação do OP de que não se esperava que as pessoas escrevessem seu próprio software, porque essa certamente não foi minha experiência. Se você pudesse comprar um computador, poderia pagar uma equipe de desenvolvimento, e realmente não havia muito software enlatado por aí.
David Thornley
Os problemas com a programação de escopo único foram reconhecidos muito cedo, muito antes dos computadores terem vários megabytes de memória. ALGOL, a primeira linguagem com escopo léxico, apareceu em 1958.
kevin Cline
4

Meu Deus, isso foi há muitos anos (memórias borbulhantes :)).

Não sei o idioma a que você se refere, mas em geral nos adaptamos ao que tínhamos. Não era realmente um grande problema. Você precisava prestar mais atenção aos nomes var, que geralmente continham (de forma resumida, naqueles dias o número de bytes era precioso) referência a sub ou função, como mIORead1se você tivesse um manipulador para ler dados de um arquivo 1 ou tivesse vários contra-vars como i, j, k, etc., pelos quais, por seu próprio sistema, você sabia para que servem, se poderiam ser reutilizados e assim por diante. Era mais hardcore (sem capacetes ou luvas naquela época) :-)

epistemex
fonte
3

Isso é bastante semelhante à programação de CLPs, embora os CLPs modernos agora permitam que você tenha "tags" (também conhecidas como variáveis) que são locais para um programa. Ainda assim, muitas pessoas apenas programam usando todas as tags globais.

Descobri que, se você quiser fazer isso, precisará usar uma convenção de nomenclatura estruturada. Por exemplo: Motor1_DriveContactor_Run. Se o seu idioma acontece com estruturas de apoio (às vezes conhecidos como tipos definidos pelo usuário), então você também pode usar os para criar uma hierarquia de dados estruturados, tais como: Motor[1].DriveContactor.Run.

Isso mantém tudo organizado, e geralmente o intellisense é decente o suficiente para ajudá-lo.

Scott Whitlock
fonte
2

Na verdade, eu aprendi a programar em uma linguagem chamada Authorware, onde tudo era global. Felizmente, ele tinha Arrays e, depois de um certo ponto, algo chamado Lists, que era semelhante a objetos genéricos.

Na verdade, um programa Authorware tinha uma estrutura física (o Authorware era baseado em uma metáfora de fluxograma) e sua linguagem de script era baseada no Pascal à moda antiga. O que fizemos foi relacionar a estrutura física aos índices em uma matriz e, frequentemente, os índices da matriz conteriam listas que trataríamos como um objeto local para a peça física que estávamos usando.

O Authorware foi projetado para o eLearning; portanto, um dos ícones que tínhamos era uma página. As páginas seriam anexadas a um Framework. Portanto, para a Página 1, procuramos em alguma Matriz no índice 1 (o Authorware foi indexado em 1) e extraímos os dados para essa página, onde seria armazenada uma Lista que atuaria como um pseudo-objeto. A página teria uma lógica que extrairia as "propriedades" do objeto pelo nome. Se você não possui Objetos, mas possui Matrizes, pode simplesmente ter uma convenção sobre quais dados vão para onde.

Na verdade, não é tão diferente do que fazemos quando recuperamos dados de um banco de dados e executamos injeção de dependência, exceto que tudo é realmente global, e você está simplesmente escolhendo colocar tudo em caixinhas e olhar apenas as que você ' está preocupado com agora.

Dependendo do que você está tentando fazer e do que o seu idioma suporta, isso pode ajudá-lo a pelo menos dividir as coisas em partes mais gerenciáveis.

Amy Blankenship
fonte
Também trabalhei com a Macromedia Authorware, @ amy-blankenship. Não me lembro de qual versão era a última vez que trabalhei com ela, talvez 3. Foi substituída pelo Flash / Showckwave ou ainda existe?
Tulains Córdova
Eles eram coisas diferentes. A Macromedia causou muita confusão na versão 5 (de ambos) chamando tudo de Shockwave, incluindo Director, quando empacotado para a web. O Authorware foi descontinuado pela Adobe após a aquisição, o Flash ainda está em andamento.
quer
1

Quando eu estava na universidade, fomos ensinados longamente sobre "O problema variável global" - uma coleção de bugs e problemas de manutenção de código causados ​​por muitas variáveis ​​globais.

Algumas variáveis ​​são mais perigosas que outras.

Seguro : Variáveis ​​que não afetam o fluxo de controle, por exemplo, Sobrenome

Perigoso : Qualquer variável que afecta o fluxo de controle do programa, por exemplo, DeliveryStatus

Mais perigoso primeiro:

  • Status do composto (modo e submodo)
  • Valores compostos (total, subtotal)
  • Status único (modo)
  • Valores únicos (contagem)

Para evitar o "problema variável global", é necessário

  • Documente cada variável e função.
  • Mantenha as variáveis ​​relacionadas próximas (com o código que as utiliza) na mesma seção do código-fonte.
  • Oculte as variáveis ​​"perigosas", para que outros programadores não saibam de sua existência. Evite usá-los diretamente, especialmente em outras seções do código.
  • Forneça funções que leiam / gravem variáveis ​​perigosas (para que outros programadores não precisem).

Para estruturar seu código , quando nenhuma estrutura estiver disponível no idioma, use comentários e convenções 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";

fonte
0

Não sei como eles fizeram.

Mas acho que as linguagens modernas de POO tiveram um problema muito semelhante em relação à colisão de nomes .

A solução está adotando o espaço para nome . É um conceito abstrato, mas amplamente adotado por várias implementações (pacotes Java, namespace .NET, módulos Python).

Se o idioma que você está usando não tiver uma limitação muito estreita sobre o comprimento da nomeação, você poderá aplicar o espaço para nome a uma boa nomeação de variável.

Portanto, o nome da variável também representa o escopo da variável.

Tente definir um padrão de nomeação como este: order_detail_product_code, order_detail_product_unit_price. Ou para os contadores ou swaps temporários: tmp_i, tmp_swap.

Alberto De Caro
fonte
0

Nas linguagens em que todas as variáveis ​​são globais (usei algumas), usamos uma convenção de nomenclatura de variáveis. Por exemplo: se eu realmente quisesse usar uma variável como global, poderia usar o prefixo "m_" ou "_". Claro que isso ainda depende dos desenvolvedores para ter essa disciplina

bytedev
fonte