Newsgroup: it.comp.lang.perl
Titolo: includere librerie con path relativo

Salve,
     ho una cartella con lo script principale e la cartella "lib" con 
tutte le librerie che vengono poi incluse nello script...ora questa 
cartella può essere spostata in diverse cartelle quindi cambia 
l'absolute path dello script e delle lib...vorrei sapere come fare ad 
ottenere l'absolute path si uno script per poi modificare (spero che si 
possa fare!!!) a runtime il valore da accostare a "use lib" ... 
ho bisogno di dare a use lib un path assoluto perchè lo script viene 
eseguito da cron
grazie

 eseguito da cron
il seguente script sembra funzionare:
use strict;
use warnings;
BEGIN {
   use Cwd 'abs_path';
   abs_path($0) =~ m|^ ( (?: .* / (?: \.\.?\z )? )? ) ([^/]*) |xs;
   unshift( @INC, $1 . 'lib' );
}
use Proc::Daemon;
use Proc::PID::File;
foreach my $inc ( @INC )
{
   print "$inc\n";
}
__END__;
cmq, ho sempre creduto che BEGIN fosse la primissima cosa ad essere 
eseguita...tuttavia se sposto prima del blocco {} di BEGIN i moduli da 
caricare lo script va in errore: "Can't locate..."
use Proc::Daemon;
use Proc::PID::File;
BEGIN {
   use Cwd 'abs_path';
   abs_path($0) =~ m|^ ( (?: .* / (?: \.\.?\z )? )? ) ([^/]*) |xs;
   unshift( @INC, $1 . 'lib' );
}

 caricare lo script va in errore: "Can't locate..."
Le direttive use sono sempre eseguite in fase di BEGIN, per cui è come
se avessi:
BEGIN { use Whatever; }
Per maggiori dettagli perldoc -f use
Ciao,
   Flavio.

 }
Devi distinguere tra "compile time" e "run time".
Un blocco BEGIN ti garantisce che il suo body venga eseguito in fase di 
compilazione, quindi certamente prima di qualsiasi altra porzione di 
codice la cui esecuzione è differita al run time.
Però anche "use" è eseguita in compile time, quindi se nel tuo codice 
compare prima di BEGIN, viene eseguita prima.
In altre parole una "use" a sua volta altro non è che una BEGIN 
camuffata (come sta scritto su Programming Perl ;-)
Ciao,
Emanuele.

 eseguito da cron
Ti consiglio di fare cosě.
Diciamo che il tuo script si chiama "
mioscript.pl
". Prepara nella stessa
directory uno script shell con il seguente contenuto.
 #!/bin/sh
 mydir=$(dirname $0)
 exec perl -I$mydir/lib $mydir/
mioscript.pl
 $@
Nel cron inserirai una chiamata allo script shell. Gli eventuali argomenti
($@) saranno passati allo script perl.
Max

 (compresi memory leak praticamente introvabili).
Mi interessa. Puoi espandere il concetto ?
S.
-- 
Stefano Rodighiero      |  
http://larsen.perlmonk.org
mailto:
lar...@perl.it
   |  Italian Perl Mongers: 
http://www.perl.it

 mailto:
lar...@perl.it
   |  Italian Perl Mongers:
http://www.perl.it
Sei nel tuo periodo "approfondimenti"? 
http://www.perlmonks.org/?node_id=641294
Ciao,
   Flavio :)

 
http://www.perlmonks.org/?node_id=641294
Mai stato più lontano dall'esserlo ,)
Grazie per il link!


 
http://www.perlmonks.org/?node_id=641294
Ecco, ora ho *anche* visto il link :D
 
Diciamo allora che sono nel periodo in cui sono ignorante, 
e quello dura e durerà a lungo.


 S.
Il modo migliore per vedere quali sono le precauzioni aggiuntive che lib 
adotta rispetto ad una semplice unshift su @INC, è proprio dare 
un'occhiata al codice di 
lib.pm
:
http://search.cpan.org/src/NWCLARK/perl-5.8.8/lib/lib_pm.PL
(a rigore si tratta del template di 
lib.pm
, ma 
lib.pm
 lo si vede 
benissimo ;-)
Le subroutine interessanti sono "import" e "_get_dirs", che effettuano 
una serie di controlli (utili soprattutto per la portabilità).
Poi per quanto riguarda più specificamente i potenziali memory leak, 
essi derivano dalla possibilità che il frammento di codice che aggiunge 
un certo path ad @INC venga (inavvertitamente) eseguito più volte: in 
questo caso continuerebbero ad essere aggiunti elementi ad @INC (con lo 
stesso valore), senza alcun controllo.
Invece anche laddove un ipotetico <use lib 'un/certo/path'> venisse 
eseguito più volte, lib eliminerebbe comunque tutti i duplicati da @INC.
Il frammento di codice di 
lib.pm
 che se ne incarica è:
 
     # remove trailing duplicates
     @INC = grep { ++$names{$_} == 1 } @INC;
presente alla fine della sub import.
Un saluto,
Emanuele.

 stesso valore), senza alcun controllo.
Ma il memory leak in questo caso sarebbe dato dal fatto che @INC è un
po' più grande del dovuto (per una qualsiasi definizione di "un po'
più", che mi rendo conto può essere anche "molto più") o da altri
meccanismi che la presenza di duplicati può comportare?

 meccanismi che la presenza di duplicati può comportare?
Credo si intenda che, in caso di loop (ma dovrei pensare ad un esempio
di svista di questo genere), @INC può diventare arbitrariamente grande.


polettix wrote:

Esattamente la prima che hai detto (che può essere "molto più" ad 
esempio nel caso di un'applicazione server-side che riesegue la unshift 
su un @INC persistente ad ogni invocazione del client).
Altri effetti perversi per via delle duplicazioni dei path in @INC non 
dovrebbero essercene, perché la require si ferma non appena trovata la 
libreria richiesta, ignorando quindi gli eventuali duplicati (e la use 
fa lo stesso perché utilizza la require).
Tra le funzioni che fanno uso di @INC rimane la "do", che anch'essa 
dovrebbe fare lo stesso (ma non ci posso mettere la mano sul fuoco come 
per la altre due).
Non è un gran memory leak (né come probabilità né come /crescita/), ma 
rimane un memory leak ;-)
Ciao,
Emanuele.

 rimane un memory leak ;-)
Beh, l'esempio dell'ambiente persistente mi sembra già di per sé
sufficientemente inquietante.
Ciao e grazie,
   Flavio.