Generating functions with Macros in Perl

A

Andreas Lundgren

Hi!

I'm building an API for a HW, and this API has a lot of wrapper
functions that wraps Win32OLE-calls. All these wrapper functions are
quite alike. In stead of writing a lot of duplicated Win32OLE-code, I
would like to generate these functions using Marcos.

Basically I want to define one macro that expands to several
functions.

_____Simple Example_____
Template: define ADDX(Xname, Xval) <- Here i need help, how to write
this kind of macro?!?

The intension is that when I put this in my script
ADDX("Two",2)
ADDX("Four",4)

It should be expanded and make these two functions available:

sub AddTwo
{
$ret = _@[0] + 2
}

sub AddFour
{
$ret = _@[0] + 4
}



_____In the real case_____

Macro definitions should be something like this:
SET_VALUE(f_name, method, no_of_params)

Later I will include the macro with for example this parameters:

SET_VALUE("InitDriver", "ext_driver_init", 4)

And it should expand to something like this:

sub InitDriver # Here the "InitDriver" is from Marco Expansion
{
( 4 == scalar( @_ ) ) or die( "Incorrect Number Of Arguments.\n" );
# Here the "4" is from Marco Expansion
ole_arg_list = join(';',@_);

my $ewaApp = Win32::OLE->new('ewa.Application');
# Some code for the Win32OLE

$ewaApp.call(['MethodNameIn','Params'],
['ext_driver_init',ole_arg_list]);
# Here the "ext_driver_init" is from Marco Expansion
}

Is it possible to write macros that create functions like this?

BR,
Andreas - Sweden
 
W

Wolf Behrenhoff

Am 26.08.2011 10:06, schrieb Andreas Lundgren:
Hi!

I'm building an API for a HW, and this API has a lot of wrapper
functions that wraps Win32OLE-calls. All these wrapper functions are
quite alike. In stead of writing a lot of duplicated Win32OLE-code, I
would like to generate these functions using Marcos.

Basically I want to define one macro that expands to several
functions.

_____Simple Example_____
Template: define ADDX(Xname, Xval) <- Here i need help, how to write
this kind of macro?!?

The intension is that when I put this in my script
ADDX("Two",2)
ADDX("Four",4)

It should be expanded and make these two functions available:

sub AddTwo
{
$ret = _@[0] + 2
}

sub AddFour
{
$ret = _@[0] + 4
}

I think you could probably use currying.

For example:

sub makeAdder {
my $value = shift;
return sub {
return $value + $_[0]
}
}

my $addTwo = makeAdder(2);
my $addFour = makeAdder(4);

print $addTwo->(5), "\n"; #prints 7
print $addFour->(5), "\n"; #prints 9


- Wolf
 
A

Andreas Lundgren

print $addTwo->(5), "\n"; #prints 7
print $addFour->(5), "\n"; #prints 9

Hi!

This is a way to get close, but I would need generate a real function
in runtime. Something called exactly like a function. I guess that a
pre processor is needed in order to first generate code before
executing the code... Is there no such thing in Perl?

BR,
Andreas
 
D

Dr.Ruud

ATTRIBUTION DAMMIT - Wolf wrote:

This is a way to get close, but I would need generate a real function
in runtime. Something called exactly like a function. I guess that a
pre processor is needed in order to first generate code before
executing the code... Is there no such thing in Perl?

Explore Perl's compile phase. Plenty support for lambda there.
 
W

Wolf Behrenhoff

Am 01.09.2011 13:09, schrieb Andreas Lundgren:
Hi!

This is a way to get close, but I would need generate a real function
in runtime. Something called exactly like a function.

Why? What is the problem with calling it the way I have shown? It is a
"real" function. Just that you have a ref to it in a scalar variable.
I guess that a
pre processor is needed in order to first generate code before
executing the code... Is there no such thing in Perl?

Again, why do you want that?

You could do:
*addTwo = \&$addTwo;
and then call addTwo(2). But still, what is wrong with calling a coderef
with $coderef->();

- Wolf
 
J

Jürgen Exner

Andreas Lundgren said:
This is a way to get close, but I would need generate a real function
in runtime. Something called exactly like a function. I guess that a
pre processor is needed in order to first generate code before
executing the code... Is there no such thing in Perl?

Maybe you are looking for something as simple as eval()?

jue
 
A

Andreas Lundgren

Am 01.09.2011 13:09, schrieb Andreas Lundgren:


Why? What is the problem with calling it the way I have shown? It is a
"real" function. Just that you have a ref to it in a scalar variable.


Again, why do you want that?

You could do:
*addTwo = \&$addTwo;
and then call addTwo(2). But still, what is wrong with calling a coderef
with $coderef->();

- Wolf

Hi!

The software that utalize the API is already written, and I cannot
update that sw. I need to keep the API backward compatible. But maybe
in combination with global symbol table like bugbear suggest would
solve that problem!

Thanks for the help!

BR,
Andreas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top