Class: Class
- Defined in:
- lib/conject/extended_metaid.rb,
lib/conject/class_ext_object_peers.rb,
lib/conject/class_ext_construct_with.rb,
lib/conject/class_ext_object_context.rb,
lib/conject/class_ext_provide_with_objects.rb
Instance Method Summary collapse
- #construct_with(*syms) ⇒ Object
- #has_object_definition? ⇒ Boolean
- #object_context ⇒ Object
- #object_peers(*syms) ⇒ Object
- #provide_with_objects(*syms) ⇒ Object
Instance Method Details
#construct_with(*syms) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/conject/class_ext_construct_with.rb', line 4 def construct_with(*syms) klass = self # # Create the .object_definition accessor for this class. # # The ObjectDefinition stores information # on the dependencies required to # build new instances. # object_def = Conject::ObjectDefinition.new(:owner => klass, :component_names => syms) klass. :object_definition do @object_definition end # TODO: actually, just use meta_eval here to set the ivar and move on. klass. :set_object_definition do |od| #XXX @object_definition = od end klass.set_object_definition(object_def) # XXX klass. do private :set_object_definition end # XXX # # Define internal accessor methods for instances of klass # # The internal hash of dependencies, keyed by name: klass.class_def_private :components do @_components ||= {} end # Have the components been set for this instance yet? klass.class_def_private :components_set? do !@_components.nil? end # Define an internal reader method per dependency: syms.each do |object_name| Conject::Utilities.generate_accessor_method_names(object_name).each do |mname| class_def_private mname do components[object_name] end end end # Define the internal setter method that installs dependencies # in an instance of klass. # #set_components respects the rules set forth in the ObjectDefinition # for this class, and will raise a detailed exception if the rules # are violated. klass.class_def_private :set_components do |component_map| return if components_set? # do not repeat. In inheritance town, a superclass must currently rely on all # of its deps to be declared and set by subclass functionality. obj_def = self.class.object_definition required = obj_def.component_names provided = component_map.keys if required.to_set != provided.to_set # Explain the diff between what was required and what was actually provided: raise Conject::CompositionError.new( :object_definition => obj_def, :required => required, :provided => provided) end # set all the components components.clear.merge! component_map end # .object_context_prep is used internally by klass to maintain some state regarding # its internal restructuring. klass. :object_context_prep do @object_context_prep ||= { :initialize_has_been_wrapped => false } end klass. do private :object_context_prep end klass. :new do |component_map| obj = allocate if has_object_definition? # Apply the given components obj.__send__(:set_components, component_map) else raise "#{self.class} has an ancestor that uses construct_with, but has not declared any component dependencies. Will not be able to instantiate!" end arg_count = obj.method(:initialize).arity case arg_count when 0 obj.__send__ :initialize when 1, -1 # See Footnote a) at the bottom of this file obj.__send__ :initialize, component_map else # We're not equipped to handle this raise "User-defined initialize method defined with #{arg_count} parameters; must either be 0, other wise 1 or -1 (varargs) to receive the component map." end obj end end |
#has_object_definition? ⇒ Boolean
108 109 110 |
# File 'lib/conject/class_ext_construct_with.rb', line 108 def has_object_definition? respond_to?(:object_definition) and !object_definition.nil? end |
#object_context ⇒ Object
2 3 4 |
# File 'lib/conject/class_ext_object_context.rb', line 2 def object_context Conject.default_object_context end |
#object_peers(*syms) ⇒ Object
3 4 5 6 7 8 |
# File 'lib/conject/class_ext_object_peers.rb', line 3 def object_peers(*syms) if !syms.empty? @_conject_object_peers = syms end @_conject_object_peers || [] end |
#provide_with_objects(*syms) ⇒ Object
3 4 5 6 7 8 9 10 11 12 13 14 |
# File 'lib/conject/class_ext_provide_with_objects.rb', line 3 def provide_with_objects(*syms) klass = self # Define an internal reader method per dependency: syms.each do |object_name| Conject::Utilities.generate_accessor_method_names(object_name).each do |mname| class_def_private mname do object_context[object_name] end end end end |