[baltimorepm] Closures and Late-Binding Subroutine Calls

Stephen Belcher sbelcher at gmail.com
Thu Apr 26 10:19:44 PDT 2012


I'm trying to allow someone to set up a class B as a subclass of class
A::Base::Class using an anonymous callback sub which isolates the
configuration methods and keeps them out of both A::Base::Class and B in
order to keep the namespace clear, but doesn't require the person using
class A::Base::Class to know that all the configuration actually happens
in A::Base::Class::ConfigurationSubclass (and keep said person from having
to type `my ($x)
= A::Base::Class::ConfigurationSubclass::config_this(42);
A::Base::Class::ConfigurationSubclass::config_that($x
+ 5);`).

Ultimately, if the programmer knew that
`A::Base::Class::ConfigurationSubclass` was the direct way to configure
their package, and didn't mind all the extra typing and the damage to the :
key, he or she could do it, and the world wouldn't stop (this is Perl after
all, I think it's in the contract somewhere that we have to provide at
least two methods to achieve the same result). However, for his or her own
sanity, `__PACKAGE__->configure(sub { my ($x) = config_this(42);
config_that($x + 5); });` is also a possibility.

Ultimately, the way I've rewritten the file in (
https://gist.github.com/2499830#file_crazier.pl) utilizing some hints from
a CPAN Macro module I found per Alan's suggestion (localizing exported
method calls to the aforementioned B class), has some known caveats (a sub
named A::Base::Class::ConfigurationSubclass::config_this's existence would
clobber any value of $B::config_this, @B::config_this, etc. during the call
to configure(), for instance). I think they're probably livable though.
Solving the one I mentioned isn't impossible but it comes with what I think
is an unreasonable speed penalty. There are probably others, but nothing
significant I've thought of yet.

That being said, I don't think I've seen Perl modules configured this way
in the past, and if it's because people have assessed it as a known
possibility and discounted it as completely wrong-headed, I'm still
relatively fresh in the process of writing the module that'd use it, and I
can probably be talked back off the ledge if there are good reasons not to
do it.

--Stephen



On Thu, Apr 26, 2012 at 12:44 PM, John SJ Anderson <genehack at genehack.org>wrote:

> On Thursday, April 26, 2012 at 10:24 AM, Stephen Belcher wrote:
>
> Hi all,
>
> I'm wondering if anyone has an answer to this?
> https://gist.github.com/2499830
>
> Looking at the gist, and specifically at the last section of it, I'm
> wondering why you can't just use the fully specified method name. I.e.,
> instead of
>
>
>     sub configure {
>
>         my ($coderef) = sub {
>
>             hello;
>
>         };
>
> do
>
>     sub configure {
>         my ($coderef) = sub {
>             PackageA::hello;
>         };
>
>
>
>
> Essentially, I want to create a coderef while in the scope of one package,
> and delay binding of the subroutine calls until the actual execution, which
> will happen in or relative to another package, meaning that the subroutines
> that eventually resolve will be the ones located in the second package, not
> the first. This is different from what normally happens in closures.
>
> It sounds like you have some problem you're trying to decide, and you have
> gotten onto this particular path of solving it, and it's not really the
> right solution. Perhaps you could explain what you're trying to achieve
> with this code? (Not the "call a method in packageB but use packageA's
> context for method resolution", but the problem you were working on solving
> _before_ you started on this…)
>
>  chrs,
> john.
>
>
>
> _______________________________________________
> Baltimore-pm mailing list
> Baltimore-pm at pm.org
> http://mail.pm.org/mailman/listinfo/baltimore-pm
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/baltimore-pm/attachments/20120426/0456bcd0/attachment-0001.html>


More information about the Baltimore-pm mailing list