fix bug I795J9

This commit is contained in:
denghao 2023-09-18 14:35:55 +08:00
parent e881a1b844
commit bf2c5e546b
4 changed files with 399 additions and 105 deletions

59
Makefile.PL Normal file
View File

@ -0,0 +1,59 @@
# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.029.
use strict;
use warnings;
use 5.008000;
use ExtUtils::MakeMaker 6.78;
my %WriteMakefileArgs = (
"ABSTRACT" => "install subroutines into packages easily",
"AUTHOR" => "Ricardo SIGNES <cpan\@semiotic.systems>",
"CONFIGURE_REQUIRES" => {
"ExtUtils::MakeMaker" => "6.78"
},
"DISTNAME" => "Sub-Install",
"LICENSE" => "perl",
"MIN_PERL_VERSION" => "5.008000",
"NAME" => "Sub::Install",
"PREREQ_PM" => {
"B" => 0,
"Carp" => 0,
"Scalar::Util" => 0,
"strict" => 0,
"warnings" => 0
},
"TEST_REQUIRES" => {
"ExtUtils::MakeMaker" => 0,
"File::Spec" => 0,
"Test::More" => "0.96"
},
"VERSION" => "0.929",
"test" => {
"TESTS" => "t/*.t"
}
);
my %FallbackPrereqs = (
"B" => 0,
"Carp" => 0,
"ExtUtils::MakeMaker" => 0,
"File::Spec" => 0,
"Scalar::Util" => 0,
"Test::More" => "0.96",
"strict" => 0,
"warnings" => 0
);
unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
delete $WriteMakefileArgs{TEST_REQUIRES};
delete $WriteMakefileArgs{BUILD_REQUIRES};
$WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs;
}
delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
WriteMakefile(%WriteMakefileArgs);

View File

@ -1,75 +1,76 @@
use v5.8.0;
use strict; use strict;
use warnings; use warnings;
package Sub::Install; package Sub::Install;
# ABSTRACT: install subroutines into packages easily # ABSTRACT: install subroutines into packages easily
$Sub::Install::VERSION = '0.929';
use Carp; use Carp;
use Scalar::Util (); use Scalar::Util ();
=head1 SYNOPSIS #pod =head1 SYNOPSIS
#pod
use Sub::Install; #pod use Sub::Install;
#pod
Sub::Install::install_sub({ #pod Sub::Install::install_sub({
code => sub { ... }, #pod code => sub { ... },
into => $package, #pod into => $package,
as => $subname #pod as => $subname
}); #pod });
#pod
=head1 DESCRIPTION #pod =head1 DESCRIPTION
#pod
This module makes it easy to install subroutines into packages without the #pod This module makes it easy to install subroutines into packages without the
unsightly mess of C<no strict> or typeglobs lying about where just anyone can #pod unsightly mess of C<no strict> or typeglobs lying about where just anyone can
see them. #pod see them.
#pod
=func install_sub #pod =func install_sub
#pod
Sub::Install::install_sub({ #pod Sub::Install::install_sub({
code => \&subroutine, #pod code => \&subroutine,
into => "Finance::Shady", #pod into => "Finance::Shady",
as => 'launder', #pod as => 'launder',
}); #pod });
#pod
This routine installs a given code reference into a package as a normal #pod This routine installs a given code reference into a package as a normal
subroutine. The above is equivalent to: #pod subroutine. The above is equivalent to:
#pod
no strict 'refs'; #pod no strict 'refs';
*{"Finance::Shady" . '::' . "launder"} = \&subroutine; #pod *{"Finance::Shady" . '::' . "launder"} = \&subroutine;
#pod
If C<into> is not given, the sub is installed into the calling package. #pod If C<into> is not given, the sub is installed into the calling package.
#pod
If C<code> is not a code reference, it is looked for as an existing sub in the #pod If C<code> is not a code reference, it is looked for as an existing sub in the
package named in the C<from> parameter. If C<from> is not given, it will look #pod package named in the C<from> parameter. If C<from> is not given, it will look
in the calling package. #pod in the calling package.
#pod
If C<as> is not given, and if C<code> is a name, C<as> will default to C<code>. #pod If C<as> is not given, and if C<code> is a name, C<as> will default to C<code>.
If C<as> is not given, but if C<code> is a code ref, Sub::Install will try to #pod If C<as> is not given, but if C<code> is a code ref, Sub::Install will try to
find the name of the given code ref and use that as C<as>. #pod find the name of the given code ref and use that as C<as>.
#pod
That means that this code: #pod That means that this code:
#pod
Sub::Install::install_sub({ #pod Sub::Install::install_sub({
code => 'twitch', #pod code => 'twitch',
from => 'Person::InPain', #pod from => 'Person::InPain',
into => 'Person::Teenager', #pod into => 'Person::Teenager',
as => 'dance', #pod as => 'dance',
}); #pod });
#pod
is the same as: #pod is the same as:
#pod
package Person::Teenager; #pod package Person::Teenager;
#pod
Sub::Install::install_sub({ #pod Sub::Install::install_sub({
code => Person::InPain->can('twitch'), #pod code => Person::InPain->can('twitch'),
as => 'dance', #pod as => 'dance',
}); #pod });
#pod
=func reinstall_sub #pod =func reinstall_sub
#pod
This routine behaves exactly like C<L</install_sub>>, but does not emit a #pod This routine behaves exactly like C<L</install_sub>>, but does not emit a
warning if warnings are on and the destination is already defined. #pod warning if warnings are on and the destination is already defined.
#pod
=cut #pod =cut
sub _name_of_code { sub _name_of_code {
my ($code) = @_; my ($code) = @_;
@ -193,28 +194,28 @@ BEGIN {
}); });
} }
=func install_installers #pod =func install_installers
#pod
This routine is provided to allow Sub::Install compatibility with #pod This routine is provided to allow Sub::Install compatibility with
Sub::Installer. It installs C<install_sub> and C<reinstall_sub> methods into #pod Sub::Installer. It installs C<install_sub> and C<reinstall_sub> methods into
the package named by its argument. #pod the package named by its argument.
#pod
Sub::Install::install_installers('Code::Builder'); # just for us, please #pod Sub::Install::install_installers('Code::Builder'); # just for us, please
Code::Builder->install_sub({ name => $code_ref }); #pod Code::Builder->install_sub({ name => $code_ref });
#pod
Sub::Install::install_installers('UNIVERSAL'); # feeling lucky, punk? #pod Sub::Install::install_installers('UNIVERSAL'); # feeling lucky, punk?
Anything::At::All->install_sub({ name => $code_ref }); #pod Anything::At::All->install_sub({ name => $code_ref });
#pod
The installed installers are similar, but not identical, to those provided by #pod The installed installers are similar, but not identical, to those provided by
Sub::Installer. They accept a single hash as an argument. The key/value pairs #pod Sub::Installer. They accept a single hash as an argument. The key/value pairs
are used as the C<as> and C<code> parameters to the C<install_sub> routine #pod are used as the C<as> and C<code> parameters to the C<install_sub> routine
detailed above. The package name on which the method is called is used as the #pod detailed above. The package name on which the method is called is used as the
C<into> parameter. #pod C<into> parameter.
#pod
Unlike Sub::Installer's C<install_sub> will not eval strings into code, but #pod Unlike Sub::Installer's C<install_sub> will not eval strings into code, but
will look for named code in the calling package. #pod will look for named code in the calling package.
#pod
=cut #pod =cut
sub install_installers { sub install_installers {
my ($into) = @_; my ($into) = @_;
@ -238,22 +239,22 @@ sub install_installers {
} }
} }
=head1 EXPORTS #pod =head1 EXPORTS
#pod
Sub::Install exports C<install_sub> and C<reinstall_sub> only if they are #pod Sub::Install exports C<install_sub> and C<reinstall_sub> only if they are
requested. #pod requested.
#pod
=head2 exporter #pod =head2 exporter
#pod
Sub::Install has a never-exported subroutine called C<exporter>, which is used #pod Sub::Install has a never-exported subroutine called C<exporter>, which is used
to implement its C<import> routine. It takes a hashref of named arguments, #pod to implement its C<import> routine. It takes a hashref of named arguments,
only one of which is currently recognize: C<exports>. This must be an arrayref #pod only one of which is currently recognize: C<exports>. This must be an arrayref
of subroutines to offer for export. #pod of subroutines to offer for export.
#pod
This routine is mainly for Sub::Install's own consumption. Instead, consider #pod This routine is mainly for Sub::Install's own consumption. Instead, consider
L<Sub::Exporter>. #pod L<Sub::Exporter>.
#pod
=cut #pod =cut
sub exporter { sub exporter {
my ($arg) = @_; my ($arg) = @_;
@ -272,6 +273,158 @@ sub exporter {
BEGIN { *import = exporter({ exports => [ qw(install_sub reinstall_sub) ] }); } BEGIN { *import = exporter({ exports => [ qw(install_sub reinstall_sub) ] }); }
#pod =head1 SEE ALSO
#pod
#pod =over
#pod
#pod =item L<Sub::Installer>
#pod
#pod This module is (obviously) a reaction to Damian Conway's Sub::Installer, which
#pod does the same thing, but does it by getting its greasy fingers all over
#pod UNIVERSAL. I was really happy about the idea of making the installation of
#pod coderefs less ugly, but I couldn't bring myself to replace the ugliness of
#pod typeglobs and loosened strictures with the ugliness of UNIVERSAL methods.
#pod
#pod =item L<Sub::Exporter>
#pod
#pod This is a complete Exporter.pm replacement, built atop Sub::Install.
#pod
#pod =back
#pod
#pod =head1 EXTRA CREDITS
#pod
#pod Several of the tests are adapted from tests that shipped with Damian Conway's
#pod Sub-Installer distribution.
#pod
#pod =cut
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Sub::Install - install subroutines into packages easily
=head1 VERSION
version 0.929
=head1 SYNOPSIS
use Sub::Install;
Sub::Install::install_sub({
code => sub { ... },
into => $package,
as => $subname
});
=head1 DESCRIPTION
This module makes it easy to install subroutines into packages without the
unsightly mess of C<no strict> or typeglobs lying about where just anyone can
see them.
=head1 PERL VERSION
This library should run on perls released even an extremely long time ago. It
should work on any version of perl released in the last ten years.
Although it may work on older versions of perl, no guarantee is made that the
minimum required version will not be increased. The version may be increased
for any reason, and there is no promise that patches will be accepted to lower
the minimum required perl.
=head1 FUNCTIONS
=head2 install_sub
Sub::Install::install_sub({
code => \&subroutine,
into => "Finance::Shady",
as => 'launder',
});
This routine installs a given code reference into a package as a normal
subroutine. The above is equivalent to:
no strict 'refs';
*{"Finance::Shady" . '::' . "launder"} = \&subroutine;
If C<into> is not given, the sub is installed into the calling package.
If C<code> is not a code reference, it is looked for as an existing sub in the
package named in the C<from> parameter. If C<from> is not given, it will look
in the calling package.
If C<as> is not given, and if C<code> is a name, C<as> will default to C<code>.
If C<as> is not given, but if C<code> is a code ref, Sub::Install will try to
find the name of the given code ref and use that as C<as>.
That means that this code:
Sub::Install::install_sub({
code => 'twitch',
from => 'Person::InPain',
into => 'Person::Teenager',
as => 'dance',
});
is the same as:
package Person::Teenager;
Sub::Install::install_sub({
code => Person::InPain->can('twitch'),
as => 'dance',
});
=head2 reinstall_sub
This routine behaves exactly like C<L</install_sub>>, but does not emit a
warning if warnings are on and the destination is already defined.
=head2 install_installers
This routine is provided to allow Sub::Install compatibility with
Sub::Installer. It installs C<install_sub> and C<reinstall_sub> methods into
the package named by its argument.
Sub::Install::install_installers('Code::Builder'); # just for us, please
Code::Builder->install_sub({ name => $code_ref });
Sub::Install::install_installers('UNIVERSAL'); # feeling lucky, punk?
Anything::At::All->install_sub({ name => $code_ref });
The installed installers are similar, but not identical, to those provided by
Sub::Installer. They accept a single hash as an argument. The key/value pairs
are used as the C<as> and C<code> parameters to the C<install_sub> routine
detailed above. The package name on which the method is called is used as the
C<into> parameter.
Unlike Sub::Installer's C<install_sub> will not eval strings into code, but
will look for named code in the calling package.
=head1 EXPORTS
Sub::Install exports C<install_sub> and C<reinstall_sub> only if they are
requested.
=head2 exporter
Sub::Install has a never-exported subroutine called C<exporter>, which is used
to implement its C<import> routine. It takes a hashref of named arguments,
only one of which is currently recognize: C<exports>. This must be an arrayref
of subroutines to offer for export.
This routine is mainly for Sub::Install's own consumption. Instead, consider
L<Sub::Exporter>.
=head1 SEE ALSO =head1 SEE ALSO
=over =over
@ -295,6 +448,39 @@ This is a complete Exporter.pm replacement, built atop Sub::Install.
Several of the tests are adapted from tests that shipped with Damian Conway's Several of the tests are adapted from tests that shipped with Damian Conway's
Sub-Installer distribution. Sub-Installer distribution.
=cut =head1 AUTHOR
1; Ricardo SIGNES <cpan@semiotic.systems>
=head1 CONTRIBUTORS
=for stopwords Chad Granum David Steinbrunner Ricardo SIGNES Signes
=over 4
=item *
Chad Granum <chad.granum@dreamhost.com>
=item *
David Steinbrunner <dsteinbrunner@pobox.com>
=item *
Ricardo SIGNES <rjbs@codesimply.com>
=item *
Ricardo Signes <rjbs@semiotic.systems>
=back
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2005 by Ricardo SIGNES.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut

7
xt/author/pod-syntax.t Normal file
View File

@ -0,0 +1,7 @@
#!perl
# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests.
use strict; use warnings;
use Test::More;
use Test::Pod 1.41;
all_pod_files_ok();

View File

@ -0,0 +1,42 @@
use Test::More tests => 2;
note 'Checking Changes';
my $changes_file = 'Changes';
my $newver = '0.929';
my $trial_token = '-TRIAL';
my $encoding = 'UTF-8';
SKIP: {
ok(-e $changes_file, "$changes_file file exists")
or skip 'Changes is missing', 1;
ok(_get_changes($newver), "$changes_file has content for $newver");
}
done_testing;
sub _get_changes
{
my $newver = shift;
# parse changelog to find commit message
open(my $fh, '<', $changes_file) or die "cannot open $changes_file: $!";
my $changelog = join('', <$fh>);
if ($encoding) {
require Encode;
$changelog = Encode::decode($encoding, $changelog, Encode::FB_CROAK());
}
close $fh;
my @content =
grep { /^$newver(?:$trial_token)?(?:\s+|$)/ ... /^\S/ } # from newver to un-indented
split /\n/, $changelog;
shift @content; # drop the version line
# drop unindented last line and trailing blank lines
pop @content while ( @content && $content[-1] =~ /^(?:\S|\s*$)/ );
# return number of non-blank lines
return scalar @content;
}