cloudinary 1.29.0 → 2.0.0

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.
@@ -1,284 +0,0 @@
1
- #
2
- # = ostruct.rb: OpenStruct implementation
3
- #
4
- # Author:: Yukihiro Matsumoto
5
- # Documentation:: Gavin Sinclair
6
- #
7
- # OpenStruct allows the creation of data objects with arbitrary attributes.
8
- # See OpenStruct for an example.
9
- #
10
-
11
- #
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.
16
- #
17
- # == Examples:
18
- #
19
- # require 'ostruct'
20
- #
21
- # person = OpenStruct.new
22
- # person.name = "John Smith"
23
- # person.age = 70
24
- # person.pension = 300
25
- #
26
- # puts person.name # -> "John Smith"
27
- # puts person.age # -> 70
28
- # puts person.address # -> nil
29
- #
30
- # An OpenStruct employs a Hash internally to store the methods and values and
31
- # can even be initialized with one:
32
- #
33
- # australia = OpenStruct.new(:country => "Australia", :population => 20_000_000)
34
- # p australia # -> <OpenStruct country="Australia" population=20000000>
35
- #
36
- # Hash keys with spaces or characters that would normally not be able to use for
37
- # method calls (e.g. ()[]*) will not be immediately available on the
38
- # OpenStruct object as a method for retrieval or assignment, but can be still be
39
- # reached through the Object#send method.
40
- #
41
- # measurements = OpenStruct.new("length (in inches)" => 24)
42
- # measurements.send("length (in inches)") # -> 24
43
- #
44
- # data_point = OpenStruct.new(:queued? => true)
45
- # data_point.queued? # -> true
46
- # data_point.send("queued?=",false)
47
- # data_point.queued? # -> false
48
- #
49
- # Removing the presence of a method requires the execution the delete_field
50
- # method as setting the property value to +nil+ will not remove the method.
51
- #
52
- # first_pet = OpenStruct.new(:name => 'Rowdy', :owner => 'John Smith')
53
- # first_pet.owner = nil
54
- # second_pet = OpenStruct.new(:name => 'Rowdy')
55
- #
56
- # first_pet == second_pet # -> false
57
- #
58
- # first_pet.delete_field(:owner)
59
- # first_pet == second_pet # -> true
60
- #
61
- #
62
- # == Implementation:
63
- #
64
- # An OpenStruct utilizes Ruby's method lookup structure to and find and define
65
- # the necessary methods for properties. This is accomplished through the method
66
- # method_missing and define_method.
67
- #
68
- # This should be a consideration if there is a concern about the performance of
69
- # the objects that are created, as there is much more overhead in the setting
70
- # of these properties compared to using a Hash or a Struct.
71
- #
72
- class OpenStruct
73
- #
74
- # Creates a new OpenStruct object. By default, the resulting OpenStruct
75
- # object will have no attributes.
76
- #
77
- # The optional +hash+, if given, will generate attributes and values
78
- # (can be a Hash, an OpenStruct or a Struct).
79
- # For example:
80
- #
81
- # require 'ostruct'
82
- # hash = { "country" => "Australia", :population => 20_000_000 }
83
- # data = OpenStruct.new(hash)
84
- #
85
- # p data # -> <OpenStruct country="Australia" population=20000000>
86
- #
87
- def initialize(hash=nil)
88
- @table = {}
89
- if hash
90
- hash.each_pair do |k, v|
91
- k = k.to_sym
92
- @table[k] = v
93
- new_ostruct_member(k)
94
- end
95
- end
96
- end
97
-
98
- # Duplicate an OpenStruct object members.
99
- def initialize_copy(orig)
100
- super
101
- @table = @table.dup
102
- @table.each_key{|key| new_ostruct_member(key)}
103
- end
104
-
105
- #
106
- # Converts the OpenStruct to a hash with keys representing
107
- # each attribute (as symbols) and their corresponding values
108
- # Example:
109
- #
110
- # require 'ostruct'
111
- # data = OpenStruct.new("country" => "Australia", :population => 20_000_000)
112
- # data.to_h # => {:country => "Australia", :population => 20000000 }
113
- #
114
- def to_h
115
- @table.dup
116
- end
117
-
118
- #
119
- # Yields all attributes (as a symbol) along with the corresponding values
120
- # or returns an enumerator if not block is given.
121
- # Example:
122
- #
123
- # require 'ostruct'
124
- # data = OpenStruct.new("country" => "Australia", :population => 20_000_000)
125
- # data.each_pair.to_a # => [[:country, "Australia"], [:population, 20000000]]
126
- #
127
- def each_pair
128
- return to_enum __method__ unless block_given?
129
- @table.each_pair{|p| yield p}
130
- end
131
-
132
- #
133
- # Provides marshalling support for use by the Marshal library.
134
- #
135
- def marshal_dump
136
- @table
137
- end
138
-
139
- #
140
- # Provides marshalling support for use by the Marshal library.
141
- #
142
- def marshal_load(x)
143
- @table = x
144
- @table.each_key{|key| new_ostruct_member(key)}
145
- end
146
-
147
- #
148
- # Used internally to check if the OpenStruct is able to be
149
- # modified before granting access to the internal Hash table to be modified.
150
- #
151
- def modifiable
152
- begin
153
- @modifiable = true
154
- rescue
155
- raise TypeError, "can't modify frozen #{self.class}", caller(3)
156
- end
157
- @table
158
- end
159
- protected :modifiable
160
-
161
- #
162
- # Used internally to defined properties on the
163
- # OpenStruct. It does this by using the metaprogramming function
164
- # define_singleton_method for both the getter method and the setter method.
165
- #
166
- def new_ostruct_member(name)
167
- name = name.to_sym
168
- unless respond_to?(name)
169
- define_singleton_method(name) { @table[name] }
170
- define_singleton_method("#{name}=") { |x| modifiable[name] = x }
171
- end
172
- name
173
- end
174
- protected :new_ostruct_member
175
-
176
- def method_missing(mid, *args) # :nodoc:
177
- mname = mid.id2name
178
- len = args.length
179
- if mname.chomp!('=')
180
- if len != 1
181
- raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
182
- end
183
- modifiable[new_ostruct_member(mname)] = args[0]
184
- elsif len == 0
185
- @table[mid]
186
- else
187
- raise NoMethodError, "undefined method `#{mid}' for #{self}", caller(1)
188
- end
189
- end
190
-
191
- # Returns the value of a member.
192
- #
193
- # person = OpenStruct.new('name' => 'John Smith', 'age' => 70)
194
- # person[:age] # => 70, same as ostruct.age
195
- #
196
- def [](name)
197
- @table[name.to_sym]
198
- end
199
-
200
- #
201
- # Sets the value of a member.
202
- #
203
- # person = OpenStruct.new('name' => 'John Smith', 'age' => 70)
204
- # person[:age] = 42 # => equivalent to ostruct.age = 42
205
- # person.age # => 42
206
- #
207
- def []=(name, value)
208
- modifiable[new_ostruct_member(name)] = value
209
- end
210
-
211
- #
212
- # Remove the named field from the object. Returns the value that the field
213
- # contained if it was defined.
214
- #
215
- # require 'ostruct'
216
- #
217
- # person = OpenStruct.new('name' => 'John Smith', 'age' => 70)
218
- #
219
- # person.delete_field('name') # => 'John Smith'
220
- #
221
- def delete_field(name)
222
- sym = name.to_sym
223
- singleton_class.__send__(:remove_method, sym, "#{name}=")
224
- @table.delete sym
225
- end
226
-
227
- InspectKey = :__inspect_key__ # :nodoc:
228
-
229
- #
230
- # Returns a string containing a detailed summary of the keys and values.
231
- #
232
- def inspect
233
- str = "#<#{self.class}"
234
-
235
- ids = (Thread.current[InspectKey] ||= [])
236
- if ids.include?(object_id)
237
- return str << ' ...>'
238
- end
239
-
240
- ids << object_id
241
- begin
242
- first = true
243
- for k,v in @table
244
- str << "," unless first
245
- first = false
246
- str << " #{k}=#{v.inspect}"
247
- end
248
- return str << '>'
249
- ensure
250
- ids.pop
251
- end
252
- end
253
- alias :to_s :inspect
254
-
255
- attr_reader :table # :nodoc:
256
- protected :table
257
-
258
- #
259
- # Compares this object and +other+ for equality. An OpenStruct is equal to
260
- # +other+ when +other+ is an OpenStruct and the two objects' Hash tables are
261
- # equal.
262
- #
263
- def ==(other)
264
- return false unless other.kind_of?(OpenStruct)
265
- @table == other.table
266
- end
267
-
268
- #
269
- # Compares this object and +other+ for equality. An OpenStruct is eql? to
270
- # +other+ when +other+ is an OpenStruct and the two objects' Hash tables are
271
- # eql?.
272
- #
273
- def eql?(other)
274
- return false unless other.kind_of?(OpenStruct)
275
- @table.eql?(other.table)
276
- end
277
-
278
- # Compute a hash-code for this OpenStruct.
279
- # Two hashes with the same content will have the same hash code
280
- # (and will be eql?).
281
- def hash
282
- @table.hash
283
- end
284
- end