Should I choose x.yy or x.yyy versioning scheme for my Perl module?

Short answer


Longer answer

Both schemes are simple and short. x.yy is shorter by a single digit, but it is prone to a trap. One day, when you want to update your 0.13 module with a minor change you might say to yourself, "Gee, it's such a minor change that I think I'll release it as 0.13.1 instead of 0.14. Semantic versioning and all that." So you did, and boom. PAUSE would accept it but would refuse to index it. Why?? You would scratch your head for a while. Turns out that according to, 0.13 > 0.13.1. Why??? Because 0.13 numifies into 0.130 and 0.13.1 numifies into 0.013001.

I've fell for it once (twice actually, before deciding to convert to x.yyy). It's amazing how many veteran CPAN authors fell for it. For example, here's Dave Cross in 2016. Others I've seen while browsing the MetaCPAN Recent page. My bad memory prevents me from remembering who and when, and I'm too lazy to check, but trust me it's embarassingly often.

You might argue it's a bug with or PAUSE or Perl for behaving unlike the rest of the world, but that's how versioning works in Perl so just avoid this trap and be done with this. You might also say, "I'll always increase the minor version and will never use x.yyy.zzz." But there's always the possibility thay you'll forget and do just that.

It's unfortunate that x.yy remains (by my guess) the most popular versioning scheme for Perl modules, but consider yourself warned.

More about versioning in Perl

Books can be written on and years can be spent debating about versioning and its best practices, including in Perl. If you want to read more, here are a few links to get you started:

Some related posts by yours truly:


List of new CPAN distributions – Aug 2018

dist author version abstract
Acme-FIREXFLY-Utils FIREXFLY 0.01 Chapter 21 exercise from the book ‘Intermediate Perl’
Acme-NAHCNUJ-Utils NAHCNUJ 0.01 Answer for exercise 21.3 of the book “Intermediate Perl”
Algorithm-Heapify-XS YVES 0.01 Perl extension for supplying simple heap primitives for arrays.
Alien-nragent PLICEASE 0.01 Download and install the NewRelic agent
Anki-Import STEVIED 0.006 Anki note generation made easy.
AnyEvent-WebDriver MLEHMANN 0.0 control browsers using the W3C WebDriver protocol
App-Git-Info SHLOMIF 0.0.1 displays a summary of information about the git repository.
App-ISBNUtils PERLANCAR 0.001 Command-line utilities related to ISBN
App-WHOGrowthReferenceUtils PERLANCAR 0.001 Utilities related to WHO growth reference
App-Weather BRADHEFF 0.01 a module that fetches the weather
App-YouTubeUtils PERLANCAR 0.001 Command-line utilities related to YouTube
App-ccdiff HMBRAND 0.20 Colored Character Diff
App-isbn PERLANCAR 0.001 Query book information by ISBN
App-ygeo PAVELSR 0.01 Extract companies data from Yandex Maps to csv file
Assert-Refute-T-Deep KHEDIN 0.01 Test::Deep plugin for Assert::Refute
Bencher-Scenarios-DataComparisonModules PERLANCAR 0.001 A collection of bencher scenarios to benchmark data structure comparison modules
Bencher-Scenarios-ISBN PERLANCAR 0.001 Benchmark ISBN modules
Boost-UUID ADDICT 0.01 perl interface for boost::uuid
CSV-Processor PAVELSR 1.00 Set of different methods that adds new columns in csv files
CtrlO-PDF ABEVERLEY 0.01 high level PDF creator
DAPNET-API RUNE 0.1 Use the DAPNET API from Perl
DBD-SQLeet DDMITOV 1.58 SQLite3 DBI Driver with optional encryption
DBIx-Connector-Retry GSG 0.90 DBIx::Connector with block retry support
Dancer2-Template-Alloy CVLIBRARY 0.001 Template::Alloy engine for Dancer2
Data-Cmp PERLANCAR 0.001 Compare two data structures, return -1/0/1 like cmp
DateTime-Calendar-TauStation CFRANKS 0.1.1 Handle TauStation GCT datetimes
DateTime-TauStation CFRANKS 0.1 Handle TauStation GCT datetimes
Dist-Zilla-Plugin-Babble LEONT 0.001 EXPERIMENTAL Automatic Babble substitution in Dist::Zilla
Dist-Zilla-Plugin-FFI PLICEASE 0.01 FFI related Dist::Zilla plugins
Dist-Zilla-Plugin-PodKnit YANICK 0.0.1 craft from warm and fuzzy documentation for your Perl code
Dist-Zilla-PluginBundle-QBit MADSKILL 0.8 Dist::Zilla bundle for build and release QBit Framework packages
ELF-sign PRIVI 0.03 X509 signing of elf execuables
FFI-Build PLICEASE 0.02 Build shared libraries for use with FFI::Platypus
File-Generator LSKATZ 0.2
File-Print-Many NHORNE 0.01 Print to more than one file descriptor at once
Function-Return KFLY 0.01 add return type for a function
GCloud-CLIWrapper JLMARTIN 0.01 Module to use Google Cloud APIs via the gcloud CLI
Game-DijkstraMap JMATES 0.01 a numeric grid of weights plus some related functions
Geo-Code ERUCI 1.1 Perl module for converting latitude,longitude to a single ten byte geocode string or three geonames, and vice versa.
HTML-FormFu-TauStation CFRANKS 1.182320 HTML::FormFu modules for working with GCT (Galactic Time Coordinated) datetimes and durations from the online game Tau Station
Image-Synchronize LSTROUS 1.0 a module for synchronizing filesystem modification timestamps of images, movies, and related files.
Keyword-Pluggable KARASIK 1.00 define new keywords in pure Perl
Lexical-TypeTiny TOBYINK 0.001 my Int $n
List-Unique-DeterministicOrder SLAFFAN 0.001 Store and access a list of keys using a deterministic order based on the sequence of insertions and deletions
MIME-Signature FANY 0.1 appends signature to mail messages
MooX-Should RRWO v0.1.0 optional type restrictions for Moo attributes
Net-Doveadm FELIPE 0.01 Dovecot’s administrative interface protocol
NewRelic-Agent-FFI PLICEASE 0.01 Perl Agent for NewRelic APM
Parallel-ForkManager-Segmented SHLOMIF 0.0.1 use Parallel::ForkManager on batches / segments of items.
Perl-Critic-Policy-ValuesAndExpressions-ProhibitEmptyPostfixLoop XSAWYERX 0.001 Prohibit writing an postfix loop with no statement
PerlX-Define TOBYINK 0.100 cute syntax for defining constants
Pod-Knit YANICK 0.0.1 Stitches together POD documentation
Pod-Readme-Brief ARISTOTLE 1.000 A short simple README with just the essentials
Pod-Weaver-PluginBundle-SHLOMIF SHLOMIF 0.001000 SHLOMIF’s default Pod::Weaver config
Pod-Weaver-PluginBundle-SLOYD SLOYD 0.0001 SLOYD’s default Pod::Weaver configuration
Repetition-Interval MALLEN 0.001 A library to calculate intervals for spaced repetition memorization
Sah-Schemas-EAN PERLANCAR 0.001 Various Sah schemas related to EAN (International/European Article Number)
Sah-Schemas-ISBN PERLANCAR 0.001 Various Sah schemas related to ISBN (International Standard Book Number)
School-Evaluation-Gibbmers BORISD 0.001 render a chart
Serge-Sync-Plugin-TranslationService-crowdin DRAGOSV 0.900.0 Crowdin translation server ( synchronization plugin
Set-Hash-Keys VANHOESEL 0.01 Treat Hashes as Sets, based on the keys only
Sub-Params BARNEY v1.0.0 Handle function arguments
Syntax-Keyword-Dynamically PEVANS 0.01 dynamically change the value of a variable
TT2-Play-Area NEWELLC 0.001 Simple site to allow playing with TT2 syntax and built in plugins.
Task-QuadPres SHLOMIF 0.0.1 install the CPAN dependencies of Quad-Pres.
Test-Deeply-Float PERLANCAR 0.001 Test equality of data structure, compare numbers with tolerance
Test-Harness-KS KIVILAHTI 0.001 Harness the power of clover and junit in one easy to use wrapper.
Test-Module BALAJIRAM 0.001 brief summary of what this module is used for
Test-New-Module BALAJIRAM 0.001 brief summary of what this module is used for
TextFileParser BALAJIRAM 0.1821900 a Perl extension to ease the parsing of text files. Can be used as a base class to write your own parser.
Unicode-Homoglyph-Replace BIGPRESH 0.01 replace homoglyphs with their ASCII lookalike equivalents
WHO-GrowthReference-Table PERLANCAR 0.001 Lookup height/weight in the WHO growth chart (a.k.a. growth reference, growth standards)
WWW-ELISA VPEIL 0.01 a module for working the the REST API ELi:SA (
WWW-Scrape-BillionGraves NHORNE 0.01 Scrape the BillionGraves website
Weather-Fetch BRADHEFF 0.01 a module that fetches the weather
WebService-Mocean KIANMENG 0.01 Perl library for integration with MoceanSMS gateway,
Win32-Console-PatchForRT33513 KUERBIS 0.001 Patch for RT33513.
decorators STEVAN 0.01 Apply decorators to your methods
elf-sign PRIVI 0.02 X509 signing of elf execuables
lib-archive TOMK 0.1 load pure-Perl modules directly from TAR archives
namespace-lexical TOBYINK 0.001 like namespace::clean but instead of deleting subs, makes them lexical
namespace-local KHEDIN 0.02 Confine imports to the current scope
overload-x LNATION 0.01 The great new overload::x!
perl5-Data-MoneyCurrency EDF 0.04 Get currency information for different currencies
plenigo PLENIGO 0.2 plenigo Perl SDK

List of new CPAN distributions – Jul 2018

dist author version abstract
AI-MXNet-Gluon-Contrib SKOLYCHEV 1.3 Perl interface to MXNet Gluon Contrib
AI-MXNet-Gluon-ModelZoo SKOLYCHEV 1.3 Perl interface to MXNet Gluon ModelZoo
Acme-CPANModules-CLI-Sort PERLANCAR 0.001 Various CLIs to perform sorting
Acme-JTM-Experiment JMASLAK 1.182080 Testing Perl Constructs on CPAN Testers
Alien-Build-Plugin-Cleanse-BuildDir SLAFFAN 0.01 Alien::Build plugin to cleanse the build dir
Alien-caca YANICK 0.0.1 Alien package for the Colored ASCII Art library
Alt-Alien-cmake3-System PLICEASE 0.0401 Simplified alternative to Alien::cmake3 that uses system cmake
App-SlowQuitApps DCONWAY 0.000002 Simplify configuration of SlowQuitApps app on MacOS
App-ansifold UTASHIRO 0.01 fold command handling ANSI terminal sequences
App-cointoss TULAMILI 0.12 The command "cointoss" for a Bernoulli and a binomial distribution as well is provided.
App-colorplus TULAMILI 0.31 The great new App::colorplus!
App-csv2tsv TULAMILI 0.51 A command line utility "csv2tsv" for easy and fairly properly transforming from CSV to TSV.
App-freqtable PERLANCAR 0.001 Print frequency table of lines/words/characters/bytes/numbers
App-githook_perltidy MLAWREN v0.11.9 run perltidy and podtidy before Git commits
App-horsekicks TULAMILI 0.13 The great new App::horsekicks!
App-keycommon TULAMILI 0.0010 You can combine multiple TSV (also machine-readable CSV) files which share a common key column.
App-lensort PERLANCAR 0.001 Sort lines of text by their length
App-matrixpack TULAMILI 0.0012 The great new App::matrixpack!
App-randskip TULAMILI 0.0003 Samples lines randomly with an efficient internal mechanism – a random number is generated per a output line not per an input line – both with replacement and without replacement.
App-shufflerow TULAMILI 0.32 A command utility of shuffling the lines (even the paragraphs) with many useful functions together.
App-summ PERLANCAR 0.001 Print summary statistics of a series of numbers
App-t1generate TULAMILI 0.23 The generator of random numbers obeying the Cauchy distribution (t distribution with df = 1).
App-t2generate TULAMILI 0.23 The generator of random numbers obeying the Cauchy distribution (t distribution with df = 2).
App-unichar BDFOY 0.012 get info about a character
Astro-Coord-ECI-TLE-Iridium WYANT 0.099_01 Class to compute Iridium Classic flares
Bencher-Scenarios-DateTimeFormatDurationISO8601 PERLANCAR 0.001 Scenarios to benchmark DateTime::Format::Duration::ISO8601
Bencher-Scenarios-DateTimeFormatISO8601 PERLANCAR 0.001 Scenarios to benchmark DateTime::Format::ISO8601
Bencher-Scenarios-DateTimeFormatISO8601Format PERLANCAR 0.001 Scenarios to benchmark DateTime::Format::ISO8601::Format
BioSAILs-Command JILLROWE 1.0 Command line wrapper for the BioX-Workflow-Command and HPC-Runner-Command libraries.
CellBIS-Random YUSRIDEB 0.1 Tool for Randomize characters in strings.
CellBIS-SQL-Abstract YUSRIDEB 0.1 SQL Abstract
Config-HAProxy SGRAY 1.00 Parser for HAProxy configuration file
DBIx-CSV PERLANCAR 0.001 Generate CSV from SQL query result
DBIx-Class-Helper-Row-Enumeration RRWO v0.1.0 Add methods for emum values
DBIx-Conn-MySQL PERLANCAR 0.001 Shortcut to connect to MySQL database
DBIx-Conn-Pg PERLANCAR 0.001 Shortcut to connect to PostgreSQL database
DBIx-Conn-SQLite PERLANCAR 0.001 Shortcut to connect to SQLite database
DBIx-TSV PERLANCAR 0.001 Generate TSV from SQL query result
Devel-MAT-Dumper PEVANS 0.36 write a heap dump file for later analysis
Dist-Zilla-Plugin-TestML1Includer INGY 0.0.1 Ship your TestML1 version
Dist-Zilla-PluginBundle-ATOOMIC ATOOMIC 1.00 ATOOMIC's plugin bundle
EPFL-Net-SSLTest WILLBELL 1.00 Website SSL accessibility validator
EPFL-Net-ipv6Test WILLBELL 1.00 Website IPv6 accessibility validator API
Email-Extractor PAVELSR 0.01 Fast email crawler
File-AddInc HKOBA 0.001 FindBin(+ use lib) alike for *.pm modulino (instead of *.pl)
File-Find-CaseCollide SHLOMIF 0.0.1 find collisions in filenames, differing only in case
Finance-Currency-Convert-Mandiri PERLANCAR 0.001 Convert currency using Bank Mandiri
Git-LowLevel BYTERAZOR 0.1 LowLevel Blob/Tree/Commit operations on a GIT Repository
HO-class SKNPP 0.06 class builder for hierarchical objects
HiD-Generator-BibtexPage BYTERAZOR 0.2 HiD Bibtex publication list page generator
JavaScript-V8-XS GONZUS 0.000002 Perl XS binding for the V8 JavaScript engine
Model-Envoy-Storage-Redis HOWARS v0.1.0 A Model::Envoy plugin for peristing model information in a Redis store.
Mojolicious-Plugin-InputValidation FROGGS 0.01 Validate incoming requests
Mojolicious-Plugin-Loco WROG 0.001 launch local GUI via default web browser
Mojolicious-Plugin-Status SRI 0.01 Mojolicious server status
MooX-Enumeration TOBYINK 0.001 shortcuts for working with enum attributes in Moo
Net-EGTS RSHADOW 0.01 Perl Interface to EGTS protocol. GOST R 56360-2015.
Net-IP-Checker PAVELSR 0.01 IPv4/IPv6 addresses validator
Net-Statsd-Client-Telegraf PVIGIER 0.1 Send data to the statsd plugin of telegraf, with support for influxDB's tagging system
Net-Wireless-802_11-Scan-FreeBSD VVELOX v0.0.0 A interface to the wireless interface AP scanning built into ifconfig on FreeBSD
OmniDisco-Prometheus ADUITSIS 0.001 Class representing a Prometheus metric
POE-Filter-ThruPut BINGOS 1.00 a POE filter that passes data through unchanged whilst counting bytes sent and received
Perl-Critic-MergeProfile SKIRMESS 0.001 merge multiple Perl::Critic profiles into one
Perl-LanguageServer GRICHTER 0.01 Language Server for Perl
Plack-Middleware-LogStderr AMALEK 0.001 Everything printed to STDERR sent to psgix.logger or other logger
Prometheus-Tiny ROBN 0.001 A tiny Prometheus client
Prometheus-Tiny-Shared ROBN 0.001 A tiny Prometheus client backed by a shared memory region
QuickTermChart-QuickTermChart SHADKAM 0.01 QuickTermChart/
SemanticWeb-Schema RRWO v0.0.1 Moo classes for classes
Sport-Analytics-NHL ROMM 1.00 Interface to the National Hockey League data
Template-Plugin-URI DBOYS 0.01 A Template Plugin To Use URI Objects
Test-Deep-HashRec RJBS 0.001 test hash entries for required and optional fields
Tex-Hyphen-Pattern IPENBURG 0.100 class for providing a collection of TeX hyphenation
Text-ANSI-Fold UTASHIRO 0.01 Text folding with ANSI sequence and Asian wide characters.
Text-Locus SGRAY 1.00 text file locations
Text-Table-ASV PERLANCAR 0.001 Generate TSV
Time-Random LNATION 0.01 Generate a random time in time.
Transport-AU-PTV PUGLET 0.01 access Melbourne public transport data.
Types-HTML5 TOBYINK 0.001 types for parsing strings of HTML into DOMs
WebService-Hexonet-Connector HEXONET 1.01 Connector library for the insanely fast Hexonet Backend API.
WebService-KvKAPI WATERKIP 0.001 Query the Dutch Chamber of Commerence (KvK) API
WordPress-DBIC-Schema MELMOTHX 1.00 Database schema for WordPress
Yandex-Geo PAVELSR 0.01 Performs queries using Yandex Maps Company Search API
getemails PAVELSR 0.01 Fast email crawler
githook-perltidy MLAWREN v0.11.7_1 run perltidy and podtidy before Git commits
quick_term_chart SHADKAM 180718 a light perl script to quickly draw chart within the terminal input data can be piped to it
ygeo PAVELSR 0.01 command line utility based on Yandex::Geo that prints data to csv

List of new CPAN distributions – Jun 2018

dist author version abstract
AWS-XRay FUJIWARA 0.01 AWS X-Ray tracing library
Acme-CPANModules-Import-CPANRatings-User-perlancar PERLANCAR 0.001 Modules mentioned by CPANRatings user perlancar
Acme-CPANModules-Import-CPANRatings-User-stevenharyanto PERLANCAR 0.001 Modules mentioned by CPANRatings user stevenharyanto
Alt-Devel-CallParser-ButWorking TOBYINK 0.002 Devel::CallParser patched to fix RT#110623
Apache2_4-AuthCookieMultiDBI DETAILS 0.01 An AuthCookie module backed by a DBI database for apache 2.4.
App-ConMenu MMUELLER 1.00 Very simple Menu For Console commands Platform Agnostic
App-Cpanx JACOBG 0.01 A CPAN downloader script
App-CreateAcmeCPANModulesImportCPANRatingsModules PERLANCAR 0.001 Create Acme::CPANModules::Import::CPANRatings::User::* modules
App-ExifUtils PERLANCAR 0.001 Utilities related to EXIF
App-Greple-msdoc UTASHIRO 0.01 Greple module for access MS office documents
App-JC-Client BYTERAZOR 0.001 command line client for JIRA
App-ListPerlReleases PERLANCAR 0.001 List Perl releases
App-MarkFiles BRENNEN v0.0.1 some utility functions for marking and operating on files
App-Prove-Plugin-Elasticsearch TEODESIAN 0.001 Prove Plugin to upload test results to elastic search as they are executed
App-ReportPrereqs SKIRMESS 0.001 Report prerequisite versions
App-Unding BORISD 0.001 dark magic encrypted wallet
App-boxmuller TULAMILI 0.23 Provides the command which produces Gaussian distributed random numbers, as well as log-normal distributed numbers.
App-buffer TULAMILI 0.01 Reads the whole input and then writes into STDOUT. Useful to copy/paste operation.
App-cryp-arbit PERLANCAR 0.001 Cryptocurrency arbitrage utility
App-linenum PERLANCAR 0.001 Add line number to lines
App-np05bctl TTKCIAR 1.03 Command line utility for controlling NP-05B networked power switch
App-optex-msdoc UTASHIRO 0.01 module to replace MS document by its text contents
App-readbuffer TULAMILI 0.02 Reads the whole input and then writes into STDOUT. Useful to copy/paste operation.
App-saikoro TULAMILI 0.22 A random number (matrix) generator of uniform distributions. Saikoro is a Japanese dice.
App-showreverse KLPTWO 0.0.2 given an ip block in cidr notation, show all reverse IP lookups
App_JC BYTERAZOR 0.001 command line client for JIRA
App_JC_Client BYTERAZOR 0.001 command line client for JIRA
App_JIRA_Client BYTERAZOR 0.001 command line client for JIRA
Bencher-Scenarios-MemoryCacheModules PERLANCAR 0.001 Scenarios to benchmark memory cache modules
Bot-BasicBot-Pluggable-Module-DateTimeCalc GENE 0.01 Calculate date-time operations
CLI-Coin-Toss TULAMILI 0.32 Several random number generators by CLI (Command Line Interface) are provided.
CLI-Contingency-Table TULAMILI 0.51 Command line programs for making a contingency tables in 1-way, 2-way.
CLI-KeyValue-Hack TULAMILI 0.07 Provides CLI commands for key-value text data files in TSV.
CLI-LaTeX-Table TULAMILI 0.51 The great new CLI::LaTeX::Table!
CLI-Numbers-Hack TULAMILI 0.21 commands for handling a bunch of numbers for `finding denominator', `N-th min/max', `cumulative sum' and so on.
CLI-Table-Key-Finder TULAMILI 0.31 These CLIs help you to find key column(s) of a table, as fast as possible, hopefully.
CLI-Table-Util TULAMILI 0.05 If you are given table text file, what would you do? This provides CLI commands "colsummary", "colsplit", "colchop" and so on.
CLI-TextLines-Hack TULAMILI 0.06 The great new CLI::TextLines::Hack!
CLI-TextLines-Utils TULAMILI 0.08 The great new CLI::TextLines::Utils!
CPAN-Cpanorg-Auxiliary JKEENAN 0.01 Methods used in infrastructure
CPP-Boost-Mini MRAQ v1.67.0 C++ Boost library (no perl interface).
Catmandu-FileStore HOCHSTEN 1.10 Namespace for packages that can make files persistent
Class-XSConstructor TOBYINK 0.001 a super-fast (but limited) constructor in XS
Code-TidyAll-Plugin-TSLint SHLOMIF 0.001 Use tslint with tidyall
Commandable PEVANS 0.01 utilities for commandline-based programs
Const-Dual BAMBR 0.01 numeric constants that know their names
DBD-MariaDB PALI 0.90_01 MariaDB and MySQL driver for the Perl5 Database Interface (DBI)
DBIx-TextTableAny PERLANCAR 0.001 Generate text table from SQL query result using Text::Table::Any
Dancer2-Plugin-FontSubset YANICK 0.0.1 Generate font subsets on-the-fly
Dancer2-Plugin-Showterm YANICK 0.0.1 Replay terminal typescript captures
Dancer2-Session-DatabasePlugin AKALINUX 1.0001 Dancer2 Session implementation for databases
Dancer2-Template-Mustache YANICK 0.0.1 Wrapper for the Mustache template system
Data-Edit-Conversion PRBRENAN 20180610 Perform a restartable series of steps in parallel
Data-Format ROZCOVO 0.2 Perl module to format data
Data-Format-Validate ROZCOVO 0.1 Perl module to validate data
Data-MuForm-Model-DBIC GSHANK 0.01 MuForm class with DBIC model already applied
Data-Random-NL WATERKIP 1.0 Tools for generating random Dutch numbers
Data-Sah-Coerce-perl-str-str_to_cryptoexchange_currency_pair PERLANCAR 0.001 Coerce string into cryptoexchange currency pair, e.g. LTC/USD
Data-Sah-Coerce-perl-str-str_to_currency_pair PERLANCAR 0.001 Coerce string into currency pair, e.g. USD/IDR
Data-Sah-Coerce-perl-str-str_to_fiat_or_cryptocurrency_code PERLANCAR 0.001 Coerce string containing fiat/cryptocurrency code/name/safename to uppercase code
Data-Sah-CoerceBundle-Num-str_num_en PERLANCAR 0.001 Use Parse::Number::EN to parse number
Data-Sah-CoerceBundle-Num-str_num_id PERLANCAR 0.001 Use Parse::Number::ID to parse number
Data-Validate-DNS-SSHFP MSCHOUT 0.01 Validate DNS SSH Fingerprint (SSHFP) Record Values
Data-Validate-DNS-TLSA MSCHOUT 0.01 Validate DNS Transport Layer Security Association (TLSA) Record Values
DateTime-Format-ISO8601-Format PERLANCAR 0.001 Format DateTime as ISO8601 date/time string
Devel-KYTProf-Logger-XRay FUJIWARA 0.01 Logger for AWS::XRay
Device-GBA ATHREEF 0.001 Perl Interface to the Gameboy Advance
Device-Power-Synaccess-NP05B TTKCIAR 1.02 Manage and monitor the Synaccess NP-05B networked power strip
Dist-Zilla-Plugin-ContributorCovenant KYZN 0.01 Add Contributor Covenant as Code of Conduct
Dist-Zilla-Plugin-XSVersion JEFFOBER 0.01 a thing
Dist-Zilla-PluginBundle-Author-JMASLAK JMASLAK 0.001 JMASLAK's Plugin Bundle
Dist-Zilla-PluginBundle-Author-MINTLAB WATERKIP 0.01 An plugin bundle for all distributions by MINTLAB
Dist-Zilla-Role-CheckPackageDeclared PERLANCAR 0.001 Role to check if a package is provided by your distribution
Dita-Project PRBRENAN 20180530 Dita conversion utilities.
Elasticsearch-Model AMIRI 0.0.1 Does one thing only: helps to deploy a Moose model and accompanying document classes to Elasticsearch.
Electronics-SigGen-FY3200 PEVANS 0 control a FeelTech FY32xx signal generator
Email-SendGrid-V3 GSG 0.90 Class for building a message to be sent through the SendGrid v3 Web API
EventStore-Tiny MEMOWE 0.2 A minimal event sourcing framework.
FFI-TinyCC-Inline PLICEASE 0.27_01 Embed Tiny C code in your Perl program
File-Update SHLOMIF 0.0.1 update/modify/mutate a file only on change in contents.
Finance-AMEX-Transaction THINC 0.001 Parse AMEX transaction files: EPRAW, EPPRC, EPTRN, CBNOT, GRRCN
Finance-Currency-Convert-BCA PERLANCAR 0.152 Convert currency using BCA (Bank Central Asia)
Format ROZCOVO 0.2
HiD-BibtexPage BYTERAZOR 0.001 HiD Bibtex publication list page generator
HiD-Generator-GitRepositories BYTERAZOR 0.1 HiD GitRepository listing generator
Log-ger-UseDataDumper PERLANCAR 0.001 Use Data::Dumper (with nicer defaults) to dump data structures
Log-ger-UseJSON PERLANCAR 0.001 Use JSON::MaybeXS to dump data structures (as JSON)
Module-Extract-DeclaredVersion BDFOY 1.021 Extract the version of Perl a module declares
MojoX-ConfigAppStart GRYPHON 1.01 Start a Mojolicious application with Config::App
Mojolicious-Command-generate-DBIxCustomModel WFSO v1.0.1 generate DBIx::Custom model directory structure
Mojolicious-Plugin-Prometheus-Shared-FastMmap TYLDUM 0.1_01 Mojolicious Plugin
MooX-XSConstructor TOBYINK 0.001 glue between Moo and Class::XSConstructor
Net-Mattermost-Bot MIKEJONES 0.01 A base class for Mattermost bots.
Net-RDAP GBROWN 0.1 an interface to the Registration Data Access Protocol (RDAP).
Net-TL1UDP PCARTER 1.02 Transaction Language 1 (TL-1) UDP Interface
OpenGL-Sandbox NERDVANA 0.01_1 Easy access to a variety of OpenGL prototyping tools
OpenGL-Sandbox-V1 NERDVANA 0.01_1 Portions of OpenGL::Sandbox which depend on OpenGL 1.x API
OpenGL-Sandbox-V1-FTGLFont NERDVANA 0.01_1 Wrapper around FTGL Font library which renders TrueType in OpenGL 1.x
OpenOffice-OODoc-HeadingStyles VANHOESEL 0.01 utilities for manipulating OpenOffice::OODoc objects
OpenOffice-OODoc-InsertDocument VANHOESEL 0.01 insert, merge or append OpenOffice::OODoc objects
PAUSE-Permissions-MetaCPAN SKAJI 0.001 get module permissions from MetaCPAN API
PMVersions-Util PERLANCAR 0.001 Utilities related to pmversions.ini
Parse-Date-Month-ID PERLANCAR 0.001 Parse month name from Indonesian text
Password-Policy-Rule-Pwned HOUSTON 0.00 Compare text to known pwned passwords list
Perinci-Sub-XCompletionBundle-App-cryp PERLANCAR 0.001 Completion routines for the 'cryp' app family
Perl-Critic-Policy-Variables-RequireHungarianNotation MZIESCHA v0.0.1 prohibit hungarian notation
Perl-Critic-TooMuchCode GUGOD 0.01 perlcritic add-ons that generally check for un-needed stuffs.
Plack-Middleware-LogStderr-StderrToLogger AMALEK 0.001 Everything printed to STDERR sent to psgix.logger or other logger
Plack-Middleware-XRay FUJIWARA 0.01 Plack middleware for AWS X-Ray tracing
Python-Version SLOYD 0.0000_01 Python PEP440 compatible version string parser in Perl
Python-Versions SLOYD 0.0000_01 Python PEP440 compatible version string parser in Perl
RPi-GPIOExpander-MCP23017 STEVEB 0.01 Interface to the MCP23017 GPIO Expander Integrated Circuit over I2C
SMS-Send-CZ-Bulkgate RADIUSCZ 1.000 SMS::Send driver for Bulkgate – Czech Republic
Search-Natural ROZCOVO 0.1
Serge-Sync-Plugin-TranslationService-phraseapp DRAGOSV 0.900.0 Serge PhraseApp translation server ( synchronization plugin
Task-FreecellSolver-Testing-MultiConfig SHLOMIF 0.0.1 install the CPAN dependencies of the Freecell Solver multi-config test suite.
Template-Plugin-Filter-IDN MSCHOUT 0.01 Template Toolkit plugin for encoding and decoding International Domain Names.
Test-RequiredMinimumDependencyVersion SKIRMESS 0.001 Require a minimum version for your dependencies
Test-Spelling-Comment SKIRMESS 0.001 TODO
Test2-Tools-HTTP PLICEASE 0.07 Test HTTP / PSGI
Test2-Tools-HTTP-UA-Mojo PLICEASE 0.02 Mojo user agent wrapper for Test2::Tools::HTTP
TestML1 INGY 0.55 A Generic Software Testing Meta Language
Text-Editor-Perl PRBRENAN 20180616 Perl source code head-less editor written in Perl.
Text-NGrammer NIDS 0.01 Pure Perl extraction of n-grams and skip-grams
Text-Shingle NIDS 0.01 Pure Perl implementation of shingles for pieces of text
Text-Table-LTSV PERLANCAR 0.001 Generate LTSV
Text-Table-TSV PERLANCAR 0.001 Generate TSV
Tie-Reduce TOBYINK 0.001 a scalar that reduces its old and new values to a single value
WWW-YNAB DOY 0.01 Wrapper for the YNAB API
WebService-HIBP DDICK 0.01 An interface to the Have I Been Pwned webservice at
device-power-synaccess-np05b TTKCIAR 1.00 Manage and monitor the Synaccess NP-05B networked power strip
voiceIt-voiceIt2 HASSANIS 0

List of new CPAN distributions – May 2018

dist author version abstract
Acme-CPANModules-BloomFilters PERLANCAR 0.001 Bloom filter modules on CPAN
Acme-CPANRatings PERLANCAR 0.001 A dummy module just so we can rate CPAN Ratings (the site itself)
Acme-PERLANCAR-Test-Versioning PERLANCAR 0.001 Test versioning
Acme-UNIVERSAL-can-t TOBYINK 0.001 the opposite of UNIVERSAL::can
Action-CircuitBreaker HANGY 0.1 Module to try to perform an action, with an option to suspend execution after a number of failures.
Alien-TidyHTML5 RRWO v0.1.0 Download and install HTML Tidy
Alien-libdeflate KIWIROY 0.01 Fetch/build/stash the libdeflate headers and libs for libdeflate
Apache2-Camelcadedb MBARBON 0.01 mod_perl2 integration for Devel::Camelcadedb
App-Environ-Que KAKTUS 0.1 Perl library to enqueue tasks in Ruby Que
App-GnuplotUtils PERLANCAR 0.001 Utilities related to plotting data using gnuplot
App-Prove-Plugin-TermTable PLICEASE 0.02 Set the size of the console for Term::Table
App-Sandy TMILLER 0.17 A straightforward and complete next-generation sequencing read simulator
App-fiatx PERLANCAR 0.001 Convert two currencies using current rate
App-ypath BDFOY 0.012 Extract information from YAML
Authen-Passphrase-Argon2 LNATION 0.01 Store and check password using Argon2
Backup-Hanoi BORISD 0.001 select backup according to algo
Bencher-Scenarios-ProgressAny PERLANCAR 0.001 Scenarios to benchmark Progress::Any
Binance-API TASKULA 1.00 Perl implementation for Binance API
Bing-ContentAPI BGERRARD 1.00 Perl interface to the Bing Ads Content API
Business-OnlinePayment-Mock OAXLIN 0.001 A backend for mocking fake results in the Business::OnlinePayment environment
CLI-Files-Utils TULAMILI 0.103 File bunch utilies 'dirhier' and 'madeafter' to supplement the functionality of the "ls" and "find" commands.
CLI-LatexTable TULAMILI 0.116 Copy-paste almost any kind of table such as Excel
CLI-latextable TULAMILI 0.114 The great new CLI::latextable!
CXC-Optics-Prescription-LVS DJERIUS 0.01 a really awesome library
Cache-Method-Cache-FastMmap RRWO v0.1.0 Cache method results using Cache::FastMmap
Catmandu-HTML HOCHSTEN 0.01 Modules for handling HTML data within the Catmandu framework
Class-Method-Cache-FastMmap RRWO v0.1.1 Cache method results using Cache::FastMmap
Code-TidyAll-Plugin-Flake8 SHLOMIF 0.0.1 run flake8 using Code::TidyAll
DBIx-Class-Helper-ResultSet-WindowFunctions RRWO v0.1.0 Add support for window functions to DBIx::Class
DBIx-Class-Relationship-Abbreviate ALBATROSS 0.001 allows you to abbreviate result class names in your relationships
Data-MuFormX-Registry JJNAPIORK 0.001 Manage a hierachry of Data::MuForm classes
Data-Sah-Coerce-perl-str-str_to_cryptocurrency_code PERLANCAR 0.001 Coerce string containing cryptocurrency code/name/safename to code
Data-Sah-Coerce-perl-str-str_to_cryptocurrency_safename PERLANCAR 0.001 Coerce string containing cryptocurrency code/name/safename to safename
Data-Sah-Coerce-perl-str-str_to_cryptoexchange_safename PERLANCAR 0.001 Coerce string containing cryptoexchange code/name/safename to safename
Data-Sah-CoerceBundle-App-cryp PERLANCAR 0.001 Coercion rules for the 'cryp' app family
Date-Indiction RPAVLOV 0.01 Compute a year's indiction as used in old Russian chronicles
Date-Vruceleto RPAVLOV 0.01 Compute year's vruceleto and solar cycle as used in old Russian calendar
Digest-HighwayHash MGV 0.000_001 fast strong hash function
Docker-Registry JLMARTIN 0.02 A client for talking to Docker Registries
Dot RSLOVERS v1.0.0 The beginning of a Perl universe
Email-Stuffer-TestLinks BINARY 0.01 validates links in HTML emails sent by Email::Stuffer>send_or_die()
Eval-Reversible GSG 0.90 Evals with undo stacks
File-ByLine JMASLAK 1.000 Line-by-line file access loops
Finance-Currency-FiatX PERLANCAR 0.001 Convert fiat currency using current rate
Float-Truncate MCCHEUNG 0.01 Ttruncate Float decimal length by special length
Games-Axmud ASLEWIS v1.1.0 Axmud, a modern Multi-User Dungeon (MUD) client written in Perl5 / GTK2
HTML5-DOM ZHUMARIN 1.00 Super fast html5 DOM library with css selectors (based on Modest/MyHTML)
IO-K8s JLMARTIN 0.01 Objects representing things found in the Kubernetes API
ISO-639_1 LDIDRY 0.01 ISO 639-1 Language informations
Image-Find-Loops PRBRENAN 20180502 Find loops in an image.
JTM-Boilerplate JMASLAK 1.020 Default Boilerplate for Joelle Maslak's Code
JavaScript-V8-CommonJS CAFEGRATZ 0.01 Modules/1.0 for JavaScript::V8
Koha-Contrib-ARK FREDERICD 1.0.0 ARK Management
Kubectl-CLIWrapper JLMARTIN 0.01 Module to use the Kubernetes API via the kubectl CLI
Lingua-RU-Declension MALLEN 0.001 Decline Russian pronouns, adjectives and nouns
Log-Log4perl-Layout-ColoredPatternLayout TOMGRACEY 0.01 multicolor log messages
Log-Log4perl-Shortcuts STEVIED 0.006 shortcut functions to make log4perl even easier
Log-ger-Level-Like-Syslog PERLANCAR 0.001 Define logging levels like those described in RFC 3164 (syslog protocol)
Math-Business-BlackscholesMerton BINARY 1.23 Algorithm of Math::Business::BlackScholesMerton for binary and non-binary options
Model-Envoy HOWARS 0.1 A Moose Role that can be used to build a model layer that keeps business logic separate from your storage layer.
Mojo-SAML JBERGER 0.01 A SAML2 toolkit using the Mojo toolkit
Mojolicious-Plugin-Cron DMANTO 0.014 a Cron-like helper for Mojolicious and Mojolicious::Lite projects
Mojolicious-Plugin-GistGithubProxy RENEEB 0.01 Mojolicious::Plugin::GistGithubProxy – a small proxy that can be useful when you embed gists in your website
Mojolicious-Plugin-GoogleFontProxy RENEEB 0.01 a small proxy that can be useful when you embed gists in your website
Mojolicious-Plugin-NoIndex RENEEB 0.01 add meta tag to HTML output to define a policy for robots
Mojolicious-Plugin-NoReferrer RENEEB 0.01 add meta tag to HTML output to define a referrer policy
Mojolicious-Plugin-PromiseActions MRAMBERG 0.01 Automatic async and error handling for Promises
Mojolicious-Plugin-SecurityHeader RENEEB 0.01 Mojolicious Plugin
MooX-AttributeFilter VRURG 0.001000 Implements 'filter' option for Moo-class attributes
MooseX-AttributeFilter KITTEN 0.01 MooX::AttributeFilter with cute antlers OwO
MooseX-Storage-MaybeDeferred UFOBAT v0.0.1 A role for the less indecesive programmers
MouseX-Types-Enum IKENOX 1.00 Object-oriented, Java-like enum type declaration based on Mouse
PMLTQ-Command-printtrees MATY 0.0.1 generate svg trees for given treebank
Parse-SSA DISI 1.0 SSA/ASS Parser
Path-Class-Tiny BAREFOOT 0.01 a Path::Tiny wrapper for Path::Class compatibility
Perinci-CmdLine-sero PERLANCAR 0.001 Perinci::CmdLine::Lite subclass for App::sero
Plack-Middleware-Auth-FCGI GUIMARD 0.01 authentication middleware that query remote FastCGI server
Plack-Middleware-Camelcadedb MBARBON 0.02 interactive debugging for Plack applications
Qgoda GUIDO v0.9.2 The Qgoda Static Site Generator
RPi-RTC-DS3231 STEVEB 0.01 Interface to the DS3231 Real-Time Clock IC over I2C
Sah-Schemas-App-cryp PERLANCAR 0.001 Various Sah schemas for the 'cryp' app family
Serge-Sync-Plugin-TranslationService-mojito DRAGOSV 0.9 Serge Mojito translation server ( synchronization plugin
Serge-Sync-Plugin-TranslationService-zanata DRAGOSV 0.9 Serge Zanata translation server ( synchronization plugin
Software-LicenseMoreUtils DDUMONT 0.001 More utilities and a summary for Software::License
Stor JASEI 0.10.2 Save/retrieve a file to/from primary storage
TaskPipe TOMGRACEY 0.01 A task management framework for building web scrapers and crawlers
Template-Plugin-Path-Tiny RRWO v0.1.0 use Path::Tiny objects from within templates
Test-Conditions MMCCLENN 0.8 test multiple conditions across a large data structure or list in a simple and compact way
Test-Spec-Acceptance MEIS 0.01 Aliases for acceptance-like testing using Test::Spec
Test2-Tools-JSON-Pointer PLICEASE 0.01 Compare parts of JSON string to data structure using JSON pointers VERSION
Test2-Tools-SkipUntil DFARRELL 0.01 skip tests until a date is reached
Text-PerlPP CXW v0.3.1 Perl preprocessor: process Perl code within any text file
Types-Bool FERREIRA 0.1.0 Booleans as objects for Perl
Unix-OpenBSD-Random JMATES 0.01 interface to arc4random(3) on OpenBSD
WebService-AcousticBrainz GENE 0.01 Access to the AcousticBrainz API
WebService-Pokemon KIANMENG 0.03 A module to access the Pokémon data through RESTful API from
WebService-RESTCountries KIANMENG 0.01 A Perl module to interface with the REST Countries ( webservice.
WebService-Swapi KIANMENG 0.1.6 A Perl module to interface with the Star Wars API ( webservice.
Webservice-Pokemon KIANMENG 0.001 A module to access the Pokémon data through RESTful API from
binance-perl-api TASKULA 1.00 Perl implementation for Binance API
cppAdaptive MFJONKER 0.01 cppAdaptive2 XS
cppAdaptive2 MFJONKER 0.01 cppAdaptive2 XS
ssa DISI 0


This post is a "thinking out loud" post, about an unimplemented feature I'm planning.

The problem

The most often complaint I get when I release a Perinci::CmdLine -based Perl application is the huge dependencies of Perinci::CmdLine (currently Perinci::CmdLine::Lite only has 24 direct non-core dependencies, but recursively it has 98 non-core dependencies in 92 unique distributions). By the way, you can produce these numbers "very easily" using lcpan and td:

% lcpan mods -lx Perinci::CmdLine::Lite
| module                 | version | abstract                                              | dist                 | author    | rel_mtime            | is_core |
| Perinci::CmdLine::Lite | 1.812   | A Rinci/Riap-based command-line application framework | Perinci-CmdLine-Lite | PERLANCAR | 2018-05-01T08:42:19Z | 0       |
% lcpan deps Perinci::CmdLine::Lite --noinclude-core | wc -l
% lcpan deps Perinci::CmdLine::Lite --noinclude-core -R | wc -l
% lcpan deps Perinci::CmdLine::Lite --noinclude-core -R --flatten | \
    td select module | lcpan mod2dist | td select value | sort | uniq | wc -l

Sort of ironic because years ago I used to mock Moose 's high number of dependencies and avoid it like the plague, and then ending up creating the same situation with my own distribution. Correction: a much worse situation than the current Moose:

% lcpan mods -lx Moose
| module | version | abstract                              | dist  | author | rel_mtime            | is_core |
| Moose  | 2.2010  | A postmodern object system for Perl 5 | Moose | ETHER  | 2018-02-16T22:01:37Z | 0       |
% lcpan deps Moose --noinclude-core | wc -l
% lcpan deps Moose --noinclude-core -R | wc -l
% lcpan deps Moose --noinclude-core -R --flatten | \
    td select module | lcpan mod2dist | td select value | sort | uniq | wc -l

I arrange the modules into many distributions because I am trying to keep things modular. So when I only need a specific subset of functionality, I don't have to pull the whole thing (and along with it its large list of dependencies). Maybe I went overboard? Maybe. Nevertheless.

The high number of dependencies presents an inconvenience and annoyance when users want to install my application, especially since CPAN clients like cpan and cpanm default to testing distributions before installing them.

One solution: Perinci::CmdLine::Inline

One solution I created for this problem is Perinci::CmdLine::Inline (PC:Inline) which basically "pre-assembles" the application with sort of a "mini", "embedded" Perinci::CmdLine during distribution build time, so that when a user installs the application she doesn't need to get Perinci::CmdLine anymore. This also has another benefit of faster application startup time due to the "pre-assembling" thingy. But this pre-assembling has some downsides too. Whenever I create a new version of PC:Inline, I will have to rebuild all the applications again. PC:Inline also does not (read: will not, because of the lack of Riap layer) have all the features of a proper Perinci::CmdLine. I use PC:Inline only for simpler applications that need to be very light (has no non-core dependencies, or starts fast) like hr, wordlist, zodiac-of.

Another solution: fatpacking, datapacking

Another solution is fatpacking or datapacking. I've tried this in the past with the pause script, and it works rather well. Except that when it comes to packaging the CPAN distribution as a Debian package, the Debian policy forbids "convenience copies" of code.

Past solution: lumping

Yet another solution which I've tried in the past is what I call "lumping": in a lump distribution I include modules from other distributions (the dependencies) but leave them unindexed. For example, I created a distribution called Perinci-CmdLine-Any-Lumped that contains modules from Perinci-CmdLine-Any (Perinci::CmdLine::Any) as well as all its recursive pure-perl non-core dependencies, like Data::Sah, Data::Sah::Coerce, and so on. After installing just one lump distribution, a user will have perhaps 100+ extra (but "hidden") modules from various distributions on her system. The perl interpreter will see those extra modules fine. The modules are "hidden" only in the sense that the original distributions of those modules are not listed as installed (because they aren't).

I abandoned this solution because it feels really dirty. The extra modules lumped into the lump distribution are actually "orphan" modules because the lump distribution does not publicly confess that it includes the modules. And I'm pretty sure lump distributions are not good candidates for Debian perl packages, but it's okay.

Another proposed solution: clumping

This post will describe another solution which I'm thinking of (with an equally stupid name so if the idea ended up being really stupid, the name would have already fitted): clumping.

A clump distribution is named "Clump-SOMETHING" and will contain modules from several other distributions (called "source distributions"). The purpose of a clump distribution is to package several other distributions as a single distribution for the purpose of reducing the number of dependencies for the end-user.

For example, a clump distribution called "Clump-Data-Sah" will contain modules from Data-Sah as well as Data-Sah-Coerce, Data-Sah-Format, and so on.


To help build this distribution, a Dist::Zilla plugin will be created and used: DZP:Clump. To use this plugin, we list the source distributions that we want to include:


The plugin will gather module files from the source distributions as well as merge the dependencies from the source distributions into the dependencies for the clump distribution.

Dependencies that end up being in the clump distribution can be "netted out". For example, Data-Sah depends on Data::Sah::Coerce which is in the Data-Sah-Coerce distribution which is also another source distribution in the clump, so this dependency now does not need to be specified in Clump-Data-Sah.

Clumping and module versions

The version number of a module inside the clump distribution will be the original version joined by ".0". So for example, if the original version number of module M1 is "0.001" then M1's version number in the clump distribution is "0.001.0". If M2's original version is "0.1.2" then M2's version in the clump is "" and so on. As far as perl concerns the two version numbers in each case are the same:

version->parse("0.001") == version->parse("0.001.0")
version->parse("0.1.2") == version->parse("")

The module version will have to be checked to satisfy the above relationship and if it does not, a new release will need to be made in the source distribution first to remedy this. For example, M3's original version is 0.02. If we append ".0" to it to become "0.02.0" then the new version will be less than the original version:

version->parse("0.02") > version->parse("0.02.0")
# because 0.02   is 0.020
# and     0.02.0 is 0.002.0

To include M3 in the clump, we will need to make a new release of M3 in the original source distribution first, say of version 0.030. Then M3 version 0.030 can now be included in the clump, as version 0.030.0.

Yes, this means the clump distribution will contain different version numbers. Which is usually not recommended for a "normal" Perl distribution but is appropriate here.

Clumping and the PAUSE indexer

When the clump distribution is released, PAUSE will index the clump distribution and now modules included in the clump will be indexed as belonging to the clump distribution instead of their original distribution.

When user installs one of these modules, she will be getting it (and automatically a lot of other modules too) from the clump distribution, thus reducing the number of distributions she needs to install to satisfy all the dependencies of an application.

Developing modules that are included in clumps

Ideally, modules are still developed in its original source distribution, e.g. Data::Sah::Coerce in Data-Sah-Coerce. When I want to release a new version of Data::Sah::Coerce, I can just release a new version of Data-Sah-Coerce. Now the module will be indexed by PAUSE as belonging to the new Data-Sah-Coerce.

As more and more modules are being "unclumped" as new releases of the source distributions come along, the level of inconvenience to end-users will once again increase. To remedy this, from time to time I can release a new clump distribution again that contains newer "snapshots" of modules.

This is the reason why version of modules in the clump is being kept the same (albeit with extra ".0"): so version bump in the original source distribution will be able to "eclipse" the clumped version on CPAN later. Even when the original distribution bumps using an extra subversion, e.g. 0.001 to 0.001.1 it will still eclipse the clumped version. The next clumped version will be

Clumping vs lumping

This clump solution is cleaner than the lumping solution because in the former case, no modules are "hidden". Basically clumping is lumping, but the included modules are "acknowledged" and properly indexed. The $orig_version . ".0" thing is really the only novel element here. Because the modules are now not hidden, their dependencies must now also be handled.

As to Debian packaging, the source distributions and not the clump distribution are the ones that will be packaged so there should not be an issue with "convenience copies" or "bundling".

Generating random passwords according to patterns with genpw

There are several modules on CPAN for generating random passwords, but last time I checked, none of them are flexible enough. Different websites or applications have different requirements (sometimes ridiculous ones) for passwords. True, most modules allow setting minimum/maximum length, and some of them allow customizing the number of special characters, or number of digits, but what I want is some sort of template/pattern that the generator would follow. So I created genpw.

Basic functionality

genpw is your usual random password generator CLI. When run without any arguments, it returns a single random password (8-20 characters long, comprising letters/digits):

% genpw

To return several passwords:

% genpw 5

To set exact length or minimum/maximum of length:

% genpw -l 4
% genpw --min-len 12 --max-len 14


In addition to the above basic customization, genpw allows you to specify a pattern (or several patterns to pick randomly, for that matter). A pattern is a string that is similar to a printf pattern where conversion sequences like %d will be replaced with actual random characters. Here are the available conversions:

%l   Random Latin letter (A-Z, a-z)
%d   Random digit (0-9)
%h   Random hexdigit (0-9a-f)
%a   Random letter/digit (Alphanum) (A-Z, a-z, 0-9; combination of %l and %d)
%s   Random ASCII symbol, e.g. "-" (dash), "_" (underscore), etc.
%x   Random letter/digit/ASCII symbol (combination of %a and %s)
%m   Base64 character (A-Z, a-z, 0-9, +, /)
%b   Base58 character (A-Z, a-z, 0-9 minus IOl0)
%B   Base56 character (A-Z, a-z, 0-9 minus IOol01)
%%   A literal percent sign
%w   Random word

You can specify %NC (where N is a positive integer, and C is the conversion) to mean a sequence of random characters (or a random word) with the exact length of N. Or %N$MC (where N and M are positive integers) to mean random characters (or word) with length between N and M.

Unsupported conversion will be unchanged, like in printf.

Some examples:

Generate random digits between 10 and 12 characters long:

% genpw -p '%10$12d'

Generate a random UUID:

% genpw -p '%8h-%4h-%4h-%4h-%12h'

Like the above, but in uppercase:

% genpw -p '%8h-%4h-%4h-%4h-%12h' -U


The %w conversion in pattern mean to replace with a random word. Words are fetched from STDIN (and will be shuffled before use). For example, the command below will generate password in the form of a random word + 4 random digits:

% genpw -p '%w%4d' < /usr/share/dict/words

Instead of from STDIN, you can also fetch words from the various WordList::* modules available on CPAN (and installed locally). A separate CLI provides this functionality: genpw-wordlist, which is basically just a wrapper to extract the words from the wordlist module(s) then feed it to App::genpw. By default, if you don't specify -w option(s) to select wordlist modules, the CLI will use WordList::EN::Enable:

% genpw-wordlist -p '%w%4d'

Generate 5 passwords comprising 8-character word followed by between four to six random digits:

% genpw-wordlist 5 -p '%8w-%4$6d'

Configuration file

To avoid you from having to type patterns again and again, you can use a configuration file. For example, put this in $HOME/genpw.conf:

patterns = %8h-%4h-%4h-%4h-%12h
case = upper

then you can just say:

% genpw -P uuid


The speed is not great, around 2000 passwords/sec on my laptop, though I believe this should not matter for most use-cases.


genpw is a flexible random password generator where you can specify patterns or templates for the password. I'm still working on a few things, like how to enable secure random source in the most painless way. There are also various CLI variants to generate specific kinds of passwords as straightforward as possible: genpw-base56, genpw-base64, genpw-id, and the aforementioned genpw-wordlist.