Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to introspect into the scope of a Scalar at runtime?

If I have the following variables

my $a    = 0;
my $*b   = 1;
state $c = 2;
our $d   = 3;

I can easily determine that $*b is dynamic but $a is not with the following code

say $a.VAR.dynamic;
say $*b.VAR.dynamic;

Is there any way to similarly determine that $c is a state variable and $d is a package-scoped variable? (I know that I could do so with a will trait on each variable declaration, but I'm hopping there is a way that doesn't require annotating every declaration. Maybe something with ::(...) interpolation?)

like image 808
codesections Avatar asked May 09 '21 04:05

codesections


People also ask

Does the introspection endpoint return the same information for all queries?

The introspection endpoint does not necessarily need to return the same information for all queries of the same token. For example, two different resource servers (if they authenticate themselves when making the introspection request) may get different views of the state of the token.

Is it possible to encode a vector as a scalar?

A lot is possible in mathematics, and I will sketch, right now, a simple method of encoding a vector as a scalar; but I warn - this method has no uses. I am unaware of any useful methods of encoding a vector with real components as a scalar.

How do you turn a scalar into a vector?

A vector has a scalar magnitude and a direction that can be expressed as a unit vector. You can take the magnitude of any vector: A = | A → | and you can turn any scalar into a vector by multiplying it by a unit vector: A → = A a ^ where a ^ = A → A. How is a scalar converted into a vector?

Is it possible to cache the response of the introspection endpoint?

Consumers of the introspection endpoint may wish to cache the response of the endpoint for performance reasons. As such, it is important to consider the performance and security trade-offs when deciding to cache the values.


Video Answer


3 Answers

In the case of the package-scoped variable, not too hard:

our $foo = 'bar';
say $foo.VAR.name ∈ OUR::.keys

where we're using the OUR pseudopackage. However, there's no such thing as a STATE pseudopackage. They obviously show up in the LEXICAL pseudopackage, but I can't find a way to check if they're a state variable or not. Sorry.

like image 74
jjmerelo Avatar answered Jan 03 '23 19:01

jjmerelo


To my knowledge, there is no way to recognize a state variable. Like any lexical, it lives in the lexpad. The only thing different about it, is that it effectively has code generated to do the initialization the first time the scope is entered.

like image 34
Elizabeth Mattijsen Avatar answered Jan 03 '23 19:01

Elizabeth Mattijsen


As Elizabeth Mattijsen correctly noted, it is currently not possible to see whether a variable is a state variable at run time. ... at least technically at runtime.

However, as Jonathan Worthington's comment implies, it is possible to check this at compile time. And, absent deep meta-programming shenanigans, whether a variable is a state variable is immutable after compile-time. And, of course, it's possible to make note of some info at compile time and then use it at runtime.

Thus, it's possible to know, at runtime, whether a variable is a state one with (compile-time) code along the following lines, which provides a list-state-vars trait that lists all the state variables in a function:

multi trait_mod:<is>(Sub \f, :$list-state-vars) {
    use nqp;
    given f.^attributes.first({.name eq '@!compstuff'}).get_value(f)[0] {
       say .list[0].list.grep({try .decl ~~ 'statevar'}).map({.name});
    }
};

This code is obviously pretty fragile/dependent on the Rakudo implementation details of QAST. Hopefully this will be much easier with RAST, but this basic approach is already workable and, in the meantime, this guide to QAST hacking is a helpful resource for this sort of meta programming.

like image 32
codesections Avatar answered Jan 03 '23 21:01

codesections