view release on metacpan or search on metacpan
        * Allow the custom OPs to be deparsed with B::Deparse.
          (Graham @haarg Knop)
        * Optimize the shared object size by moving common call checker
          logic into a function. (James Raspass)
0.116     2017-05-13 15:13:41+02:00 Europe/Amsterdam
        * Changes rephrasing. (Ilmari)
        * Restore 5.6 compatibility
        * Replace docs with a link to Ref::Util
0.115     2017-05-12 09:48:02+02:00 Europe/Amsterdam
        * This (and 0.114) is effectively Ref-Util 0.113. It is being
          released as Ref-Util-XS to make room for Ref-Util's new
          pure-Perl implementation.
0.114
0.113     2017-01-16 19:36:58+01:00 Europe/Amsterdam
{
   "abstract" : "XS implementation for Ref::Util",
   "author" : [
      "Sawyer X <xsawyerx@cpan.org>",
      "Aaron Crane <arc@cpan.org>",
      "Vikenty Fesunov <vyf@cpan.org>",
      "Gonzalo Diethelm <gonzus@cpan.org>",
      "Karen Etheridge <ether@cpan.org>",
      "Graham Knop <haarg@cpan.org>"
   ],
   "dynamic_config" : 0,
   "generated_by" : "Dist::Zilla version 6.010, CPAN::Meta::Converter version 2.150010",
         },
         "requires" : {
            "B::Concise" : "0",
            "ExtUtils::MakeMaker" : "0",
            "File::Spec" : "0",
            "Test::More" : "0.96"
         }
      }
   },
   "provides" : {
      "Ref::Util::XS" : {
         "file" : "lib/Ref/Util/XS.pm",
         "version" : "0.117"
      }
   },
   "release_status" : "stable",
   "resources" : {
      "bugtracker" : {
         "web" : "https://github.com/p5pclub/ref-util-xs/issues"
      },
      "repository" : {
---
abstract: 'XS implementation for Ref::Util'
author:
  - 'Sawyer X <xsawyerx@cpan.org>'
  - 'Aaron Crane <arc@cpan.org>'
  - 'Vikenty Fesunov <vyf@cpan.org>'
  - 'Gonzalo Diethelm <gonzus@cpan.org>'
  - 'Karen Etheridge <ether@cpan.org>'
  - 'Graham Knop <haarg@cpan.org>'
build_requires:
  B::Concise: '0'
  ExtUtils::MakeMaker: '0'
configure_requires:
  ExtUtils::MakeMaker: '0'
dynamic_config: 0
generated_by: 'Dist::Zilla version 6.010, CPAN::Meta::Converter version 2.150010'
license: mit
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: '1.4'
name: Ref-Util-XS
provides:
  Ref::Util::XS:
    file: lib/Ref/Util/XS.pm
    version: '0.117'
requires:
  Exporter: '5.57'
  XSLoader: '0'
  perl: '5.006'
resources:
  bugtracker: https://github.com/p5pclub/ref-util-xs/issues
  repository: git://github.com/p5pclub/ref-util-xs.git
version: '0.117'
Makefile.PL view on Meta::CPAN
# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.010.
use strict;
use warnings;
use 5.006;
use ExtUtils::MakeMaker;
my %WriteMakefileArgs = (
  "ABSTRACT" => "XS implementation for Ref::Util",
  "AUTHOR" => "Sawyer X <xsawyerx\@cpan.org>, Aaron Crane <arc\@cpan.org>, Vikenty Fesunov <vyf\@cpan.org>, Gonzalo Diethelm <gonzus\@cpan.org>, Karen Etheridge <ether\@cpan.org>, Graham Knop <haarg\@cpan.org>",
  "CONFIGURE_REQUIRES" => {
    "ExtUtils::MakeMaker" => 0
  },
  "DISTNAME" => "Ref-Util-XS",
  "LICENSE" => "mit",
  "MIN_PERL_VERSION" => "5.006",
  "NAME" => "Ref::Util::XS",
  "PREREQ_PM" => {
    "Exporter" => "5.57",
    "XSLoader" => 0
  },
  "TEST_REQUIRES" => {
    "B::Concise" => 0,
    "ExtUtils::MakeMaker" => 0,
    "File::Spec" => 0,
    "Test::More" => "0.96"
  },
This archive contains the distribution Ref-Util-XS,
version 0.117:
  XS implementation for Ref::Util
This software is Copyright (c) 2018 by Sawyer X.
This is free software, licensed under:
  The MIT (X11) License
This README file was generated by Dist::Zilla::Plugin::Readme v6.010.
    SvGETMAGIC(ref);                                    \
    SETs( COND(cond) ? &PL_sv_yes : &PL_sv_no );        \
  }
#define DECL_RUNTIME_FUNC(x, cond)                              \
    static void                                                 \
    THX_xsfunc_ ## x (pTHX_ CV *cv)                             \
    {                                                           \
        dXSARGS;                                                \
        if (items != 1)                                         \
            Perl_croak(aTHX_ "Usage: Ref::Util::XS::" #x "(ref)");  \
        FUNC_BODY(cond);                                        \
    }
#define DECL_XOP(x) \
    static XOP x ## _xop;
#define DECL_MAIN_FUNC(x, cond)                 \
    static OP *                                 \
    x ## _op(pTHX)                              \
    {                                           \
    static OP *                                                                \
    THX_ck_entersub_args_ ## x(pTHX_ OP *entersubop, GV *namegv, SV *ckobj)    \
    {                                                                          \
        return call_checker_common(aTHX_ entersubop, namegv, ckobj, x ## _op); \
    }
#if !USE_CUSTOM_OPS
#define DECL(x, cond) DECL_RUNTIME_FUNC(x, cond)
#define INSTALL(x, ref) \
    newXSproto("Ref::Util::XS::" #x, THX_xsfunc_ ## x, __FILE__, "$");
#else
#define DECL(x, cond)                           \
    DECL_RUNTIME_FUNC(x, cond)                  \
    DECL_XOP(x)                                 \
    DECL_MAIN_FUNC(x, cond)                     \
    DECL_CALL_CHK_FUNC(x)
#define INSTALL(x, ref)                                               \
    {                                                                 \
        CV *cv;                                                       \
        XopENTRY_set(& x ##_xop, xop_name, #x);                       \
        XopENTRY_set(& x ##_xop, xop_desc, "'" ref "' ref check");    \
        XopENTRY_set(& x ##_xop, xop_class, OA_UNOP);                 \
        Perl_custom_op_register(aTHX_ x ##_op, & x ##_xop);           \
        cv = newXSproto_portable(                                     \
            "Ref::Util::XS::" #x, THX_xsfunc_ ## x, __FILE__, "$"         \
        );                                                            \
        cv_set_call_checker(cv, THX_ck_entersub_args_ ## x, (SV*)cv); \
    }
// This function extracts the args for the custom op, and deletes the remaining
// ops from memory, so they can then be replaced entirely by the custom op.
/*
    This is how the ops will look like:
    $ perl -MO=Concise -E'is_arrayref($foo)'
DECL(is_blessed_ref,       !PLAIN)
DECL(is_blessed_scalarref, JUSTSCALAR && !PLAIN)
DECL(is_blessed_arrayref,  REFTYPE(== SVt_PVAV) && !PLAIN)
DECL(is_blessed_hashref,   REFTYPE(== SVt_PVHV) && !PLAIN)
DECL(is_blessed_coderef,   REFTYPE(== SVt_PVCV) && !PLAIN)
DECL(is_blessed_globref,   REFTYPE(== SVt_PVGV) && !PLAIN)
DECL(is_blessed_formatref, FORMATREF && !PLAIN)
DECL(is_blessed_ioref,     REFTYPE(== SVt_PVIO) && !PLAIN)
DECL(is_blessed_refref,    REFREF && !PLAIN)
MODULE = Ref::Util::XS		PACKAGE = Ref::Util::XS
PROTOTYPES: DISABLE
BOOT:
    {
        INSTALL( is_ref, "" )
        INSTALL( is_scalarref, "SCALAR" )
        INSTALL( is_arrayref,  "ARRAY"  )
        INSTALL( is_hashref,   "HASH"   )
        INSTALL( is_coderef,   "CODE"   )
lib/Ref/Util/XS.pm view on Meta::CPAN
package Ref::Util::XS;
# ABSTRACT: XS implementation for Ref::Util
$Ref::Util::XS::VERSION = '0.117';
use strict;
use warnings;
use XSLoader;
use Exporter 5.57 'import';
our %EXPORT_TAGS = ( 'all' => [qw<
    is_ref
    is_scalarref
    is_arrayref
lib/Ref/Util/XS.pm view on Meta::CPAN
    is_blessed_arrayref
    is_blessed_hashref
    is_blessed_coderef
    is_blessed_globref
    is_blessed_formatref
    is_blessed_refref
>] );
our @EXPORT_OK   = ( @{ $EXPORT_TAGS{'all'} } );
XSLoader::load('Ref::Util::XS', $Ref::Util::XS::{VERSION} ? ${ $Ref::Util::XS::{VERSION} } : ());
if (_using_custom_ops()) {
  for my $op (@{$EXPORT_TAGS{all}}) {
    no strict 'refs';
    *{"B::Deparse::pp_$op"} = sub {
      my ($deparse, $bop, $cx) = @_;
      my @kids = $deparse->deparse($bop->first, 6);
      my $sib = $bop->first->sibling;
      if (ref $sib ne 'B::NULL') {
        push @kids, $deparse->deparse($sib, 6);
lib/Ref/Util/XS.pm view on Meta::CPAN
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Ref::Util::XS - XS implementation for Ref::Util
=head1 VERSION
version 0.117
=head1 SYNOPSIS
    use Ref::Util;
    # Don't use Ref::Util::XS directly!
    if (is_arrayref($something) {
        print for @$something;
    }
    elsif (is_hashref($something)) {
        print for sort values %$something;
    }
=head1 DESCRIPTION
Ref::Util::XS is the XS implementation of Ref::Util, which provides several
functions to help identify references in a more convenient way than the
usual approach of examining the return value of C<ref>.
You should use L<Ref::Util::XS> by installing L<Ref::Util> itself: if the system
you install it on has a C compiler available, C<Ref::Util::XS> will be
installed and used automatically, providing a significant speed boost to
everything that uses C<Ref::Util>.
See L<Ref::Util> for full documentation of the available functions.
=head1 THANKS
The following people have been invaluable in their feedback and support.
=over 4
=item * Yves Orton
=item * Steffen Müller
t/all-permutations.t view on Meta::CPAN
use strict;
use warnings;
use Test::More 'tests' => 5;
use Ref::Util::XS ':all';
use constant FORMAT_REFS_WORK => ("$]" >= 5.007);
# FIXME: plain regular expressions, blessed regular expressions
my $plain_formatref = do {
    format FH1 =
.
    *FH1{'FORMAT'};
};
t/all-permutations.t view on Meta::CPAN
my @all_keys     = sort keys %all;
my @plain_keys   = sort keys %plain;
my @blessed_keys = sort keys %blessed;
subtest 'non-refs' => sub {
    foreach my $value ( 0, 1, 'string', '', undef, '0', '0e0' ) {
        # better string representation for test output
        my $rep = defined $value ? $value eq '' ? q{''} : $value : '(undef)';
        for my $name (grep /^is_/, @Ref::Util::XS::EXPORT_OK) {
            next if !FORMAT_REFS_WORK && $name =~ /formatref/;
            my $func = do { no strict 'refs'; \&{"Ref::Util::XS::$name"} };
            ok( !$func->($value), "$name($rep) is false" );
        }
    }
    done_testing();
};
subtest 'plain references only work on is_plain functions' => sub {
    # each %plain should fail each test of the %blessed
    foreach my $plain_type (@plain_keys) {
t/arrayref.t view on Meta::CPAN
use strict;
use warnings;
use Test::More tests => 7;
BEGIN {
    use_ok('Ref::Util::XS');
    Ref::Util::XS->import('is_arrayref');
}
can_ok( Ref::Util::XS::, 'is_arrayref' );
Ref::Util::XS::is_arrayref(\1);
ok( !is_arrayref(\1), 'Correctly identify scalarref' );
ok( !is_arrayref({}), 'Correctly identify hashref' );
ok( !is_arrayref(sub {}), 'Correctly identify coderef' );
ok( !is_arrayref(qr//), 'Correctly identify regexpref' );
ok( is_arrayref([]), 'Correctly identify arrayref' );
t/b-concise.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use Ref::Util::XS 'is_arrayref';
require B::Concise;
plan skip_all => 'This version of B::Concise does not have "compile"'
    if !B::Concise->can('compile');
plan skip_all => 'nothing to do when no custom ops'
    if !Ref::Util::XS::_using_custom_ops();
plan tests => 2;
sub func { is_arrayref([]) }
my $walker = B::Concise::compile('-exec', 'func', \&func);
B::Concise::walk_output(\ my $buf);
eval { $walker->() };
my $exn = $@;
t/dynamic.t view on Meta::CPAN
use strict;
use warnings;
use Ref::Util::XS;
use Test::More tests => 2;
my $cb = Ref::Util::XS->can('is_arrayref');
ok( $cb->([]), 'is_arrayref with can()' );
ok( !$cb->({}), 'is_arrayref with can()' );
use strict;
use warnings;
use Test::More tests => 1;
use Ref::Util::XS 'is_arrayref';
sub arrayref { [] }
ok( is_arrayref( arrayref() ), 'Got arrayref from expression' );
t/functions.t view on Meta::CPAN
        [bless(sub {}),              'blessed code'],
        [$blessed_glob,              'blessed glob'],
        [do { bless \\(my $x = 1) }, 'blessed ref'],
        [$blessed_format,            'blessed format'],
    );
    plan tests => 26 * @cases + 1;  # extra one is for use_ok() above
}
BEGIN {
    use_ok('Ref::Util::XS');
    Ref::Util::XS->import(qw<
        is_ref
        is_scalarref
        is_arrayref
        is_hashref
        is_coderef
        is_regexpref
        is_globref
        is_formatref
        is_ioref
        is_refref
use strict;
use warnings;
use Test::More tests => 2;
use Ref::Util::XS qw<is_arrayref is_hashref>;
# Call multiple routines in a single list expression:
my @got = ( is_arrayref([]), is_hashref({}) );
ok( $got[0], 'got arrayref in list context' );
ok( $got[1], 'got hashref in list context' );
t/magic-readonly.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use Ref::Util::XS qw<is_hashref is_plain_hashref is_blessed_hashref>;
eval { require Readonly; Readonly->import; 1; }
or plan 'skip_all' => 'Readonly is required for this test';
plan 'tests' => 3;
Readonly::Scalar( my $rh2 => { a => { b => 2 } } );
ok( is_hashref($rh2), 'Readonly objects work!' );
ok( is_plain_hashref($rh2), 'They are not plain!' );
use strict;
use warnings;
use Ref::Util::XS qw<is_arrayref>;
use Test::More 'tests' => 1;
my ( $x, $y );
{
    package Foo;
    sub TIESCALAR { bless {}, shift }
    sub FETCH { $x }
}
t/toomany.t view on Meta::CPAN
use strict;
use warnings;
use Test::More tests => 6;
use Ref::Util::XS qw<is_arrayref is_hashref>;
my $array_func = \&is_arrayref;
my $hash_func = \&is_hashref;
is(prototype($array_func), '$', 'is_arrayref has "$" prototype');
is(prototype($hash_func), '$', 'is_hashref has "$" prototype');
# We have to use string eval for this, because when the custom op is being
# used, we expect the direct calls to fail at compile time
my @cases = (
t/toomany.t view on Meta::CPAN
    [is_hashref => 'is_hashref([], 17)',
     'direct hash call with too many arguments'],
    [is_hashref => '$hash_func->([], 17)',
     'hash call through coderef with too many arguments'],
);
for my $case (@cases) {
    my ($name, $code, $desc) = @$case;
    scalar eval $code;
    my $exn = $@;
    like($exn, qr/^(?: \QUsage: Ref::Util::XS::$name(ref)\E
                     | \QToo many arguments for Ref::Util::XS::$name\E\b )/x,
         $desc);
}
tools/bench.pl view on Meta::CPAN
use strict;
use warnings;
use constant { 'AMOUNT' => 1e8 };
use Ref::Util::XS qw<is_arrayref is_plain_arrayref is_plain_hashref>;
use Scalar::Util ();
use Data::Util ':check';
use Dumbbench;
use Dumbbench::Instance::PerlSub;
my $bench = Dumbbench->new(
    'target_rel_precision' => 0.005, # seek ~0.5%
    'initial_runs'         => 20,    # the higher the more reliable
);
my $amount = AMOUNT();
my $ref    = [];
no warnings;
$bench->add_instances(
    Dumbbench::Instance::PerlSub->new(
        'name' => 'Ref::Util::XS::is_plain_arrayref (CustomOP)',
        'code' => sub { Ref::Util::XS::is_plain_arrayref($ref) for ( 1 .. $amount ) },
    ),
    Dumbbench::Instance::PerlSub->new(
        'name' => 'ref(), reftype(), !blessed()',
        'code' => sub {
            ref $ref
                && Scalar::Util::reftype($ref) eq 'ARRAY'
                && !Scalar::Util::blessed($ref)
                for ( 1 .. $amount );
        },