Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternate syntax on introspecting modules/classes/etc

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.

like image 696
Vadim Belman Avatar asked Aug 21 '18 22:08

Vadim Belman


People also ask

What is introspection in C++?

Code Introspection is used for examining the classes, methods, objects, modules, keywords and get information about them so that we can utilize it. Introspection reveals useful information about your program’s objects.

Can I use the student variable in another module?

This module has two variables and a class called student. The variable section can be used in another module as it is prefixed with the keyword “export” but the student_name variable cannot be accessed in another module as it is not prefixed with the keyword “export”.

What is introspection in Python?

Everything in python is an object. Every object in Python may have attributes and methods. By using introspection, we can dynamically examine python objects. Code Introspection is used for examining the classes, methods, objects, modules, keywords and get information about them so that we can utilize it.

How to allow classes defined in a module to be accessible?

How to allow classes defined in a module to be accessible outside of a module ? In typescript by using an import statement, a module can be utilized in another module. any variables, classes, methods, or other objects declared in a module are not accessible outside of it.


1 Answers

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... )

my $pkg-arg = (Int, 'Int').pick;
my \pkg-sym = $pkg-arg && ::($pkg-arg);
my \sub-ref = &pkg-sym::($subname);

There are two obviously useful ways to refer to a package:

  • Its symbolic name. Int is 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:

my $pkg-arg = (Int, 'Int').pick;

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:

my \pkg-sym = $pkg-arg && ::($pkg-arg);

If $pkg-arg is a symbolic name, it'll be False. With a False LHS the && short-circuits and returns its LHS. If $pkg-arg is a string name, then the && will instead return its RHS, which is ::($pkg-arg) which is a symbol lookup using $pkg-arg as a string name.

The upshot is that pkg-sym ends up containing a package symbolic name (or a Failure if the lookup failed to find a matching symbolic name).

Which leaves the last line. That looks for a sub named $subname in the package pkg-sym:

my \sub-ref = &pkg-sym::($subname);

The & is needed to ensure the RHS is treated as a reference rather than as an attempt to call a routine. And pkg-sym has to be a sigilless identifier otherwise the code won't work.

At the end of these three lines of code sub-ref contains either a Failure or a reference to the wanted sub.

like image 126
raiph Avatar answered Sep 23 '22 01:09

raiph