Por que o comportamento de escopo padrão em Perl é da maneira que é?

Dec 10 2020

Estou aprendendo Perl para a escola e atualmente estou aprendendo sobre o uso da mypalavra - chave e sobre o escopo em Perl. (Para referência, eu estava olhando como devo usar a palavra-chave "meu" em Perl? ). Espero que esta pergunta já não tenha sido feita em outro lugar, mas se não ... por que o comportamento padrão do Perl é da maneira que é?

Parece-me que um escopo padrão no estilo C faz mais sentido ... você declara uma variável dentro de um bloco, a variável existe dentro desse bloco e, uma vez que você sai desse bloco, essa variável não está mais acessível. Por que em Perl, para especificar esse comportamento, você deve usar a mypalavra - chave? Parece que limitar o escopo de uma variável apenas onde ela é usada seria um bom comportamento padrão, e usar myo tempo todo parece ser muito redundante e contribuir para a desordem do código.

Parece um pouco como entrar no supermercado e imediatamente declarar em voz alta sua marca preferida de tal e tal coisa antes de continuar com suas compras, apenas no caso de alguém ao seu redor estar curioso (o que provavelmente não era).

(Possível duplicata, esta questão pode ser retirada ... Por que declarar a variável Perl com "meu" no escopo do arquivo?. )

Respostas

9 ikegami Dec 10 2020 at 06:30

Se você deseja variáveis ​​com escopo léxico, você precisa de alguma forma de declaração. [1]


Parece-me que um escopo padrão no estilo C faz mais sentido ... você declara uma variável dentro de um bloco, a variável existe dentro desse bloco e, uma vez que você sai desse bloco, essa variável não está mais acessível

É exatamente assim que funciona em Perl. Onde se declara uma variável usando int iem C, usa-se my $iem Perl. Ambos criam uma variável com escopo léxico, ou seja, uma variável que só é visível no bloco atual e nos blocos contidos. Ao executar o código fora do bloco, a variável não está acessível. O escopo das variáveis ​​em Perl é o mesmo que o escopo das variáveis ​​em C. [2]

// Can't use `i` here.           # Can't use `$i` here.
{                                {
   // Can't use `i` here.           # Can't use `$i` here. int i = 4; my $i = 4;
   printf("%d\n", i);       4       say $i; { { printf("%d\n", i); 4 say $i;
      int i = 5;                       my $i = 5; printf("%d\n", i); 5 say $i;
   }                                }
   printf("%d\n", i);       4       say $i; } } // Can't use `i` here. # Can't use `$i` here.

  1. Python não tem declarações de variáveis ​​explícitas, mas também não tem variáveis ​​com escopo léxico; Variáveis ​​Python têm escopo de função.

  2. No entanto, o tempo de vida das variáveis ​​não é o mesmo. Um escalar pode ser mantido ativo após o final do bloco no qual ele reside em Perl, mas esse não é o caso para variáveis ​​semelhantes em C (variáveis ​​com "duração de armazenamento automático").

    Por exemplo,

    # You can't use `@a` outside of the sub,
    # But you can use the created array anonymously.
    sub f { my @a = qw( abc def ); return \@a; }
    

    Nesse sentido, my $xé mais semelhante a uma estrutura alocada dinamicamente.

6 Schwern Dec 10 2020 at 07:00

Porque foi assim que Larry Wall fez em 1987 e Perl 5 continua compatível com essa decisão. Variáveis ​​lexicais não foram introduzidas até o Perl 5 em 1994 e até então havia uma grande base instalada de programas Perl 4.

Vou especular por quê. Perl não foi concebido como uma linguagem de aplicação, tornou-se uma. Perl 1 foi escrito em 1987 como uma alternativa mais poderosa para sed , awk e Bourne shell .

Se você tem um problema que normalmente usaria sed ou awk ou sh, mas ele excede suas capacidades ou deve ser executado um pouco mais rápido, e você não quer escrever bobagens em C, então perl pode ser para você.

Do manual do Perl 1.0 .

Os programas sed e awk geralmente têm apenas uma linha. E no shell as variáveis ​​são globais. Dado o propósito do Perl 1, estava tudo bem.

Os padrões de engenharia de software aceitos mudaram muito nas últimas décadas. Na época em que os sistemas eram menores e mais simples, as variáveis ​​globais eram mais aceitáveis. À medida que a complexidade aumenta, as variáveis ​​globais são cada vez mais um perigo.

1 lordadmira Dec 12 2020 at 11:15

Estritamente falando, o escopo padrão das variáveis ​​em Perl é o pacote global. Variáveis que não precisam ser declaradas . Isso diz muito sobre a filosofia do Perl. É orientado a tarefas e se destaca em prototipagem rápida e programação rápida e suja. Você pode escrever programas completos na linha de comando para realizar tarefas bastante complexas ( perl -e). Apenas um masoquista faria perl -e 'use strict; ...'. Você apenas escreve variáveis ​​e elas funcionam. Uma dessas filosofias é DWIM - faça o que quero dizer. Isso é o completo oposto da maioria das linguagens de programação "rígidas", nas quais você precisa definir o mundo antes de fazer qualquer coisa.

Em seguida, no tempo bom de Larry nós fomos strict, use vars, my, our, e statepara completar a gestão das variáveis. Eles trabalham para nós, não o contrário. Na verdade, pode ser considerado uma programação rude não colocar certos dados em globais. Porque eu não necessariamente sei melhor do que o próximo cara e se ele quer introspectar ou modificar meu código ou módulo, tudo bem e amigável.

Aqui estão alguns links muito instrutivos para palestras de Larry Wall, o criador do Perl.

Perl, a primeira linguagem de computador pós-moderna

A Cultura de Perl

Mas, falando sério, se há um germe de uma ideia importante na cultura Perl, é esta: controle demais é tão mortal quanto controle insuficiente. Precisamos de controle e precisamos do caos.

Programar é difícil, vamos fazer o script ...

As frustrações da programação do shell Unix levaram diretamente à criação do Perl. Descobri que o shell scripting era intrinsecamente limitado pelo fato de que a maioria de seus verbos não está sob seu controle e os substantivos são empobrecidos, restritos a strings e arquivos, com tipologia sabe-se lá o quê. Não quero falar com uma linguagem de computador estúpida. Quero que minha linguagem de computador entenda as strings que digito.

Para obter mais informações, visite perl.com