Class: Hashing::Hasher

Inherits:
Object
  • Object
show all
Defined in:
lib/hashing/hasher.rb

Overview

This class contains the interface “exported” by a call to the ‘.hasherize` method in any class that includes the module [Hashing].

Since:

  • 0.0.1

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host_class, ivars = nil) ⇒ Hasher

Returns a new instance of Hasher.

Parameters:

  • host_class (Class)

    the class whose ivars will be used to serialize

  • ivars (Array<Symbol>) (defaults to: nil)

    the ivars that will be serialized

Since:

  • 0.0.1



12
13
14
15
# File 'lib/hashing/hasher.rb', line 12

def initialize(host_class, ivars = nil)
  @host_class = host_class
  add ivars
end

Instance Attribute Details

#ivarsObject (readonly)

Since:

  • 0.0.1



8
9
10
# File 'lib/hashing/hasher.rb', line 8

def ivars
  @ivars
end

Instance Method Details

#add(ivar_names) ⇒ Hasher

This method can be called to define which ivars will be used as keys in the final hash. Ivar names passed as arguments to this method will be used to create instances of [Ivar]. Those have the real logic of serialization and unserialization of an [Ivar]. This method also keeps a reference to the last ivars passed as parameter. This is necessary to allow us to do the following call:

hasherize(:ivar1, :ivar2).to(->(value){})

The previous call will configure the ‘:to` strategy for `:ivar1` and `:ivar2`.

Parameters:

  • ivar_names (Array<Symbol>)

    ivars to be used to hasherize the instance

Returns:

Since:

  • 0.0.1



122
123
124
125
126
127
128
# File 'lib/hashing/hasher.rb', line 122

def add(ivar_names)
  ivar_names = Array(ivar_names)
  @current_ivars = ivar_names.map { |ivar_name| Ivar.new ivar_name }
  @ivars ||= []
  @ivars += @current_ivars
  self
end

#collection(type) ⇒ Hasher

Provides the api to say if an ivar is a collection (#map) of instances of a class that includes Hashing. The idea here is just to be able to restore nested Hashing objects.

Returns:

Since:

  • 0.1.0



83
84
85
86
87
88
89
# File 'lib/hashing/hasher.rb', line 83

def collection(type)
  # replace current ivar for it's collection version...
  collections = @current_ivars.map { |ivar| IvarCollection.new ivar, type }
  @current_ivars.each { |ivar| @ivars.delete ivar }
  @ivars += collections
  self
end

#from(strategy) ⇒ Hasher

Provides the api to configure the logic to serialize an instance of a class that includes Hashing into a hash object.

Parameters:

  • strategy (#call)

    the logic to convert some value to a [Hash]

Returns:

Since:

  • 0.1.0



37
38
39
# File 'lib/hashing/hasher.rb', line 37

def from(strategy)
  logic_for :from_hash, strategy
end

#load(hash) ⇒ Object

This method will be called to reconstruct an instance of the type which includes Hashing. The ‘loader` in which `#call` will be called here is the one passed to the #loading. If none was passed, this method will just call `.new` in the host class passing the [Hash] as argument.

Parameters:

  • hash (Hash)

    serialized by a call to #to_h

Since:

  • 0.0.1



149
150
151
152
153
# File 'lib/hashing/hasher.rb', line 149

def load(hash)
  check_for_unconfigured_keys hash
  loader = @loading || ->(serialized) { @host_class.new serialized }
  loader.call process_hash_values hash
end

#loading(strategy) ⇒ Hasher

Configures the strategy to (re)create an instance of the ‘hasherized ®’ class based on a ‘Hash` instance. This strategy will be used by the `.from_hash({})` method.

This configuration is optional, if it’s not called, then the strategy will be just repassing the ‘Hash` to the initializer.

Parameters:

  • strategy (#call)

Returns:

  • (Hasher)

    (fluent interface)

Since:

  • 0.0.1



100
101
102
103
# File 'lib/hashing/hasher.rb', line 100

def loading(strategy)
  @loading = strategy
  self
end

#reader(should_create_attr_reader = true) ⇒ Hasher

Provides the api to create attr_readers in the host class for the current configured ivars (those passed to #add).

@example: creating attr_reader from :path and :commit

hasherize(:path, :commit).reader true

The example above will create accessors for :path and :commit

Returns:

Since:

  • 0.1.0



52
53
54
55
56
57
# File 'lib/hashing/hasher.rb', line 52

def reader(should_create_attr_reader = true)
  if should_create_attr_reader
    @current_ivars.each { |ivar| @host_class.send :attr_reader, ivar.to_sym }
  end
  self
end

#to(strategy) ⇒ Hasher

Provides the api to configure the strategy to serialize an instance of a class that includes Hashing into a hash object.

Parameters:

  • strategy (#call)

    the logic to convert some value to a [Hash]

Returns:

Since:

  • 0.1.0



26
27
28
# File 'lib/hashing/hasher.rb', line 26

def to(strategy)
  logic_for :to_h, strategy
end

#to_h(instance) ⇒ Hash

Provides the logic to transform an instance of a Hashing class into an hash object.

Returns:

  • (Hash)

    a new hash in which keys are the ivar names and values the string value for those ivars.

Since:

  • 0.0.1



134
135
136
137
138
139
140
# File 'lib/hashing/hasher.rb', line 134

def to_h(instance)
  pairs = @ivars.map { |ivar|
    ivar_value = instance.instance_variable_get :"@#{ivar.to_sym}"
    [ivar.to_sym, ivar.to_h(ivar_value)]
  }
  Hash[pairs]
end

#using(serializator) ⇒ Hasher

Provides the api to indicate an object with the serialization and unserialization logic.

@example: using Base64 to serialize and unserialize some ivar:

hahserize(:content).unsing(Base64).to(:encode64).from(:decode64)

Note: any object can be passe to #using, and the methods in these object passed as arguments to #to and #from need to be public.

Returns:

Since:

  • 0.1.0



71
72
73
74
# File 'lib/hashing/hasher.rb', line 71

def using(serializator)
  @serializator = serializator
  self
end