I'm rewriting a framework from Perl5 to Perl6 for my work purposes. At some place I need to collect information from other modules/classes by executing a public sub they might provide; or they may not. So, it necessary to find out if the sub is present. This is not a big deal when a module is referenced directly (Foo::<&my-sub>) or by a symbolic name in a string (&::("Foo")::my-sub). But for the simplicity of it I would like to allow to pass module names as-is (lets say collector is the method collecting the info):
self.collector( Foo );
Where Foo could be the following:
module Foo {
use Bar;
use Baz;
our sub my-sub { Bar, 'Baz' }
}
And this is where I'm missing something important from Perl6 syntax because the following:
method collector ( $mod ) {
my $mod-name = $mod.WHO;
my @mods;
with &::($mod-name)::my-sub {
@mods.push: &$_();
}
}
is currently the only way I can perform the task.
I didn't try a type capture yet though. Should work as expected, I guess. So, the question is more about extending my knowelge of the syntax.
The final solution from the exchange with Vadim in the comments on their question. It's arguably insane. They think it's beautiful. And who am I to argue? .oO( Haha, hoho, heehee... )
There are two obviously useful ways to refer to a package:
Its symbolic name.
Intis the symbolic name of the Int class.Its string name.
'Int'is the string name of the Int class.Vadim, reasonably enough, wants a solution for both.
In the solution in this answer I simulate the two types of argument by randomly picking one and assigning it to
$pkg-arg:Now we need to normalize. If we've got a symbolic name we're good to go. But if it's a string name, we need to turn that into the symbolic name.
Vadim showed a couple ways to do this in the comments on their question. This solution uses a third option:
If
$pkg-argis a symbolic name, it'll beFalse. With aFalseLHS the&&short-circuits and returns its LHS. If$pkg-argis a string name, then the&&will instead return its RHS, which is::($pkg-arg)which is a symbol lookup using$pkg-argas a string name.The upshot is that
pkg-symends up containing a package symbolic name (or aFailureif the lookup failed to find a matching symbolic name).Which leaves the last line. That looks for a sub named
$subnamein the packagepkg-sym:The
&is needed to ensure the RHS is treated as a reference rather than as an attempt to call a routine. Andpkg-symhas to be a sigilless identifier otherwise the code won't work.At the end of these three lines of code
sub-refcontains either aFailureor a reference to the wanted sub.