File: PP.pm

package info (click to toggle)
libparams-util-perl 1.102-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,044 kB
  • sloc: perl: 5,398; makefile: 3
file content (276 lines) | stat: -rw-r--r-- 6,362 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
package Params::Util::PP;

use strict;
use warnings;

our $VERSION = '1.102';

=pod

=head1 NAME

Params::Util::PP - PurePerl Params::Util routines

=cut

use Scalar::Util ();
use overload     ();

Scalar::Util->can("looks_like_number") and Scalar::Util->import("looks_like_number");
# Use a private pure-perl copy of looks_like_number if the version of
# Scalar::Util is old (for whatever reason).
Params::Util::PP->can("looks_like_number") or *looks_like_number = sub {
    local $_ = shift;

    # checks from perlfaq4
    return 0 if !defined($_);
    if (ref($_))
    {
        return overload::Overloaded($_) ? defined(0 + $_) : 0;
    }
    return 1 if (/^[+-]?[0-9]+$/);    # is a +/- integer
    ## no critic (RegularExpressions::ProhibitComplexRegexes)
    return 1 if (/^(?:[+-]?)(?=[0-9]|\.[0-9])[0-9]*(?:\.[0-9]*)?(?:[Ee](?:[+-]?[0-9]+))?$/);     # a C float
    return 1 if ($] >= 5.008 and /^(?:Inf(?:inity)?|NaN)$/i) or ($] >= 5.006001 and /^Inf$/i);

    0;
};

## no critic (Subroutines::ProhibitSubroutinePrototypes, Subroutines::RequireArgUnpacking)
## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)

sub _XScompiled { return 0; }

sub _STRING ($)
{
    my $arg = $_[0];
    return (defined $arg and not ref $arg and length($arg)) ? $arg : undef;
}

sub _IDENTIFIER ($)
{
    my $arg = $_[0];
    return (defined $arg and not ref $arg and $arg =~ m/^[^\W\d]\w*\z/s) ? $arg : undef;
}

sub _CLASS ($)
{
    my $arg = $_[0];
    return (defined $arg and not ref $arg and $arg =~ m/^[^\W\d]\w*(?:::\w+)*\z/s) ? $arg : undef;
}

sub _CLASSISA ($$)
{
    return (defined $_[0] and not ref $_[0] and $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s and $_[0]->isa($_[1])) ? $_[0] : undef;
}

sub _CLASSDOES ($$)
{
    return (defined $_[0] and not ref $_[0] and $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s and $_[0]->DOES($_[1])) ? $_[0] : undef;
}

sub _SUBCLASS ($$)
{
    return (defined $_[0] and not ref $_[0] and $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s and $_[0] ne $_[1] and $_[0]->isa($_[1]))
      ? $_[0]
      : undef;
}

sub _NUMBER ($)
{
    my $arg = $_[0];
    return (defined $arg and not ref $arg and looks_like_number($arg)) ? $arg : undef;
}

sub _POSINT ($)
{
    my $arg = $_[0];
    return (defined $arg and not ref $arg and $arg =~ m/^[1-9]\d*$/) ? $arg : undef;
}

sub _NONNEGINT ($)
{
    my $arg = $_[0];
    return (defined $arg and not ref $arg and $arg =~ m/^(?:0|[1-9]\d*)$/) ? $arg : undef;
}

sub _SCALAR ($)
{
    return (ref $_[0] eq 'SCALAR' and defined ${$_[0]} and ${$_[0]} ne '') ? $_[0] : undef;
}

sub _SCALAR0 ($)
{
    return ref $_[0] eq 'SCALAR' ? $_[0] : undef;
}

sub _ARRAY ($)
{
    return (ref $_[0] eq 'ARRAY' and @{$_[0]}) ? $_[0] : undef;
}

sub _ARRAY0 ($)
{
    return ref $_[0] eq 'ARRAY' ? $_[0] : undef;
}

sub _ARRAYLIKE
{
    return (
        defined $_[0] and ref $_[0] and ((Scalar::Util::reftype($_[0]) eq 'ARRAY')
            or overload::Method($_[0], '@{}'))
    ) ? $_[0] : undef;
}

sub _HASH ($)
{
    return (ref $_[0] eq 'HASH' and scalar %{$_[0]}) ? $_[0] : undef;
}

sub _HASH0 ($)
{
    return ref $_[0] eq 'HASH' ? $_[0] : undef;
}

sub _HASHLIKE
{
    return (
        defined $_[0] and ref $_[0] and ((Scalar::Util::reftype($_[0]) eq 'HASH')
            or overload::Method($_[0], '%{}'))
    ) ? $_[0] : undef;
}

sub _CODE ($)
{
    return ref $_[0] eq 'CODE' ? $_[0] : undef;
}

sub _CODELIKE($)
{
    return (
        (Scalar::Util::reftype($_[0]) || '') eq 'CODE'
          or Scalar::Util::blessed($_[0]) and overload::Method($_[0], '&{}')
    ) ? $_[0] : undef;
}

sub _INVOCANT($)
{
    return (
        defined $_[0]
          and (
            defined Scalar::Util::blessed($_[0])
            or
            # We used to check for stash definedness, but any class-like name is a
            # valid invocant for UNIVERSAL methods, so we stopped. -- rjbs, 2006-07-02
            _CLASS($_[0])
          )
    ) ? $_[0] : undef;
}

sub _INSTANCE ($$)
{
    return (Scalar::Util::blessed($_[0]) and $_[0]->isa($_[1])) ? $_[0] : undef;
}

sub _INSTANCEDOES ($$)
{
    return (Scalar::Util::blessed($_[0]) and $_[0]->DOES($_[1])) ? $_[0] : undef;
}

sub _REGEX ($)
{
    return (defined $_[0] and 'Regexp' eq ref($_[0])) ? $_[0] : undef;
}

sub _SET ($$)
{
    my $set_param = shift;
    _ARRAY($set_param) or return undef;
    foreach my $item (@$set_param)
    {
        _INSTANCE($item, $_[0]) or return undef;
    }
    return $set_param;
}

sub _SET0 ($$)
{
    my $set_param = shift;
    _ARRAY0($set_param) or return undef;
    foreach my $item (@$set_param)
    {
        _INSTANCE($item, $_[0]) or return undef;
    }
    return $set_param;
}

# We're doing this longhand for now. Once everything is perfect,
# we'll compress this into something that compiles more efficiently.
# Further, testing file handles is not something that is generally
# done millions of times, so doing it slowly is not a big speed hit.
sub _HANDLE
{
    my $it = shift;

    # It has to be defined, of course
    unless (defined $it)
    {
        return undef;
    }

    # Normal globs are considered to be file handles
    if (ref $it eq 'GLOB')
    {
        return $it;
    }

    # Check for a normal tied filehandle
    # Side Note: 5.5.4's tied() and can() doesn't like getting undef
    if (tied($it) and tied($it)->can('TIEHANDLE'))
    {
        return $it;
    }

    # There are no other non-object handles that we support
    unless (Scalar::Util::blessed($it))
    {
        return undef;
    }

    # Check for a common base classes for conventional IO::Handle object
    if ($it->isa('IO::Handle'))
    {
        return $it;
    }

    # Check for tied file handles using Tie::Handle
    if ($it->isa('Tie::Handle'))
    {
        return $it;
    }

    # IO::Scalar is not a proper seekable, but it is valid is a
    # regular file handle
    if ($it->isa('IO::Scalar'))
    {
        return $it;
    }

    # Yet another special case for IO::String, which refuses (for now
    # anyway) to become a subclass of IO::Handle.
    if ($it->isa('IO::String'))
    {
        return $it;
    }

    # This is not any sort of object we know about
    return undef;
}

sub _DRIVER ($$)
{
    ## no critic (BuiltinFunctions::ProhibitStringyEval)
    return (defined _CLASS($_[0]) and eval "require $_[0];" and not $@ and $_[0]->isa($_[1]) and $_[0] ne $_[1]) ? $_[0] : undef;
}

1;