Class: Jsof::WrapObject
- Inherits:
-
Object
- Object
- Jsof::WrapObject
- Defined in:
- lib/jsof/wrap_object.rb
Overview
Wrapper class for Object(Hash).
Class Method Summary collapse
-
.assignable?(val) ⇒ Boolean
Check value can be wrapped by this type.
-
.define_attr(sym, type: nil) ⇒ Object
Define explicit accessor methods for attribute(property).
- .inherited(subclass) ⇒ Object
-
.initialize ⇒ Object
Place to define properties by define_attr.
- .initialized=(val) ⇒ Object
-
.initialized? ⇒ Boolean
Whether self.initialize was already called or not.
- .resolve_typeof_properties ⇒ Object
-
.typeof_properties ⇒ Hash{Symbol => Class, Jsof::WrapArrayType, Proc}
Explicitly defined properties.
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, val) ⇒ Object
-
#clear_internal ⇒ Object
Clean internal cache.
-
#initialize(obj = {}, allow_implicit_attr: nil) ⇒ WrapObject
constructor
Create wrapper for Hash.
-
#internal_object ⇒ Object
Return reference to wrapped array.
- #method_missing(name, *args) ⇒ Object
-
#to_h ⇒ Object
Return reference to wrapped array.
-
#to_hash ⇒ Object
Return reference to wrapped array.
Constructor Details
#initialize(obj = {}, allow_implicit_attr: nil) ⇒ WrapObject
Create wrapper for Hash.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/jsof/wrap_object.rb', line 9 def initialize(obj = {}, allow_implicit_attr: nil) unless self.class.initialized? self.class.resolve_typeof_properties self.class.initialize() self.class.initialized = true end @internal_object = obj @wrapped = {} @is_allow_implicit_attr = allow_implicit_attr if @is_allow_implicit_attr == nil @is_allow_implicit_attr = self.class.typeof_properties.empty? end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
115 116 117 118 119 120 121 122 123 |
# File 'lib/jsof/wrap_object.rb', line 115 def method_missing(name, *args) raise NoMethodError.new("", name) unless @is_allow_implicit_attr if name.to_s.end_with?('=') self[name.to_s[0...-1].to_sym] = args.first else self[name] end end |
Class Method Details
.assignable?(val) ⇒ Boolean
Check value can be wrapped by this type. TODO: Currently, will not check properties’s types, but this behavior might be changed in future version.
76 77 78 79 80 81 |
# File 'lib/jsof/wrap_object.rb', line 76 def self.assignable?(val) # TODO: return true if val == nil return true if val.is_a? Hash false end |
.define_attr(sym, type: nil) ⇒ Object
Define explicit accessor methods for attribute(property).
62 63 64 65 66 67 68 69 70 |
# File 'lib/jsof/wrap_object.rb', line 62 def self.define_attr(sym, type: nil) @typeof_properties[sym] = type self.define_method(sym) do self[sym] end self.define_method((sym.to_s + "=").to_sym) do |val| self[sym] = val end end |
.inherited(subclass) ⇒ Object
25 26 27 |
# File 'lib/jsof/wrap_object.rb', line 25 def self.inherited(subclass) subclass.instance_variable_set(:@typeof_properties, @typeof_properties.dup) end |
.initialize ⇒ Object
Place to define properties by define_attr. Override this for derived class. This method will be called when the first instace is created.
51 52 53 |
# File 'lib/jsof/wrap_object.rb', line 51 def self.initialize # override end |
.initialized=(val) ⇒ Object
45 46 47 |
# File 'lib/jsof/wrap_object.rb', line 45 def self.initialized=(val) @initialized = val end |
.initialized? ⇒ Boolean
Whether self.initialize was already called or not.
42 43 44 |
# File 'lib/jsof/wrap_object.rb', line 42 def self.initialized? @initialized end |
.resolve_typeof_properties ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/jsof/wrap_object.rb', line 33 def self.resolve_typeof_properties @typeof_properties.keys.each do |sym| if @typeof_properties[sym].is_a? Proc @typeof_properties[sym] = @typeof_properties[sym].call end end end |
.typeof_properties ⇒ Hash{Symbol => Class, Jsof::WrapArrayType, Proc}
Explicitly defined properties.
30 31 32 |
# File 'lib/jsof/wrap_object.rb', line 30 def self.typeof_properties @typeof_properties end |
Instance Method Details
#[](key) ⇒ Object
88 89 90 91 92 93 94 95 96 |
# File 'lib/jsof/wrap_object.rb', line 88 def [](key) sym = key.to_sym return @wrapped[sym] if @wrapped.key?(sym) elem = @internal_object[sym] boxed = Jsof::WrapHelper.boxing(elem, self.class.typeof_properties[sym]) @wrapped[sym] = boxed if elem != boxed return boxed end |
#[]=(key, val) ⇒ Object
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/jsof/wrap_object.rb', line 98 def []=(key, val) sym = key.to_sym if type = self.class.typeof_properties[sym] raise TypeError unless Jsof::WrapHelper.assignable?(type, val) end boxed = Jsof::WrapHelper.boxing(val, self.class.typeof_properties[sym]) @wrapped[sym] = boxed if Jsof::WrapHelper.wrapped_value?(boxed) @internal_object[sym] = Jsof::WrapHelper.unboxing(val) val end |
#clear_internal ⇒ Object
Clean internal cache. Call this after you changed wrapped object directly.
111 112 113 |
# File 'lib/jsof/wrap_object.rb', line 111 def clear_internal @wrapped.clear end |
#internal_object ⇒ Object
Return reference to wrapped array.
84 85 86 |
# File 'lib/jsof/wrap_object.rb', line 84 def internal_object @internal_object end |
#to_h ⇒ Object
Return reference to wrapped array.
131 132 133 |
# File 'lib/jsof/wrap_object.rb', line 131 def to_h @internal_object end |
#to_hash ⇒ Object
Return reference to wrapped array.
126 127 128 |
# File 'lib/jsof/wrap_object.rb', line 126 def to_hash @internal_object end |