Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

`meta` module experimentation

3 views
Skip to first unread message

Paul "LeoNerd" Evans

unread,
Dec 29, 2023, 1:15:06 PM12/29/23
to Perl5 Porters
As part of PP0022, the metaprogramming API, I've uploaded a new
version of the `meta` module to CPAN:

https://metacpan.org/pod/meta

I've also started using it in a few modules, notably my various
Syntax::Operator::* modules, for implementing symbol export at `use`
time. As an example, here's a change that was made:

- no strict 'refs';
- $on ? *{"${caller}::$_"} = \&{$_}
+ $callerpkg //= meta::get_package( $caller );
+
+ $on ? $callerpkg->add_symbol( '&'.$_ => \&{$_} )

I'll gradually go around more of my modules, looking for more places
where `no strict 'refs'` currently appears and replace them with some
nicer code based on `meta`.

The entire point of experimenting with this module on CPAN is to allow
us to get a good feel for what API shape is best, so it'd be really
useful in that regard if more folks could start to make use of this and
test it out in a variety of situations. I'd love to receive more
feedback on what new bits of API need adding, or what changes to make
to things already there.

Once this becomes a bit more battle-tested and stable the module will
become a core-supplied dual-life one, but before that happens we need
more folks testing it out.

Thanks,


SEE ALSO

https://github.com/Perl/PPCs/blob/main/ppcs/ppc0022-metaprogramming.md

--
Paul "LeoNerd" Evans

leo...@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/

Ruud H.G. van Tol via perl5-porters

unread,
Dec 30, 2023, 7:15:04 AM12/30/23
to perl5-...@perl.org

On 2023-12-29 19:10, Paul "LeoNerd" Evans wrote:
> [...]
> https://github.com/Perl/PPCs/blob/main/ppcs/ppc0022-metaprogramming.md
> |set_subname |$metasub->set_subname($name);# returns $metasub Sets the subname for a previously-anonymous
> subroutine, such as one generated by|sub { ... }|syntax.
> TODO: Specify what happens if you try to do this on a regular symbol
> table subroutine. We probably shouldn't allow it.
|I would expect it to create an (deep) alias. But I don't know how||(for
example)||further properties like prototype and signature are keyed, and
inherited. If any subroutine-name is merely a lookup-name, to get to the
one and only plausible subroutine-structure, that would be feasible. --
Ruud |

Ruud H.G. van Tol via perl5-porters

unread,
Dec 30, 2023, 7:15:05 AM12/30/23
to perl5-...@perl.org
(no idea why my previous email was so weirdly formatted, likely a recent
Thunderbird bug)

Paul "LeoNerd" Evans

unread,
Dec 31, 2023, 10:15:05 AM12/31/23
to perl5-...@perl.org, Smylers
On Sat, 30 Dec 2023 21:26:33 +0100 (CET)
"Smylers  " via perl5-porters <perl5-...@perl.org> wrote:

> > + $callerpkg //= meta::get_package( $caller );
> > +
> > + $on ? $callerpkg->add_symbol( '&'.$_ => \&{$_} )
>
> With get_package() returning an object, it's effectively a
> constructor — but it doesn't really look like one. Elsewhere in Perl,
> constructors are mostly class methods, on the class of the object
> you'll get back. And the ones that aren't are generally imported
> ‘shortcut’ functions (such as path in Path::Tiny), which don't
> specify a namespace when being used. Calling meta::get_package() as a
> function is a slightly awkward combination of the two.
>
> Apologies for the bikeshedding, especially when you've obviously
> thought about this way more than I have (so please feel free to
> completely ignore me), but might it seem more intuitive — and also
> less likely to make users question the syntax to use for constructors
> in completely unrelated classes — if it meta::get_package($name) were
> instead something like:
>
> meta::package->get($name)
>
> with the object returned being an instance of the meta::package class?

Yes; that's a reasonable thought. It's the way that
Object::Pad::MOP::Class works, for example. It didn't feel very "core
perlish", but that's very subjective. Perhaps it would be better as a
class constructor in that form, indeed.

I could add some alternative forms in that shape and see how each feels
to use in practice.

I should also add (that I forgot to add in documentation so far) that
the whole thing is very experimental anyway, so no promises about API
stability at this time. Now's a great time to experiment with what
might work and find the best shape.

> Then the subsections ‘Methods on Metapackages’, ‘Methods on
> Metasymbols’, and so on, could be ‘meta::package methods’,
> ‘meta::symbol’ methods, etc, which would probably be clearer, because
> the various classes would be explicit. Currently the docs mention
> that different types of objects can be returned, but doesn't say what
> packages those are in ... which seems a little ironic for a
> metaprogramming feature!

Mmmyes another entirely fair point there :)

Paul "LeoNerd" Evans

unread,
Jan 5, 2024, 6:00:06 PMJan 5
to Perl5 Porters
Some updates:

Latest CPAN version now has experimental warnings, and adds a few more
methods. It expands on the `get` idea to have `try_get` (that returns
undef) and some `get_or_add` for lazy creation. I found that was
necessary for making this change:

- no strict 'refs';
- push @{"${caller}::ISA"}, __PACKAGE__;
+ my $callermeta = meta::package->get( $caller );
+ push @{ $callermeta->get_or_add_symbol( '@ISA' )->reference },

I've also raised a PR to edit the PPC0022 document to bring it a little
more in line with what the current state of the implementation actually
is:

https://github.com/Perl/PPCs/pull/46

I don't really have a good feel for how quickly we should keep editing
the PPC document to track the implementation, so will take further
guidance from folks if anyone has any comment to make.

Paul "LeoNerd" Evans

unread,
Jan 6, 2024, 7:15:05 AMJan 6
to Sam Kington, Perl5 Porters
On Sat, 6 Jan 2024 00:34:37 +0000
Sam Kington <s...@illuminated.co.uk> wrote:

> This is purely bikeshedding, but “get or add” rubbed me up the wrong
> way at first; like the method is both an accessor and a constructor?
>
> (SQL goes the other way and lets you say “CREATE TABLE IF NOT
> EXISTS”.)
>
> I wonder if ensure_symbol would be less weird?

Yeah, perhaps. I don't know. I spent a long time thinking on verbs and
got #perl/Libera.chat involved as well. We came up with quite a lot of
verbs but none of them really felt like it conveyed the "create if not
exists yet" feel.

Though also I was trying to view it from a lens of "how would new users
react to this word?". The name `get_or_create` is a bit long and clumsy
but it's really clear what it does when you first encounter it. Maybe
something like `ensure` is a bit more subtle and needs reading
documentation before you really understand what it does.

Yes it is a bike-shed but it's one I spent a long time thinking about,
and I'm glad to see others are still thinking and discussing it too. So
I'm happy to continue to think it over.

Martijn Lievaart via perl5-porters

unread,
Jan 7, 2024, 6:45:05 AMJan 7
to perl5-...@perl.org
Op 06-01-2024 om 23:45 schreef James Watson:
> Likewise, get_or_add sits uneasily for me. Partly language pedantry, as it’s behaviour is more like get_or_add_and_get.
>
> That aside though, I wonder if this couldn’t be collapsed into get_symbol (etc), much as get_package /add_package have changed since the PPC? If $valueref is provided, get_or_add behavior, if no $valueref and it doesn’t exist, throw the exception. Allows the ensure_symbol behavior, optionally. Naively, it seems this would capture the likely intent(s) of the programmer, but I’m sure I’m missing something…


At first glance looks like a good solution, but gets very confusing if
you want to use undef as the default value when adding the symbol. Not
sure if that is a realistic scenario though, and also not sure if the
drawback is bigger than the advantages, because it does feel natural.


HTH,

M4


Michael Conrad

unread,
Jan 8, 2024, 12:30:04 PMJan 8
to perl5-...@perl.org
On 1/5/24 19:34, Sam Kington wrote:
>> +   push @{ $callermeta->get_or_add_symbol( '@ISA' )->reference },
>
> This is purely bikeshedding, but “get or add” rubbed me up the wrong
> way at first
> ...
> I wonder if ensure_symbol would be less weird?

How about $callermeta->symbol('@ISA', AUTOCREATE)->... where AUTOCREATE
is the constant 1.  Other flags could be added later.  Absence of flags
means it either returns undef or dies if the symbol isn't defined.

-Mike


0 new messages