Newsgroup: it.comp.lang.perl
Titolo: Barbatrucco per il nome di una sub

Ok spero di non chiedere castronerie...
mi sarebbe molto utile riuscire a far funzionare la seguente porzione di
codice:
#!/usr/bin/perl
use strict;
my$task=<STDIN>;
chomp;
############################################################
$task =~ /{gino|pino|tore}/ or die "Task errato: $task\n";
&conteni$task;
############################################################
sub contenipino {
	print "Contenipino\n!!!" and exit 0;
}
sub contenigino {
	print "Contenigino\n!!!" and exit 0;
}
sub contenitore {
	print "Contenitore\n!!!" and exit 0;
}
Tra le due file di ################ ho messo le linee secondo me
cruciali...
nella prima non sono sicuro di essermi ricordato bene la sintassi (vabbè
adesso controllo... ;-))
nella seconda casca l'asino perché ovviamente così non funziona... c'è
qualche speranza di poter utilizzare  tale notazione così pesantemente
comoda? :-) (ovv. per il mio caso che è ben diverso dal codice di
esempio che ho trascritto....)
TIA
Wiz of Id

 ############################################################
Qui non ha chompato $task (che quindi ha un CR in fondo) e stai cercando di
matchare o "{gino" o "pino" o "tore}".
Inoltre con strict i riferimenti soft che vuoi usare sono proibiti e se
anche non lo fossero, e' sintatticamente errato &conteni$task.
Soluzione con il tuo approccio (sbagliato):
chomp $task;
$task =~ /gino|pino|tore/ or die "Task errato: $task\n";
eval "&conteni$task";
Soluzione 'pulita': usare un hash di reference a funzioni.
#!/usr/bin/perl
use strict;
my %conteni = ( tore => sub { print "Contenitore!!!\n" and exit 0; },
                pino => sub { print "Contenipino!!!\n" and exit 0; },
                gino => sub { print "Contenigino!!!\n" and exit 0; },
              );
my$task=<STDIN>;
chomp $task;
$task =~ /gino|pino|tore/ or die "Task errato: $task\n";
&{$conteni{$task}};
O, megli , le ultime due righe possono essere:
 if (exists $conteni{$task})
   { 
     &{$conteni{$task}};
   }
 else 
   { 
     die "Task errato: $task\n";
   }
 
Che e' piu' pulito, in quanto ti permette di aggiungere callback in %conteni
senza dover modificare anche la sezione di chiamata (per verificare
l'esistenza della funzione).   
 
Naturalmente, se le funzioni da chiamare sono piu' complesse o debbono anche
essere chiamate in altro contesto, puoi anche definire l'hash con
 sub contenitore { ....}
 $conteni{'tore'} = \&contenitore;
 
Maurizio
-- 
Maurizio M. Munafo' / 
mmmu...@netscape.net
"Consider Phlebas, who was once handsome and tall as you" (T.S.Eliot)

 &conteni$task;
Questo non può funzionare. Hai almeno tre alternative per otterere
l'effetto che desideravi. Le elenco sotto.  La 1. non funziona sotto "use
strict". La 2. non mi piace, ma può funzionare. La 3. è la migliore.
 1.
    &{ "conteni" . $task };  
    # da evitare; non funziona con strict refs
 
 2. 
    eval " conteni$task "; 
    # non funziona se perl è eseguito con -T,
    # nel qual caso occorre fare qualche giochino, come:
    $task =~ /(gino|pino|tore)/;
    eval " conteni$1 "; # usiamo $1
 3.
   %func_map = ( 
     'pino' => \&contenipino,
     'gino' => \&contenigino,
     'tore' => \&contenitore
    );
   $func_map{$task}->(); #invochiamo la funzione
Max