structure 0.20.1 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -6,6 +6,3 @@ rvm:
6
6
  - rbx
7
7
  - rbx-2.0
8
8
  - ree
9
- branches:
10
- only:
11
- - master
data/lib/structure.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'forwardable'
2
1
  begin
3
2
  JSON::JSON_LOADED
4
3
  rescue NameError
@@ -13,7 +12,6 @@ end
13
12
  # end
14
13
  #
15
14
  class Structure
16
- extend Forwardable
17
15
  include Enumerable
18
16
 
19
17
  # A namespaced basic object.
@@ -102,6 +100,29 @@ class Structure
102
100
  key name, Array, []
103
101
  end
104
102
 
103
+ alias_method :new_original, :new
104
+
105
+ def new(hsh)
106
+ hsh = hsh.inject({}) do |a, (k, v)|
107
+ a[Inflector.underscore(k)] =
108
+ case v
109
+ when Hash
110
+ Structure.new(v)
111
+ when Array
112
+ v.map { |e| e.is_a?(Hash) ? Structure.new(e) : e }
113
+ else
114
+ v
115
+ end
116
+ a
117
+ end
118
+
119
+ klass = Class.new(Structure) do
120
+ hsh.keys.each { |k| key k }
121
+ end
122
+
123
+ klass.new(hsh)
124
+ end
125
+
105
126
  # Lazy-eval undefined constants, typically other structures,
106
127
  # assuming they will be defined later in the text.
107
128
  def const_missing(name)
@@ -109,7 +130,9 @@ class Structure
109
130
  end; private :const_missing
110
131
 
111
132
  def inherited(child)
112
- child.def_delegator child, :defaults
133
+ if self.eql? Structure
134
+ class << child; alias_method :new, :new_original; end
135
+ end
113
136
  end; private :inherited
114
137
  end
115
138
 
@@ -118,7 +141,7 @@ class Structure
118
141
  # A hash, if provided, seeds the attributes.
119
142
  def initialize(hsh = {})
120
143
  @attributes = defaults.inject({}) do |a, (k, v)|
121
- a[k] = v.is_a?(Array) ? v.dup : v
144
+ a[k] = v.dup rescue v
122
145
  a
123
146
  end
124
147
 
@@ -163,6 +186,26 @@ class Structure
163
186
  def ==(other)
164
187
  other.is_a?(self.class) && attributes == other.attributes
165
188
  end
189
+
190
+ def defaults
191
+ self.class.defaults
192
+ end; private :defaults
193
+
194
+ module Inflector
195
+ # Makes an underscored, lowercase form from the expression in the
196
+ # string.
197
+ #
198
+ # You know where this is lifted from.
199
+ def self.underscore(camel_cased_word)
200
+ word = camel_cased_word.to_s.dup
201
+ word.gsub!(/::/, '/')
202
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
203
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
204
+ word.tr!("-", "_")
205
+ word.downcase!
206
+ word
207
+ end
208
+ end
166
209
  end
167
210
 
168
- require 'structure/active_support' if defined?(Rails)
211
+ require 'structure/ext/active_support' if defined?(Rails)
@@ -1,3 +1,3 @@
1
1
  class Structure
2
- VERSION = '0.20.1'
2
+ VERSION = '0.21.0'
3
3
  end
@@ -26,6 +26,24 @@ class TestStructure < Test::Unit::TestCase
26
26
  assert_kind_of Fixnum, double
27
27
  end
28
28
 
29
+ def test_anonymous
30
+ hsh = { 'FirstName' => 'John', 'LastName' => 'Doe' }
31
+ str = Structure.new(hsh)
32
+ assert_equal hsh['FirstName'], str.first_name
33
+ assert_equal hsh['LastName'], str.last_name
34
+ assert_raise(NoMethodError) { str.FirstName }
35
+ end
36
+
37
+ def test_anonymous_recursion
38
+ hsh = { 'Name' => 'John',
39
+ 'Address' => { 'City' => 'Oslo' },
40
+ 'Friends' => [{ 'Name' => 'Jane' }]
41
+ }
42
+ str = Structure.new(hsh)
43
+ assert_equal hsh['Address']['City'], str.address.city
44
+ assert_equal hsh['Friends'].first['Name'], str.friends.first.name
45
+ end
46
+
29
47
  def test_enumeration
30
48
  assert_respond_to Person.new, :map
31
49
  end
@@ -80,7 +98,7 @@ class TestStructure < Test::Unit::TestCase
80
98
 
81
99
  require 'active_support/ordered_hash'
82
100
  require 'active_support/json'
83
- require 'structure/active_support'
101
+ require 'structure/ext/active_support'
84
102
 
85
103
  assert_equal true, person.as_json(:only => :name).has_key?(:name)
86
104
  assert_equal false, person.as_json(:except => :name).has_key?(:name)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: structure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.1
4
+ version: 0.21.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-06 00:00:00.000000000Z
12
+ date: 2011-09-10 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: Structure is a typed, nestable key/value container.
15
15
  email:
@@ -25,7 +25,7 @@ files:
25
25
  - README.md
26
26
  - Rakefile
27
27
  - lib/structure.rb
28
- - lib/structure/active_support.rb
28
+ - lib/structure/ext/active_support.rb
29
29
  - lib/structure/version.rb
30
30
  - structure.gemspec
31
31
  - test/structure_test.rb
@@ -43,7 +43,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
43
43
  version: '0'
44
44
  segments:
45
45
  - 0
46
- hash: -2865426665799321471
46
+ hash: -3352714224337607479
47
47
  required_rubygems_version: !ruby/object:Gem::Requirement
48
48
  none: false
49
49
  requirements:
@@ -52,7 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
52
  version: '0'
53
53
  segments:
54
54
  - 0
55
- hash: -2865426665799321471
55
+ hash: -3352714224337607479
56
56
  requirements: []
57
57
  rubyforge_project: structure
58
58
  rubygems_version: 1.8.6