Test clef hash dans un document en ligne (dans un eval)
4 réponses
Yves Martin
Bonjour,
J'ai un warning dont j'aimerai me débarrasser dans un script.
Mon code correspond à ceci: a.pl
- ouvre un fichier FILE
- évaluation de b.pl (qui écrit dans FILE avec un inline document)
- ferme FILE
Et l'exécution lève 15 warnings identiques à l'endroit où j'évalue 'b.pl':
Use of uninitialized value in concatenation (.) or string at (eval 5) line 1.
Après quelques recherches, je constate qu'il s'agit de warning concernant
l'accès à des valeurs $options{"myparam"} non défini dans le document inline.
Pour simplifier, j'ai réalisé un cas test:
#!/usr/bin/perl
use strict;
use warnings;
open(FILE, ">test.txt");
my %options = ("test" => "coucou");
my $exp = "print FILE <<EOF_server;\n$options{\"truc\"}\n$options{\"test\"}\nEOF_server\nreturn 1;";
À (at) Wed, 25 Jan 2006 15:14:34 +0100, Yves Martin écrivait (wrote):
Comment éviter ce warning ? C'est à dire tester l'existence de $options{"truc"} avant de l'inclure dans le document en ligne ?
if (defined $options{truc}) { ... }
En revanche, il me semble que vous utilisez 'eval' dans une situation où ce n'est pas adapté...
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/> Perl en français - <http://perl.enstimac.fr/>
Yves Martin
Paul Gaborit writes:
À (at) Wed, 25 Jan 2006 15:14:34 +0100, Yves Martin écrivait (wrote):
Comment éviter ce warning ? C'est à dire tester l'existence de $options{"truc"} avant de l'inclure dans le document en ligne ?
if (defined $options{truc}) { ... }
Malheureusement dans un document en ligne (<<EOF .... EOF) seul '$options{truc}' est interprété...
Je cherche une construction équivalente à celle de bash:
${parameter:-word} Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
mais utilisable directement en document en ligne comme
print FILE <<EOF Mon template de fichier avec mon paramêtre $options{truc} inclu... Et support d'une valeur par défaut. EOF
Si $options{truc} n'existe pas, j'aimerai le remplacer par un chaîne vide pour éviter les warning de concaténation.
En revanche, il me semble que vous utilisez 'eval' dans une situation où ce n'est pas adapté...
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le contexte global du script, c'est bien pratique ;)
-- Yves Martin
Paul Gaborit <Paul.Gaborit@invalid.invalid> writes:
À (at) Wed, 25 Jan 2006 15:14:34 +0100,
Yves Martin <ymartin@nospam.fr> écrivait (wrote):
Comment éviter ce warning ? C'est à dire tester l'existence de
$options{"truc"} avant de l'inclure dans le document en ligne ?
if (defined $options{truc}) {
...
}
Malheureusement dans un document en ligne (<<EOF .... EOF) seul
'$options{truc}' est interprété...
Je cherche une construction équivalente à celle de bash:
${parameter:-word}
Use Default Values. If parameter is unset or null, the expansion of word is
substituted. Otherwise, the value of parameter is substituted.
mais utilisable directement en document en ligne comme
print FILE <<EOF
Mon template de fichier avec mon paramêtre $options{truc}
inclu... Et support d'une valeur par défaut.
EOF
Si $options{truc} n'existe pas, j'aimerai le remplacer par un chaîne vide pour
éviter les warning de concaténation.
En revanche, il me semble que vous utilisez 'eval' dans une situation où ce
n'est pas adapté...
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le
contexte global du script, c'est bien pratique ;)
À (at) Wed, 25 Jan 2006 15:14:34 +0100, Yves Martin écrivait (wrote):
Comment éviter ce warning ? C'est à dire tester l'existence de $options{"truc"} avant de l'inclure dans le document en ligne ?
if (defined $options{truc}) { ... }
Malheureusement dans un document en ligne (<<EOF .... EOF) seul '$options{truc}' est interprété...
Je cherche une construction équivalente à celle de bash:
${parameter:-word} Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
mais utilisable directement en document en ligne comme
print FILE <<EOF Mon template de fichier avec mon paramêtre $options{truc} inclu... Et support d'une valeur par défaut. EOF
Si $options{truc} n'existe pas, j'aimerai le remplacer par un chaîne vide pour éviter les warning de concaténation.
En revanche, il me semble que vous utilisez 'eval' dans une situation où ce n'est pas adapté...
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le contexte global du script, c'est bien pratique ;)
-- Yves Martin
Paul Gaborit
À (at) Wed, 25 Jan 2006 17:55:14 +0100, Yves Martin écrivait (wrote):
Malheureusement dans un document en ligne (<<EOF .... EOF) seul '$options{truc}' est interprété...
Parce que vous cherchez à faire faire à l'interpolation ce qu'on fait habituellement par des mécanismes de 'template'. Il y a de nombreux modules pour faire cela. L'un des plus puissants est Template::Toolkit. On peut aussi faire à la main (cf. ci-dessous).
Je cherche une construction équivalente à celle de bash:
${parameter:-word} Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
mais utilisable directement en document en ligne comme
print FILE <<EOF Mon template de fichier avec mon paramêtre $options{truc} inclu... Et support d'une valeur par défaut. EOF
Si $options{truc} n'existe pas, j'aimerai le remplacer par un chaîne vide pour éviter les warning de concaténation.
Ce que je vous propose, c'est de faire votre propre mécanisme de template. Lorsque vous utilisez de "HERE document", je vous conseille de toujours préciser eplicitement si vous voulez ou non de l'interpolation (en mettant soit "EOF" soit 'EOF'). Donc le code que je vous propose :
------------------------------------------------------------ my %options = (truc => "ok"); # bidule n'est pas défini !
my $template = << 'EOF'; Mon template de fichier avec mon paramètre --truc-- inclu... et --bidule-- ? EOF (my $result = $template) =~ s{--([a-z]+)--}{$options{$1} || "N/A"}ge; print $result; ------------------------------------------------------------
Lorsqu'on exécute, on obtient :
------------------------------------------------------------ Mon template de fichier avec mon paramètre ok inclu... et N/A ? ------------------------------------------------------------
J'ai choisi '--' comme délimiteur mais vous pouvez évidemment adpaté cela à votre situation. Les options non définies sont remplacées par 'N/A' mais vous pouvez mettre la chaîne vide si vous préférez...
En revanche, il me semble que vous utilisez 'eval' dans une situation où ce n'est pas adapté...
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le contexte global du script, c'est bien pratique ;)
Ça peut sembler pratique mais dans 99% des cas, c'est inutile, inefficace *et* risqué...
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/> Perl en français - <http://perl.enstimac.fr/>
À (at) Wed, 25 Jan 2006 17:55:14 +0100,
Yves Martin <ymartin@nospam.fr> écrivait (wrote):
Malheureusement dans un document en ligne (<<EOF .... EOF) seul
'$options{truc}' est interprété...
Parce que vous cherchez à faire faire à l'interpolation ce qu'on fait
habituellement par des mécanismes de 'template'. Il y a de nombreux
modules pour faire cela. L'un des plus puissants est
Template::Toolkit. On peut aussi faire à la main (cf. ci-dessous).
Je cherche une construction équivalente à celle de bash:
${parameter:-word}
Use Default Values. If parameter is unset or null, the expansion
of word is substituted. Otherwise, the value of parameter is
substituted.
mais utilisable directement en document en ligne comme
print FILE <<EOF
Mon template de fichier avec mon paramêtre $options{truc}
inclu... Et support d'une valeur par défaut.
EOF
Si $options{truc} n'existe pas, j'aimerai le remplacer par un
chaîne vide pour éviter les warning de concaténation.
Ce que je vous propose, c'est de faire votre propre mécanisme de
template. Lorsque vous utilisez de "HERE document", je vous conseille
de toujours préciser eplicitement si vous voulez ou non de
l'interpolation (en mettant soit "EOF" soit 'EOF').
Donc le code que je vous propose :
------------------------------------------------------------
my %options = (truc => "ok"); # bidule n'est pas défini !
my $template = << 'EOF';
Mon template de fichier avec mon paramètre --truc--
inclu... et --bidule-- ?
EOF
(my $result = $template) =~ s{--([a-z]+)--}{$options{$1} || "N/A"}ge;
print $result;
------------------------------------------------------------
Lorsqu'on exécute, on obtient :
------------------------------------------------------------
Mon template de fichier avec mon paramètre ok
inclu... et N/A ?
------------------------------------------------------------
J'ai choisi '--' comme délimiteur mais vous pouvez évidemment adpaté
cela à votre situation. Les options non définies sont remplacées par
'N/A' mais vous pouvez mettre la chaîne vide si vous préférez...
En revanche, il me semble que vous utilisez 'eval' dans une situation où ce
n'est pas adapté...
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le
contexte global du script, c'est bien pratique ;)
Ça peut sembler pratique mais dans 99% des cas, c'est inutile,
inefficace *et* risqué...
--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
À (at) Wed, 25 Jan 2006 17:55:14 +0100, Yves Martin écrivait (wrote):
Malheureusement dans un document en ligne (<<EOF .... EOF) seul '$options{truc}' est interprété...
Parce que vous cherchez à faire faire à l'interpolation ce qu'on fait habituellement par des mécanismes de 'template'. Il y a de nombreux modules pour faire cela. L'un des plus puissants est Template::Toolkit. On peut aussi faire à la main (cf. ci-dessous).
Je cherche une construction équivalente à celle de bash:
${parameter:-word} Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
mais utilisable directement en document en ligne comme
print FILE <<EOF Mon template de fichier avec mon paramêtre $options{truc} inclu... Et support d'une valeur par défaut. EOF
Si $options{truc} n'existe pas, j'aimerai le remplacer par un chaîne vide pour éviter les warning de concaténation.
Ce que je vous propose, c'est de faire votre propre mécanisme de template. Lorsque vous utilisez de "HERE document", je vous conseille de toujours préciser eplicitement si vous voulez ou non de l'interpolation (en mettant soit "EOF" soit 'EOF'). Donc le code que je vous propose :
------------------------------------------------------------ my %options = (truc => "ok"); # bidule n'est pas défini !
my $template = << 'EOF'; Mon template de fichier avec mon paramètre --truc-- inclu... et --bidule-- ? EOF (my $result = $template) =~ s{--([a-z]+)--}{$options{$1} || "N/A"}ge; print $result; ------------------------------------------------------------
Lorsqu'on exécute, on obtient :
------------------------------------------------------------ Mon template de fichier avec mon paramètre ok inclu... et N/A ? ------------------------------------------------------------
J'ai choisi '--' comme délimiteur mais vous pouvez évidemment adpaté cela à votre situation. Les options non définies sont remplacées par 'N/A' mais vous pouvez mettre la chaîne vide si vous préférez...
En revanche, il me semble que vous utilisez 'eval' dans une situation où ce n'est pas adapté...
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le contexte global du script, c'est bien pratique ;)
Ça peut sembler pratique mais dans 99% des cas, c'est inutile, inefficace *et* risqué...
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/> Perl en français - <http://perl.enstimac.fr/>
Yves Martin
Paul Gaborit writes:
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le contexte global du script, c'est bien pratique ;)
Ça peut sembler pratique mais dans 99% des cas, c'est inutile, inefficace *et* risqué...
Merci pour les exemples et les conseils... mon problème, c'est que mon "template" doit pouvoir faire un peu ce qu'il veut: notamment récupérer des points de mesures par ssh ou snmp pour générer les blocs de service dans un fichier de configuration Nagios (efficacité et risque n'ont pas être pris en compte).
En tout cas, je vais implémenter un mécanisme de remplacement comme proposé, c'est le plus propre.
A bientôt pour une autre question ;) -- Yves Martin
Paul Gaborit <Paul.Gaborit@invalid.invalid> writes:
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le
contexte global du script, c'est bien pratique ;)
Ça peut sembler pratique mais dans 99% des cas, c'est inutile,
inefficace *et* risqué...
Merci pour les exemples et les conseils... mon problème, c'est que mon
"template" doit pouvoir faire un peu ce qu'il veut: notamment récupérer des
points de mesures par ssh ou snmp pour générer les blocs de service dans un
fichier de configuration Nagios (efficacité et risque n'ont pas être pris en
compte).
En tout cas, je vais implémenter un mécanisme de remplacement comme proposé,
c'est le plus propre.
A bientôt pour une autre question ;)
--
Yves Martin
Vu les informations que j'ai fourni ici, je suis d'accord mais dans le contexte global du script, c'est bien pratique ;)
Ça peut sembler pratique mais dans 99% des cas, c'est inutile, inefficace *et* risqué...
Merci pour les exemples et les conseils... mon problème, c'est que mon "template" doit pouvoir faire un peu ce qu'il veut: notamment récupérer des points de mesures par ssh ou snmp pour générer les blocs de service dans un fichier de configuration Nagios (efficacité et risque n'ont pas être pris en compte).
En tout cas, je vais implémenter un mécanisme de remplacement comme proposé, c'est le plus propre.
A bientôt pour une autre question ;) -- Yves Martin