Class: Tap::Support::InstanceConfiguration

Inherits:
Object
  • Object
show all
Defined in:
lib/tap/support/instance_configuration.rb

Overview

InstanceConfiguration serves as a forwarding hash, where get and set operations for configurations are sent to instance methods rather than to an underlying data store.

class Sample
  attr_accessor :key
end
sample = Sample.new

class_config = ClassConfiguration.new(Sample)
class_config.add(:key)

config = InstanceConfiguration.new(class_config)
config.bind(sample)

sample.key = 'value'
config[:key]                # => 'value'

config[:key] = 'another'
sample.key                  # => 'another'

Non-config keys are simply stored:

config[:not_a_key] = 'value'
config[:not_a_key]          # => 'value'

config.store                # => {:not_a_key => 'value'}
config.to_hash              # => {:key => 'another', :not_a_key => 'value'}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(class_config, receiver = nil, store = {}) ⇒ InstanceConfiguration

Returns a new instance of InstanceConfiguration.



44
45
46
47
48
# File 'lib/tap/support/instance_configuration.rb', line 44

def initialize(class_config, receiver=nil, store={})
  @receiver = receiver
  @store = store
  @class_config = class_config
end

Instance Attribute Details

#class_configObject (readonly)

The ClassConfiguration specifying config keys



42
43
44
# File 'lib/tap/support/instance_configuration.rb', line 42

def class_config
  @class_config
end

#receiverObject (readonly)

The bound receiver



36
37
38
# File 'lib/tap/support/instance_configuration.rb', line 36

def receiver
  @receiver
end

#storeObject (readonly)

The underlying data store for non-config keys



39
40
41
# File 'lib/tap/support/instance_configuration.rb', line 39

def store
  @store
end

Instance Method Details

#==(another) ⇒ Object

Equal if the to_hash values of self and another are equal.



141
142
143
# File 'lib/tap/support/instance_configuration.rb', line 141

def ==(another)
  another.respond_to?(:to_hash) && to_hash == another.to_hash
end

#[](key) ⇒ Object

Retrieves the value corresponding to the key. If bound? and the key is a class_config key, then the value is obtained from the config.reader method on the receiver.



116
117
118
119
120
121
122
# File 'lib/tap/support/instance_configuration.rb', line 116

def [](key)
  case 
  when bound? && config = class_config.map[key.to_sym]
    config.reader ? receiver.send(config.reader) : store[key]
  else store[key]
  end
end

#[]=(key, value) ⇒ Object

Associates the value the key. If bound? and the key is a class_config key, then the value will be forwarded to the config.writer method on the receiver.



105
106
107
108
109
110
111
# File 'lib/tap/support/instance_configuration.rb', line 105

def []=(key, value)
  case 
  when bound? && config = class_config.map[key.to_sym]
    config.writer ? receiver.send(config.writer, value) : store[key] = value
  else store[key] = value
  end
end

#bind(receiver) ⇒ Object

Binds self to the specified receiver. Mapped keys are removed from store and sent to their writer method on receiver.

Raises:

  • (ArgumentError)


65
66
67
68
69
70
71
72
73
74
75
# File 'lib/tap/support/instance_configuration.rb', line 65

def bind(receiver)
  raise "already bound to: #{@receiver}" if bound?
  raise ArgumentError, "receiver cannot be nil" if receiver == nil
  
  class_config.each_pair do |key, config|
    receiver.send(config.writer, store.delete(key)) if config.writer
  end
  @receiver = receiver
  
  self
end

#bound?Boolean

Returns true if self is bound to a receiver

Returns:

  • (Boolean)


78
79
80
# File 'lib/tap/support/instance_configuration.rb', line 78

def bound?
  receiver != nil
end

#dupObject

Duplicates self, returning an unbound InstanceConfiguration.



95
96
97
98
99
100
# File 'lib/tap/support/instance_configuration.rb', line 95

def dup
  duplicate = super()
  duplicate.instance_variable_set(:@receiver, nil)
  duplicate.instance_variable_set(:@store, @store.dup)
  duplicate
end

#each_pairObject

Calls block once for each key-value pair stored in self.



130
131
132
133
134
135
136
137
138
# File 'lib/tap/support/instance_configuration.rb', line 130

def each_pair # :yields: key, value
  class_config.each_pair do |key, config|
    yield(key, receiver.send(config.reader)) if config.reader
  end if bound?
  
  store.each_pair do |key, value|
    yield(key, value)
  end
end

#has_key?(key) ⇒ Boolean

True if the key is assigned in self.

Returns:

  • (Boolean)


125
126
127
# File 'lib/tap/support/instance_configuration.rb', line 125

def has_key?(key)
  (bound? && class_config.key?(key)) || store.has_key?(key) 
end

#inspectObject

Overrides default inspect to show the to_hash values.



168
169
170
# File 'lib/tap/support/instance_configuration.rb', line 168

def inspect
  "#<#{self.class}:#{object_id} to_hash=#{to_hash.inspect}>"
end

#to_hashObject

Returns self as a hash.



146
147
148
149
150
151
152
# File 'lib/tap/support/instance_configuration.rb', line 146

def to_hash
  hash = store.dup
  class_config.keys.each do |key|
    hash[key] = self[key]
  end if bound?
  hash
end

#to_yaml(opts) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/tap/support/instance_configuration.rb', line 154

def to_yaml(opts)
  hash = {}
  store.each_pair do |key, value|
    hash[key.to_s] = value
  end
  
  class_config.each_pair do |key, config|
    hash[key.to_s] = bound? ? self[key] : config.default
  end
  
  hash.to_yaml(opts)
end

#unbindObject

Unbinds self from the specified receiver. Mapped values are stored in store. Returns the unbound receiver.



84
85
86
87
88
89
90
91
92
# File 'lib/tap/support/instance_configuration.rb', line 84

def unbind
  class_config.each_pair do |key, config|
    store[key] = receiver.send(config.reader) if config.reader
  end
  r = receiver
  @receiver = nil
  
  r
end

#update(class_config = self.class_config) ⇒ Object

Updates self to ensure that each class_config key has a value in self; the config.default value is set if a value does not already exist.

Returns self.



55
56
57
58
59
60
# File 'lib/tap/support/instance_configuration.rb', line 55

def update(class_config=self.class_config)
  class_config.each_pair do |key, config|
    self[key] ||= config.default
  end
  self
end