Class: Safer::HashProtocol

Inherits:
Object
  • Object
show all
Defined in:
lib/safer/hashprotocol.rb

Overview

Check that the keys in a Hash object follow a set of constraints.

Usage

In this example, we use a Hash to simulate keyword parameters to our function.

class YourClass
  SHP = Safer::HashProtocol
  # we support two versions of the keyword arguments to our function.
  # In both versions, the Hash is required to have a :type field.
  CommonKeywords = SHP::HasKey.create(:type)
  # In the old version, a person's full name is presented in the :name
  # keyword.
  V1Keywords = SHP::HasKey.create(:name)
  # In the new version, the full name is separated into :familyName
  # and :givenName.
  V2Keywords = SHP::HasKey.create(:familyName, :givenName)
  # Check if the keywords in the Hash match Version1 (that is,
  # :name and :type fields must be present in the Hash, and no other
  # fields should be present).
  V1Check = SHP::Only.new(SHP::All.new(*CommonKeywords + *V1Keywords))
  # Check if the keywords in the Hash match Version2 (that is,
  # :familyName, :givenName, and :type fields must be present in the Hash,
  # and no other fields should be present).
  V2Check = SHP::Only.new(SHP::All.new(*CommonKeywords + *V2Keywords))
  # Check if the Hash matches either version 1 or version 2.
  ValidCheck = SHP::Any.new(V1Check, V2Check)
  def my_fn(h)
    if ! (ValidCheck === h)
      raise ArgumentError, "h should conform to #{ValidCheck.description}"
    end
    case h
    when V1Check
      v1_process(h[:name], h[:type])
    when V2Check
      v2_process(h[:familyName], h[:givenName], h[:type])
    end
  end
end

Rationale

It is a common design practice in Ruby code to use Hash objects to get an analogue to function keyword arguments in other languages. Among other uses, this practice simplifies the implementation of embedded DSLs within Ruby. When used in this way, the Hash keys are semantically meaningful, and are generally entered by hand. It’s important to get these Hashes right. Safer::HashProtocol is intended to help, by simultaneously providing a means of documenting the key combinations required of a Hash, and by detecting when the Hash does not contain a valid set of keys.

Defined Under Namespace

Classes: All, Any, Base, Compound, HasKey, Not, Only, ProtocolBase, Single

Constant Summary collapse

Protocol =

Object signature required of HashProtocol objects. Derived from ProtocolBase.

Safer::Protocol.create_from_class(ProtocolBase)