Re: Enabling all MY methods of the same name in multiple modules
[email protected] (David Christensen) Fri, 16 Jul 2021 15:23:31 -0700
| Newsgroups | perl.module-authors |
|---|---|
| Message-ID | <[email protected]> |
On 7/16/21 7:11 AM, Leon Timmermans wrote: > On Fri, Jul 16, 2021 at 8:57 AM David Christensen <[email protected]> > wrote: > >> module-authors: >> >> I have extended EUMM in a Perl distribution by implementing a module >> that overrides various methods in the "MY" package namespace and by >> using that MY override module in Makefile.PL, per "Overriding MakeMaker >> Methods" in: >> >> https://metacpan.org/pod/ExtUtils::MakeMaker >> >> >> I would like to split the single distribution into multiple >> distributions. Multiple distributions will have a MY override module. >> A given MY method may be implemented in multiple modules. A given >> Makefile.PL may 'use' one or more modules. Method name collisions are >> expected. I will architect the distributions to avoid circular >> dependencies. >> >> >> AIUI simply use'ing modules with the same package namespace and the same >> subroutine (method) names will result in later definitions redefining >> earlier definitions, generating compiler warnings and making the earlier >> definitions inaccessible. >> >> >> Is there a mechanism to daisy-chain multiple package::subroutine >> definitions such that a MY method call by EUMM will return the >> concatenated results of all definitions? >> >> >> David >> > > In general, I don't think it's a good idea for any module to add methods to > MY:: directly (or at least not by default), exactly for that reason. Thank you for confirming the redefinition problem. > MY should only live in Makefile.PL. As I will need this functionality in several Makefile.PL's, I plan to put the common code into a helper module. > For methods without side-effects on $self, > combining them is could be done like this: > > my @extensions = (...); > load($_) for @extensions; > my @methods = map { $_. "::postamble" } @extensions; > sub MY::postamble { > my ($self, %args) = @_; > return join "\n\n", map { $self->$_(%args) } @methods; > } That looks like the right idea. But, I may need code within 'package MY' for SUPER to work right. > Another alternative is to insert yourself in the inheritance tree between > MY:: and whatever happens to be its base-class ($MY::ISA[0]), so you can > chain them. This may work better with side-effects. That is a novel idea (for myself). I will keep it in mind if other approaches fail. Thank you for the reply. :-) David