-
Notifications
You must be signed in to change notification settings - Fork 581
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve include time of Mojo::Base by extracting monkey_patch
Commit 7e9a2ad introduced a "require Mojo::Util" causing a significant chain of further dependencies being pulled in which IMHO should be avoided for the very base module which is in particular being advertised as useful for just enabling strictures and common import checks. This commit moves out the function "monkey_patch" into its own module to break or prevent the circular dependency between Mojo::Base and Mojo::Util. With that the import of Mojo::Base is more efficient, `time perl -e 'use Mojo::Base` on my system reduced from 224±12.08 ms to 52.0±2.3 ms which I consider a considerable improvement for Mojo::Base which is used as a baseclass in many cases. Further minor changes included: * Directly require MonkeyPatch for cleaner subclassing + POD * Correct use of MonkeyPatch with empty import * Combine monkey_patch and class_to_path in new Mojo::BaseUtil
- Loading branch information
Showing
5 changed files
with
106 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package Mojo::BaseUtil; | ||
|
||
# Only using pure Perl as the only purpose of this module is to break a circular dependency involving Mojo::Base | ||
use strict; | ||
use warnings; | ||
|
||
use Exporter qw(import); | ||
use Sub::Util qw(set_subname); | ||
|
||
our @EXPORT_OK = (qw(class_to_path monkey_patch)); | ||
|
||
sub class_to_path { join '.', join('/', split(/::|'/, shift)), 'pm' } | ||
|
||
sub monkey_patch { | ||
my ($class, %patch) = @_; | ||
no strict 'refs'; | ||
no warnings 'redefine'; | ||
*{"${class}::$_"} = set_subname("${class}::$_", $patch{$_}) for keys %patch; | ||
} | ||
|
||
1; | ||
|
||
=encoding utf8 | ||
=head1 NAME | ||
Mojo::BaseUtil - Common utility functions used in Mojo::Base, re-exported in Mojo::Util | ||
=head1 SYNOPSIS | ||
use Mojo::BaseUtil qw(class_to_patch monkey_path); | ||
my $path = class_to_path 'Foo::Bar'; | ||
monkey_patch 'MyApp', foo => sub { say 'Foo!' }; | ||
=head1 DESCRIPTION | ||
L<Mojo::BaseUtil> provides functions to both C<Mojo::Base> and C<Mojo::Util> so that C<Mojo::Base> does not have to load | ||
the rest of C<Mojo::Util> while preventing a circular dependency. | ||
=head1 SEE ALSO | ||
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>. | ||
=cut |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use Mojo::Base -strict; | ||
|
||
use Test::More; | ||
use Sub::Util qw(subname); | ||
|
||
use Mojo::BaseUtil qw(class_to_path monkey_patch); | ||
|
||
subtest 'class_to_path' => sub { | ||
is Mojo::BaseUtil::class_to_path('Foo::Bar'), 'Foo/Bar.pm', 'right path'; | ||
is Mojo::BaseUtil::class_to_path("Foo'Bar"), 'Foo/Bar.pm', 'right path'; | ||
is Mojo::BaseUtil::class_to_path("Foo'Bar::Baz"), 'Foo/Bar/Baz.pm', 'right path'; | ||
is Mojo::BaseUtil::class_to_path("Foo::Bar'Baz"), 'Foo/Bar/Baz.pm', 'right path'; | ||
is Mojo::BaseUtil::class_to_path("Foo::Bar::Baz"), 'Foo/Bar/Baz.pm', 'right path'; | ||
is Mojo::BaseUtil::class_to_path("Foo'Bar'Baz"), 'Foo/Bar/Baz.pm', 'right path'; | ||
}; | ||
|
||
subtest 'monkey_patch' => sub { | ||
{ | ||
|
||
package MojoMonkeyTest; | ||
sub foo {'foo'} | ||
} | ||
ok !!MojoMonkeyTest->can('foo'), 'function "foo" exists'; | ||
is MojoMonkeyTest::foo(), 'foo', 'right result'; | ||
ok !MojoMonkeyTest->can('bar'), 'function "bar" does not exist'; | ||
monkey_patch 'MojoMonkeyTest', bar => sub {'bar'}; | ||
ok !!MojoMonkeyTest->can('bar'), 'function "bar" exists'; | ||
is MojoMonkeyTest::bar(), 'bar', 'right result'; | ||
monkey_patch 'MojoMonkeyTest', foo => sub {'baz'}; | ||
ok !!MojoMonkeyTest->can('foo'), 'function "foo" exists'; | ||
is MojoMonkeyTest::foo(), 'baz', 'right result'; | ||
ok !MojoMonkeyTest->can('yin'), 'function "yin" does not exist'; | ||
ok !MojoMonkeyTest->can('yang'), 'function "yang" does not exist'; | ||
monkey_patch 'MojoMonkeyTest', | ||
yin => sub {'yin'}, | ||
yang => sub {'yang'}; | ||
ok !!MojoMonkeyTest->can('yin'), 'function "yin" exists'; | ||
is MojoMonkeyTest::yin(), 'yin', 'right result'; | ||
ok !!MojoMonkeyTest->can('yang'), 'function "yang" exists'; | ||
is MojoMonkeyTest::yang(), 'yang', 'right result'; | ||
}; | ||
|
||
subtest 'monkey_patch (with name)' => sub { | ||
is subname(MojoMonkeyTest->can('foo')), 'MojoMonkeyTest::foo', 'right name'; | ||
is subname(MojoMonkeyTest->can('bar')), 'MojoMonkeyTest::bar', 'right name'; | ||
}; | ||
|
||
done_testing(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters