fancy-open-struct 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ repo_token: ATscazUF1vqixUbLan70hDzMHNPsrSu0b
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --format progress
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.8.7"
4
+ - "1.9.2"
5
+ - "1.9.3"
6
+ - "2.0.0"
7
+ - jruby-18mode # JRuby in 1.8 mode
8
+ - jruby-19mode # JRuby in 1.9 mode
9
+ - rbx
10
+ # uncomment this line if your project needs to run something other than `rake`:
11
+ # script: bundle exec rspec spec
data/Gemfile CHANGED
@@ -7,5 +7,4 @@ group :development do
7
7
  else
8
8
  gem 'simplecov'
9
9
  end
10
- gem 'pry'
11
10
  end
@@ -1,9 +1,23 @@
1
- = fancy-open-struct
1
+ = FancyOpenStruct
2
2
 
3
- OpenStruct subclass that returns nested (recursive) hash attributes as FancyOpenStructs,
4
- and also allows usage of Hash methods for getting and setting values.
3
+ {<img src="http://allthebadges.io/tomchapin/fancy-open-struct/badge_fury.png" alt="Version" />}[http://allthebadges.io/tomchapin/fancy-open-struct/badge_fury]
4
+ {<img src="http://allthebadges.io/tomchapin/fancy-open-struct/gemnasium.png" alt="Dependencies" />}[http://allthebadges.io/tomchapin/fancy-open-struct/gemnasium]
5
+ {<img src="http://allthebadges.io/tomchapin/fancy-open-struct/travis.png" alt="Build Status" />}[http://allthebadges.io/tomchapin/fancy-open-struct/travis]
6
+ {<img src="http://allthebadges.io/tomchapin/fancy-open-struct/coveralls.png" alt="Coverage" />}[http://allthebadges.io/tomchapin/fancy-open-struct/coveralls]
7
+ {<img src="http://allthebadges.io/tomchapin/fancy-open-struct/code_climate.png" alt="Code Climate" />}[http://allthebadges.io/tomchapin/fancy-open-struct/code_climate]
5
8
 
6
- It allows for hashes within hashes to be called in a chain of methods:
9
+ FancyOpenStruct is a subclass of OpenStruct, and is a variant of RecursiveOpenStruct.
10
+
11
+ This gem allows you to convert nested hashes into a structure where keys and values can be
12
+ navigated and modified via dot-syntax, like: foo.bar = :something. This particular gem also adds support
13
+ for the Hash methods you know and love (such as length or merge), and also allows you to access and modify
14
+ the contained data structure the same way that you would handle a normal Hash.
15
+
16
+ == Usage
17
+
18
+ FancyOpenStruct allows for hashes within hashes to be called in a chain of methods:
19
+
20
+ require 'fancy-open-struct'
7
21
 
8
22
  fos = FancyOpenStruct.new( { :fooa => { :foob => 'fooc' } } )
9
23
 
@@ -15,6 +29,8 @@ Also, if needed, nested hashes can still be accessed as hashes:
15
29
 
16
30
  Get and set values either via dot syntax, or hash syntax (Hash keys are handled as Symbols):
17
31
 
32
+ fos = FancyOpenStruct.new
33
+
18
34
  fos.foo = 'bar'
19
35
  fos[:foo] # 'bar'
20
36
 
data/Rakefile CHANGED
@@ -42,4 +42,4 @@ task :fix_permissions do
42
42
  FileUtils.chmod 0755, ['lib','spec'], :verbose => true
43
43
  end
44
44
 
45
- task :build => :fix_permissions
45
+ task :build => :fix_permissions
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
- require './lib/fancy_open_struct'
3
+ require './lib/fancy-open-struct'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "fancy-open-struct"
@@ -12,38 +12,32 @@ Gem::Specification.new do |s|
12
12
  s.licenses = ["MIT"]
13
13
 
14
14
  s.summary = "OpenStruct subclass that returns nested hash attributes as FancyOpenStructs"
15
- s.description = <<-QUOTE .gsub(/^ /,'')
15
+ s.description = <<-QUOTE.gsub(/^ /, '')
16
16
  FancyOpenStruct is a subclass of OpenStruct, and is a variant of RecursiveOpenStruct.
17
- It differs from OpenStruct in that it allows nested hashes to be treated in a recursive
18
- fashion, and it also provides Hash methods for getting and setting values.
17
+ This allows you to convert nested hashes into a structure where keys and values can be
18
+ navigated and modified via dot-syntax, like: foo.bar = :something. This particular gem
19
+ also adds support for Hash methods (such as length or merge), and also allows you to
20
+ access and modify the data structure the same way that you would handle a normal Hash.
19
21
 
20
- For example:
21
-
22
- fos = FancyOpenStruct.new({ :a => { :b => 'c' } })
23
- fos.a.b # 'c'
24
-
25
- fos.foo = 'bar'
26
- fos[:foo] # 'bar'
27
-
28
- fos.length # 2
29
-
30
- Also, nested hashes can still be accessed as hashes:
31
-
32
- fos.a_as_a_hash # { :b => 'c' }
33
-
34
- QUOTE
22
+ QUOTE
35
23
 
36
24
  s.files = `git ls-files`.split("\n")
37
25
  s.test_files = `git ls-files spec`.split("\n")
38
26
  s.require_paths = ["lib"]
39
27
  s.extra_rdoc_files = [
40
- "LICENSE.txt",
41
- "README.rdoc"
28
+ "LICENSE.txt",
29
+ "README.rdoc"
42
30
  ]
43
31
 
44
- s.add_development_dependency(%q<rspec>, [">= 0"])
45
- s.add_development_dependency(%q<bundler>, [">= 0"])
46
- s.add_development_dependency(%q<rdoc>, [">= 0"])
47
- s.add_development_dependency(%q<pry>, [">= 0"])
32
+ s.add_development_dependency "bundler"
33
+ s.add_development_dependency "rake"
34
+ s.add_development_dependency "rspec"
35
+ s.add_development_dependency "rdoc"
36
+ s.add_development_dependency "pry"
37
+ s.add_development_dependency "coveralls"
38
+ s.add_development_dependency "guard"
39
+ s.add_development_dependency "guard-rspec"
40
+ s.add_development_dependency "guard-bundler"
41
+ s.add_development_dependency "simplecov-multi"
48
42
  end
49
43
 
@@ -1 +1,125 @@
1
- require 'fancy_open_struct'
1
+ require 'ostruct'
2
+ require 'forwardable'
3
+
4
+ class FancyOpenStruct < OpenStruct
5
+ VERSION = "0.1.3"
6
+
7
+ extend Forwardable
8
+
9
+ hash_methods = Hash.instance_methods(false) - (Hash.instance_methods(false) & OpenStruct.instance_methods(false))
10
+ def_delegators :@table, *hash_methods
11
+
12
+ def initialize(hash=nil, args={})
13
+ @recurse_over_arrays = args.fetch(:recurse_over_arrays, false)
14
+ @table = {}
15
+ if hash
16
+ for k, v in hash
17
+ @table[k.to_sym] = v
18
+ new_ostruct_member(k)
19
+ end
20
+ end
21
+ @sub_elements = {}
22
+ end
23
+
24
+ def to_h
25
+ @table.dup.update(@sub_elements) do |k, oldval, newval|
26
+ if newval.kind_of?(self.class)
27
+ newval.to_h
28
+ elsif newval.kind_of?(Array)
29
+ newval.map { |a| a.kind_of?(self.class) ? a.to_h : a }
30
+ else
31
+ raise "Cached value of unsupported type: #{newval.inspect}"
32
+ end
33
+ end
34
+ end
35
+
36
+ def new_ostruct_member(name)
37
+ name = name.to_sym
38
+ unless self.respond_to?(name)
39
+ define_singleton_method name do
40
+ v = @table[name]
41
+ if v.is_a?(Hash)
42
+ @sub_elements[name] ||= self.class.new(v, :recurse_over_arrays => @recurse_over_arrays)
43
+ elsif v.is_a?(Array) and @recurse_over_arrays
44
+ @sub_elements[name] ||= recurse_over_array v
45
+ else
46
+ v
47
+ end
48
+ end
49
+ define_singleton_method("#{name}=") { |x| modifiable[name] = x }
50
+ define_singleton_method("#{name}_as_a_hash") { @table[name] }
51
+ end
52
+ name
53
+ end
54
+
55
+ def recurse_over_array array
56
+ array.map do |a|
57
+ if a.is_a? Hash
58
+ self.class.new(a, :recurse_over_arrays => true)
59
+ elsif a.is_a? Array
60
+ recurse_over_array a
61
+ else
62
+ a
63
+ end
64
+ end
65
+ end
66
+
67
+ def debug_inspect(io = STDOUT, indent_level = 0, recursion_limit = 12)
68
+ display_recursive_open_hash(io, @table, indent_level, recursion_limit)
69
+ end
70
+
71
+ def display_recursive_open_hash(io, ostrct_or_hash, indent_level, recursion_limit)
72
+
73
+ if recursion_limit <= 0
74
+ # protection against recursive structure (like in the tests)
75
+ io.puts ' '*indent_level + '(recursion limit reached)'
76
+ else
77
+ #puts ostrct_or_hash.inspect
78
+ if ostrct_or_hash.is_a?(self.class)
79
+ ostrct_or_hash = ostrct_or_hash.marshal_dump
80
+ end
81
+
82
+ # We'll display the key values like this : key = value
83
+ # to align display, we look for the maximum key length of the data that will be displayed
84
+ # (everything except hashes)
85
+ data_indent = ostrct_or_hash \
86
+ .reject { |k, v| v.is_a?(self.class) || v.is_a?(Hash) } \
87
+ .max { |a, b| a[0].to_s.length <=> b[0].to_s.length }[0].to_s.length
88
+ # puts "max length = #{data_indent}"
89
+
90
+ ostrct_or_hash.each do |key, value|
91
+ if value.is_a?(self.class) || value.is_a?(Hash)
92
+ io.puts ' '*indent_level + key.to_s + '.'
93
+ display_recursive_open_hash(io, value, indent_level + 1, recursion_limit - 1)
94
+ else
95
+ io.puts ' '*indent_level + key.to_s + ' '*(data_indent - key.to_s.length) + ' = ' + value.inspect
96
+ end
97
+ end
98
+ end
99
+
100
+ true
101
+ end
102
+
103
+ def []=(*args)
104
+ len = args.length
105
+ raise ArgumentError, "wrong number of arguments (#{len} for 2)", caller(1) if len != 2
106
+ modifiable[new_ostruct_member(args[0].to_sym)] = args[1]
107
+ end
108
+
109
+ def method_missing(mid, *args) # :nodoc:
110
+ mname = mid.id2name
111
+ len = args.length
112
+ if mname.chomp!('=')
113
+ raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1) if len != 1
114
+ # Set up an instance method to point to the key/value in the table and set the value
115
+ modifiable[new_ostruct_member(mname.to_sym)] = args[0]
116
+ elsif @table.has_key?(mid)
117
+ # The table has apparently been modified externally, so we need to set up
118
+ # an instance method to point to the key/value in the table.
119
+ new_ostruct_member(mname.to_sym)
120
+ self.send(mid)
121
+ else
122
+ nil
123
+ end
124
+ end
125
+ end
@@ -1,125 +1 @@
1
- require 'ostruct'
2
- require 'forwardable'
3
-
4
- class FancyOpenStruct < OpenStruct
5
- VERSION = "0.1.2"
6
-
7
- extend Forwardable
8
-
9
- hash_methods = Hash.instance_methods(false) - (Hash.instance_methods(false) & OpenStruct.instance_methods(false))
10
- def_delegators :@table, *hash_methods
11
-
12
- def initialize(hash=nil, args={})
13
- @recurse_over_arrays = args.fetch(:recurse_over_arrays, false)
14
- @table = {}
15
- if hash
16
- for k, v in hash
17
- @table[k.to_sym] = v
18
- new_ostruct_member(k)
19
- end
20
- end
21
- @sub_elements = {}
22
- end
23
-
24
- def to_h
25
- @table.dup.update(@sub_elements) do |k, oldval, newval|
26
- if newval.kind_of?(self.class)
27
- newval.to_h
28
- elsif newval.kind_of?(Array)
29
- newval.map { |a| a.kind_of?(self.class) ? a.to_h : a }
30
- else
31
- raise "Cached value of unsupported type: #{newval.inspect}"
32
- end
33
- end
34
- end
35
-
36
- def new_ostruct_member(name)
37
- name = name.to_sym
38
- unless self.respond_to?(name)
39
- define_singleton_method name do
40
- v = @table[name]
41
- if v.is_a?(Hash)
42
- @sub_elements[name] ||= self.class.new(v, :recurse_over_arrays => @recurse_over_arrays)
43
- elsif v.is_a?(Array) and @recurse_over_arrays
44
- @sub_elements[name] ||= recurse_over_array v
45
- else
46
- v
47
- end
48
- end
49
- define_singleton_method("#{name}=") { |x| modifiable[name] = x }
50
- define_singleton_method("#{name}_as_a_hash") { @table[name] }
51
- end
52
- name
53
- end
54
-
55
- def recurse_over_array array
56
- array.map do |a|
57
- if a.is_a? Hash
58
- self.class.new(a, :recurse_over_arrays => true)
59
- elsif a.is_a? Array
60
- recurse_over_array a
61
- else
62
- a
63
- end
64
- end
65
- end
66
-
67
- def debug_inspect(io = STDOUT, indent_level = 0, recursion_limit = 12)
68
- display_recursive_open_hash(io, @table, indent_level, recursion_limit)
69
- end
70
-
71
- def display_recursive_open_hash(io, ostrct_or_hash, indent_level, recursion_limit)
72
-
73
- if recursion_limit <= 0
74
- # protection against recursive structure (like in the tests)
75
- io.puts ' '*indent_level + '(recursion limit reached)'
76
- else
77
- #puts ostrct_or_hash.inspect
78
- if ostrct_or_hash.is_a?(self.class)
79
- ostrct_or_hash = ostrct_or_hash.marshal_dump
80
- end
81
-
82
- # We'll display the key values like this : key = value
83
- # to align display, we look for the maximum key length of the data that will be displayed
84
- # (everything except hashes)
85
- data_indent = ostrct_or_hash \
86
- .reject { |k, v| v.is_a?(self.class) || v.is_a?(Hash) } \
87
- .max { |a, b| a[0].to_s.length <=> b[0].to_s.length }[0].to_s.length
88
- # puts "max length = #{data_indent}"
89
-
90
- ostrct_or_hash.each do |key, value|
91
- if value.is_a?(self.class) || value.is_a?(Hash)
92
- io.puts ' '*indent_level + key.to_s + '.'
93
- display_recursive_open_hash(io, value, indent_level + 1, recursion_limit - 1)
94
- else
95
- io.puts ' '*indent_level + key.to_s + ' '*(data_indent - key.to_s.length) + ' = ' + value.inspect
96
- end
97
- end
98
- end
99
-
100
- true
101
- end
102
-
103
- def []=(*args)
104
- len = args.length
105
- raise ArgumentError, "wrong number of arguments (#{len} for 2)", caller(1) if len != 2
106
- modifiable[new_ostruct_member(args[0].to_sym)] = args[1]
107
- end
108
-
109
- def method_missing(mid, *args) # :nodoc:
110
- mname = mid.id2name
111
- len = args.length
112
- if mname.chomp!('=')
113
- raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1) if len != 1
114
- # Set up an instance method to point to the key/value in the table and set the value
115
- modifiable[new_ostruct_member(mname.to_sym)] = args[0]
116
- elsif @table.has_key?(mid)
117
- # The table has apparently been modified externally, so we need to set up
118
- # an instance method to point to the key/value in the table.
119
- new_ostruct_member(mname.to_sym)
120
- self.send(mid)
121
- else
122
- nil
123
- end
124
- end
125
- end
1
+ require 'fancy-open-struct'
@@ -5,6 +5,12 @@ require 'pry'
5
5
 
6
6
  if ENV['COVERAGE'] == 'true'
7
7
  require 'simplecov'
8
+ require 'coveralls'
9
+
10
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
11
+ SimpleCov::Formatter::HTMLFormatter,
12
+ Coveralls::SimpleCov::Formatter
13
+ ]
8
14
  SimpleCov.start
9
15
  end
10
16
 
@@ -13,6 +19,7 @@ end
13
19
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
14
20
 
15
21
  RSpec.configure do |config|
16
- config.filter_run focus: true
22
+ config.treat_symbols_as_metadata_keys_with_true_values = true
17
23
  config.run_all_when_everything_filtered = true
24
+ config.filter_run :focus
18
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fancy-open-struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,10 +9,10 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-26 00:00:00.000000000 Z
12
+ date: 2014-05-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rspec
15
+ name: bundler
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
@@ -28,7 +28,23 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
- name: bundler
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
32
48
  requirement: !ruby/object:Gem::Requirement
33
49
  none: false
34
50
  requirements:
@@ -75,12 +91,102 @@ dependencies:
75
91
  - - ! '>='
76
92
  - !ruby/object:Gem::Version
77
93
  version: '0'
78
- description: ! "FancyOpenStruct is a subclass of OpenStruct, and is a variant of RecursiveOpenStruct.\nIt
79
- differs from OpenStruct in that it allows nested hashes to be treated in a recursive\nfashion,
80
- and it also provides Hash methods for getting and setting values.\n\nFor example:\n\n
81
- \ fos = FancyOpenStruct.new({ :a => { :b => 'c' } })\n fos.a.b # 'c'\n\n fos.foo
82
- = 'bar'\n fos[:foo] # 'bar'\n\n fos.length # 2\n\nAlso, nested hashes can
83
- still be accessed as hashes:\n\n fos.a_as_a_hash # { :b => 'c' }\n\n"
94
+ - !ruby/object:Gem::Dependency
95
+ name: coveralls
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: guard
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: guard-rspec
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: guard-bundler
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: simplecov-multi
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ description: ! 'FancyOpenStruct is a subclass of OpenStruct, and is a variant of RecursiveOpenStruct.
175
+
176
+ This allows you to convert nested hashes into a structure where keys and values
177
+ can be
178
+
179
+ navigated and modified via dot-syntax, like: foo.bar = :something. This particular
180
+ gem
181
+
182
+ also adds support for Hash methods (such as length or merge), and also allows you
183
+ to
184
+
185
+ access and modify the data structure the same way that you would handle a normal
186
+ Hash.
187
+
188
+
189
+ '
84
190
  email: tchapin@gmail.com
85
191
  executables: []
86
192
  extensions: []
@@ -88,9 +194,11 @@ extra_rdoc_files:
88
194
  - LICENSE.txt
89
195
  - README.rdoc
90
196
  files:
197
+ - .coveralls.yml
91
198
  - .document
92
199
  - .gitignore
93
200
  - .rspec
201
+ - .travis.yml
94
202
  - Gemfile
95
203
  - LICENSE.txt
96
204
  - README.rdoc