The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


MooX::Types::CLike - C-like data types for Moo


   package MyPackage;
   use Moo;
   use MooX::Types::CLike qw(:all);

   has 'foo' => (
      isa => Int     # or Int32, Signed32
   has 'bar' => (
      isa => Short   # or SmallInt, Int16, Signed16

   use Scalar::Util qw(blessed);
   use Math::BigFloat;
   use Sub::Quote;

   has 'baz' => (
      isa => Double  # or Float64, Binary64

      # A Double number gets pretty big, so make sure we use big numbers
      coerce => quote_sub q{
            unless (blessed $_[0] =~ /^Math::BigFloat|^bignum/);


Given the popularity of various byte-sized data types in C-based languages, databases, and computers in general, there's a need for validating those data types in Perl & Moo(se). This module covers the gamut of the various number and character types in all of those forms.

The number types will validate that the number falls within the right bit length, that unsigned numbers do not go below zero, and "Perl unsafe" numbers are using either Math::Big* or bignum/bigfloat. (Whether a number is "Perl safe" depends on your Perl's|ivsize, or data from Data::Float.) Big numbers are also checked to make sure they have an accuracy that supports the right number of significant decimal digits. (However, BigInt/Float defaults to 40 digits, which is above the 34 digits for 128-bit numbers, so you should be safe.)

Char types will validate that it's a single character, using Perl's Unicode-complaint length function. The bit check types (all of them other than WChar) will also check that the ASCII/Unicode code (ord) is the right bit length.

IEEE 754 decimal floating types are also available, which are floats that use a base-10 mantissa. And the SQL Server "money" types, which are basically decimal numbers stored as integers.


MooX::Types::CLike - C-like types for Moo


All available types (including lots of aliases) are listed below:

   ### Integers ###
             [SIGNED]                                   | [UNSIGNED]
     4-bit = SNibble SSemiOctet Int4 Signed4            | Nibble SemiOctet UInt4 Unsigned4
     8-bit = SByte SOctet TinyInt Int8 Signed8          | Byte Octet UnsignedTinyInt UInt8 Unsigned8
    16-bit = Short SmallInt Int16 Signed16              | UShort UnsignedSmallInt UInt16 Unsigned16
    24-bit = MediumInt Int24 Signed24                   | UnsignedMediumInt UInt24 Unsigned24
    32-bit = Int Int32 Signed32                         | UInt UnsignedInt UInt32 Unsigned32
    64-bit = Long LongLong BigInt Int64 Signed64        | ULong ULongLong UnsignedBigInt UInt64 Unsigned64
   128-bit = SOctaWord SDoubleQuadWord Int128 Signed128 | OctaWord DoubleQuadWord UInt128 Unsigned128

   ### Floats (binary) ###
   (Total, Exponent) bits; Significand precision = Total - Exponent - 1 (sign bit)

   ( 16,  4) bits = ShortFloat
   ( 16,  5) bits = Half Float16 Binary16
   ( 32,  8) bits = Single Real Float Float32 Binary32
   ( 40,  8) bits = ExtendedSingle Float40
   ( 64, 11) bits = Double Float64 Binary64
   ( 80, 15) bits = ExtendedDouble Float80
   (104,  8) bits = Decimal    # not a IEEE 754 decimal, but C#'s bizarre "128-bit" float
   (128, 15) bits = Quadruple Quad Float128 Binary128

   ### Floats (decimal) ###
   (Digits, Exponent Max)

   ( 32,  8) = Decimal32
   ( 64, 11) = Decimal64
   (128, 15) = Decimal128

   ### "Money" ###
   (Bits, Scale)

   ( 32,  4) = SmallMoney
   ( 64,  4) = Money Currency
   (128,  6) = BigMoney  # doesn't exist; might change if it does suddenly exists

   ### Chars ###
   WChar = Single character (with Perl's natural Unicode-compliance)
   Bit check types = Char/Char8, Char16, Char32, Char48, Char64


Since there are so many different aliases in this module, using :all (while available) probably isn't a good idea. So, there are some Exporter tags available, grouped by language:

   # NOTE: Some extra types are included to fill in the gaps for signed vs. unsigned and
   # byte vs. char.

   :c       = Char Byte Short UShort Int UInt Long ULong Float Double ExtendedDouble
   :stdint  = Int4 UInt4 ... Int128 UInt128 (except 24-bit)
   :c#      = SByte Byte Char16 Short UShort Int UInt Long ULong Float Double Decimal
   :ieee754 = Binary16,32,64,128 and Decimal32,64,128
   :tsql    = TinyInt SmallInt Int BigInt SmallMoney Money Float64 Real
   :mysql   = TinyInt SmallInt MediumInt Int BigInt (and Unsigned versions) Float Double
   :ansisql = SmallInt Int Float Real Double

   :is_*    = All of the is_* functions for that tag
   :*+is    = Both the Moo and is_* functions for that tag


The Int type is also used by MooX::Types::MooseLike::Base, and is even used (but not exported) as a subtype for the Integer classes. So be careful not to import both of them at the same time, as they have different meanings.

Most C-based languages use a char type to indicate both an 8-bit number and a single character, as all strings in those languages are represented as a series of character codes. Perl, as a dynamic language, has a single scalar to represent both strings and numbers. Thus, to separate the validation of the two, the term Byte or Octet means the numeric 8-bit types, and the term Char means the single character string types.

The term long in C/C++ is ambiguous depending on the bits of the OS: 32-bits for 32-bit OSs and 64-bits for 64-bit OSs. Since the 64-bit version makes more sense (ie: short < int < long), that is the designation chosen. To avoid confusion, you can just use LongLong and ULongLong.

The confusion is even worse for float types, with the long modifier sometimes meaning absolutely nothing in certain hardware platforms. Long isn't even used in this module for those types, in favor of IEEE 754's "Extended" keyword.

The floats will support infinity and NaN, since C floats support this. This may not be desirable, so you might want to subtype the float and test for Inf/NaN if you don't want these. Furthermore, the "Perl safe" scalar tests for floats include checks to make sure it supports Inf/NaN. However, the odds of it NOT supporting those (since Perl should be using IEEE 754 floats for NV) are practically zero.

Hopefully, I've covered all possible types of floats found in the wild. If not, let me know and I'll add it in. (For that matter, let me know if I'm missing any type found in the wild.)


The project homepage is

The latest version of this module is available from the Comprehensive Perl Archive Network (CPAN). Visit to find a CPAN site near you, or see


Internet Relay Chat

You can get live help by using IRC ( Internet Relay Chat ). If you don't know what IRC is, please read this excellent guide: Please be courteous and patient when talking to us, as we might be busy or sleeping! You can join those networks/channels and get help:


    You can connect to the server at '' and join this channel: #distzilla then talk to this person for help: SineSwiper.

Bugs / Feature Requests

Please report any bugs or feature requests via


Brendan Byrd <>


This software is Copyright (c) 2013 by Brendan Byrd.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)