Newsgroup: it.comp.lang.perl
Titolo: perchè ancora errore??

Salve a tutti,
	vorrei che all'avvio, il mio interprete si accorgesse in che OS
è e di conseguenza mi carichi dei moduli oppure altri...
Ho scritto questo pezzetto si codice sotto linux:
<CODE>
BEGIN{
	if($^O=~/Win/i){
 	       use Win32;
	}
}
</CODE>
Tuttavia mi da sempre errore perchè non trova Win32...
Come mai? :-(
Come posso fare questo controllo all'avvio dello script?
-- 
nathanvi
ICQ --> 20318568
mail --> vitto.z A_T 
tiscali.it

 
Prova cosi':
BEGIN{
	if($^O=~/Win/i){
  	    eval "use Win32";
             die $@ if $@;
	}
}
Ciao
gmax
-- 
   ____ ____  _____ _   _
  / _  |    \(____ ( \ / )
( (_| | | | / ___ |) X (
  \___ |_|_|_\_____(_/ \_)
(_____|
Sapere, saper fare, fare, far sapere
http://gmax.oltrelinux.com

Come posso fare questo controllo all'avvio dello script?
me sembra un pochino contorto :)
ma stai cercando di far caricare win32 su linux?
non riconosce il sistema?
qual'è l'errore?
--
pigmalion at home
http://www.pigmalion.info/

 
Allora funziona ma adesso mi dici come diavolo ti è venuto 
in mente :-)
Come hai capito che ci voleva l'eval?
E soprattutto perchè ci vuole eval e non basta una semplice istruzione?
Io pensavo che eval servisse semplicemente per rendere codice una
variabile...


 Come posso fare questo controllo all'avvio dello script?
Per rispondere bisogna prima richiamare qualche nozione sul
ciclo di vita di uno script Perl. L'interprete perl puo` 
trovarsi essenzialmente in due stati: o sta compilando del
codice, oppure lo sta eseguendo. 
Naturalmente, visto che si sta parlando di Perl, esistono 
tecniche per sovvertire questo normale comportamento. Una di
queste tecniche e` l'uso dei blocchi BEGIN, che vengono 
eseguiti non appena vengono compilati, e quindi ancora nella
fase di compilazione. In altre parole scrivere un blocco 
BEGIN equivale a dire: "Scusa perl, so che sei occupato a
leggere il mio programma e a compilarlo, ma non potresti 
_eseguire_ questo codice _non_appena_ lo hai compilato?"
E lui, gentilmente, esegue. 
Detto questo, bisogna ricordare ancora un particolare che
riguarda use. Come puoi leggere in 'perldoc -f use': 
  " [use Module LIST] is exactly equivalent to
    BEGIN { require Module; import Module LIST; } "
Perl "traduce" sempre le direttive use() in un blocco 
BEGIN, in maniera tale che la require() (alla quale use()
e`, nel senso spiegato, equivalente) venga eseguito a 
"compile time", cioe` prima del resto del codice del 
programma, il cui funzionamento probabilmente si basa 
sull'avvenuta esecuzione della use(). Il tutto in maniera
incondizionata, come hai avuto modo di constatare con 
il tuo pezzo di codice. 
Per avere ulteriore dimostrazione di quanto detto, si puo`
usare il modulo B::Deparse, che per cosi` dire va a sbirciare
quello che fa il compilatore, per poi riferirlo.
Dato il seguente script 
win.pl
:
  --------------------------------------------------------
    BEGIN{
      if($^O=~/Win/i){
             use Win32;
      }
    }
  --------------------------------------------------------
si puo` vedere a cosa equivale il risultato della compilazione
con questo comando:
  --------------------------------------------------------
    lorenzo@alice:~$ perl -MO=Deparse 
win.pl
 
    use Win32;
    sub BEGIN {
        if ($^O =~ /Win/i) {
            ();
        }
    }
 
win.pl
 syntax OK
  --------------------------------------------------------
Le soluzioni a questo problema sono almeno due. 
Una e` quella di gmax, che usa la forma eval EXPR. 
Il Camelbook propone una spiegazione di eval() che secondo me
e` particolarmente significativa in questo contesto:
  "A given compile phase does mostly compile-time stuff,
  but it also does some run-time stuff via BEGIN blocks.
  A given run phase does mostly run-time stuff, but it can
  do compile-time stuff through operators like eval STRING"
L'eval di gmax riceve il codice contenuto nell'espressione,
lo compila e lo esegue in un'unica tornata, come se fosse
eseguito da un interprete separato (ma influenzando, e questo
e` fondamentale, lo stesso ambiente).
L'altra soluzione, secondo me piu` facile da capire e, credo, 
piu` tipica, e` fare quello che fa use(), ma senza farlo in 
un blocco BEGIN. In altre parole, usare require().
  --------------------------------------------------------
    BEGIN{
      if($^O=~/Win/i){
             require Win32;
             # qui forse ci vuola anche una import(),
             # non conosco il modulo Win32
      }
    }
  --------------------------------------------------------
ciao,
S.
-- 
Stefano Rodighiero      |  
http://larsen.perlmonk.org
mailto:
lar...@perl.it
   |  
http://www.perl.it

 variabile...
Se usi la forma
eval { BLOCCO }
allora BLOCCO viene compilato, e quindi puo' generare errori.
Stefano lo ha spiegato in dettaglio.


 qual'è l'errore?
Con eval non ho più avuto errori.
:-)
