rubysl-ostruct 1.0.0 → 2.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cec4600c9a826de169dba5d1d1fc1001deb47131
4
- data.tar.gz: 2c55660cb71f7a1e0e4f0def92394ad110403c65
3
+ metadata.gz: 25ef06576d34ac774a46a52f900e3b3057d0e9d5
4
+ data.tar.gz: 365deda9a3abdef2615f0057f3e0a7f229a7f24b
5
5
  SHA512:
6
- metadata.gz: eadd488f253fda93f4bbe152d78c4e1b197d80f64da0b1cd0ab8edfbc58564641ca5161ee01fef51791ee746212dd68d8a7f10504b53ea6e88578605eddcf609
7
- data.tar.gz: bd53d995542bf0d11e579abfd4b219ef6565b2384f449468efe22cd3a92f943534889ed66814b9b243b91ca9906467d5e5d051cd3a51c010234fea3d02eb0473
6
+ metadata.gz: bdce30cac56bc487845665ef339d436dcc8147be59bbb9587c2b1a1a2a7aad5486153869a72a05533ad29db3b26ee715f08d853633a3f241af9f6bf898f4ad53
7
+ data.tar.gz: 407fe1f2dba5e83592e9701eefa25bf429534676db0d9ab297c948cf7e559f14b22522c724a2c2d418c0671480597fa8ab2741fdf12c4b8ccd4b11a88b85ecfb
@@ -1,7 +1,6 @@
1
1
  language: ruby
2
2
  env:
3
3
  - RUBYLIB=lib
4
- script: bundle exec mspec
4
+ script: bundle exec mspec spec
5
5
  rvm:
6
- - 1.8.7
7
- - rbx-nightly-18mode
6
+ - rbx-nightly-19mode
@@ -9,31 +9,79 @@
9
9
  #
10
10
 
11
11
  #
12
- # OpenStruct allows you to create data objects and set arbitrary attributes.
13
- # For example:
12
+ # An OpenStruct is a data structure, similar to a Hash, that allows the
13
+ # definition of arbitrary attributes with their accompanying values. This is
14
+ # accomplished by using Ruby's metaprogramming to define methods on the class
15
+ # itself.
14
16
  #
15
- # require 'ostruct'
17
+ # == Examples:
16
18
  #
17
- # record = OpenStruct.new
18
- # record.name = "John Smith"
19
- # record.age = 70
20
- # record.pension = 300
21
- #
22
- # puts record.name # -> "John Smith"
23
- # puts record.address # -> nil
19
+ # require 'ostruct'
24
20
  #
25
- # It is like a hash with a different way to access the data. In fact, it is
26
- # implemented with a hash, and you can initialize it with one.
21
+ # person = OpenStruct.new
22
+ # person.name = "John Smith"
23
+ # person.age = 70
24
+ # person.pension = 300
27
25
  #
28
- # hash = { "country" => "Australia", :population => 20_000_000 }
29
- # data = OpenStruct.new(hash)
26
+ # puts person.name # -> "John Smith"
27
+ # puts person.age # -> 70
28
+ # puts person.address # -> nil
30
29
  #
31
- # p data # -> <OpenStruct country="Australia" population=20000000>
30
+ # An OpenStruct employs a Hash internally to store the methods and values and
31
+ # can even be initialized with one:
32
+ #
33
+ # country_data = { :country => "Australia", :population => 20_000_000 }
34
+ # australia = OpenStruct.new(country_data)
35
+ # p australia # -> <OpenStruct country="Australia" population=20000000>
36
+ #
37
+ # You may also define the hash in the initialization call:
38
+ #
39
+ # australia = OpenStruct.new(:country => "Australia", :population => 20_000_000)
40
+ # p australia # -> <OpenStruct country="Australia" population=20000000>
41
+ #
42
+ # Hash keys with spaces or characters that would normally not be able to use for
43
+ # method calls (e.g. ()[]*) will not be immediately available on the
44
+ # OpenStruct object as a method for retrieval or assignment, but can be still be
45
+ # reached through the Object#send method.
46
+ #
47
+ # measurements = OpenStruct.new("length (in inches)" => 24)
48
+ # measurements.send("length (in inches)") # -> 24
49
+ #
50
+ # data_point = OpenStruct.new(:queued? => true)
51
+ # data_point.queued? # -> true
52
+ # data_point.send("queued?=",false)
53
+ # data_point.queued? # -> false
54
+ #
55
+ # Removing the presence of a method requires the execution the delete_field
56
+ # method as setting the property value to +nil+ will not remove the method.
57
+ #
58
+ # first_pet = OpenStruct.new(:name => 'Rowdy', :owner => 'John Smith')
59
+ # first_pet.owner = nil
60
+ # second_pet = OpenStruct.new(:name => 'Rowdy')
61
+ #
62
+ # first_pet == second_pet # -> false
63
+ #
64
+ # first_pet.delete_field(:owner)
65
+ # first_pet == second_pet # -> true
66
+ #
67
+ #
68
+ # == Implementation:
69
+ #
70
+ # An OpenStruct utilizes Ruby's method lookup structure to and find and define
71
+ # the necessary methods for properties. This is accomplished through the method
72
+ # method_missing and define_method.
73
+ #
74
+ # This should be a consideration if there is a concern about the performance of
75
+ # the objects that are created, as there is much more overhead in the setting
76
+ # of these properties compared to using a Hash or a Struct.
32
77
  #
33
78
  class OpenStruct
34
79
  #
35
- # Create a new OpenStruct object. The optional +hash+, if given, will
36
- # generate attributes and values. For example.
80
+ # Creates a new OpenStruct object. By default, the resulting OpenStruct
81
+ # object will have no attributes.
82
+ #
83
+ # The optional +hash+, if given, will generate attributes and values.
84
+ # For example:
37
85
  #
38
86
  # require 'ostruct'
39
87
  # hash = { "country" => "Australia", :population => 20_000_000 }
@@ -41,7 +89,11 @@ class OpenStruct
41
89
  #
42
90
  # p data # -> <OpenStruct country="Australia" population=20000000>
43
91
  #
44
- # By default, the resulting OpenStruct object will have no attributes.
92
+ # You may also define the hash in the initialization call:
93
+ #
94
+ # australia = OpenStruct.new(:country => "Australia",
95
+ # :population => 20_000_000)
96
+ # p australia # -> <OpenStruct country="Australia" population=20000000>
45
97
  #
46
98
  def initialize(hash=nil)
47
99
  @table = {}
@@ -53,28 +105,72 @@ class OpenStruct
53
105
  end
54
106
  end
55
107
 
56
- # Duplicate an OpenStruct object members.
108
+ # Duplicate an OpenStruct object members.
57
109
  def initialize_copy(orig)
58
110
  super
59
111
  @table = @table.dup
112
+ @table.each_key { |key| new_ostruct_member(key) }
113
+ end
114
+
115
+ #
116
+ # Converts the OpenStruct to a hash with keys representing
117
+ # each attribute (as symbols) and their corresponding values
118
+ def to_h
119
+ @table.dup
60
120
  end
61
121
 
122
+ #
123
+ # Provides marshalling support for use by the Marshal library. Returning the
124
+ # underlying Hash table that contains the functions defined as the keys and
125
+ # the values assigned to them.
126
+ #
127
+ # require 'ostruct'
128
+ #
129
+ # person = OpenStruct.new
130
+ # person.name = 'John Smith'
131
+ # person.age = 70
132
+ #
133
+ # person.marshal_dump # => { :name => 'John Smith', :age => 70 }
134
+ #
62
135
  def marshal_dump
63
136
  @table
64
137
  end
138
+
139
+ #
140
+ # Provides marshalling support for use by the Marshal library. Accepting
141
+ # a Hash of keys and values which will be used to populate the internal table
142
+ #
143
+ # require 'ostruct'
144
+ #
145
+ # event = OpenStruct.new
146
+ # hash = { 'time' => Time.now, 'title' => 'Birthday Party' }
147
+ # event.marshal_load(hash)
148
+ # event.title # => 'Birthday Party'
149
+ #
65
150
  def marshal_load(x)
66
151
  @table = x
67
152
  @table.each_key{|key| new_ostruct_member(key)}
68
153
  end
69
154
 
155
+ #
156
+ # #modifiable is used internally to check if the OpenStruct is able to be
157
+ # modified before granting access to the internal Hash table to be augmented.
158
+ #
70
159
  def modifiable
71
- if self.frozen?
72
- raise TypeError, "can't modify frozen #{self.class}", caller(2)
160
+ begin
161
+ @modifiable = true
162
+ rescue
163
+ raise TypeError, "can't modify frozen #{self.class}", caller(3)
73
164
  end
74
165
  @table
75
166
  end
76
167
  protected :modifiable
77
168
 
169
+ #
170
+ # new_ostruct_member is used internally to defined properties on the
171
+ # OpenStruct. It does this by using the metaprogramming function
172
+ # define_method for both the getter method and the setter method.
173
+ #
78
174
  def new_ostruct_member(name)
79
175
  name = name.to_sym
80
176
  unless self.respond_to?(name)
@@ -89,23 +185,32 @@ class OpenStruct
89
185
  def method_missing(mid, *args) # :nodoc:
90
186
  mname = mid.id2name
91
187
  len = args.length
92
- if mname.chomp!('=') && mname != "[]"
188
+ if mname.chomp!('=') && mid != :[]=
93
189
  if len != 1
94
190
  raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
95
191
  end
96
192
  modifiable[new_ostruct_member(mname)] = args[0]
97
- elsif len == 0
193
+ elsif len == 0 && mid != :[]
98
194
  @table[mid]
99
195
  else
100
- raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1)
196
+ raise NoMethodError, "undefined method `#{mid}' for #{self}", caller(1)
101
197
  end
102
198
  end
103
199
 
104
200
  #
105
- # Remove the named field from the object.
201
+ # Remove the named field from the object. Returning the value that the field
202
+ # contained if it has defined.
203
+ #
204
+ # require 'ostruct'
205
+ #
206
+ # person = OpenStruct.new('name' => 'John Smith', 'age' => 70)
207
+ #
208
+ # person.delete_field('name') # => 'John Smith'
106
209
  #
107
210
  def delete_field(name)
108
- @table.delete name.to_sym
211
+ sym = name.to_sym
212
+ @table.delete sym
213
+ singleton_class.__send__(:remove_method, sym, "#{name}=")
109
214
  end
110
215
 
111
216
  InspectKey = :__inspect_key__ # :nodoc:
@@ -140,7 +245,9 @@ class OpenStruct
140
245
  protected :table
141
246
 
142
247
  #
143
- # Compare this object and +other+ for equality.
248
+ # Compares this object and +other+ for equality. An OpenStruct is equal to
249
+ # +other+ when +other+ is an OpenStruct and the two object's Hash tables are
250
+ # equal.
144
251
  #
145
252
  def ==(other)
146
253
  return false unless(other.kind_of?(OpenStruct))
@@ -1,5 +1,5 @@
1
1
  module RubySL
2
- module OpenStruct
3
- VERSION = "1.0.0"
2
+ class OpenStruct
3
+ VERSION = "2.0.4"
4
4
  end
5
5
  end
@@ -16,6 +16,9 @@ Gem::Specification.new do |spec|
16
16
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
17
  spec.require_paths = ["lib"]
18
18
 
19
+ spec.required_ruby_version = "~> 2.0"
20
+
19
21
  spec.add_development_dependency "bundler", "~> 1.3"
20
22
  spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "mspec", "~> 1.5"
21
24
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubysl-ostruct
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Shirai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-27 00:00:00.000000000 Z
11
+ date: 2013-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
41
55
  description: Ruby standard library ostruct.
42
56
  email:
43
57
  - brixen@gmail.com
@@ -84,9 +98,9 @@ require_paths:
84
98
  - lib
85
99
  required_ruby_version: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '>='
101
+ - - ~>
88
102
  - !ruby/object:Gem::Version
89
- version: '0'
103
+ version: '2.0'
90
104
  required_rubygems_version: !ruby/object:Gem::Requirement
91
105
  requirements:
92
106
  - - '>='
@@ -117,3 +131,4 @@ test_files:
117
131
  - spec/table_spec.rb
118
132
  - spec/to_h_spec.rb
119
133
  - spec/to_s_spec.rb
134
+ has_rdoc: