2017-04-18 1 views
3

Perl Getopt::Long permet à un développeur d'ajouter leurs propres options à un script. Il est également possible d'autoriser plusieurs valeurs pour une option par le use of a repeat specifier, comme dans les expressions régulières. Par exemple:Ajouter Getopt :: Long options dans un hachage, même en utilisant un spécificateur de répétition

GetOptions('coordinates=f{2}' => \@coor, 'rgbcolor=i{3}' => \@color); 

De plus, option values can be stored in a hash, comme ceci:

my %h =(); 
GetOptions(\%h, 'length=i'); # will store in $h{length} 

Ce que je suis en train de faire est, combiner ces deux méthodes pour se retrouver avec un hachage de mes options, même quand ils avoir plusieurs valeurs. Par exemple, disons que je veux autoriser trois options: anniversaire (trois nombres entiers), parents (une ou deux chaînes), prénom (exactement une chaîne). Disons aussi que je veux mettre ces valeurs dans un hachage. J'ai essayé les éléments suivants:

use strict; 
use warnings; 

use Getopt::Long; 
use Data::Dumper; 

my %h =(); 
GetOptions(\%h, 'bday=i{3}', 'parents=s{1,2}', 'name=s{1}'); 

print Dumper(\%h); 

Et testé, mais la sortie est la suivante:

perl optstest.pl --bday 22 3 1986 --parents john mary --name ellen 
$VAR1 = { 
    'name' => 'ellen', 
    'parents' => 'mary', 
    'bday' => 1986 
}; 

Seule la dernière valeur de chaque option est effectivement utilisée dans le hachage. Ce que je voudrais, cependant, est:

$VAR1 = { 
    'name' => 'ellen', 
    'parents' => ['mary', 'john'], 
    'bday' => [22, 3, 1986] 
}; 

Si « ellen » serait dans un tableau, ou si tout était à l'intérieur d'un hachage, ce serait bien aussi.

N'est-il pas possible de combiner ces deux fonctionnalités de Getopt::Long, c'est-à-dire de placer des options dans un hachage et d'utiliser des spécificateurs de répétition?

Répondre

6
use Getopt::Long; 
# enable for debugging purposes 
# Getopt::Long::Configure("debug"); 
use Data::Dumper; 

my %h =(); 
GetOptions(\%h, 'bday=i{3}', '[email protected]{1,2}', '[email protected]{1}'); 

print Dumper(\%h); 

est-ce ce que vous voulez?

$VAR1 = { 
      'bday' => 1986, 
      'name' => [ 
         'ellen' 
        ], 
      'parents' => [ 
         'john', 
         'mary' 
         ] 
     }; 
+0

Je voulais 'bday' en tant que tableau, mais en effet. J'ai besoin de la notation '@ {}'. Merci! –

3

Si vous voulez un tableau, vous devez lui donner une référence à un tableau.

local @ARGV = qw(--x y z); 
my %h = (x => []); 
GetOptions(\%h, 'x=s{2}'); 
print(Dumper(\%h)); 

Vous devez spécifier si vous voulez un tableau.

local @ARGV = qw(--x y z); 
GetOptions(\my %h, '[email protected]{2}'); 
print(Dumper(\%h)); 

Sortie:

$VAR1 = { 
      'x' => [ 
        'y', 
        'z' 
       ] 
     }; 
+0

Merci pour la réponse! Je n'aime vraiment pas la première option. Tout d'abord parce qu'il va générer des tableaux vides même si une option n'est pas spécifiée dans la CLI. Ce n'est simplement pas pratique: la simple vérification de l'existence de l'option avec 'exists $ h {'option'}' retournera toujours vrai, même s'il n'est pas défini. Je ne peux pas imaginer que les développeurs de GetOpt aient prévu cet usage. La deuxième suggestion fonctionne bien, alors je vais utiliser ça. Merci. –

1

La section Options with multiple values de la documentation que vous lien vers dit aussi ce

Avertissement: Ce qui suit est une fonctionnalité expérimentale.

Il dit tout à l'heure

GetOptions (\% h, 'couleurs = s @'); # Poussera à @ {$ h {couleurs}}

donc je suppose qu'il était l'intention de l'auteur pour que cela fonctionne de la même manière avec les spécificateurs répétées, et que vous avez trouvé un bug

I suggérez que vous le signaler à Perl 5 Porters en utilisant l'perlbug utilitaire qui fait partie de l'installation Perl

+1

Considérant les autres réponses ici, pensez-vous toujours que c'est un bug? La réponse suggérée d'utiliser '@ {1,2}' fonctionne bien, mais peut-être pensez-vous que cela devrait aussi fonctionner sans une déclaration de type? –

+0

@BramVanroy: Absolument. Si la syntaxe que vous avez utilisée est incorrecte, elle ne devrait pas être acceptée par le module. Si c'est correct alors ça devrait marcher. En aucun cas, il ne doit "perdre" en silence toutes les valeurs, sauf une, d'un paramètre qui a été spécifiquement défini pour être multi-valué. Je vais soulever la question moi-même si vous préférez? – Borodin

+0

@BramVanroy: Je suppose que je dis que 'parents = s {1,2}' devrait toujours se comporter comme 'parents = s @ {1,2}' car traiter une telle valeur comme un simple scalaire est un non-sens. – Borodin