Class: FancyOpenStruct
- Inherits:
-
OpenStruct
- Object
- OpenStruct
- FancyOpenStruct
- Extended by:
- Forwardable
- Defined in:
- lib/fancy-open-struct.rb,
lib/fancy-open-struct/version.rb
Constant Summary collapse
- VERSION =
"0.3.0"
Instance Method Summary collapse
-
#[](key) ⇒ Object
Hash getter method which translates the key to a Symbol.
-
#[]=(key, value) ⇒ Object
Hash setter method which translates the key to a Symbol and also creates a getter method (OpenStruct member) for accessing the key/value later via dot syntax.
- #debug_inspect(options = {}) ⇒ Object
-
#initialize(hash = nil, args = {}) ⇒ FancyOpenStruct
constructor
A new instance of FancyOpenStruct.
- #new_ostruct_member(name) ⇒ Object
- #recurse_over_array(array) ⇒ Object
- #to_h ⇒ Object (also: #to_hash)
Constructor Details
#initialize(hash = nil, args = {}) ⇒ FancyOpenStruct
Returns a new instance of FancyOpenStruct.
13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/fancy-open-struct.rb', line 13 def initialize(hash=nil, args={}) @recurse_over_arrays = args.fetch(:recurse_over_arrays, false) @table = {} if hash for k, v in hash @table[k.to_sym] = v new_ostruct_member(k) end end @sub_elements = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(mid, *args) ⇒ Object (private)
Dynamically handle any attempts to get or set values via dot syntax if the OpenStruct member methods haven’t already been created
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/fancy-open-struct.rb', line 89 def method_missing(mid, *args) # :nodoc: mname = mid.id2name len = args.length if mname.chomp!('=') raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1) if len != 1 # Set up an instance method to point to the key/value in the table and set the value modifiable[new_ostruct_member(mname.to_sym)] = args[0] elsif @table.has_key?(mid) # The table has apparently been modified externally, so we need to set up # an instance method to point to the key/value in the table. new_ostruct_member(mname.to_sym) self.send(mid) else nil end end |
Instance Method Details
#[](key) ⇒ Object
Hash getter method which translates the key to a Symbol
75 76 77 |
# File 'lib/fancy-open-struct.rb', line 75 def [](key) @table[key.to_sym] end |
#[]=(key, value) ⇒ Object
Hash setter method which translates the key to a Symbol and also creates a getter method (OpenStruct member) for accessing the key/value later via dot syntax
81 82 83 |
# File 'lib/fancy-open-struct.rb', line 81 def []=(key, value) modifiable[new_ostruct_member(key.to_sym)] = value end |
#debug_inspect(options = {}) ⇒ Object
68 69 70 71 72 |
# File 'lib/fancy-open-struct.rb', line 68 def debug_inspect( = {}) # Refer to the "Awesome Print" gem documentation for information about which options are available # The awesome_print gem can be found at https://rubygems.org/gems/awesome_print ap(@table, ) end |
#new_ostruct_member(name) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/fancy-open-struct.rb', line 25 def new_ostruct_member(name) name = name.to_sym unless self.respond_to?(name) define_singleton_method name do v = @table[name] if v.is_a?(Hash) @sub_elements[name] ||= self.class.new(v, :recurse_over_arrays => @recurse_over_arrays) elsif v.is_a?(Array) and @recurse_over_arrays @sub_elements[name] ||= recurse_over_array v else v end end define_singleton_method("#{name}=") { |x| modifiable[name] = x } define_singleton_method("#{name}_as_a_hash") { @table[name] } end name end |
#recurse_over_array(array) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/fancy-open-struct.rb', line 44 def recurse_over_array(array) array.map do |a| if a.is_a? Hash self.class.new(a, :recurse_over_arrays => true) elsif a.is_a? Array recurse_over_array a else a end end end |
#to_h ⇒ Object Also known as: to_hash
56 57 58 59 60 61 62 63 64 |
# File 'lib/fancy-open-struct.rb', line 56 def to_h @table.dup.update(@sub_elements) do |k, oldval, newval| if newval.kind_of?(self.class) newval.to_h elsif newval.kind_of?(Array) newval.map { |a| a.kind_of?(self.class) ? a.to_h : a } end end end |