object_struct 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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