Algorithm-ToNumberMunger

 view release on metacpan or  search on metacpan

lib/Algorithm/ToNumberMunger.pm  view on Meta::CPAN


The first of the B<named-map enums>: like L</enum>, except the C<map> is baked
in from a well-known registry instead of hand-authored (and inevitably
typo'd). All named-map enums share the same lookup rules: names are matched
B<case-insensitively>; where the emitted numbers are the protocol's own wire
encoding (as here -- rcode C<3> I<is> C<NXDOMAIN>), a numeric input is passed
through unchanged, so mixed feeds (one tool logs C<NXDOMAIN>, another logs
C<3>) land in one consistent column; and an unmapped value croaks unless the
spec supplies a numeric C<default>. As with C<enum>, an unrecognized value is
often exactly the anomaly worth keeping, so C<< default => -1 >> is the usual
escape hatch.

This one maps DNS RCODE names to their IANA values: C<NOERROR> 0, C<FORMERR>
1, C<SERVFAIL> 2, C<NXDOMAIN> 3, C<NOTIMP> 4 (alias C<NOTIMPL>), C<REFUSED> 5,
C<YXDOMAIN> 6, C<YXRRSET> 7, C<NXRRSET> 8, C<NOTAUTH> 9, C<NOTZONE> 10,
C<DSOTYPENI> 11, and the extended rcodes C<BADVERS>/C<BADSIG> 16, C<BADKEY>
17, C<BADTIME> 18, C<BADMODE> 19, C<BADNAME> 20, C<BADALG> 21, C<BADTRUNC> 22,
C<BADCOOKIE> 23.

=head2 dns_qtype_enum

lib/Algorithm/ToNumberMunger.pm  view on Meta::CPAN

=head2 match

    { munger => 'match', pattern => '^xn--' }                       # punycode label
    { munger => 'match', pattern => '%[0-9A-Fa-f]{2}', mode => 'count' }

Match the input against a Perl regular expression C<pattern>: C<1>/C<0> under
the default C<< mode => 'bool' >>, or the number of non-overlapping matches
with C<< mode => 'count' >>. A true C<ignore_case> makes the match
case-insensitive. This is the catch-all shape test behind flags like "is this
label punycode" or "is the Host an IP literal", and counters like
percent-escapes in a URL -- anything L</char> and L</count> are not expressive
enough for. The pattern is compiled at build time, so a broken one fails at
C<write_info> rather than per row.

B<Trust note:> a pattern cannot execute code (Perl requires C<use re 'eval'>
for that, which this module does not enable), but a pathological pattern can
still backtrack catastrophically and stall a writer. Treat munger specs --
like the rest of C<info.json> -- as configuration from a trusted operator,
not as untrusted input.

=cut

lib/Algorithm/ToNumberMunger.pm  view on Meta::CPAN

		return ( $i + ( $v - $b[$i] ) / ( $b[ $i + 1 ] - $b[$i] ) ) / $segs;
	}; ## end sub
} ## end sub _build_quantile

=head2 scale

    { munger => 'scale', min => 0, max => 1000, clamp => 1 }

Min-max normalisation: C<(v - min) / (max - min)>, mapping C<[min, max]> onto
C<[0, 1]>. C<min> and C<max> must differ. With a true C<clamp>, results are
pinned into C<[0, 1]> so out-of-range inputs cannot escape the unit interval.

=cut

sub _build_scale {
	my ( $spec, $where ) = @_;

	my ( $min, $max ) = @{$spec}{qw(min max)};
	croak "scale munger$where requires numeric 'min' and 'max'"
		unless looks_like_number($min) && looks_like_number($max);

t/mungers.t  view on Meta::CPAN

}

# ---- match ------------------------------------------------------------------
{
	my $puny = $M->build( { munger => 'match', pattern => '^xn--' } );
	is( $puny->('xn--e1afmkfd.ru'), 1, 'match bool: punycode label matches' );
	is( $puny->('example.com'),     0, 'match bool: plain label does not' );
	is( $puny->(undef),             0, 'match bool: undef is 0' );

	my $esc = $M->build( { munger => 'match', pattern => '%[0-9A-Fa-f]{2}', mode => 'count' } );
	is( $esc->('/a%20b%2e%2Ec'), 3, 'match count: percent-escapes' );
	is( $esc->('/plain/path'),   0, 'match count: none' );

	my $ci = $M->build( { munger => 'match', pattern => 'select', ignore_case => 1 } );
	is( $ci->('SELECT * FROM'), 1, 'match ignore_case matches across case' );

	eval { $M->build( { munger => 'match' } ) };
	like( $@, qr/non-empty 'pattern'/, 'match requires a pattern' );
	eval { $M->build( { munger => 'match', pattern => '(unclosed' } ) };
	like( $@, qr/cannot compile pattern/, 'match croaks on a broken pattern at build time' );
	eval { $M->build( { munger => 'match', pattern => 'x', mode => 'nope' } ) };



( run in 3.034 seconds using v1.01-cache-2.11-cpan-7fcb06a456a )