OpenStruct
¶ ↑
The constructor can take a priming hash.
o = OpenStruct.new(:a=>1,:b=>2) o.a #=> 1 o.b #=> 2
It can also take a default procedure, just like an Hash.
o = OpenStruct.new{ |h,k| h[k] = {} } o.a #=> {}
Common usage of an OpenStruct
is via the missing method dynamic calls. An entry can be made by making an assignment and read back via the same method call.
o = OpenStruct.new o.a = 1 o.a #=> 1
Key existence can also be checked by adding a question mark.
o.a? #=> true
OpenStruct
“circa 2” has a CRUDified design. There are only a few primary methods that handle access to the underlying table and all other methods route through these. Primarily they are #read!
, #store!
, #delete!
as well as #key?
and #keys!
.
o = OpenStruct.new o.store!(:a, 1) o.read!(:a) #=> 1 o.key?(:a) #=> true o.keys! #=> [:a] o.delete!(:a) o.empty? #=> true
OpenStruct
offers a number of methods to access the underlying table. Each of these ends in a exlimation mark, and include #fetch!
, #update!
, and merge!
.
o = OpenStruct.new o.update!(:a=>1, :b=>2) o.fetch!(:a) #=> 1
Note that #merge!
is akin to Hash#merge
, not Hash#merge!
–it does not act in-place.
o = OpenStruct.new x = o.merge!(:a=>1, :b=>2) o.a #=> nil x.a #=> 1
OpenStruct
also supports Hash-like read and write operators, [] and []=.
o = OpenStruct.new o[:a] = 1 o[:a] #=> 1 o.a #=> 1
The OpenStruct
object can be converted to a simple Hash, via #to_h
.
o = OpenStruct.new(:a=>1,:b=>2) o.to_h #=> {:a=>1, :b=>2}
Iteration can be achieved with #each!
.
o = OpenStruct.new(:a=>1,:b=>2) a = {} o.each! do |k,v| a[k] = v end a #=> {:a=>1, :b=>2}
Currently all Enumerable methods will work if suffixed with an exclemation mark. But they operate directly on the underlying Hash rather than at the level of the “CRUDified” OpenStruct
itself.
o = OpenStruct.new(:a=>1,:b=>2) a = o.map!{ |k,v| [k,v] } a #=> [[:a,1], [:b,2]]
In most cases this will work fine. But it may cause some minor discrepencies in how Enumerable methods work presently and how ultimatley they should work. A fix is a bit tricky so this is an endeavor left a future release. In the rare cases where it does matters, proper enumeratorion can be assured by calling #to_enum
first.
o = OpenStruct.new(:a=>1,:b=>2) a = {} o.to_enum.each do |k,v| a[k] = v end a #=> {:a=>1, :b=>2}
OpenStruct
also has a unique method called #key!
that is used to check for an key entry, and raise a KeyError if it not found.
o = OpenStruct.new expect KeyError do o.key!(:x) end
Lastly, OpenStruct
has a convenient feature for creating cascading OpenStructs.
o = OpenStruct.cascade o.x.a = 1 o.x.a #=> 1 OpenStruct.assert === o.a