Class: Doodle::AttributeCollector

Inherits:
DoodleAttribute show all
Defined in:
lib/doodle/collector.rb

Overview

base class for attribute collector classes

Direct Known Subclasses

AppendableAttribute, KeyedAttribute

Instance Method Summary collapse

Methods inherited from DoodleAttribute

#abstract, #default_defined?, #init_defined?, #optional?, #readonly, #required?, #validate!

Methods included from DoodleAttribute::ClassMethods

#params_from_args

Methods inherited from Doodle

TypedArray, raise_exception_on_error, raise_exception_on_error=

Methods included from ClassMethods

#context, #parent

Methods included from JSON

included

Methods included from Core::ModuleMethods

#included

Constructor Details

#initialize(*args, &block) ⇒ AttributeCollector

Returns a new instance of AttributeCollector.



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
# File 'lib/doodle/collector.rb', line 63

def initialize(*args, &block)
  #p [self.class, :initialize]
  super
  define_collector
  from Hash do |hash|
    # FIXME: collector - my bogon detector just went off the scale - I forget why I have to do this here... :/
    # oh yes - because I allow forward references using symbols or strings
    resolve_collector_class
    collection = create_collection
    hash.inject(collection) do |h, (key, value)|
      h[key] = resolve_value(value)
      h
    end
  end
  from Enumerable do |enum|
    #p [:enum, Enumerable]
    # FIXME: collector
    resolve_collector_class
    # this is not very elegant but String is a classified as an
    # Enumerable in 1.8.x (but behaves differently)
    if enum.kind_of?(String) && self.init.kind_of?(String)
      post_process( resolve_value(enum) )
    else
      post_process( enum.map{ |value| resolve_value(value) } )
    end
  end
end

Instance Method Details

#post_process(results) ⇒ Object



91
92
93
94
95
# File 'lib/doodle/collector.rb', line 91

def post_process(results)
  #p [:post_process, results]
  collection = create_collection
  collection.replace(results)
end

#resolve_collector_classObject



34
35
36
37
38
39
40
41
42
# File 'lib/doodle/collector.rb', line 34

def resolve_collector_class
  # FIXME: collector - perhaps don't allow non-class collectors - should be resolved by this point
  # perhaps do this in init?
  collector_spec.each do |k, v|
    if !v.kind_of?(Class)
      collector_spec[k] = Doodle::Utils.const_resolve(v)
    end
  end
end

#resolve_value(value) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/doodle/collector.rb', line 44

def resolve_value(value)
  klasses = collector_spec.values
  # FIXME: collector - find applicable collector class
  if klasses.any? { |x| value.kind_of?(x) }
    # no change required
    #p [:resolve_value, :value, value]
    value
  elsif collector_class = klasses.select { |klass| klass.__doodle__.conversions.key?(value.class) }.first
    # if the collector_class has a specific conversion for this value class
    #p [:resolve_value, :collector_class_from, value]
    collector_class.from(value)
  else
    collector_class = klasses.first
    # try to instantiate collector_class using raw value
    #p [:resolve_value, :collector_class_new, value]
    collector_class.new(value)
  end
end