Better way to invoke dynamic function?
Better way to invoke dynamic function?
am 05.12.2007 15:34:42 von howa
I have some codes which I want to dynamically select the algorithm at
runtime, currently can be done via using eval(), e.g.
#######################
package P1;
sub foo {
print "foo";
}
sub bar {
print "bar";
}
1;
$function_to_call = "P1.bar";
eval( $function_to_call );
exit;
#######################
But the drawback is eval() is sloooow..., e.g.
##############
cmpthese( 1_000_000, {
'foo' => sub{ foo(); },
'bar' => sub{ eval("foo()"); }
});
##############
result:
bar 19967/s -- -98%
foo 1315789/s 6490% --
as you can see, using eval() is slower a lot, not to mention the
actual function execution time.
Are there any better method to archive runtime algorithm selection?
thanks.
Re: Better way to invoke dynamic function?
am 05.12.2007 15:59:44 von Joost Diepenmaat
On Wed, 05 Dec 2007 06:34:42 -0800, howa wrote:
> I have some codes which I want to dynamically select the algorithm at
> runtime, currently can be done via using eval(), e.g.
> #######################
> package P1;
>
> sub foo {
> print "foo";
> }
>
> sub bar {
> print "bar";
> }
>
> 1;
>
> $function_to_call = "P1.bar";
>
> eval( $function_to_call );
Use a function reference:
$function_to_call = \&PI::bar;
$function_to_call->();
Joost.
Re: Better way to invoke dynamic function?
am 05.12.2007 16:19:17 von Petr Vileta
Joost Diepenmaat wrote:
> On Wed, 05 Dec 2007 06:34:42 -0800, howa wrote:
>
>> I have some codes which I want to dynamically select the algorithm at
>> runtime, currently can be done via using eval(), e.g.
>> #######################
>> package P1;
>>
>> sub foo {
>> print "foo";
>> }
>>
>> sub bar {
>> print "bar";
>> }
>>
>> 1;
>>
>> $function_to_call = "P1.bar";
>>
>> eval( $function_to_call );
>
> Use a function reference:
>
> $function_to_call = \&PI::bar;
>
> $function_to_call->();
>
> Joost.
Yes and is a good idea to test if a function is defined
$func_name = 'bar';
if(defined(&{"P1::" . $func_name}))
{
(\&$func_name)->(parameters);
}
--
Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your
mail from another non-spammer site please.)
Please reply to
Re: Better way to invoke dynamic function?
am 05.12.2007 16:53:41 von howa
On 12$B7n(B5$BF|(B, $B2<8a(B10$B;~(B59$BJ,(B, Joost Diepenmaat wrote:
> On Wed, 05 Dec 2007 06:34:42 -0800, howa wrote:
> > I have some codes which I want to dynamically select the algorithm at
> > runtime, currently can be done via using eval(), e.g.
> > #######################
> > package P1;
>
> > sub foo {
> > print "foo";
> > }
>
> > sub bar {
> > print "bar";
> > }
>
> > 1;
>
> > $function_to_call = "P1.bar";
>
> > eval( $function_to_call );
>
> Use a function reference:
>
> $function_to_call = \&PI::bar;
>
> $function_to_call->();
>
> Joost.
The function name is unknown at runtime, it is input by user.
Re: Better way to invoke dynamic function?
am 05.12.2007 17:06:25 von Glenn Jackman
At 2007-12-05 10:53AM, "howa" wrote:
> On 12$B7n(B5$BF|(B, $B2<8a(B10$B;~(B59$BJ,(B, Joost Diepenmaat wrote:
> > On Wed, 05 Dec 2007 06:34:42 -0800, howa wrote:
> > > I have some codes which I want to dynamically select the algorithm at
> > > runtime, currently can be done via using eval(), e.g.
[...]
> > Use a function reference:
> >
> > $function_to_call = \&PI::bar;
> >
> > $function_to_call->();
>
> The function name is unknown at runtime, it is input by user.
Presumably the user's input is validated against some number of existing
subroutines ... you want a dispatch table. See
http://www.perlmonks.org/?node_id=456530
e.g.
my %subroutine_refs = (
choice1 => \&PI::bar,
choice2 => \&ALPHA::beta,
);
my $invalid_choice = sub { die "invalid choice"; }
( $subroutine_refs{$user_choice} or $invalid_choice )->();
--
Glenn Jackman
"You can only be young once. But you can always be immature." -- Dave Barry
Re: Better way to invoke dynamic function?
am 05.12.2007 17:38:00 von Ben Morrow
Quoth Glenn Jackman :
> At 2007-12-05 10:53AM, "howa" wrote:
> > On 12, Joost Diepenmaat wrote:
> > > On Wed, 05 Dec 2007 06:34:42 -0800, howa wrote:
> > > > I have some codes which I want to dynamically select the algorithm at
> > > > runtime, currently can be done via using eval(), e.g.
> [...]
> > > Use a function reference:
> > >
> > > $function_to_call = \&PI::bar;
> > >
> > > $function_to_call->();
> >
> > The function name is unknown at runtime, it is input by user.
>
> Presumably the user's input is validated against some number of existing
> subroutines ... you want a dispatch table. See
> http://www.perlmonks.org/?node_id=456530
>
> e.g.
> my %subroutine_refs = (
> choice1 => \&PI::bar,
> choice2 => \&ALPHA::beta,
> );
Note that you can also put the sub definitions directly in the hash,
rather than having to specify the name twice:
my %subrefs = (
choice1 => sub { ... },
choice2 => sub { ... },
);
Ben
Re: Better way to invoke dynamic function?
am 05.12.2007 19:12:35 von Uri Guttman
>>>>> "h" == howa writes:
h> The function name is unknown at runtime, it is input by user.
that is a VERY bad idea. why do newbies always think allowing users to
input a function name is a good idea?
anyhow the answer you want is a dispatch table. search google groups for
plenty of threads that have discussed them in the past. no reason to
post about them again.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Re: Better way to invoke dynamic function?
am 06.12.2007 03:34:44 von howa
Uri Guttman $BUmF;!'(B
> >>>>> "h" == howa writes:
>
>
> h> The function name is unknown at runtime, it is input by user.
>
> that is a VERY bad idea. why do newbies always think allowing users to
> input a function name is a good idea?
>
each time user add a new function, you would need to modify the
dispatch table, which might lead to error.
Re: Better way to invoke dynamic function?
am 06.12.2007 03:35:45 von Uri Guttman
>>>>> "PV" == Petr Vileta writes:
PV> Joost Diepenmaat wrote:
>> On Wed, 05 Dec 2007 06:34:42 -0800, howa wrote:
>>
>>> I have some codes which I want to dynamically select the algorithm at
>>> runtime, currently can be done via using eval(), e.g.
>>> #######################
>>> package P1;
>>> sub foo {
>>> print "foo";
>>> }
>>> sub bar {
>>> print "bar";
>>> }
>>> 1;
>>> $function_to_call = "P1.bar";
>>> eval( $function_to_call );
>> Use a function reference:
>> $function_to_call = \&PI::bar;
>> $function_to_call->();
>> Joost.
PV> Yes and is a good idea to test if a function is defined
PV> $func_name = 'bar';
PV> if(defined(&{"P1::" . $func_name})) {
PV> (\&$func_name)->(parameters);
PV> }
you are taking a bad idea and making it worse. the answer is a dispatch
table which does the checking AND the dispatching. your answer took the
OP eval code via hard refs and went back to symbolic references. not a
good journey.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Re: Better way to invoke dynamic function?
am 06.12.2007 03:42:42 von 1usa
howa wrote in news:725b040e-6f1c-4510-8f44-7e7fdca7dfab@e23g2000prf.google groups.com:
> Uri Guttman $BUmF;!'(B
>
>> >>>>> "h" == howa writes:
>>
>>
>> h> The function name is unknown at runtime, it is input by user.
>>
>> that is a VERY bad idea. why do newbies always think allowing users to
>> input a function name is a good idea?
>>
>
> each time user add a new function, you would need to modify the
> dispatch table, which might lead to error.
It is deja vu all over again. This topic has been discussed many times
in the past. Search the archives:
http://groups.google.com/group/comp.lang.perl.misc/search?gr oup=comp.lang.perl.misc&q=dispatch+table&qt_g=Search+this+gr oup
http://tinyurl.com/2bt5y5
and feel free to learn from past discussion.
Simply stated, both your scheme and objection to Uri's recommendation
are stupid but you should feel free to do as you wish.
Sinan
--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)
clpmisc guidelines:
Re: Better way to invoke dynamic function?
am 06.12.2007 04:16:31 von Uri Guttman
>>>>> "h" == howa writes:
h> Uri Guttman ÕíÆ»¡§
>> >>>>> "h" == howa writes:
>>
>>
h> The function name is unknown at runtime, it is input by user.
>>
>> that is a VERY bad idea. why do newbies always think allowing users to
>> input a function name is a good idea?
>>
h> each time user add a new function, you would need to modify the
h> dispatch table, which might lead to error.
gack!! you have users adding functions?? you want that or users calling
anything in your system vs. adding an entry into a dispatch table? i
give up.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Re: Better way to invoke dynamic function?
am 06.12.2007 15:31:06 von Ted Zlatanov
On Thu, 06 Dec 2007 03:16:31 GMT Uri Guttman wrote:
>>>>>> "h" == howa writes:
h> Uri Guttman 寫éï¼
>>> >>>>> "h" == howa writes:
>>>
>>>
h> The function name is unknown at runtime, it is input by user.
>>>
>>> that is a VERY bad idea. why do newbies always think allowing users to
>>> input a function name is a good idea?
>>>
h> each time user add a new function, you would need to modify the
h> dispatch table, which might lead to error.
UG> gack!! you have users adding functions?? you want that or users calling
UG> anything in your system vs. adding an entry into a dispatch table? i
UG> give up.
Well hang on, let's not make so many assumptions. Maybe there's a
legitimate reason for howa's need. We should find out what's really
going on.
howa, what are users really selecting through this function? Is it a
loadable module you provide, or is it a function they define for an API
your software provides? How was it done before you used Perl, if at all?
Ted