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

Re: module loading built-in

Thread Previous | Thread Next
September 17, 2022 21:30
Re: module loading built-in
Message ID:
On Sat, 17 Sept 2022, 21:31 Darren Duncan, <> wrote:

> On 2022-09-17 7:02 a.m., demerphq wrote:
> > So all I see is a bunch of folks sticking this load function in an eval.
> I interpret this that you see many people not understanding how to use the
> new
> function properly and that they incorrectly assume they have to put it in
> an
> eval to make it work like "require $foo" etc.  So that's up to education.

Er, no. It's a direct consequence of Paul's comment that load should die if
it fails. I start to get the impression you folks advocating for this
aren't on the same page with each other.

> Whatever, I don't care that much. But please don't call it "load".
> "module_load"
> > or "package_load".
> Personally I'm not stuck on any particular name, and I welcome a separate
> discussion to bikeshed the name, but on the RFC itself.
> > I'm a serous anti-fan of lazy loading patterns in library level code,
> especially
> > in a web context it is an antipattern that slows things down and
> consumes excess
> > memory. I understand and appreciate that for scripts it can be the
> opposite. One
> > thing that would sell me on adding this if we came up with a way to
> resolve the
> > conflict between those two use cases. Can we figure out a way that a
> module
> > consumer can reliably tell modules that they should *pre*load its
> dependencies
> > and not lazy load them?
> A key usage scenario I see for these new methods is when we have a library
> with
> a plugin architecture such that the specific plugin module we want to use
> is not
> known except at runtime and it is a user configuration data file etc that
> is
> naming the module to use.

This is exactly the kind of antipattern I object to in a library and
exactly the kind of thing that if you are doing performance sensitive multi
process stuff that causes serious problems and is pretty much exactly a
description of the kind of problem I'd like to see solved.

> For example, it would be a cleaner way to implement something like the DBI
> module which can use the new methods to load any DBMS driver module the
> user
> names via connect().

I don't consider that good practice so it doesnt really sell me. If you are
using a specific dbd then use it. Sql isn't that portable and DBIs
abstraction does not insulate you from the portability issues that come
from SQL.

> For another example, it would be a cleaner way to implement localization
> type
> modules that implement each user language as a Perl module, an example
> being my
> Locale::KeyedText module on CPAN.
> With the new builtins available, I wouldn't have to resort to these
> shenanigans:
>      sub template_module_is_loaded {
>          my ($self, $module_name) = @_;
>          ...
>          no strict 'refs';
>          return scalar keys %{$module_name . '::'};
>      }

This just looks like bad api design to me. If I needed something like that
I'd ensure there is a well defined method to call in the module that
returned a list of whatever was needed. Introspecting on the package stash
doesn't prove anything. Anybody can do 'sub Module::thing {}' anywhere and
break this logic.

 I don't see how it relates to having a load builtin either. Loading
package foo doesn't mean that any code will end up in the foo namespace.
Package foo can populate any or no namespaces. Package names and stashes
are only coincidentally related to each other, and are not necessarily

>      sub load_template_module {
>          my ($self, $module_name) = @_;
>          ...
>          # Note: We have to invoke this 'require' in an eval string
>          # because we need the bareword semantics, where 'require'
>          # will munge the package name into file system paths.
>          eval "require $module_name;";
>          $self->_die_with_msg( ... )
>              if $@;
>          return;
>      }

I've done things like this, but I''d never touch $@ without a false return
from an eval. Even if it might work in modern perls it's just confusing to
newbies. Treating $@ like $! Is good practice. I've seen maintainer coders
stick arbitrary code in between the eval and $@ access, which as $@ is
volatile can completely change the result. I'd consider that a bug waiting
to happen if it were in a communal code base.

So, it's not clear to me what you expect. At the start of this mail you
suggested that the proposed builtin would not need an eval, but here you
gave a function that rethrows the exception and would require an eval if I
speculatively want to load something, a pattern which I have seen far more
than the cases you describe. Eg "use this module and if it's present import
a sub, and if it's not use a roll-your-own replacement".

So does this proposed new function die if it fails to load or not?


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About