object_struct 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.0.3 (September 22, 2010)
2
+
3
+ Fix failing has_property_name? test. API change: has_property_name? is
4
+ guaranteed to return either true, or false.
5
+
1
6
  ## 0.0.2 (September 22, 2010)
2
7
 
3
8
  Protected ObjectStruct#convert method
@@ -25,7 +25,7 @@
25
25
  # @abstract You probably want to subclass ObjectStruct, to reflect your business
26
26
  # entities. See the README for example use.
27
27
  class ObjectStruct < OpenStruct
28
- VERSION = '0.0.2'
28
+ VERSION = '0.0.3'
29
29
 
30
30
  # Delegated to Hash#each
31
31
  def each &blk
@@ -74,10 +74,10 @@ class ObjectStruct < OpenStruct
74
74
  if name =~ /^has_([a-z_]+)\?$/
75
75
  if respond_to? (field = $1.to_sym)
76
76
  result = (send field)
77
- if result.respond_to?(:count) && result.method(:count).arity == 0
77
+ if result.respond_to?(:count) && result.method(:count).arity < 1
78
78
  (result.count > 0)
79
79
  else
80
- result
80
+ result ? true : false
81
81
  end
82
82
  end
83
83
  else
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Quid, Inc.
@@ -52,7 +52,6 @@ extra_rdoc_files: []
52
52
 
53
53
  files:
54
54
  - lib/object_struct/object_struct.rb
55
- - lib/object_struct/#object_struct.rb#
56
55
  - lib/object_struct.rb
57
56
  - test/test_data.json
58
57
  - test/test_object_struct.rb
@@ -1,154 +0,0 @@
1
- # ---------------------------------------------------------------------------
2
- # Copyright 2010, Quid, Inc.
3
- #
4
- # object_struct is free software: you can redistribute it and/or modify
5
- # it under the terms of the GNU General Public License as published by
6
- # the Free Software Foundation, either version 3 of the License, or
7
- # (at your option) any later version.
8
- #
9
- # object_struct is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with object_struct. If not, see <http://www.gnu.org/licenses/>.
16
- #
17
- # ---------------------------------------------------------------------------
18
-
19
-
20
- # Inherit from ObjectStruct to allow object-style accesses to a hash parameter
21
- # passed to {ObjectStruct#initialize initialize}. Properties are lazy-loaded.
22
- #
23
- # @see OpenStruct
24
- #
25
- # @abstract You probably want to subclass ObjectStruct, to reflect your business
26
- # entities. See the README for example use.
27
- class ObjectStruct < OpenStruct
28
- VERSION = '0.0.2 '
29
-
30
- # Delegated to Hash#each
31
- def each &blk
32
- to_h.each &blk
33
- end
34
-
35
- # Delegated to Hash#values
36
- def values
37
- to_h.values
38
- end
39
-
40
- # Specify the type of a particular property.
41
- #
42
- # @param [Hash] options The options hash. Pass any :property_name => ClassName
43
- # to enforce that type.
44
- #
45
- # @option options [Boolean] :plural (false) Whether the property is plural,
46
- # e.g. an Array of the class specified. (Yes, this means that if you have a
47
- # property named :plural, you cannot specify its type.)
48
- def self.property_type(options)
49
- plural = options.delete(:plural)
50
- property, type = *options.first
51
- class_name = plural ? property.to_s.classify : property.to_s.camelize
52
- Object.const_set class_name, Class.new(type)
53
- end
54
-
55
- # Create a new ObjectStruct.
56
- #
57
- # @param [Hash] data a Hash representing your data. Keys are used to identify
58
- # the type of the property.
59
- def initialize(data)
60
- @table = Hash.new {|h, k| raise NoMethodError, "undefined property #{k} for #{self}"}
61
- data = {'data' => data} unless data.respond_to? :each
62
- for k,v in data
63
- @table[k.to_sym] = self.class.value_maybe_promise(k, v)
64
- new_ostruct_member(k)
65
- end
66
- end
67
-
68
- # Provides has_property_name? methods. Intercepts messages matching
69
- # /^has_[a-z_]+\?$/. If the method matches this regex, ObjectStruct will see
70
- # if it responds to such a property. If that property responds to a count
71
- # method, it will furthermore make sure #count is greater than zero.
72
- # @return the property, if it exists, nil otherwise
73
- def method_missing(name, *args)
74
- if name =~ /^has_([a-z_]+)\?$/
75
- if respond_to? (field = $1.to_sym)
76
- result = (send field)
77
- if result.respond_to?(:count) && result.method(:count).arity == 0
78
- (result.count > 0)
79
- else
80
- result
81
- end
82
- end
83
- else
84
- super(name, *args)
85
- end
86
- end
87
-
88
- # Specifically provide the object_id. If your objects have IDs, choose a more
89
- # descriptive name.
90
- def id
91
- object_id
92
- end
93
-
94
- protected
95
-
96
- def new_ostruct_member(name)
97
- name = name.to_sym
98
- unless self.respond_to?(name)
99
- class << self; self; end.class_eval do
100
- define_method(name) { ObjectStruct.demand @table[name] }
101
- define_method("#{name}=") { |x| @table[name] = x }
102
- end
103
- end
104
- name
105
- end
106
-
107
- # Recursively convert a value to an ObjectStruct (or a class matching the
108
- # type, if it exists).
109
- #
110
- # @param [Array, Hash] value the value to convert. Arrays are converted
111
- # recursively, each value to the requested type. Hashes are converted
112
- # directly to the requested type.
113
- #
114
- # @param [String, #to_s] type the type of the value (or values in the array).
115
- # This method falls back to ObjectStruct if it cannot find a class matching
116
- # the type.
117
- #
118
- # @return [type/ObjectStruct, Array<type/ObjectStruct>, value] the type
119
- # requested, or an ObjectStruct; or an Array thereof; or the value if it
120
- # neither an Array nor Hash.
121
- def self.convert(value, type = nil)
122
- klass = ((value.is_a? Array) ? type.to_s.classify : type.to_s.camelize).constantize rescue ObjectStruct
123
-
124
- case value
125
- when Array
126
- value.map{|e| convert(e, klass.to_s)}
127
- when Hash
128
- klass.new(value)
129
- else
130
- value
131
- end
132
- end
133
-
134
- private
135
-
136
- def to_h
137
- result = {}
138
- @table.each {|name, value| result[name.to_s] = value}
139
- result
140
- end
141
-
142
- def self.value_maybe_promise(key, value)
143
- case value
144
- when Array, Hash
145
- Lazy::Promise.new {convert(value, key)}
146
- else
147
- value
148
- end
149
- end
150
-
151
- def self.demand value
152
- (value.is_a? Lazy::Promise) ? value.__result__ : value
153
- end
154
- end