cpf-val for Ruby

Gem Version Gem Downloads Ruby Version Test Status Last Update Date Project License

🌎 Acessar documentaΓ§Γ£o em portuguΓͺs

A Ruby utility to validate CPF (Brazilian Individual's Taxpayer ID) values.

Ruby Support

Ruby 3.2 Ruby 3.3 Ruby 3.4
Passing βœ” Passing βœ” Passing βœ”

Features

  • βœ… Fixed 11-digit CPF: Validates the standard 11-digit Brazilian CPF via the official modulo-11 algorithm
  • βœ… Flexible input: Accepts String or Array of strings; array elements are concatenated in order
  • βœ… Format agnostic: Strips every non-digit character before validation
  • βœ… Repeated-digit rejection: All-identical-digit bases (e.g. 111.111.111-11, 00000000000) are rejected
  • βœ… Error handling: Typed API-misuse errors with a CpfVal::Error marker for library-wide rescue
  • βœ… Minimal dependencies: cpf-dv for check-digit calculation and lacus-utils for type descriptions in error messages
  • βœ… Dual API style: Object-oriented (CpfVal::CpfValidator) and functional (CpfVal.cpf_val)

Installation

Install the gem directly:

gem install cpf-val

Or add it to your Gemfile and run bundle install:

gem 'cpf-val'

Require

require 'cpf-val'

Quick Start

require 'cpf-val'

validator = CpfVal::CpfValidator.new

validator.is_valid('12345678909')       # => true
validator.is_valid('123.456.789-09')    # => true
validator.is_valid('12345678910')       # => false (invalid check digits)
validator.is_valid('00000000000')       # => false (repeated digits)

Functional helper:

require 'cpf-val'

CpfVal.cpf_val('12345678909')      # => true
CpfVal.cpf_val('123.456.789-09')   # => true
CpfVal.cpf_val('12345678910')      # => false

Usage

The main entry points are the class CpfVal::CpfValidator and the helper CpfVal.cpf_val.

CpfVal::CpfValidator

  • initialize: Takes no arguments. CPF validation has no configuration options.

  • is_valid(cpf_input): Validates a CPF value.

    Input is normalized to a string (arrays of strings are concatenated). Every non-digit character is then stripped. If the sanitized length is not exactly 11, its base is an all-identical-digit sequence, or the check digits do not match (CpfDV::CpfCheckDigits from cpf-dv), the method returns false β€” no exception is raised for validation failure.

    If the input is not a String or an Array of strings, CpfVal::TypeMismatchError is raised.

require 'cpf-val'

validator = CpfVal::CpfValidator.new

validator.is_valid('123.456.789-09')             # => true
validator.is_valid('12345678909')                # => true
validator.is_valid(['123', '456', '789', '09'])  # => true
validator.is_valid('12345678910')                # => false (invalid check digits)
validator.is_valid('11111111111')                # => false (repeated digits)

Functional helper

CpfVal.cpf_val builds a new CpfVal::CpfValidator and calls is_valid(cpf_input) once. It takes only the input value:

require 'cpf-val'

CpfVal.cpf_val('11144477735')      # => true
CpfVal.cpf_val('111.444.777-35')   # => true
CpfVal.cpf_val('11144477736')      # => false

Input formats

String: Plain digits or a formatted CPF (e.g. 123.456.789-09, 499.784.420-90, 011_258_960_00). Non-digit characters are stripped before validation; the result must be exactly 11 digits.

Array of strings: Each element must be a String; values are concatenated (e.g. per digit, grouped segments, or mixed with punctuation). Non-string elements raise CpfVal::TypeMismatchError.

require 'cpf-val'

CpfVal.cpf_val(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '9'])  # => true
CpfVal.cpf_val(['123.456', '789-09'])  # => true

Error handling

This package raises only for API misuse (wrong input type). Validation failures (wrong length, ineligible base such as repeated digits, invalid check digits) return false and do not raise.

Every custom error includes the CpfVal::Error marker module. This package defines no CpfVal::DomainError and no domain leaves β€” invalid CPF data never raises a domain error.

Summary

Class Inherits from Category Trigger condition
CpfVal::TypeMismatchError CpfVal::TypeMismatchError < TypeError < StandardError (+ include CpfVal::Error) API misuse CPF input is not a String or Array of strings

CpfVal::Error (marker module)

  • Inheritance: module marker mixed into every library error via include (not a class).
  • Category: N/A (rescue target only) β€” not a failure mode by itself.
  • When it is raised: Never raised directly; included by every custom error the library raises.
  • Example: N/A
  • How to rescue it:
rescue CpfVal::Error
  # everything this library raises

CpfVal::TypeMismatchError

  • Inheritance: CpfVal::TypeMismatchError < TypeError < StandardError (includes CpfVal::Error)
  • Category: API misuse β€” the caller passed a value of the wrong type.
  • When it is raised: Raised when the CPF input is not a String or an Array of strings (including when an array contains a non-string element).
  • Example:
require 'cpf-val'

begin
  CpfVal.cpf_val(12_345_678_909)
rescue CpfVal::TypeMismatchError => e
  puts e.message
  # CPF input must be of type string or string[]. Got integer number.
end
  • How to rescue it:
rescue CpfVal::TypeMismatchError
  # this library's type-contract violation

rescue TypeError
  # native type errors, including this library's TypeMismatchError

Rescue granularity

Each level is shown as its own standalone example (do not merge them into one rescue ladder β€” a broad TypeError handler would make narrower clauses unreachable).

require 'cpf-val'

# 1) Single native class β€” catches misuse errors of that kind,
#    including non-library ones already handled elsewhere in the consumer's code.
begin
  CpfVal.cpf_val(123)
rescue TypeError
  # CpfVal::TypeMismatchError and any other TypeError (library or not)
end
require 'cpf-val'

# 2) CpfVal::DomainError β€” not applicable: this package defines no DomainError
#    (and no domain leaves). Invalid CPF data returns false instead of raising.
# begin
#   CpfVal.cpf_val(123)
# rescue CpfVal::DomainError  # NameError β€” constant is not defined
# end
require 'cpf-val'

# 3) CpfVal::Error β€” catches everything the library raises, regardless of native ancestry.
begin
  CpfVal.cpf_val(123)
rescue CpfVal::Error
  # every custom error that includes CpfVal::Error
end
require 'cpf-val'

# 4) Specific leaf class β€” catches only that exact failure mode.
begin
  CpfVal.cpf_val(123)
rescue CpfVal::TypeMismatchError
  # only CpfVal::TypeMismatchError
end

Notable attributes on raised errors:

  • TypeMismatchError: actual_input, actual_type, expected_type

API

Exports

After require 'cpf-val':

  • CpfVal.cpf_val: (cpf_input) -> Boolean β€” convenience helper.
  • CpfVal::CpfValidator: Class to validate CPF (no options); accepts String or Array<String> in is_valid.
  • CpfVal::CPF_LENGTH: 11 (constant).
  • CpfVal::VERSION: gem version string.
  • Type predicate: CpfVal::CpfInput β€” CpfVal::CpfInput.accept?(value) / CpfVal::CpfInput === value is true only for String or Array<String>.
  • Errors: CpfVal::Error, CpfVal::TypeMismatchError.

Contribution & Support

We welcome contributions! Please see our Contributing Guidelines for details. If you find this project helpful, please consider:

License

This project is licensed under the MIT License β€” see the LICENSE file for details.

Changelog

See CHANGELOG for a list of changes and version history.


Made with ❀️ by Lacus Solutions