Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

interpolazione variabili

8 views
Skip to first unread message

liftman

unread,
Mar 11, 2017, 8:50:52 AM3/11/17
to
Sperando che esista ancora qualcuno che legge 'sto NG..

Il subject è sibillino, ma cerco di chiarirmi :-)

Ho la necessità di leggere (e stampare) una frase da un array, che
contenga una variabile e che detta variabile venga stampata come valore.

per capirsi, ho un array '@frasi' con frasi di questo genere:

ciao $nome tutto bene?
un saluto a $nome
...
dopo tanto tempo ritorna $nome
ecc. ecc.

ma se cerco di stamparle con:

my $nome = 'pippo';
my $saluto = $frasi[rand(scalar(@frasi))];

ottango le frasi così come le ho sritte sopra e non così:

ciao pippo tutto bene?
sarà sicuramente una stronzata, ma non sono riuscito a trovare info in
merito che non siano i classici 'ciao' . $nome - 'tutto bene?' o "ciao
$nome tutto bene?".

Ah dimenticavo... l'array è su disco e vi accedo con Tie::File, ma
suppongo che non c'entri niente.

grazie a chi potrà darmi una dritta!







--
Fri(END), Boyfri(END), Girlfri(END), Bestfri(END). Everything has an END
except...Fam(ILY)! It Has 3 Letters that say I LOVE YOU

enoquick

unread,
Mar 11, 2017, 9:32:53 PM3/11/17
to
Il 11/03/2017 07:50, liftman ha scritto:
> Sperando che esista ancora qualcuno che legge 'sto NG..
>
> Il subject è sibillino, ma cerco di chiarirmi :-)
>
> Ho la necessità di leggere (e stampare) una frase da un array, che
> contenga una variabile e che detta variabile venga stampata come valore.
>
> per capirsi, ho un array '@frasi' con frasi di questo genere:
>
> ciao $nome tutto bene?
> un saluto a $nome
> ...
> dopo tanto tempo ritorna $nome
> ecc. ecc.
>
> ma se cerco di stamparle con:
>
> my $nome = 'pippo';
> my $saluto = $frasi[rand(scalar(@frasi))];
>
> ottango le frasi così come le ho sritte sopra e non così:
>
> ciao pippo tutto bene?
> sarà sicuramente una stronzata, ma non sono riuscito a trovare info in
> merito che non siano i classici 'ciao' . $nome - 'tutto bene?' o "ciao
> $nome tutto bene?".
>
> Ah dimenticavo... l'array è su disco e vi accedo con Tie::File, ma
> suppongo che non c'entri niente.
>
> grazie a chi potrà darmi una dritta!
>
>
>
>
>
>
>

se ricordo bene (il perl e' un po che non lo uso in modo approfondito)
quello che fa per te e' eval

Es:
perl -e '$a="bbbb";$b="\$a";print $b,"\n";print eval $b,"\n"'


liftman

unread,
Mar 12, 2017, 4:46:29 AM3/12/17
to
Il 12/03/2017 03:32, enoquick ha scritto:

> se ricordo bene (il perl e' un po che non lo uso in modo approfondito)
> quello che fa per te e' eval
>
> Es:
> perl -e '$a="bbbb";$b="\$a";print $b,"\n";print eval $b,"\n"'

a dire il vero dopo aver postato, ho fatto altri esperimenti ed ho
provato appnto eval(), ma mi ritornava una stringa vuota... sicuramente
ho capito male io come usarla, faccio altri esperimenti, grazie!

liftman

unread,
Mar 12, 2017, 10:02:30 AM3/12/17
to
Il 12/03/2017 09:46, liftman ha scritto:

>> Es:
>> perl -e '$a="bbbb";$b="\$a";print $b,"\n";print eval $b,"\n"'
>
> a dire il vero dopo aver postato, ho fatto altri esperimenti ed ho
> provato appnto eval(), ma mi ritornava una stringa vuota... sicuramente
> ho capito male io come usarla, faccio altri esperimenti, grazie!

ho fatto altre prove, al di fuori dell'intero script e sono arrivato
alla conclusione che sono io a sbagliare qualcosa, almeno spero.. :-D
Infatti queste poche righe funzionano come mi sarei aspettato:

my $test;
my $nome = 'pippo';
my @frasi = ("ciao $nome come stai?", "saluti a $nome", "$nome non
conosce il perl");
print $frasi[rand(scalar(@frasi))] . "\n";;
print $frasi[rand(scalar(@frasi))] . "\n";;
print $frasi[rand(scalar(@frasi))] . "\n";;

$test = $frasi[rand(scalar(@frasi))];
print $test . "\n";
$test = $frasi[rand(scalar(@frasi))];
print $test . "\n";
$test = $frasi[rand(scalar(@frasi))];
print $test . "\n";
$test = $frasi[rand(scalar(@frasi))];
print $test . "\n";

e ricevo in output:

liftman@test:~/test$ perl -w eval3.pl
saluti a pippo
ciao pippo come stai?
ciao pippo come stai?
saluti a pippo
pippo non conosce il perl
saluti a pippo
ciao pippo come stai?

ergo, si tratta al solito di un PEBKAC ed eval() in questo contesto non
serve ad una fava :-D ingago ancora...

vediamo il mio codice originale:

my $nome = $1;
tie @frasi, 'Tie::File', 'frasi';
my $mess = "$frasi[rand(scalar(@frasi))]";
untie @frasi;

ai miei occhi, pare praticamente lo stesso codice dell'esempio, con
l'unica differenza dell'uso di Tie::File, quindi riprovo modificando il
test:

#!/usr/bin/env perl
use strict;
use warnings;
use Tie::File;
my @frasi;
my $nome = 'pippo';
tie @frasi, 'Tie::File', 'frasi';
print $frasi[rand(scalar(@frasi))] . "\n";;
print $frasi[rand(scalar(@frasi))] . "\n";;
print $frasi[rand(scalar(@frasi))] . "\n";;
my $test = $frasi[rand(scalar(@frasi))];
print $test . "\n";
$test = $frasi[rand(scalar(@frasi))];
print $test . "\n";
$test = $frasi[rand(scalar(@frasi))];
print $test . "\n";
$test = $frasi[rand(scalar(@frasi))];
print $test . "\n";
untie @frasi

e il risultato:

liftman@test:~/test$ perl -w eval3.pl
$nome non conosce il perl
ciao $nome come stai?
ciao $nome come stai?
ciao $nome come stai?
ciao $nome come stai?
ciao $nome come stai?
ciao $nome come stai?

a questo punto sono perplesso.. preferivo essere io a sbagliare,
evidentemente Tie::File, ha un funzionamento anomalo, se proprio non si
vuol parlare di bug. Forse sono l'unico al mondo che ha bisogno di
interpolare una variabile all'interno di un array, letto da disco? :-)

Alla fine, perdendo "elasticità" nel mio script, posso pure evitare il
file su disco, e scrivere tutto diretamente, ma vorrei trovare una
soluzione...

enoquick

unread,
Mar 12, 2017, 3:23:03 PM3/12/17
to
Per forza che qui eval non serve,l'espansione viene gia fatta.
Quando dichiari
> my $nome = 'pippo';
> my @frasi = ("ciao $nome come stai?", "saluti a $nome", "$nome non
> conosce il perl");

$nome viene sostituito con il suo valore in quanto la stringa e'
racchiusa tra doppi quote:

my @frasi = ('ciao $nome come stai?', 'saluti a $nome', '$nome non
> conosce il perl');

Cosi l'espansione di $nome non viene fatta

liftman

unread,
Mar 12, 2017, 5:11:25 PM3/12/17
to
Il 12/03/2017 20:23, enoquick ha scritto:

> Per forza che qui eval non serve,l'espansione viene gia fatta.
> Quando dichiari
>> my $nome = 'pippo';
>> my @frasi = ("ciao $nome come stai?", "saluti a $nome", "$nome non
>> conosce il perl");
>
> $nome viene sostituito con il suo valore in quanto la stringa e'
> racchiusa tra doppi quote:
>
> my @frasi = ('ciao $nome come stai?', 'saluti a $nome', '$nome non
>> conosce il perl');
>
> Cosi l'espansione di $nome non viene fatta

ops.. è vero, ho cannato l'esempio..
resta il fatto che usando un file su disco non interpola, ho provato a
mettere doppi apici dappertutto, anche nelle frasi sul file, ma al
msssimo mi vengono stampati pure i doppi apici...

>> vediamo il mio codice originale:
>>
>> my $nome = $1;
>> tie @frasi, 'Tie::File', 'frasi';
>> my $mess = "$frasi[rand(scalar(@frasi))]";
>> untie @frasi;

ricritto paro paro, senza altro codice:
quindi sono sempre allo stesso punto. Se scrivo l'array nel codice e con
i doppi apici funziona, altrimenti (pare) di no.

questa espressione:

my $test = $frasi[rand(scalar(@frasi))];

ho provato a "virgolettarla" credo, in tutti i modi, con e senza eval,
ma continua a stampare la variabile senza interpolare..
Continuo a sperimentare...

liftman

unread,
Mar 12, 2017, 5:50:45 PM3/12/17
to
Il 12/03/2017 22:11, liftman ha scritto:

> Continuo a sperimentare...

mi sono giocato gli ultimi neuroni ma alla fine ho trovato una soluzione :-)

$test = $frasi[rand(scalar(@frasi))];
$test =~ s/\$nome/$nome/;
print $test . "\n";

per stavolta sono a posto, grazie comunque per l'aiuto morale .-D

enoquick

unread,
Mar 12, 2017, 6:50:22 PM3/12/17
to
Il 12/03/2017 15:50, liftman ha scritto:
> Il 12/03/2017 22:11, liftman ha scritto:
>
>> Continuo a sperimentare...
>
> mi sono giocato gli ultimi neuroni ma alla fine ho trovato una soluzione
> :-)
>
> $test = $frasi[rand(scalar(@frasi))];
> $test =~ s/\$nome/$nome/;
> print $test . "\n";
>
> per stavolta sono a posto, grazie comunque per l'aiuto morale .-D
>

Va bene anche con una regex ma anche con una
$test=eval($frasi[rand(scalar(@frasi))])

perl -e 'my $a="pippo"; print eval($a)' #funziona


Comunque l'importante e'che hai risolto

liftman

unread,
Mar 12, 2017, 7:27:09 PM3/12/17
to
Il 12/03/2017 23:50, enoquick ha scritto:

> Va bene anche con una regex ma anche con una
> $test=eval($frasi[rand(scalar(@frasi))])
>
> perl -e 'my $a="pippo"; print eval($a)' #funziona

purtroppo no.. e nemmeno se elimino Tie::File e lascio l'array nel listato:

#!/usr/bin/env perl
use strict;
use warnings;
use Tie::File;
my $test;
my @frasi;
my $nome = 'pippo';
tie @frasi, 'Tie::File', 'frasi';
$test = $frasi[rand(scalar(@frasi))];
$test =~ s/\$nome/$nome/;
print $test . "\n";
$test = eval($frasi[rand(scalar(@frasi))]);
print $test . "\n";
$test = $frasi[rand(scalar(@frasi))];
print eval($test) . "\n";
untie @frasi

liftman@test:~/test$ perl -w eval3.pl
saluti a pippo
Use of ?PATTERN? without explicit operator is deprecated at (eval 2)
Use of uninitialized value $test in print at eval3.pl

#!/usr/bin/env perl
use strict;
use warnings;
use Tie::File;
my $test;
my $nome = 'pippo';
my @frasi = ("ciao $nome come stai?", "saluti a $nome", "$nome non
conosce il perl");
$test = $frasi[rand(scalar(@frasi))];
$test =~ s/\$nome/$nome/;
print $test . "\n";
$test = eval($frasi[rand(scalar(@frasi))]);
print $test ;

liftman@test:~/test$ perl -w eval3.pl
saluti a pippo
Use of uninitialized value $test in print at eval3.pl...

> Comunque l'importante e'che hai risolto

questa è la cosa più importante, l'uso 8o l'abuso...) di eval, lo lascio
ad un'altra volta :-D

Aldo Calpini

unread,
Mar 13, 2017, 6:57:57 PM3/13/17
to
On 12/03/17 23:50, enoquick wrote:
> perl -e 'my $a="pippo"; print eval($a)' #funziona

no, non "funziona". sei solo stato fortunato :-)

se usassi warning (o ancora meglio strict) vedresti che non stai affatto
facendo quello che pensi.

perl -we 'my $a="pippo"; print eval($a)'
Unquoted string "pippo" may clash with future reserved word at (eval 1)
line 2.
pippo

tu stai valutando pippo come una bareword, che solo fortuitamente
coincide con la rappresentazione stringa di se stessa. maggiori
informazioni, se ti servono, le trovi qui:

https://perlmaven.com/barewords-in-perl

ma soprattutto *questo* non funziona:

perl -e 'my $a="pippo 1"; print eval($a)'
Number found where operator expected at (eval 1) line 1, near "pippo 1"
(Do you need to predeclare pippo?)

ovvero, stai cercando di eseguire il contenuto di $a come codice. che e'
una pessima, pessima idea.

quello che tu volevi fare e':

perl -e 'my $a="pippo"; print eval "qq{$a}";'

(il qq{} e' solo piu' leggibile delle virgolette, altrimenti sarebbe
stato "\"$a\"").

le virgolette vanno raddoppiate per dire a Perl di valutare la *stringa*
(non il codice) contenuta in $a, come se fosse scritta fra virgolette,
ovvero con interpolazione delle variabili.

applicato all'esempio di liftman, questo e' quello che funziona:

print eval "qq{$frasi[rand(scalar(@frasi))]\n}";


cheers,
Aldo

enoquick

unread,
Mar 13, 2017, 9:42:15 PM3/13/17
to
Il 13/03/2017 16:57, Aldo Calpini ha scritto:
> On 12/03/17 23:50, enoquick wrote:
>> perl -e 'my $a="pippo"; print eval($a)' #funziona
>
> no, non "funziona". sei solo stato fortunato :-)
>
No funziona per come e' scritto

> se usassi warning (o ancora meglio strict) vedresti che non stai affatto
> facendo quello che pensi.
>
Grazie,ma non l'ho messo apposta (ne error) perche eval potrebbe dare
problemi scritto quel modo
Insomma,e voluto

enoquick

unread,
Mar 13, 2017, 9:44:46 PM3/13/17
to
Non sto ad approfondire il codice,e' comunque meglio la scelta delle
regex che eval in questo modo.

liftman

unread,
Mar 14, 2017, 2:50:04 AM3/14/17
to
Il 13/03/2017 23:57, Aldo Calpini ha scritto:

> ovvero, stai cercando di eseguire il contenuto di $a come codice. che e'
> una pessima, pessima idea.
>
> quello che tu volevi fare e':
>
> perl -e 'my $a="pippo"; print eval "qq{$a}";'
>
> (il qq{} e' solo piu' leggibile delle virgolette, altrimenti sarebbe
> stato "\"$a\"").
>
> le virgolette vanno raddoppiate per dire a Perl di valutare la *stringa*
> (non il codice) contenuta in $a, come se fosse scritta fra virgolette,
> ovvero con interpolazione delle variabili.
>
> applicato all'esempio di liftman, questo e' quello che funziona:
>
> print eval "qq{$frasi[rand(scalar(@frasi))]\n}";

adesso mi è un poco più chiara la faccenda, anche se, visto che
funziona, lascio la regex :-)
0 new messages