++ed by:

133 PAUSE users
110 non-PAUSE users.

Jesse Vincent
and 1 contributors


To verify that B::Concise properly reports whether functions are XS, perl, or optimized constant subs, we test against a few core packages which have a stable API, and which have functions of all 3 types.


5 core packages are tested; Digest::MD5, B, B::Deparse, Data::Dumper, and POSIX. These have a mix of the 3 expected implementation types; perl, XS, and constant (optimized constant subs).

%$testpkgs specifies what packages are tested; each package is loaded, and the stash is scanned for the function-names in that package.

Each value in %$testpkgs is a hash-of-lists (HoL) whose keys are implementation-types and values are lists of function-names of that type.

To keep these HoLs smaller and more managable, they may carry an additional 'dflt' => $impl_Type, which means that unnamed functions are expected to be of that default implementation type. Those unnamed functions are known from the scan of the package stash.


Each function is 'rendered' by B::Concise, and result is matched against regexs for each possible implementation-type. For some packages, some functions may be unimplemented on some platforms.

To slay this maintenance dragon, the regexs used in like() match against renderings which indicate that there is no implementation.

If a function is implemented differently on different platforms, the test for that function will fail on one of those platforms. These specific functions can be skipped by a 'skip' => [ @list ] to the HoL mentioned previously. See usage for skip in B's HoL, which avoids testing a function which doesnt exist on non-threaded builds.


-v and -V trigger 2 levels of verbosity.

-a uses Module::CoreList to run all core packages through the test, which gives some interesting results.

-c causes the expected XS/non-XS results to be marked with corrections, which are then reported at program END, in a form that's readily cut-and-pastable into this file.

-r <file> reads a file, as written by -c, and adjusts the expected results accordingly. The file is 'required', so @INC settings apply.

If module-names are given as args, those packages are run through the test harness; this is handy for collecting further items to test, and may be useful otherwise (ie just to see).


./perl -Ilib -wS ext/B/t/concise-xs.t -c Storable

Tests Storable.pm for XS/non-XS routines, writes findings (along with test results) to stdout. You could edit results to produce a test file, as in next example

./perl -Ilib -wS ext/B/t/concise-xs.t -r ./storable

Loads file, and uses it to set expectations, and run tests

./perl -Ilib -wS ext/B/t/concise-xs.t -avc > ../foo-avc 2> ../foo-avc2

Gets module list from Module::Corelist, and runs them all through the test. Since -c is used, this generates corrections, which are saved in a file, which is edited down to produce ../all-xs

./perl -Ilib -wS ext/B/t/concise-xs.t -cr ../all-xs > ../foo 2> ../foo2

This runs the tests specified in the file created in previous example. -c is used again, and stdout verifies that all the expected results given by -r ../all-xs are now seen.

Looking at ../foo2, you'll see 34 occurrences of the following error:

# err: Can't use an undefined value as a SCALAR reference at # lib/B/Concise.pm line 634, <DATA> line 1.