Class: DIY::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/diy.rb,
lib/diy/factory.rb

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context_hash, extra_inputs = {}) ⇒ Context

Accepts a Hash defining the object context (usually loaded from objects.yml), and an additional Hash containing objects to inject into the context.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/diy.rb', line 17

def initialize(context_hash, extra_inputs={})
  raise "Nil context hash" unless context_hash
  raise "Need a hash" unless context_hash.kind_of?(Hash)
  [ "[]", "keys" ].each do |mname|
    unless extra_inputs.respond_to?(mname) 
      raise "Extra inputs must respond to hash-like [] operator and methods #keys and #each" 
    end
  end

  # store extra inputs
  if extra_inputs.kind_of?(Hash)
    @extra_inputs= {}
    extra_inputs.each { |k,v| @extra_inputs[k.to_s] = v } # smooth out the names
  else
    @extra_inputs = extra_inputs
  end

  collect_object_and_subcontext_defs context_hash

  # init the cache
  @cache = {}
  @cache['this_context'] = self
end

Class Attribute Details

.auto_requireObject

Enable / disable automatic requiring of libraries. Default: true



11
12
13
# File 'lib/diy.rb', line 11

def auto_require
  @auto_require
end

Class Method Details

.from_file(fname, extra_inputs = {}) ⇒ Object

Convenience: create a new DIY::Context by loading from the named file.



49
50
51
52
# File 'lib/diy.rb', line 49

def self.from_file(fname, extra_inputs={})
  raise "nil file name" unless fname
  self.from_yaml(File.read(fname), extra_inputs)
end

.from_yaml(io_or_string, extra_inputs = {}) ⇒ Object

Convenience: create a new DIY::Context by loading from a String (or open file handle.)



43
44
45
46
# File 'lib/diy.rb', line 43

def self.from_yaml(io_or_string, extra_inputs={})
  raise "nil input to YAML" unless io_or_string
  Context.new(YAML.load(io_or_string), extra_inputs)
end

Instance Method Details

#build_everythingObject Also known as: build_all, preinstantiate_singletons

Every top level object in the Context is instantiated. This is especially useful for systems that have “floating observers”… objects that are never directly accessed, who would thus never be instantiated by coincedence. This does not build any subcontexts that may exist.



115
116
117
# File 'lib/diy.rb', line 115

def build_everything
  @defs.keys.each { |k| self[k] }
end

#construct_factory(key) ⇒ Object



15
16
17
18
19
20
21
22
23
# File 'lib/diy/factory.rb', line 15

def construct_factory(key)
  factory_def = @defs[key]
#      puts "requiring #{factory_def.library}"
  require factory_def.library	if factory_def.library

			big_c = get_class_for_name_with_module_delimeters(factory_def.class_name)

  FactoryFactory.new(big_c)
end

#contains_object(obj_name) ⇒ Object

Returns true if the context contains an object with the given name



106
107
108
109
# File 'lib/diy.rb', line 106

def contains_object(obj_name)
  key = obj_name.to_s
  @defs.keys.member?(key) or extra_inputs_has(key)
end

#get_object(obj_name) ⇒ Object Also known as: []

Return a reference to the object named. If necessary, the object will be instantiated on first use. If the object is non-singleton, a new object will be produced each time.



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/diy.rb', line 57

def get_object(obj_name)
  key = obj_name.to_s
  obj = @cache[key]
  unless obj
    if extra_inputs_has(key)
      obj = @extra_inputs[key]
    else
      case @defs[key]
      when MethodDef
        obj = construct_method(key)
      when FactoryDef
        obj = construct_factory(key)
        @cache[key] = obj
      else
        obj = construct_object(key)
        @cache[key] = obj if @defs[key].singleton?
      end
    end
  end
  obj
end

#keysObject

Provide a listing of object names



90
91
92
# File 'lib/diy.rb', line 90

def keys
  (@defs.keys.to_set + @extra_inputs.keys.to_set).to_a
end

#set_object(obj_name, obj) ⇒ Object Also known as: []=

Inject a named object into the Context. This must be done before the Context has instantiated the object in question.



82
83
84
85
86
# File 'lib/diy.rb', line 82

def set_object(obj_name,obj)
  key = obj_name.to_s
  raise "object '#{key}' already exists in context" if @cache.keys.include?(key)
  @cache[key] = obj
end

#within(sub_context_name) {|context| ... } ⇒ Object

Instantiate and yield the named subcontext

Yields:

  • (context)


95
96
97
98
99
100
101
102
103
# File 'lib/diy.rb', line 95

def within(sub_context_name)
  # Find the subcontext definitaion:
  context_def = @sub_context_defs[sub_context_name.to_s]
  raise "No sub-context named #{sub_context_name}" unless context_def
  # Instantiate a new context using self as parent:
  context = Context.new( context_def, self )

  yield context
end