[ruby/ostruct] Refactor handling of frozen OpenStruct. Simplify new_ostruct_member!
This commit is contained in:
parent
5e7ec05319
commit
ebb8de7302
@ -93,9 +93,7 @@ class OpenStruct
|
|||||||
@table = {}
|
@table = {}
|
||||||
if hash
|
if hash
|
||||||
hash.each_pair do |k, v|
|
hash.each_pair do |k, v|
|
||||||
k = k.to_sym
|
self[k] = v
|
||||||
@table[k] = v
|
|
||||||
new_ostruct_member!(k)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -165,42 +163,31 @@ class OpenStruct
|
|||||||
@table.each_key{|key| new_ostruct_member!(key)}
|
@table.each_key{|key| new_ostruct_member!(key)}
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Used internally to check if the OpenStruct is able to be
|
|
||||||
# modified before granting access to the internal Hash table to be modified.
|
|
||||||
#
|
|
||||||
def modifiable? # :nodoc:
|
|
||||||
begin
|
|
||||||
@modifiable = true
|
|
||||||
rescue
|
|
||||||
raise FrozenError, "can't modify frozen #{self.class}", caller(3)
|
|
||||||
end
|
|
||||||
@table
|
|
||||||
end
|
|
||||||
private :modifiable?
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Used internally to defined properties on the
|
# Used internally to defined properties on the
|
||||||
# OpenStruct. It does this by using the metaprogramming function
|
# OpenStruct. It does this by using the metaprogramming function
|
||||||
# define_singleton_method for both the getter method and the setter method.
|
# define_singleton_method for both the getter method and the setter method.
|
||||||
#
|
#
|
||||||
def new_ostruct_member!(name) # :nodoc:
|
def new_ostruct_member!(name) # :nodoc:
|
||||||
name = name.to_sym
|
|
||||||
unless respond_to?(name)
|
unless respond_to?(name)
|
||||||
define_singleton_method(name) { @table[name] }
|
define_singleton_method(name) { @table[name] }
|
||||||
define_singleton_method("#{name}=") {|x| modifiable?[name] = x}
|
define_singleton_method("#{name}=") {|x| @table[name] = x}
|
||||||
end
|
end
|
||||||
name
|
|
||||||
end
|
end
|
||||||
private :new_ostruct_member!
|
private :new_ostruct_member!
|
||||||
|
|
||||||
|
def freeze
|
||||||
|
@table.freeze
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
def method_missing(mid, *args) # :nodoc:
|
def method_missing(mid, *args) # :nodoc:
|
||||||
len = args.length
|
len = args.length
|
||||||
if mname = mid[/.*(?==\z)/m]
|
if mname = mid[/.*(?==\z)/m]
|
||||||
if len != 1
|
if len != 1
|
||||||
raise ArgumentError, "wrong number of arguments (given #{len}, expected 1)", caller(1)
|
raise ArgumentError, "wrong number of arguments (given #{len}, expected 1)", caller(1)
|
||||||
end
|
end
|
||||||
modifiable?[new_ostruct_member!(mname)] = args[0]
|
self[mname]= args[0]
|
||||||
elsif len == 0
|
elsif len == 0
|
||||||
elsif @table.key?(mid)
|
elsif @table.key?(mid)
|
||||||
raise ArgumentError, "wrong number of arguments (given #{len}, expected 0)"
|
raise ArgumentError, "wrong number of arguments (given #{len}, expected 0)"
|
||||||
@ -240,7 +227,9 @@ class OpenStruct
|
|||||||
# person.age # => 42
|
# person.age # => 42
|
||||||
#
|
#
|
||||||
def []=(name, value)
|
def []=(name, value)
|
||||||
modifiable?[new_ostruct_member!(name)] = value
|
name = name.to_sym
|
||||||
|
new_ostruct_member!(name)
|
||||||
|
@table[name] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
# :call-seq:
|
# :call-seq:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user