Skip to content

Commit 1111d7d

Browse files
committed
Make it possible to force Specio to use only pure Perl dependencies
We do this by switching between Clone and Clone::PP. This is useful for cases like fatpacking a program, where XS just doesn't work.
1 parent 4ccb09d commit 1111d7d

20 files changed

+250
-15
lines changed

Changes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
{{$NEXT}}
22

3+
- Made it possible to force Specio to only use pure Perl dependencies by setting the
4+
SPECIO_IMPLEMENTATION environment variable to "PP". Requested by @arodland (Andrew Rodland). GH
5+
#23.
6+
7+
38
0.50 2025-02-18
49

510
- Fixed a bug in the Int type that caused it to accept numbers like 124512.000000000123, which when

Makefile.PL

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ my %WriteMakefileArgs = (
2323
"B" => 0,
2424
"Carp" => 0,
2525
"Clone" => 0,
26+
"Clone::Choose" => 0,
27+
"Clone::PP" => 0,
2628
"Devel::StackTrace" => 0,
2729
"Eval::Closure" => 0,
2830
"Exporter" => 0,
2931
"IO::File" => 0,
3032
"List::Util" => "1.33",
3133
"MRO::Compat" => 0,
34+
"Module::Implementation" => 0,
3235
"Module::Runtime" => 0,
3336
"Role::Tiny" => "1.003003",
3437
"Role::Tiny::With" => 0,
@@ -64,6 +67,8 @@ my %FallbackPrereqs = (
6467
"B" => 0,
6568
"Carp" => 0,
6669
"Clone" => 0,
70+
"Clone::Choose" => 0,
71+
"Clone::PP" => 0,
6772
"Devel::StackTrace" => 0,
6873
"Eval::Closure" => 0,
6974
"Exporter" => 0,
@@ -73,6 +78,7 @@ my %FallbackPrereqs = (
7378
"IO::File" => 0,
7479
"List::Util" => "1.33",
7580
"MRO::Compat" => 0,
81+
"Module::Implementation" => 0,
7682
"Module::Runtime" => 0,
7783
"Role::Tiny" => "1.003003",
7884
"Role::Tiny::With" => 0,

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Specio - Type constraints and coercions for Perl
44

55
# VERSION
66

7-
version 0.50
7+
version 0.51
88

99
# SYNOPSIS
1010

@@ -390,6 +390,12 @@ distribution better in some way.
390390
If one of these is installed then stack traces that end up in Specio code will
391391
have much better subroutine names for any frames.
392392

393+
# FORCING PURE PERL MODE
394+
395+
For some use cases (notably fat-packing a program), you may want to force
396+
Specio to use pure Perl code instead of XS code. This can be done by setting
397+
the environment variable `SPECIO_IMPLEMENTATION` to `PP`.
398+
393399
# WHY THE NAME?
394400

395401
This distro was originally called "Type", but that's an awfully generic top

cpanfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
requires "B" => "0";
55
requires "Carp" => "0";
66
requires "Clone" => "0";
7+
requires "Clone::Choose" => "0";
8+
requires "Clone::PP" => "0";
79
requires "Devel::StackTrace" => "0";
810
requires "Eval::Closure" => "0";
911
requires "Exporter" => "0";
1012
requires "IO::File" => "0";
1113
requires "List::Util" => "1.33";
1214
requires "MRO::Compat" => "0";
15+
requires "Module::Implementation" => "0";
1316
requires "Module::Runtime" => "0";
1417
requires "Role::Tiny" => "1.003003";
1518
requires "Role::Tiny::With" => "0";
@@ -71,12 +74,16 @@ on 'develop' => sub {
7174
requires "Test::EOL" => "0";
7275
requires "Test::Mojibake" => "0";
7376
requires "Test::More" => "0.88";
77+
requires "Test::Needs" => "0";
7478
requires "Test::NoTabs" => "0";
7579
requires "Test::Pod" => "1.41";
7680
requires "Test::Pod::Coverage" => "1.08";
7781
requires "Test::Portability::Files" => "0";
7882
requires "Test::Spelling" => "0.17";
7983
requires "Test::Version" => "2.05";
8084
requires "Test::Without::Module" => "0";
85+
requires "lib" => "0";
8186
requires "namespace::autoclean" => "0";
87+
requires "open" => "0";
88+
requires "utf8" => "0";
8289
};

dist.ini

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ prereqs_skip = Mouse
1313
prereqs_skip = namespace::autoclean
1414
prereqs_skip = Sub::Name
1515
prereqs_skip = XString
16+
pod_coverage_skip = Specio::PP
17+
pod_coverage_skip = Specio::XS
1618
stopwords_file = .stopwords
1719
use_github_issues = 1
1820
Test::TidyAll.minimum_perl = 5.010000
@@ -38,3 +40,7 @@ Sub::Quote = 0
3840

3941
[MetaNoIndex]
4042
directory = t/lib
43+
44+
[PurePerlTests]
45+
:version = 0.06
46+
env_var = SPECIO_TEST_PP

lib/Specio.pm

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,33 @@ use 5.008;
77

88
our $VERSION = '0.51';
99

10+
use Module::Implementation;
11+
12+
use Exporter qw( import );
13+
14+
BEGIN {
15+
# This env var exists for the benefit of the PurePerlTests dzil plugin, which only knows how to
16+
# set an env var to a true value.
17+
if ( $ENV{SPECIO_TEST_PP} ) {
18+
## no critic (Variables::RequireLocalizedPunctuationVars)
19+
$ENV{SPECIO_IMPLEMENTATION} = 'PP';
20+
}
21+
22+
my $loader = Module::Implementation::build_loader_sub(
23+
implementations => [ 'XS', 'PP' ],
24+
symbols => ['_clone'],
25+
);
26+
$loader->();
27+
}
28+
29+
# It's a bit weird to put this in the root module, but this way the env var that
30+
# Module::Implementation::build_loader_sub uses will be named "SPECIO_IMPLEMENTATION". That way, if
31+
# in the future there are other optional XS components besides the Clone implementation, we don't
32+
# end up with a bunch of different env vars.
33+
#
34+
## no critic (Modules::ProhibitAutomaticExportation)
35+
our @EXPORT = qw( _clone );
36+
1037
1;
1138

1239
# ABSTRACT: Type constraints and coercions for Perl
@@ -406,6 +433,12 @@ have much better subroutine names for any frames.
406433
407434
=back
408435
436+
=head1 FORCING PURE PERL MODE
437+
438+
For some use cases (notably fatpacking a program), you may want to force Specio
439+
to use pure Perl code instead of XS code. This can be done by setting the
440+
environment variable C<SPECIO_IMPLEMENTATION> to C<PP>.
441+
409442
=head1 WHY THE NAME?
410443
411444
This distro was originally called "Type", but that's an awfully generic top
@@ -414,4 +447,3 @@ the word "species". It's short, relatively easy to type, and not used by any
414447
other distro.
415448
416449
=cut
417-

lib/Specio/OO.pm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ use strict;
44
use warnings;
55

66
use Carp qw( confess );
7-
use Clone ();
7+
use Clone::Choose ();
88
use List::Util 1.33 qw( all );
99
use MRO::Compat;
1010
use Role::Tiny;
1111
use Scalar::Util qw( weaken );
12+
use Specio qw( _clone );
1213
use Specio::Helpers qw( perlstring );
1314
use Specio::PartialDump qw( partial_dump );
1415
use Specio::TypeChecks;
@@ -335,7 +336,7 @@ sub clone {
335336
$new->{$key}
336337
= !$ref ? $value
337338
: $ref eq 'CODE' ? $value
338-
: $BuiltinTypes{$ref} ? Clone::clone($value)
339+
: $BuiltinTypes{$ref} ? _clone($value)
339340
: $value->clone;
340341
}
341342

lib/Specio/PP.pm

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package Specio::PP;
2+
3+
use strict;
4+
use warnings;
5+
6+
our $VERSION = '0.51';
7+
8+
use Clone::PP qw( clone );
9+
10+
use Exporter qw( import );
11+
12+
## no critic (Modules::ProhibitAutomaticExportation)
13+
our @EXPORT = qw( _clone );
14+
15+
## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)
16+
sub _clone {
17+
return clone(shift);
18+
}
19+
20+
1;

lib/Specio/XS.pm

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package Specio::XS;
2+
3+
use strict;
4+
use warnings;
5+
6+
our $VERSION = '0.51';
7+
8+
use Clone qw( clone );
9+
10+
use Exporter qw( import );
11+
12+
## no critic (Modules::ProhibitAutomaticExportation)
13+
our @EXPORT = qw( _clone );
14+
15+
## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)
16+
sub _clone {
17+
return clone(shift);
18+
}
19+
20+
1;

t/combines.t

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,19 @@ use strict;
22
use warnings;
33

44
use FindBin qw( $Bin );
5-
use lib "$Bin/lib";
5+
6+
my $lib_path;
7+
8+
BEGIN {
9+
if ( $Bin =~ /xt/ ) {
10+
$lib_path = "$Bin/../../t";
11+
}
12+
else {
13+
$lib_path = "$Bin";
14+
}
15+
}
16+
17+
use lib "$lib_path/lib";
618

719
use Test::Fatal;
820
use Test::More 0.96;

0 commit comments

Comments
 (0)