develooper Front page | perl.perl5.porters | Postings from June 2022

Re: Pre-RFC: A built-in ability for lexical import/export

Thread Previous | Thread Next
From:
Paul "LeoNerd" Evans
Date:
June 27, 2022 13:40
Subject:
Re: Pre-RFC: A built-in ability for lexical import/export
Message ID:
20220627144015.4c341811@shy.leonerd.org.uk
On Fri, 24 Jun 2022 16:44:27 +0100
"Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:

> I was thinking that maybe it should be just exposed as a builtin::
> function itself, perhaps as
> 
>   builtin::lexically_export $name, \&func;

I've had a bit of a go at implementing this:

  https://github.com/leonerd/perl5/tree/lexically-export

> Perhaps it should take a whole kv-list of name/ref pairs, so you can
> export lots in one go:
> 
>   builtin::lexically_export
>     one => \&one,
>     two => \&two, ...

It currently doesn't do this yet, but shouldn't be hard to add.


In the process of writing it I've come up with some more questions, to
which I don't have an easy answer:

  * Should it support things other than functions? Should we support

      lexically_export VAR => \my $scalar;

  * If so, should names be sigil-prefixed?

      lexically_export '$VAR' => \my $scalar, '&func' => sub {...};

While I don't think it is common to want to export things other than
functions, it does occasionally happen (e.g. think the $LOG variable of
various logger modules, or the $METRICS of Metrics::Any). It would be
nice to support these in some way.

If we do support them, it raises the question on whether the "name"
argument to lexically_export() itself should include the sigil part of
it. In the vastly-common majority of cases, they'll all just be
functions, so it feels annoying to have to '&'-prefix them all -
especially if it would otherwise break the neat way of using
"name => \&name" notation.

On the other hand, it would lead to an awkward situation if you wanted
to export more than one item of the same basename:

  lexically_export
    FOO => \my $s, FOO => \my @arr, FOO => \my %hash, FOO => sub {};

This would technically be fine as it would create four separately named
items in the caller - $FOO, @FOO, %FOO and &FOO (callable as FOO()).
But it does feel strange, and breaks the otherwise neat hash-like
name/value pair structure of the arguments. I'm not sure I like it.

Instead, perhaps a compromise idea taken from the way Exporter.pm
works; which is to say that sigils would be required for
scalar/hash/array variables, but not required for regular functions.

  lexically_export
    name   => \&function,   # a regular function
    '$VAR' => \my $scalar,  # a scalar variable
    '@VAR' => \my @arr,     # an array variable
    '%VAR' => \my %hash,    # a hash variable

    '&func' => \&func,      # also permitted for symmetry, but not
                            #   required

I.e. the model being "if no sigil is specified, presume &"; and
additionally, error if the sigil doesn't match the thing being
referenced.


I think this feels sane - does anyone disagree?

-- 
Paul "LeoNerd" Evans

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

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About