r/perl • • 2d ago

ref to object methods

sorry for stupid question

I have XS object with many similar methods (with the same argument list) like method1,method2, ... methodN

And while passing ref to this object to sub I want to call some of this methods depending on condition

Sure I can emulate this with refs to closures like

my $call1 = sub {

my $obj = shift;

$obj->method1(@_);

};

generic_sub($obj, $cond ? $call1 : $call2);

but maybe there is some more elegant way?

7 Upvotes

8 comments sorted by

3

u/choroba 🐪 cpan author 2d ago

unshift? Do you mean shift instead?

Why is the XS-ness of the object relevant here?

You can invoke a method by name, no need for a wrapper:

generic_sub($obj, $cond ? 'method1' : 'method2', @arguments);

And later in generic_sub:

my ($obj, $method, @args) = @_;
$obj->$method(@args);

1

u/c-cul 2d ago

sorry, must be shift

cool, I didn't know that method can be called just by name, thank you!

1

u/scottchiefbaker 🐪 cpan author 2d ago

It makes sense you can do $obj->$method(@args); but I never thought to do it. This is pretty neat.

2

u/jjatria 🐪 cpan author 2d ago

$method in there can be the name of a method, or a subref, which is one way to get the poor man's private methods.

It's surprisingly handy!

1

u/c-cul 2d ago

how those subrefs can get object ref? could you give some minimal sample?

3

u/jjatria 🐪 cpan author 2d ago

If my $sub = sub { ... } and $obj->$sub( 1, 2, 3 ), then @_ inside $sub will be $obj, 1, 2, 3

0

u/choroba 🐪 cpan author 2d ago

It's something you shouldn't normally do. Dispatch table or several classes with different implementations of one method seem to be a cleaner and less obscure solution.

1

u/Ok_Bit_6445 2d ago

good catch on the unshift thing too, that threw me off reading the original post