Am 21.03.2014 um 14:34 schrieb Sebastian Willert via RT <bug-List-MoreUtils@rt.cpan.org>:
Show quoted text> Queue: List-MoreUtils
> Ticket <URL:
https://rt.cpan.org/Ticket/Display.html?id=94013 >
>
> On Fri Mar 21 07:41:42 2014, REHSACK wrote:
>> First approach for near future in 0.400_004.
>>
>> I hope we have a constructive discussion soon how to long-term-deal
>> with that issue.
>
> Thanks for applying the fix for 0.400.
Naming it a hotfix and call it a day :)
Show quoted text> I still have problems seeing your rational for removing the possibility of using List::MoreUtils via require. As far as I can tell importing LMU into its own namespace solves everything cleanly and with just one line of code (and two lines of comments explaining why it is done).
This has to do with the history and the API breakage by self-volunteered maintainer.
I now have to cleanup the mess he left - and I had to make a choice. While ether and ribasushi voted strongly against immediate API change, the only other option was a depreciation of the broken API and a slow move while giving users the option to choose. Does it explain? If not, you should join IRC (probably with some other Moose colleagues, because I don’t intend to have the same 30min talk in IRC more often then necessary ^^).
Show quoted text> With this fix, the somewhat wide-spread usage of LMU as
> require List::MoreUtils; List::MoreUtils::all([...]);
> (and variations thereof) is functionally equivalent to
> use List::MoreUtils qw/:all/; all([...]);
> Isn't that what you want?
Sorry to say - it’s not. ›use List::MoreUtils 'any‘‹ currently means ›use List::MoreUtils 'any‘ => { impl => 'alias' }‹, but in a few month it’ll mean ›use List::MoreUtils 'any‘ => { impl => ’tassilo' }‹.
Show quoted text> Keep in mind, that there are use-cases in which the reliance
> on ->import is at least impractical. E.g.:
>
> require List::MoreUtils;
> my $class = Moose::Meta::Class->create( Foo => (
> methods => { bar => sub{ List::MoreUtils::all([...]); }}
> ));
require List::MoreUtils;
my $class = Moose::Meta::Class->create( Foo => (
methods => { bar => sub{ (List::MoreUtils->_exporter_expand_sub('all‘, {impl => ’tassilo'}))[1]->(...); }}
));
require List::MoreUtils;
my $all = (List::MoreUtils->_exporter_expand_sub('all‘, {impl => ’tassilo'}))[1];
my $class = Moose::Meta::Class->create( Foo => (
methods => { bar => sub{ $all->(...); }}
));
require List::MoreUtils::Impl::Alias;
my $class = Moose::Meta::Class->create( Foo => (
methods => { bar => sub{ List::MoreUtils::Impl::Alias::all(...); }}
));
You see, timtowtdoi
Show quoted text> is straight-forward, while I am having a hard time figuring out how to do same sanely with import. I don't say it can't be done (I see at least three more complicated ways of achieving similar results), I'm just trying to show you an in my opinion perfectly legitimate way to use LMU that relies on require instead of ->import.
And if it would be acceptable to switch immediately from the broken API back to the original one without breaking other modules, I would agree. But thanks to - let’s say an accident - we’re now in trouble and that causes the loose-loose-situation you’ve also joined :)
And "but many modules needs ...“ is an argument for both sides. 0.4xx has the approach to give ages users a way to keep their environments sane and their algorithms stable as well as don’t break well maintained recent code.
Unfortunately permitting the „require“ use-case will pretend a kind of safety and/or stability which isn’t there.
Show quoted text> Granted: this particular piece of code would work with ->import, but only because perl would resolve &all to mean &__PACKAGE__::all which seems very fragile to me, breaks all kinds of best encapsulation practices and would e.g. prohibit having an 'all' function in the "host" namespace.
>
> As I said, I don't see a compelling reason to get rid of require, and at least a few reasons (potentially breaking tons of legacy installs is just the biggest) to keep it around.
I hope I could help you with those explanations - additionally I added a rough overview to 0.400_004 pod and don’t intend to remove quickly.
TL;DR:
* as Tassilo I have the approach to do the things "right“ - not easy.
* this means reverting introduced API pollution
* this means breaking code relying on documented behavior when doing the easy way (one function, use == require+import)
Cheers
--
Jens Rehsack
rehsack@gmail.com