Skip to content
This gem provides an api to run sequential checks
Branch: master
Clone or download
Latest commit 3262164 Jul 13, 2017
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitignore Added Verifier::DependentCallbacks Jul 13, 2017
.rubocop.yml switched to rubocop-config-umbrellio (#14) Jul 11, 2017
.travis.yml Ready to work Apr 3, 2017
LICENSE add coveralls badge (#13) Jul 11, 2017

Verifly v0.2

Build StatusCoverage Status

This gem provides an api to run sequential checks like 'ActiveModel::Validations' do, but with generic messages instead of errors.

It also provides additional components to build it which could be used to imporve code readability. See Applicator, ApplicatorWithOptions and ClassBuilder along with Verifier


$ gem install verifly

and then in code

require 'verifly'



Abstract =
  extend Verifly::ClassBuilder::Mixin

  class WithString < self
    def self.build_class(x)
      self if x.is_a?(String)

  Generic =

  self.buildable_classes = [WithString, Generic]
  # or, vice versa
  def self.buildable_classes
    [WithString, Generic]
end"foo") # =>"foo") # =>"foo")

or see it at

Why don't just use Uber::Builder? (Uber is cool, you should try it) There are two reasons: firstly, it is an unnecessary dependency. We dont want npm hell, do we? Uber::Builder realy does not do much work, it's just a pattern. Secondly, this implementation looks more clear to me, because children are deciding whether they will handle arguments, not parents.

So to use it, you have to:

  1. Write some classes with duck type .class_builder(*args)

  2. Invoke[<%= array_of_classes %>]).call(*args)

  3. ????


It's simple and clear, but not very sugary. So, otherwise, you may do following:

  1. Write an abstract class

  2. Extend Verifly::ClassBuilder::Mixin

  3. Inherit from the abstract class in different implementations

  4. If some implementations have common ancestors (not including the abstract class), you can implement common ancestor's .build_class in terms of super (i.e. def self.build_class(x); super if x.is_a?(String); end)

  5. Change .build_class of other classes like self if .... Don't change default implementation's .build_class

  6. Setup .buildable_classes on the abstract class, mentioning only direct children if you done step 4

  7. Optionally redefine .build in abstract class, if you want to separate build_class and constructor params

  8. Use .build instead of new


Applicator is designed to wrap applications of applicable objects around some binding in some context


object = :bar), object, {}) # => :bar'foo', object, {}) # => :bar'context', object, {}) # => {}> { foo }, object, {}) # => :bar>(context) { context[foo] }, object, bar: :baz) # => :baz, object, {}) # => true

foo = :bar, binding, {}) # => :bar'', binding, {}) # => :bar

Applicator is good, but in most cases ApplicatorWithOptions would be a better option.


ApplicatorWithOptions is an applicator with options. The options are if: and unless: . Same as in ActiveModel::Validations, they are applied to the same binding. Main action is executed only if if: evaluates to truthy and unless: evaluates to falsey.

See examples:, if: -> { true }).call(binding, {}) # => foo, if: -> (context) { context[:bar] })
  .call(binding, { bar: true }) # => foo, if: { bar: true }).call(binding, :bar) # => foo, unless: -> { true })
  .call(binding, {}) # => nil, unless: -> (context) { context[:bar] })
  .call(binding, { bar: true }) # => foo, unless: { bar: true })
  .call(binding, :bar) # => nil


The last, but the most interesting component is Verifier. Verifiers use ApplciatorWithOptions to execute generic procedures. Procedures should call message! if they want to yield something. Note that you should implement message! by yourself (in terms of super)

class MyVerifier < Verifly::Verifier
  Message =
  verify :foo, if: { foo: true }


  def message!(text)
    super { }

  def foo
    message!('Something is wrong') if Fixnum != Bignum

In addition to Applicator's power, you also can nest your verifiers to split the logic

class MyVerifier < Verifly::Verifier
  Message =
  verify_with ChildVerifier, if: -> (context) { cotnext[:foo] }


  def message!(text)
    super { }

class ChildVerifier < MyVerifier
  verify %q(message!("it's alive!"))

Yard documentation

This gem uses yard to generate documentation about its API. Visit to see actual documentation for master.

You can’t perform that action at this time.