Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

How to bring in multimethods

by karlgoethebier (Abbot)
on Sep 20, 2023 at 13:28 UTC ( #11154546=perlquestion: print w/replies, xml ) Need Help??

karlgoethebier has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, please consider this:

Foo.pm

package Foo { use strict; use warnings; use Class::Tiny; 1; } __END__

Bar.pm

package Bar { use strict; use warnings; use Class::Tiny; 1; } __END__

Methods.pm

package Methods { use strict; use warnings; use feature qw(isa); use Logic::Easy; no warnings qw(redefine); sub frobnicate : Multi(frobnicate) { SIG [$o] where {$o isa 'Foo'}; qq(foo); } sub frobnicate : Multi(frobnicate) { SIG [$o] where {$o isa 'Bar'}; qq(bar); } 1; } __END__

run.pl

#!/usr/bin/env perl use strict; use warnings; use lib q(.); use Bar; use Foo; use Methods; use feature qw(say); my $gizmo = Foo->new(); my $mojo = Bar->new(); # dd $gizmo, $mojo; say Methods::frobnicate($_) for ($gizmo, $mojo); __END__

As expected, frobnicate cannot be imported - "there can be only one". Also with Methods->frobnicate() it does not work. Remains only Methods::frobnicate() - as to see. Or is there something else I have overlooked?

«The Crux of the Biscuit is the Apostrophe»

Replies are listed 'Best First'.
Re: How to bring in multimethods
by tobyink (Canon) on Sep 21, 2023 at 10:14 UTC

    I've got a pretty good implementation of multimethods on CPAN. I'm biased, but I think it's the best underlying implementation, though I've done almost zero work on making the syntax nice.

    use strict; use warnings; use experimental qw( signatures builtin ); use feature qw( say ); use builtin qw( true false ); use Sub::MultiMethod -all, -lexical; use Types::Common -types, -lexical; package Foo { use Class::Tiny }; package Bar { use Class::Tiny }; multifunction frobnicate => ( positional => [ InstanceOf['Foo'] ], code => sub ( $o ) { return 'It was a Foo.' }, ); multifunction frobnicate => ( positional => [ InstanceOf['Bar'] ], code => sub ( $o ) { return 'It was a Bar.' }, ); multifunction frobnicate => ( positional => [ HashRef, ArrayRef ], code => sub ( $h, $a ) { return 'They were a hashref and array +ref.' }, ); multifunction frobnicate => ( named => [ message => Str, truth => Bool ], code => sub ( $arg ) { $arg->truth ? $arg->message : 'Truth wa +s false' }, ); say frobnicate( Foo->new ); say frobnicate( Bar->new ); say frobnicate( {}, [] ); say frobnicate( message => "This will be seen", truth => true + ); say frobnicate( message => "This will NOT be seen", truth => false + ); say frobnicate( { message => "This will be seen", truth => true } + ); say frobnicate( { message => "This will NOT be seen", truth => false } + ); say frobnicate( [], undef, 123 ); # dies; no implementation available

      Thank you! I saw it already. But for unknown reasons, I have not managed it to pass [ InstanceOf['Foo'] ] to positional 🤪😎

      «The Crux of the Biscuit is the Apostrophe»

Re: How to bring in multimethods
by hv (Prior) on Sep 20, 2023 at 18:07 UTC

    As expected, frobnicate cannot be imported - "there can be only one".

    I don't understand this sentence, but I also don't see anything in Methods.pm that would allow it to be exported. What happens if you use Exporter to make frobnicate exportable? A brief look at the implementation of multimethods suggests it should work fine.

      When I call it with Exporter like this:

      package Methods { use strict; use warnings; use feature qw(isa); use Logic::Easy; use Exporter qw(import) no warnings qw(redefine); our @EXPORT_OK = qw(frobnicate); sub frobnicate : Multi(frobnicate) { SIG [$o] where {$o isa 'Foo'}; qq(foo); } sub frobnicate : Multi(frobnicate) { SIG [$o] where {$o isa 'Bar'}; qq(bar); } 1; } __END__
      #!/usr/bin/env perl use strict; use warnings; use lib q(.); use Bar; use Foo; use Methods qw(frobnicate); use feature qw(say); my $gizmo = Foo->new(); my $mojo = Bar->new(); # dd $gizmo, $mojo; say frobnicate($_) for ($gizmo, $mojo); __END__

      I get:

      karl@h3002993:~/src/perl/mmdemo$ ./run.pl Logic::Easy control failed at Methods.pm line 16. at Methods.pm line 16. </p>

      The same result with say frobnicate($gizmo);. With say frobnicate($mojo); i get bar.

      With the loop and Methods::frobnicate($_) i get the expected result.

      «The Crux of the Biscuit is the Apostrophe»

Re: How to bring in multimethods
by LanX (Saint) on Sep 20, 2023 at 14:45 UTC
    Which of those modules listed export SIG ?

    Or are you asking how to implement SIG ?

    edit

    after looking into the source of Logic::Easy (which has no POD) it seems that SIG is implemented by source filter.

    I can't see any mention of multi-methods there ¹ but since Perl doesn't do any static parameter checks when calling a sub², you'll have to construct one single sub frobnicate() which checks the arguments against patterns and delegates via dispatch table to specific sub implementations.

    Maybe message the author?

    HTH! :)

    Cheers Rolf
    (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
    Wikisyntax for the Monastery

    updates

    1) well I didn't spend much more guessing effort into this undocumented 0.02 version from MAR 26, 2005

    2) well, it does prototype checks when compiling, but that's another thing

      1. Logic
      2. No1)

      I just want to write frobnicate($object) and not Methods::frobnicate($object). With use Exporter qw(import); our @EXPORT_OK =qw(frobnicate); and use Methods qw(frobnicate); only one frobnicate is found2) and with Methods->frobnicate() nothings happens.

      1) I could read the sources for this (could take a while ;-).
      2) This yields "Logic::Easy multi dispatch failed" from Logic::Easy line 94.

      «The Crux of the Biscuit is the Apostrophe»

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11154546]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2023-12-09 17:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?











    Results (38 votes). Check out past polls.

    Notices?