[Roma.pm] Mica finisce qui... (our vs. use vars)

Emanuele Zeppieri ema_zep at libero.it
Tue Aug 7 02:08:30 PDT 2007


Aldo Calpini wrote:

> [...]
> fondamentalmente, le 
> variabili our *non* hanno uno scope.
> ma usandole come variabili di 
> package *sembra* che ce l'abbiano.

Beh, se quello di prima era un abbaglio, questa è un'insolazione :-)
Le variabili our lo scope ce l'hanno *eccome*.

Basterebbe appellarsi alla documentazione del Perl:
---------------------------------------------------
When use strict 'vars'  is in effect, our lets you use declared global
variables without qualifying them with package names,
within the lexical scope of the our declaration.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
our associates a simple name with a package variable in the current
package, for use within the current scope.
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In other words, our has the same scoping rules as my
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
---------------------------------------------------
http://perldoc.perl.org/functions/our.html

ma ormai comincia a diventare troppo facile ;-)

Perciò vengo al tuo esempio:

> prendete ad esempio questo:
> 
>   {
>       our $x = 42;
>   }
>   print "x=$x\n"; # ==> 42

Dov'è che è fallace?
Nel fatto che non usi il pragma strict vars, ovviamente.
(E questo sì che è veramente oRendo!)

Basta fare:

use strict;
{ our $x = 42 }
print $x; # Errore!

ed ottieni un errore di compilazione (del resto l'ammetti tu stesso),
che dimostra che il blocco l'effetto sulla visibilità della variabile
our ce l'ha eccome, e che quindi la variabile our è perfettamente
scopata (ed è contenta di esserlo).

Il fatto che our non possa avere effetti di limitazione di visibilità
senza strict mi sembra ovvio: our ha comunque istanziato una variabile
nello stash del package corrente (nel tuo caso main), per cui in assenza
di strict vars le variabili non qualificate rimangono comunque
utilizzabili (e vengono riferite automaticamente al package corrente).

> o perfino questo:
> 
>   $x = 42;
>   print "x=$x\n"; # ==> 42
>   {
>       our $x = 43;
>       print "x=$x\n"; # ==> 43
>   }
>   print "x=$x\n"; # ==> 43

Ti faccio notare che hai riassegnato la stessa identica variabile di 
package ($main::x), per cui che cosa ci trovi di strano nel fatto che 
dopo la seconda assegnazione alla *stessa* variabile essa assuma un 
altro valore?!!

Va be' che fa caldo...

> notate che il primo esempio ha addirittura il coraggio di non compilare 
> con use strict!

Non è sfrontatezza, è lo scope, bellezza ;-)

>il messaggio dice: Variable "$x" is not imported. ma 
> imported de che?

A parte il fatto che i messaggi sono due:

Variable "$x" is not imported ...
Global symbol "$x" requires explicit package name

Cosa ci sarebbe di strano?
Ti dice che per usare una variabile non qualificata al di fuori del suo
scope (sotto strict) la devi importare, oppure la devi qualificare col
nome del package.
In altre parole ti dice che stai utilizzando $x al di fuori del suo
scope, per l'appunto ;-)

(Concordo giusto sul fatto che il primo messaggio in genere è riferito
ad altro...)

> le variabili our introducono delle variabili di package (o, nel caso del 
> solo package main, sostanzialmente delle variabili globali), e 
> delimitarle in uno scope ne altera solo la visibilità da parte di 
> *altri* package senza qualifica completa.

Ma manco se te sbatti per teRa!
Our ne limita la visibilità *anche* nello stesso package (sotto strict),
come chiaramente (già) mostrato dallo snippet:

use strict;
{ our $x = 42 }
print $x; # Errore, qui $x non e` piu` visibile
           # e siamo sempre nello stesso package (main).

> la loro definizione non va mai 
> out-of-scope (ok, mai fino a fine programma o EOF :-).

No, come abbiamo visto va out-of-scope al di fuori del blocco che la
contiene, se sei sotto strict vars.
(In realtà ci va anche se non usi strict, ma la variabile non
qualificata rimane accessibile per via delle regole di visibilità sulle
variabili in assenza di strict vars, che sono prevalenti).

> quindi:
> 
> - non sono "scopabili" come le variabili local

Nope, come abbiamo visto, lo sono.

> - pur non essendolo, si lamentano con strict quando vengono "scopate"

Arinope, lo sono e quindi giustamente si lamentano.

> - sbrodolano la loro visibilità su altri package definiti nello stesso file

Manco pe' gnente: nel tuo esempio sei sempre nello stesso *identico*
package (main), ed hai semplicemente riassegnato un diverso valore alla
*stessa identica* variabile di package, come già detto.

Ed eccone la prova, se non fosse chiaro:

$x = 42;
print "$main::x\n"; # ==> 42
{
     our $x = 43;
     print "$main::x\n"; # ==> 43
}
print "$main::x\n"; # ==> 43

Tra l'altro, dove starebbero questi diversi package?!

Per lamentarti di questi presunti sbrodolamenti, di package avresti
dovuto definirne almeno un paio (mediante la keyword "package"), e
invece non hai definito neanche uno! (Per cui rimani sotto (il solo)
package main tutta la vita).



In definitiva, una variabile our *è* scopata e *non* sbrodola.
(Sarà strano, ma se sbrodolava e non era scopabile forse era peggio).

Ciao,
Emanuele.


More information about the Roma mailing list