Newsgroup: it.comp.lang.perl
Titolo: AIUTO! Variabili globali, statement SQL e subs

Salve
per chi conosce e usa SQL saprà di quanto sia noioso dover, ogni volta,
sostituire i singoli apici con i doppi apici nei campi di testo in questo
modo
$nome = "Giovanni Dell'Orto";
$nome =~ s/\'/\'\'/g;
$sql = "INSERT INTO [tabella] ([nome]) VALUES ('$nome')";
Al ché diventa davvero noioso quando si devono inserire decine di campi.
Allora stavo pensando di fare una funzione che faciliti le cose in tal
senso:
incollo:
# Questa funzione cerca le variabili in una stringa *NON INTERPOLATA*
(single-quoted)
# E le sostituisce con il loro valore, sostituendo i singoli apici con due
apici
# Utile per gli inserimenti SQL
sub adjust {
 my $string = shift;
 foreach(split(/ /, $string)) {
  if (/(\$[\w\d]+)/) {
   my $var = $1;
   my $value = eval($var);
   $var =~ s/\$//;
   $value =~ s/\'/\'\'/g;
   $string =~ s/\$$var/$value/;
  }
 }
 $string;
}
La sub funziona e fa quello che deve fare, c'è un solo problema: sostituisce
le variabili con il loro valore SOLO se queste sono globali.
Se faccio una cosa del genere:
sub inserisci {
    my $nome = "Giovanni Dell'Orto";
    my $comune = "Sant'Ilario d'Enza";
    my $sql = adjust(q| INSERT INTO [....eccetera.......] |);
    # [resto del codice]...
}
accade che, siccome $nome e $comune sono sono globali, non vengono
sostituite con il loro valore.
Purtroppo, per forza di cose sono costretto a usare "my" in quasi tutte le
sub del programma.
Esiste un modo per far sì che la sub "adjust" acceda ai valori delle
variabili dichiarate con my nel main?
(forse avrei potuto altre parole per formulare questa domanda... ma credo
che cosi' si capisce).
Credo che si potrebbe fare un modulo invece che una sub... qualcosa l'ho
letta nella documentazione ma non ci ho capito granchè fra "esportazione",
"simboli" ecc....
Please Help!! :-)
Guido.

Altra domanda:
ho una stringa:
$string = "('Giovanni Dell'Orto', 'Sant'Ilario d'Enza')";
Come fareste un pattern matching per cercare tutto quello che c'è fra un
apice e l'altro?
il problema è che nelle stringhe da cercare ci sono degli apici.. anzi, ci
debbono essere per forza, altrimenti è inutile :-)
$1 dovrebbe contenere "Giovanni Dell'Orto" e _NON_ "Orto" oppure "Sant"
oppure "Enza".
how-to?

variabili dichiarate con my nel main?
Nel modo in cui vuoi farlo tu, penso proprio di no: le variabili lessicali
non sono accessibili per nome in fase di esecuzione. Non puoi sperare che
l'interprete sappia che cosa vuol dire "$nome", a meno che $nome non sia
una variabile non lessicale (non necessariamente globale, una local
dovrebbe funzionare uguale).
Puoi:
1) Creare una funzione che trasformi solo il valore del campo:
   sub adjust {
     my $value = shift;
     $value =~ s/\'/\'\'/g;
     $value;
   }
   (Non l'ho verificata, ma credo che l'idea sia chiara.)
2) Crearti una tua notazione per le query parametriche, e un tuo interprete
per queste query:
Potresti per esempio decidere che i parametri sono racchiusi tra %% :
    $sql = "INSERT INTO [tabella] ([nome]) VALUES ('%%NOME%%')";
quindi il tuo interprete riconosce i parametri (cosi' come la funzione che
hai scritto riconosce le variabili), e li sostituisce con il loro valore,
usando, per esempio, un hash:
   sub adjust {
     my $string = shift;
     my $hash = shift;
     bla bla bla.... ciclo interprete {
        bla bla...
        s/$parametro/$hash->{$parametro}/g
      }
    bla bla bla....
   }
E la chiameresti piu' o meno cosi':
   sub inserisci {
    my %parametri;
    $parametri{%%NOME%%} = "Giovanni Dell'Orto";
    $parametri{%%COMUNE%%} = "Sant'Ilario d'Enza";
    my $sql = adjust(q| INSERT INTO [.. %%NOME%%, %%COMUNE%%...] |);
    # [resto del codice]...
   }
(Scrittura, perfezionamento, verifica e correzione lasciati come esercizio
per il lettore)
Non escludo anche che qualcosina in questo senso gia' ci sia. Prova a
guardare qualche modulo dbd o simili.
Ciao.

    my $sql = adjust(q| INSERT INTO [.. %%NOME%%, %%COMUNE%%...] |);
    my $sql = adjust(q| INSERT INTO [.. %%NOME%%, %%COMUNE%%...] |,
    %parametri);
(O quale che sia il modo di passare un reference ad hash: i lunedi' mattina
che cadono di martedi' sono i peggiori.)
Ciao.

 variabili dichiarate con my nel main?
Solo se le variabili sono dichiarate prima della sub.
Comunque, se non vuoi usare placeholder/bind_param(), visto che adjust()
di fatto non sfrutta l'interpolazione del Perl, tanto vale usare un %hash
e scriversi una funzione di interpolazione. Ad esempio:
 sub sql_replace_values
 {
   my ( $dbh, $hash, $sql_ref ) = @_;
   $$sql_ref =~ s/(:([\w\d]+))/ $dbh->quote( $hash->{$2} ) /ge;
 };
 
 my $sql = "UPDATE PIPPO SET PIPPO=:pippo, PLUTO=:pluto";
 my %values = ( pippo => "E' PIPPO",  pluto => "E' PLUTO" );
 
 sql_replace_values( $dbh, \%values, \$sql );
 
Max

non sono accessibili per nome in fase di esecuzione.
.... al di fuori del loro ambito statico di definizione.
(Io lo ODIO il lunedi'!!)
Ciao.

 senso:
Esiste il metodo 'quote' che fa quello che vuoi tu, se usi l'interfaccia 
DBI/DBD per lavorare con i database RDBMS (perldoc DBI). In tal caso
usando i placeholders (?, :1, ) non hai nemmeno bisogno di quotare.

Se hai bisogno di modificarle e la sub _non_ sta nello stesso package, 
un modo è di passarle come riferimento:
---ex.pl---	
#!/usr/bin/local/perl
use MyPackage;
use strict;
my $value = 'old value';
print $value,"\n";
my $result = MyPackage::mySub(\$value);
print $value,"\n";   
---ex.pl---
---MyPackage.pm---
package MyPackage;
sub mySub {
   my $value_ref = shift;
   $$value_ref = 'new value';
}
1;  
---MyPackage.pm---
	%> perl 
ex.pl
	%> old value
	%> new value
	- Enrico

how-to?
Forti di quello che abbiamo appena imparato circa il modificatore di
quantificatore ? (e posto che l'informazione serva ancora), si potrebbe
tentare di risolvere cosi`:
	while (<DATA>) {
		@stringhe = /\B'(.*?)'\B/g;
		for my $stringa (@valori) {
			print '[', $stringa, "]\n";
		}
		print "###\n";
	}
	__END__
	('Giovanni Dell'Orto', 'Sant'Ilario d'Enza')
	('Giovanni Dell'Orto', '', 'Sant'Ilario d'Enza')
Il problema e` che l'ambiguita` e` giusto dietro l'angolo e scegliere gli
apici "giusti" e` tutt'altro che banale (o, a volte, tutt'altro che
possibile).
Ciao.