Mailing List Archive

PPC - Requiring a module multiple times to return the actual module true value, not '1'
The problem

Requiring/using/loading a module returns a true value. The value can be any type of true value. However the current implementation of ‘require' always returns a ‘1’ if the module was previous required, instead of the actual last value in the module:
Eg
# Some module
package My::Mod;

{key=>”value”}; # last value ’true'


# Main program

my $result=require My::Mod;


# somewhere else in the program
my $result2=require My::Mod;

# $result will be the hash ref from the module ‘last value’
# $result2 will always be ‘1’

Currently the user needs to create their own table of required modules to cache the return value, which seems a duplication of how ‘require' tracks already required modules and deals with the bareword and file path separator complications.


Syntax changes
None required



Benefits

1. A module can be used directly as configuration, or other advanced stateful purposes.
2. Gives a uniform way of returning a value from a module instead of assuming a particular name for a package variable.
3. No logical changes to existing modules returning true values. Backward compatible


Potential problems

Returning a reference value can allow the contents of to be modified after the module has been loaded. Which depending on your context could be desirable or undesirable. However this is no different to having a package variable for the same purpose



Thank you for your time and consideration.

Ruben Westerberg
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Wed, Nov 1, 2023 at 8:08?PM Ruben Westerberg via perl5-porters <
perl5-porters@perl.org> wrote:

> *The problem*
>
> Requiring/using/loading a module returns a true value. The value can be
> any type of true value. However the current implementation of ‘require'
> always returns a ‘1’ if the module was previous required, instead of the
> actual last value in the module:
> Eg
> # Some module
> package My::Mod;
> {key=>”value”}; # last value ’true'
>
>
> # Main program
>
> my $result=require My::Mod;
>
>
> # somewhere else in the program
> my $result2=require My::Mod;
>
> # $result will be the hash ref from the module ‘last value’
> # $result2 will always be ‘1’
>
> Currently the user needs to create their own table of required modules to
> cache the return value, which seems a duplication of how ‘require' tracks
> already required modules and deals with the bareword and file path
> separator complications.
>
>
> *Syntax changes*
> None required
>
>
>
> *Benefits*
>
> 1. A module can be used directly as configuration, or other advanced
> stateful purposes.
> 2. Gives a uniform way of returning a value from a module instead of
> assuming a particular name for a package variable.
> 3. No logical changes to existing modules returning true values. Backward
> compatible
>
>
> *Potential problems*
>
> Returning a reference value can allow the contents of to be modified after
> the module has been loaded. Which depending on your context could be
> desirable or undesirable. However this is no different to having a package
> variable for the same purpose
>
>
>
> Thank you for your time and consideration.
>
> Ruben Westerberg
>


require intentionally does not execute the same file multiple times in
order to retrieve the return value. I don't feel that an implementation of
storing the return value to return on repeated requires would be a good
idea (due to problems similar to those you mentioned) nor that choosing to
return a value from a Perl module is commonly desirable.

You can use `do FILE` if you wish to execute a file and retrieve its return
value, this is the standard way to load e.g. configuration written as Perl
code. It has an unfortunate error reporting mechanism, but is usable as
described in its docs as long as `undef` does not get returned by the file.

-Dan
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Wed, Nov 1, 2023, at 20:32, Dan Book wrote:
> require intentionally does not execute the same file multiple times in order to retrieve the return value. I don't feel that an implementation of storing the return value to return on repeated requires would be a good idea (due to problems similar to those you mentioned) nor that choosing to return a value from a Perl module is commonly desirable.

I agree with Dan.

If some value from a module should be repeatedly accessible, it should be made API, like a subroutine or scalar variable.

--
rjbs
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
The do file approach forces a reevaluation which is desirable, but not always.
The package name of a variable or subroutine might not be known when a file is required, which gives a chicken and egg situation when exposing a value via an API.

The example following may be a little contrived and even wrong, but it attempts so show how this could be useful.
Note it only shows returning a package name. The possibilities are numerous and powerful if references could be used in the proposed manner.


### api.pl - a file loaded at runtime
package Some::Random::Package::With::Company::Naming::Convention

sub do_suff {}
sub do_more_suff{}

__PACKAGE__



### top level script - loads config.pl for

my $API= require “./api.pl”

$api->do_stuff();



### Somewhere else in the main program in some sub module...

my $API= require “./api.pl”

$API->do_stuff(); ## THIS WILL FAIL WITH THE CURRENT REQUIRE:
##Can't locate object method “do_stuff" via package "1"


— In this example the api.pl script ends with package name, which is unknown to the requiring script. The API package name is discovered at require time.
— It allows separation in that the naming of the api.pl is up the author and not forced to be a resolvable name for the top level script.

— Less configuration/setup/management/would in other parts of the same program when loading code dynamically as the name of the package doesn’t need to be conveyed
— Potentially less memory usage, as api modules could be required directly when needed. instead of used at compile time


This could be achieved with a do file. However:
— if the script is time consuming in initialising itself this isn’t ideal.
— Each api.pl script would have to add code to check a custom package variable as a cache to see if it needs to be initialised to avoid this. Can be error prone and clutter up a source file.



I have no idea how the require code looks under the hood as I write this email, but it seems it would already be storing a scalar (1) in its internal table.

Would it not be relatively low hanging fruit (I assume) to simply store the last value from a script and give the extra flexibility/usability as demonstrated above?

Usage would be completely opt in as the author of the required script can simply return 1 or other true value as they have always done.


Hope my example makes sense.

Thanks

Ruben




> On 12 Nov 2023, at 11:30?am, Ricardo Signes <perl.p5p@rjbs.manxome.org> wrote:
>
> On Wed, Nov 1, 2023, at 20:32, Dan Book wrote:
>> require intentionally does not execute the same file multiple times in order to retrieve the return value. I don't feel that an implementation of storing the return value to return on repeated requires would be a good idea (due to problems similar to those you mentioned) nor that choosing to return a value from a Perl module is commonly desirable.
>
> I agree with Dan.
>
> If some value from a module should be repeatedly accessible, it should be made API, like a subroutine or scalar variable.
>
> --
> rjbs
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Sun, Nov 12, 2023 at 12:00?AM Ruben Westerberg <drclaw@mac.com> wrote:

> The do file approach forces a reevaluation which is desirable, but not
> always.
> The package name of a variable or subroutine might not be known when a
> file is required, which gives a chicken and egg situation when exposing a
> value via an API.
>
> The example following may be a little contrived and even wrong, but it
> attempts so show how this could be useful.
> Note it only shows returning a package name. The possibilities are
> numerous and powerful if references could be used in the proposed manner.
>
>
> ### api.pl - a file loaded at runtime
> package Some::Random::Package::With::Company::Naming::Convention
>
> sub do_suff {}
> sub do_more_suff{}
>
> __PACKAGE__
>
>
>
> ### top level script - loads config.pl for
>
> my $API= require “./api.pl”
>
> $api->do_stuff();
> …
>
>
> ### Somewhere else in the main program in some sub module...
>
> my $API= require “./api.pl”
>
> $API->do_stuff(); ## THIS WILL FAIL WITH THE CURRENT REQUIRE:
> ##Can't locate object method “do_stuff" via package "1"
>
>
> — In this example the api.pl script ends with package name, which is
> unknown to the requiring script. The API package name is discovered at
> require time.
> — It allows separation in that the naming of the api.pl is up the author
> and not forced to be a resolvable name for the top level script.
>
> — Less configuration/setup/management/would in other parts of the same
> program when loading code dynamically as the name of the package doesn’t
> need to be conveyed
> — Potentially less memory usage, as api modules could be required directly
> when needed. instead of used at compile time
>
>
> This could be achieved with a do file. However:
> — if the script is time consuming in initialising itself this isn’t ideal.
> — Each api.pl script would have to add code to check a custom package
> variable as a cache to see if it needs to be initialised to avoid this. Can
> be error prone and clutter up a source file.
>
>
> I have no idea how the require code looks under the hood as I write this
> email, but it seems it would already be storing a scalar (1) in its
> internal table.
>
> Would it not be relatively low hanging fruit (I assume) to simply store
> the last value from a script and give the extra flexibility/usability as
> demonstrated above?
>
> Usage would be completely opt in as the author of the required script can
> simply return 1 or other true value as they have always done.
>
>
> Hope my example makes sense.
>

To be frank, I'm not sure what this approach buys you over loading it as a
normal Perl module and using the package namespace it declares to call
subroutines and methods. I will expand upon the fundamental issue however:
presuming the return value of the first require is cached somewhere, this
would then result in the second and subsequent calls receiving a value
which was created at an entirely different state of the code. These
subsequent calls could, in a different organization of subroutine calls,
suddenly become the first call, or some other entirely different order of
execution. This could easily be just as surprising as not retrieving the
expected return value at all based on who required the file first. In
general this would be a "different" behavior (thus requiring the code to
opt into it if it were ever implemented), and I'm not convinced that it is
a "better" one.

-Dan
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
The namespace might not be known at require time. The old chicken and egg problem. The requiring code would need to be modified, or otherwise provided the package name to call the subroutines. If the package name is really long and hard to remember, this is cumbersome. Short script name is much easier:

eg. Dynamic loading of a module, with an unknown namespace, into a hypothetical application from the command line

perl my-great-program —api api.pl

# vs

perl my-great-program —api Some::Name::Space::Thats::Long::And::Difficult::To::Remember

As for the sequencing problem described, I’m not sure how that differs to any other code/module being loaded at arbitrary time. Of course if the last value returned is a reference, yes, the underlying data can be changed easily at any time of the program execution.

However if it is a simple scalar (like a package name string or integer) is this not read only (ie the returned value from require is a copy I assume)?. In this case returning ‘1’ in the required script like usual would not change the behaviour of modules not opting in.

...Or is my understanding of require way off in this case?

Ruben



> On 12 Nov 2023, at 3:59?pm, Dan Book <grinnz@gmail.com> wrote:
>
> On Sun, Nov 12, 2023 at 12:00?AM Ruben Westerberg <drclaw@mac.com <mailto:drclaw@mac.com>> wrote:
>> The do file approach forces a reevaluation which is desirable, but not always.
>> The package name of a variable or subroutine might not be known when a file is required, which gives a chicken and egg situation when exposing a value via an API.
>>
>> The example following may be a little contrived and even wrong, but it attempts so show how this could be useful.
>> Note it only shows returning a package name. The possibilities are numerous and powerful if references could be used in the proposed manner.
>>
>>
>> ### api.pl <http://api.pl/> - a file loaded at runtime
>> package Some::Random::Package::With::Company::Naming::Convention
>>
>> sub do_suff {}
>> sub do_more_suff{}
>>
>> __PACKAGE__
>>
>>
>>
>> ### top level script - loads config.pl <http://config.pl/> for
>>
>> my $API= require “./api.pl <http://api.pl/>”
>>
>> $api->do_stuff();
>> …
>>
>>
>> ### Somewhere else in the main program in some sub module...
>>
>> my $API= require “./api.pl <http://api.pl/>”
>>
>> $API->do_stuff(); ## THIS WILL FAIL WITH THE CURRENT REQUIRE:
>> ##Can't locate object method “do_stuff" via package "1"
>>
>>
>> — In this example the api.pl <http://api.pl/> script ends with package name, which is unknown to the requiring script. The API package name is discovered at require time.
>> — It allows separation in that the naming of the api.pl <http://api.pl/> is up the author and not forced to be a resolvable name for the top level script.
>>
>> — Less configuration/setup/management/would in other parts of the same program when loading code dynamically as the name of the package doesn’t need to be conveyed
>> — Potentially less memory usage, as api modules could be required directly when needed. instead of used at compile time
>>
>>
>> This could be achieved with a do file. However:
>> — if the script is time consuming in initialising itself this isn’t ideal.
>> — Each api.pl <http://api.pl/> script would have to add code to check a custom package variable as a cache to see if it needs to be initialised to avoid this. Can be error prone and clutter up a source file.
>>
>>
>>
>> I have no idea how the require code looks under the hood as I write this email, but it seems it would already be storing a scalar (1) in its internal table.
>>
>> Would it not be relatively low hanging fruit (I assume) to simply store the last value from a script and give the extra flexibility/usability as demonstrated above?
>>
>> Usage would be completely opt in as the author of the required script can simply return 1 or other true value as they have always done.
>>
>>
>> Hope my example makes sense.
>
> To be frank, I'm not sure what this approach buys you over loading it as a normal Perl module and using the package namespace it declares to call subroutines and methods. I will expand upon the fundamental issue however: presuming the return value of the first require is cached somewhere, this would then result in the second and subsequent calls receiving a value which was created at an entirely different state of the code. These subsequent calls could, in a different organization of subroutine calls, suddenly become the first call, or some other entirely different order of execution. This could easily be just as surprising as not retrieving the expected return value at all based on who required the file first. In general this would be a "different" behavior (thus requiring the code to opt into it if it were ever implemented), and I'm not convinced that it is a "better" one.
>
> -Dan
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Sun, Nov 12, 2023 at 4:20?AM Ruben Westerberg <drclaw@mac.com> wrote:

> The namespace might not be known at require time. The old chicken and egg
> problem. The requiring code would need to be modified, or otherwise
> provided the package name to call the subroutines. If the package name is
> really long and hard to remember, this is cumbersome. Short script name is
> much easier:
>
> eg. Dynamic loading of a module, with an unknown namespace, into a
> hypothetical application from the command line
>
> perl my-great-program —api api.pl
>
> # vs
> perl my-great-program —api
> Some::Name::Space::Thats::Long::And::Difficult::To::Remember
>

There are plenty of solutions to this issue, but generally Perl modules are
recommended to have file paths matching their package name to begin with.
See https://metacpan.org/pod/aliased, or have the module export a
subroutine that makes sense for your use case.


>
> As for the sequencing problem described, I’m not sure how that differs to
> any other code/module being loaded at arbitrary time. Of course if the last
> value returned is a reference, yes, the underlying data can be changed
> easily at any time of the program execution.
>
> However if it is a simple scalar (like a package name string or integer)
> is this not read only (ie the returned value from require is a copy I
> assume)?. In this case returning ‘1’ in the required script like usual
> would not change the behaviour of modules not opting in.
>
> ...Or is my understanding of require way off in this case?
>

The changing of referenced structures is a huge potential issue of course,
but I was referring to the expectation of how the data is generated to
begin with. A call may be expecting to receive data that is relevant and
representative of the time at which it is called during program execution,
but may or may not receive data that was relevant and representative of a
completely different and unrelated section of code where the file was
actually loaded from.

-Dan
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
Aliasing is a nice idea. Again, however, to use it the package name would need to be known before hand. It doesn’t achieve the same result as what I’m proposing, which would allow the requiring program to NOT care what the package name is at all. The name could be returned as the true value from the required script for example and then access its api with -> calls directly. It opens up flexibility in name space usage and dynamic behaviour.

There are modules which utilise the effect the order of execution has on a module and its subsequent loads. For example constant::more and Log::OK are two of mine which conditionally define constants based on if they have been defined already in modules or from the top level program. I think that's the second the point to what I’m proposing. For ‘ normal’ modules, the user would expect nothing more than a ‘1’ in the require return. For the ‘dynamically effected' modules, the user gets what the modules gives, (which returned from a require should be constant/cached anyway) as that is what is being asked of it.

I appreciate the discussion on this.

Ruben






> On 13 Nov 2023, at 5:41?am, Dan Book <grinnz@gmail.com> wrote:
>
> On Sun, Nov 12, 2023 at 4:20?AM Ruben Westerberg <drclaw@mac.com <mailto:drclaw@mac.com>> wrote:
>> The namespace might not be known at require time. The old chicken and egg problem. The requiring code would need to be modified, or otherwise provided the package name to call the subroutines. If the package name is really long and hard to remember, this is cumbersome. Short script name is much easier:
>>
>> eg. Dynamic loading of a module, with an unknown namespace, into a hypothetical application from the command line
>>
>> perl my-great-program —api api.pl <http://api.pl/>
>>
>> # vs
>>
>> perl my-great-program —api Some::Name::Space::Thats::Long::And::Difficult::To::Remember
>
> There are plenty of solutions to this issue, but generally Perl modules are recommended to have file paths matching their package name to begin with. See https://metacpan.org/pod/aliased, or have the module export a subroutine that makes sense for your use case.
>
>>
>> As for the sequencing problem described, I’m not sure how that differs to any other code/module being loaded at arbitrary time. Of course if the last value returned is a reference, yes, the underlying data can be changed easily at any time of the program execution.
>>
>> However if it is a simple scalar (like a package name string or integer) is this not read only (ie the returned value from require is a copy I assume)?. In this case returning ‘1’ in the required script like usual would not change the behaviour of modules not opting in.
>>
>> ...Or is my understanding of require way off in this case?
>
> The changing of referenced structures is a huge potential issue of course, but I was referring to the expectation of how the data is generated to begin with. A call may be expecting to receive data that is relevant and representative of the time at which it is called during program execution, but may or may not receive data that was relevant and representative of a completely different and unrelated section of code where the file was actually loaded from.
>
> -Dan
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On 13.11.23 09:45, Ruben Westerberg via perl5-porters wrote:
>
> Aliasing is a nice idea. Again, however, to use it the package name
> would need to be known before hand. It doesn’t achieve  the same result
> as what I’m proposing, which would allow the requiring program to NOT
> care what the package name is at all. The name could be returned as the
> true value from the required script for example and then access its api
> with -> calls directly. It opens up flexibility in name space usage and
> dynamic behaviour.
>
> There are modules which utilise the effect the order of execution has on
> a module and  its subsequent loads. For example constant::more and
>  Log::OK are two of mine which  conditionally define constants based on
> if they have been defined already in modules or from the top level
> program.  I think  that's the second the point to what I’m proposing.
> For ‘ normal’ modules,  the user would expect nothing more than a ‘1’ in
> the require return. For the ‘dynamically effected' modules, the user
> gets what the modules gives, (which returned from a require should be
> constant/cached anyway) as that is what is being asked of it.

To me this sounds sufficiently different from "regular" modules that I
wonder if changing 'require' is the right way to implement it. For
example, "fully dynamic" modules could be done with 'do' and then
caching could be implemented on top of that.

(On the other hand, I'm not sure what harm, if any, would be caused by
retaining the original module return value in %INC. My guess would be a
slight increase in memory usage as some modules don't just return 1
currently.)
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Mon, Nov 13, 2023, at 03:54, Lukas Mai wrote:
> (On the other hand, I'm not sure what harm, if any, would be caused by
> retaining the original module return value in %INC. My guess would be a
> slight increase in memory usage as some modules don't just return 1
> currently.)

It would further increase the overall complexity of Perl, for a benefit that seems to be only very rarely desirable, and which can be implemented in other ways with a bit more interface. Perl is so laden with complexity already that any further complexity should be a significant win in terms of leverage, likely frequency of use, or (preferably) both.

--
rjbs
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On 11/13/23 03:45, Ruben Westerberg via perl5-porters wrote:
>
> Aliasing is a nice idea. Again, however, to use it the package name
> would need to be known before hand. It doesn’t achieve  the same
> result as what I’m proposing, which would allow the requiring program
> to NOT care what the package name is at all. The name could be
> returned as the true value from the required script for example and
> then access its api with -> calls directly. It opens up flexibility in
> name space usage and dynamic behaviour.
>
> There are modules which utilise the effect the order of execution has
> on a module and  its subsequent loads. For example constant::more and
>  Log::OK are two of mine which  conditionally define constants based
> on if they have been defined already in modules or from the top level
> program.  I think  that's the second the point to what I’m proposing.
> For ‘ normal’ modules,  the user would expect nothing more than a ‘1’
> in the require return. For the ‘dynamically effected' modules, the
> user gets what the modules gives, (which returned from a require
> should be constant/cached anyway) as that is what is being asked of it.
>
>  I appreciate the discussion on this.
>
> Ruben


The thing you're proposing would limit you to compatibility with only
future versions of perl.

But, you can accomplish your goal right now with

  sub require_file($filename) { $main::INC_RET{$filename} //=
require($filename) }

and that will work with all past versions of perl.  You could make that
a standard export of the library ecosystem you're designing.

Keep in mind that someone could be depending on the existing behavior of
require (to know when the module was already loaded) so what you're
proposing would be a breaking change.

-Mike
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On 11/13/23 14:35, Michael Conrad wrote:
> On 11/13/23 03:45, Ruben Westerberg via perl5-porters wrote:
>>
>> [snip]
>> Ruben
>
>
> The thing you're proposing would limit you to compatibility with only
> future versions of perl.
>
> But, you can accomplish your goal right now with
>
>   sub require_file($filename) { $main::INC_RET{$filename} //=
> require($filename) }
>
> and that will work with all past versions of perl.

Well, not quite *all* past versions. The defined-or operator was
introduced in perl-5.10. See 'perldoc perl5100delta'.
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Mon, 13 Nov 2023 at 20:36, Michael Conrad <mike@nrdvana.net> wrote:

> On 11/13/23 03:45, Ruben Westerberg via perl5-porters wrote:
>
>
> Aliasing is a nice idea. Again, however, to use it the package name would
> need to be known before hand. It doesn’t achieve the same result as what
> I’m proposing, which would allow the requiring program to NOT care what the
> package name is at all. The name could be returned as the true value from
> the required script for example and then access its api with -> calls
> directly. It opens up flexibility in name space usage and dynamic
> behaviour.
>
> There are modules which utilise the effect the order of execution has on a
> module and its subsequent loads. For example constant::more and Log::OK
> are two of mine which conditionally define constants based on if they have
> been defined already in modules or from the top level program. I think
> that's the second the point to what I’m proposing. For ‘ normal’ modules,
> the user would expect nothing more than a ‘1’ in the require return. For
> the ‘dynamically effected' modules, the user gets what the modules gives,
> (which returned from a require should be constant/cached anyway) as that is what
> is being asked of it.
>
> I appreciate the discussion on this.
>
> Ruben
>
>
> The thing you're proposing would limit you to compatibility with only
> future versions of perl.
>
> But, you can accomplish your goal right now with
>
> sub require_file($filename) { $main::INC_RET{$filename} //=
> require($filename) }
>
> and that will work with all past versions of perl. You could make that a
> standard export of the library ecosystem you're designing.
>
> Keep in mind that someone could be depending on the existing behavior of
> require (to know when the module was already loaded) so what you're
> proposing would be a breaking change.
>

No, that doesn't work. It would require everything that requires a file to
use this facility, and that simply isnt ever going to be true. About the
only way you can make this work is to override require very very very early
in process startup, and that is distinctly nontrivial, the Booking codebase
does this, and it was a lot of hassle that eventually lead to core fixes.

cheers,
Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Mon, 13 Nov 2023 at 20:26, Ricardo Signes <perl.p5p@rjbs.manxome.org>
wrote:

> On Mon, Nov 13, 2023, at 03:54, Lukas Mai wrote:
>
> (On the other hand, I'm not sure what harm, if any, would be caused by
> retaining the original module return value in %INC. My guess would be a
> slight increase in memory usage as some modules don't just return 1
> currently.)
>
>
> It would further increase the overall complexity of Perl, for a benefit
> that seems to be only very rarely desirable, and which can be implemented
> in other ways with a bit more interface. Perl is so laden with complexity
> already that any further complexity should be a significant win in terms of
> leverage, likely frequency of use, or (preferably) both
>

I disagree. Speaking as someone who has worked on this subject multiple
times in the past, including related core changes, I dont think the level
of complexity involved is very high. Maybe 3 out of 10.

cheers,
Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On 11/14/23 04:40, demerphq wrote:
> On Mon, 13 Nov 2023 at 20:36, Michael Conrad <mike@nrdvana.net> wrote:
>
> But, you can accomplish your goal right now with
>
>   sub require_file($filename) { $main::INC_RET{$filename} //=
> require($filename) }
>
> and that will work with all past versions of perl.  You could make
> that a standard export of the library ecosystem you're designing.
>
> Keep in mind that someone could be depending on the existing
> behavior of require (to know when the module was already loaded)
> so what you're proposing would be a breaking change.
>
>
> No, that doesn't work. It would require everything that requires a
> file to use this facility, and that simply isnt ever going to be
> true.  About the only way you can make this work is to override
> require very very very early in process startup, and that is
> distinctly nontrivial, the Booking codebase does this, and it was a
> lot of hassle that eventually lead to core fixes.
>
> cheers,
> Yves

I was making the assumption that these special files that return data
would be fully segregated from normal modules.

Normal modules (loaded by package name) can't usefully return data in
this manner, due to the original problem of it being missing on
secondary requires, so it seems safe to assume that people don't do
that.  By extension, code unaware of 'require_file' would probably not
be calling require on the special files that do return data.

But also, if Ruben is loading file names by relative path "./Foo.pm"
then it would re-load Foo.pm even if other code had already done
"require Foo;" because the duplicate loading check happens based on file
path rather than file identity.  In fact (just tested) you can re-load a
file as many times as you want just by adding another prefix of "./".

    # loads Foo 3 times, returning final value each time
    say require Foo;                 # with -I. on the command line
    say require "./Foo.pm";
    say require "././Foo.pm";

So it does seem like my require_file suggestion would work for Ruben's
example, unless some other rogue code is loading these files by path name.

-Mike
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Tue, Nov 14, 2023, at 04:43, demerphq wrote:
> On Mon, 13 Nov 2023 at 20:26, Ricardo Signes <perl.p5p@rjbs.manxome.org> wrote:__
>> It would further increase the overall complexity of Perl, for a benefit that seems to be only very rarely desirable, and which can be implemented in other ways with a bit more interface. Perl is so laden with complexity already that any further complexity should be a significant win in terms of leverage, likely frequency of use, or (preferably) both
>
> I disagree. Speaking as someone who has worked on this subject multiple times in the past, including related core changes, I dont think the level of complexity involved is very high. Maybe 3 out of 10.

I didn't say it was high, I said it was nonzero. Also, my concern is much less about the interpreter, but about the language.

--
rjbs
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
On Tue, 14 Nov 2023 at 13:39, Ricardo Signes <perl.p5p@rjbs.manxome.org>
wrote:

> On Tue, Nov 14, 2023, at 04:43, demerphq wrote:
>
> On Mon, 13 Nov 2023 at 20:26, Ricardo Signes <perl.p5p@rjbs.manxome.org>
> wrote:
>
> It would further increase the overall complexity of Perl, for a benefit
> that seems to be only very rarely desirable, and which can be implemented
> in other ways with a bit more interface. Perl is so laden with complexity
> already that any further complexity should be a significant win in terms of
> leverage, likely frequency of use, or (preferably) both
>
>
> I disagree. Speaking as someone who has worked on this subject multiple
> times in the past, including related core changes, I dont think the level
> of complexity involved is very high. Maybe 3 out of 10.
>
>
> I didn't say it was high, I said it was nonzero. Also, my concern is much
> less about the interpreter, but about the language.
>

Still not very convinced. I don't see how this would impact the language
much at all.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
Not sure if there has been any further discussion to this. I only just found the confirmation email to the joining the Perl 5 Porters list buried in my junk email. My apologies if I’ve missed some important points from people.


Ruben



> On 13 Nov 2023, at 6:45?pm, Ruben Westerberg <drclaw@mac.com> wrote:
>
>
> Aliasing is a nice idea. Again, however, to use it the package name would need to be known before hand. It doesn’t achieve the same result as what I’m proposing, which would allow the requiring program to NOT care what the package name is at all. The name could be returned as the true value from the required script for example and then access its api with -> calls directly. It opens up flexibility in name space usage and dynamic behaviour.
>
> There are modules which utilise the effect the order of execution has on a module and its subsequent loads. For example constant::more and Log::OK are two of mine which conditionally define constants based on if they have been defined already in modules or from the top level program. I think that's the second the point to what I’m proposing. For ‘ normal’ modules, the user would expect nothing more than a ‘1’ in the require return. For the ‘dynamically effected' modules, the user gets what the modules gives, (which returned from a require should be constant/cached anyway) as that is what is being asked of it.
>
> I appreciate the discussion on this.
>
> Ruben
>
>
>
>
>
>
>> On 13 Nov 2023, at 5:41?am, Dan Book <grinnz@gmail.com> wrote:
>>
>> On Sun, Nov 12, 2023 at 4:20?AM Ruben Westerberg <drclaw@mac.com <mailto:drclaw@mac.com>> wrote:
>>> The namespace might not be known at require time. The old chicken and egg problem. The requiring code would need to be modified, or otherwise provided the package name to call the subroutines. If the package name is really long and hard to remember, this is cumbersome. Short script name is much easier:
>>>
>>> eg. Dynamic loading of a module, with an unknown namespace, into a hypothetical application from the command line
>>>
>>> perl my-great-program —api api.pl <http://api.pl/>
>>>
>>> # vs
>>>
>>> perl my-great-program —api Some::Name::Space::Thats::Long::And::Difficult::To::Remember
>>
>> There are plenty of solutions to this issue, but generally Perl modules are recommended to have file paths matching their package name to begin with. See https://metacpan.org/pod/aliased, or have the module export a subroutine that makes sense for your use case.
>>
>>>
>>> As for the sequencing problem described, I’m not sure how that differs to any other code/module being loaded at arbitrary time. Of course if the last value returned is a reference, yes, the underlying data can be changed easily at any time of the program execution.
>>>
>>> However if it is a simple scalar (like a package name string or integer) is this not read only (ie the returned value from require is a copy I assume)?. In this case returning ‘1’ in the required script like usual would not change the behaviour of modules not opting in.
>>>
>>> ...Or is my understanding of require way off in this case?
>>
>> The changing of referenced structures is a huge potential issue of course, but I was referring to the expectation of how the data is generated to begin with. A call may be expecting to receive data that is relevant and representative of the time at which it is called during program execution, but may or may not receive data that was relevant and representative of a completely different and unrelated section of code where the file was actually loaded from.
>>
>> -Dan
>
Re: PPC - Requiring a module multiple times to return the actual module true value, not '1' [ In reply to ]
Ruben Westerberg via perl5-porters <perl5-porters@perl.org> wrote:
>
> Not sure if there has been any further discussion to this. […] My apologies if I’ve missed some important points from people.

See

https://www.nntp.perl.org/group/perl.perl5.porters/2023/11/msg267250.html

for a complete list of all replies.


--
Arne Johannessen
<https://arne.johannessen.de/>