Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

appeler une methode depuis un tableau

1 réponse
Avatar
S.Cantel
Bonjour,

un peu nouveau en perl je voudrais de la même maniere que l'exemple suivante
appeler une methode d'un package au lieu d'un fonction :

test.pl :

my %T = (
"foo" => \&function;
);


&{$T{'foo'}};


En fait j'ai une classe construit de la manière suiuvante :

use Ctk::Conf::Control;

package Ctk::Control;

sub new {
my $object_or_class = shift;
my $params = shift;

my $class = ref($object_or_class) || $object_or_class;
my $self = {
server => (defined $params->{server})? $params->{server}: undef,
password => (defined $params->{password})? $params->{password}:
undef,
port => (defined $params->{port})? $params->{port}: undef,
sock => (defined $params->{sock})? $params->{sock}:
undef,
connected => FALSE,
};

bless $self, $class;

return $self;
}

et une methode générique qui doit appeler d'autres méthodes en fonction des
arguments passés :
sub add_domain{
my ($self, $params) = @_;
print "Do Job [$params->{action} $params->{domain}]";

return TRUE;
}
sub upd_domain{
my ($self, $params) = @_;
print "Do Job [$params->{action} $params->{domain}]";

return TRUE;
}
sub del_domain{
my ($self, $params) = @_;
print "Do Job [$params->{action} $params->{domain}]";

return TRUE;
}

sub do_job {
my ($self, $params) = @_;

print "Do Job [$params->{action} $params->{domain}]";

my $cmds = {
'Insert' => {function => "add_domain"},
'Update' => {function => "upd_domain"},
'Delete' => {function => "del_domain"},
};

if ($cmds->{$params->{action}}) {
$f = "$cmds->{$params->{action}}->{function}($params)";
ctklog ( "F=$f");
eval $f;
}
return TRUE;

}

Test.pl :
*****
use Ctk::Control;
use Ctk::Conf::Control;

my $obj_Control = new Ctk::Control(SMTP)
or ctkdie ("cannot create Control object");

$obj_Control->connect_to_server()
or ctkdie ("error: cannot connect to SMTP server");

$obj_Control->do_job($params_sql)
or ctkdie ("error : cannot do job");

$obj_Control->disconnect();

}

Ceci ne fonctionne pas et je commence vraiment à m'arracher les cheveux :-).
En fait, j'arrive bien dans la methode do_job, mais là j'obtiens un message
comme quoi les methodes add_domain, upd et del n'existe pas pour l'objet
Ctk::Control !!!

Merci d'avance

1 réponse

Avatar
Ronan Le Hy
S.Cantel a écrit:
un peu nouveau en perl je voudrais de la même maniere que l'exemple suivante
appeler une methode d'un package au lieu d'un fonction :

test.pl :
my %T = (
"foo" => &function;
);

&{$T{'foo'}};

En fait j'ai une classe construit de la manière suiuvante :
[snip]


J'aurais bien répondu directement sur votre exemple, mais il ne tourne
pas chez moi sans modifications. Pour le problème général, trois
solutions au moins sans utiliser de eval STRING (j'évite ça quand ça
n'est pas nécessaire, c'est souvent une belle source d'erreurs pour moi):

#!/usr/bin/perl -l

use strict;
use warnings;

package Bouh;

sub new {bless {}, shift}

sub arf_m {my $self = shift; print "arf sur $self: @_"}
sub doh_m {my $self = shift; print "doh sur $self: @_"}

my $global_method_map = {arf => 'arf_m', doh => 'doh_m'};
my $global_method_map_2 = {arf => &arf_m, doh => &doh_m};

sub dyncall1
{
my ($self, $m, @args) = @_;

my $method_name = $global_method_map->{$m};
$self->$method_name(@args);
}

sub dyncall2
{
my ($self, $m, @args) = @_;
my $local_closure_map {arf => sub {$self->arf_m(@args)},
doh => sub {$self->doh_m(@args)}};

$local_closure_map->{$m}->(@args);
}

sub dyncall3
{
my ($self, $m, @args) = @_;

my $method = $global_method_map_2->{$m};
$self->$method(@args);
}

package main;

my $b1 = Bouh->new();
my $b2 = Bouh->new();

$b1->dyncall1(arf => dyncall1 =>);
$b1->dyncall2(arf => dyncall2 =>);
$b1->dyncall1(doh => dyncall1 =>);
$b1->dyncall2(doh => dyncall2 =>);

$b2->dyncall1(arf => dyncall1 =>);
$b2->dyncall2(arf => dyncall2 =>);
$b2->dyncall1(doh => dyncall1 =>);
$b2->dyncall2(doh => dyncall2 =>);

$b1->dyncall3(arf => dyncall3 =>);
$b1->dyncall3(doh => dyncall3 =>);
$b2->dyncall3(arf => dyncall3 =>);
$b2->dyncall3(doh => dyncall3 =>);


__END__

# tout ça affiche :
./meth


arf sur Bouh=HASH(0x814eb74): dyncall1
arf sur Bouh=HASH(0x814eb74): dyncall2
doh sur Bouh=HASH(0x814eb74): dyncall1
doh sur Bouh=HASH(0x814eb74): dyncall2
arf sur Bouh=HASH(0x813b9d8): dyncall1
arf sur Bouh=HASH(0x813b9d8): dyncall2
doh sur Bouh=HASH(0x813b9d8): dyncall1
doh sur Bouh=HASH(0x813b9d8): dyncall2
arf sur Bouh=HASH(0x814eb74): dyncall3
doh sur Bouh=HASH(0x814eb74): dyncall3
arf sur Bouh=HASH(0x813b9d8): dyncall3
doh sur Bouh=HASH(0x813b9d8): dyncall3

HTH

--
Ronan

What the hell does that mean? I shouldn't have to read a manual about
LISP to fix the fucking thing BEFORE I CAN EVEN USE IT.
Earle Martin in hates-software.all