Class: ThinModels::Struct

Inherits:
Object
  • Object
show all
Defined in:
lib/thin_models/struct.rb,
lib/thin_models/struct/identity.rb

Direct Known Subclasses

Typed

Defined Under Namespace

Modules: IdentityMethods Classes: Typed

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(values = nil, skip_checks = false, &lazy_values) ⇒ Struct

Returns a new instance of Struct.



11
12
13
14
15
# File 'lib/thin_models/struct.rb', line 11

def initialize(values=nil, skip_checks=false, &lazy_values)
  @values = (values || {}).reduce({}) { |m, (k, v)| m[k.to_sym] = v; m }
  @lazy_values = lazy_values if lazy_values
  check_attributes if values && !skip_checks
end

Instance Attribute Details

#lazy_valuesObject

Returns the value of attribute lazy_values.



56
57
58
# File 'lib/thin_models/struct.rb', line 56

def lazy_values
  @lazy_values
end

Class Method Details

.attributesObject



164
165
166
# File 'lib/thin_models/struct.rb', line 164

def attributes
  @attributes ||= (superclass < Struct ? superclass.attributes.dup : Set.new)
end

.json_create(json_values) ⇒ Object



156
157
158
159
160
# File 'lib/thin_models/struct.rb', line 156

def self.json_create(json_values)
  values = {}
  attributes.each {|a| values[a] = json_values[a.to_s] if json_values.has_key?(a.to_s)}
  new(values)
end

.new_skipping_checks(values, &lazy_values) ⇒ Object



7
8
9
# File 'lib/thin_models/struct.rb', line 7

def self.new_skipping_checks(values, &lazy_values)
  new(values, true, &lazy_values)
end

Instance Method Details

#[](attribute) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/thin_models/struct.rb', line 76

def [](attribute)
  check_attribute(attribute)
  attribute = attribute.to_sym
  if @values.has_key?(attribute.to_sym)
    @values[attribute.to_sym]
  else
    if @lazy_values
      @values[attribute] = @lazy_values.call(self, attribute)
    end
  end
end

#[]=(attribute, value) ⇒ Object



102
103
104
105
106
# File 'lib/thin_models/struct.rb', line 102

def []=(attribute, value)
  check_attribute(attribute)
  attribute = attribute.to_sym
  @values[attribute] = value
end

#attribute_loaded?(attribute) ⇒ Boolean Also known as: has_key?, key?

Returns:

  • (Boolean)


50
51
52
# File 'lib/thin_models/struct.rb', line 50

def attribute_loaded?(attribute)
  @values.has_key?(attribute)
end

#attributesObject



67
68
69
# File 'lib/thin_models/struct.rb', line 67

def attributes
  self.class.attributes
end

#check_attribute(attribute) ⇒ Object



23
24
25
26
27
28
# File 'lib/thin_models/struct.rb', line 23

def check_attribute(attribute)
  attributes = self.class.attributes.map(&:to_s)
  unless attributes.include?(attribute.to_s)
    fail NameError, "no attribute #{attribute} in #{self.class}"
  end
end

#check_attributesObject



17
18
19
20
21
# File 'lib/thin_models/struct.rb', line 17

def check_attributes
  @values.each_key do |attribute|
    check_attribute(attribute)
  end
end

#fetch(attribute) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/thin_models/struct.rb', line 88

def fetch(attribute)
  check_attribute(attribute)
  attribute = attribute.to_sym
  if @values.has_key?(attribute)
    @values[attribute]
  else
    if @lazy_values
      @values[attribute] = @lazy_values.call(self, attribute)
    else
      raise PartialDataError, "attribute #{attribute} not loaded"
    end
  end
end

#freezeObject



38
39
40
41
# File 'lib/thin_models/struct.rb', line 38

def freeze
  super
  @values.freeze
end

#has_lazy_values?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/thin_models/struct.rb', line 63

def has_lazy_values?
  instance_variable_defined?(:@lazy_values)
end

#initialize_copy(other) ⇒ Object

this allows ‘dup’ to work in a desirable way for these instances, ie use a dup’d properties hash instance for the dup, meaning it can be updated without affecting the state of the original.



33
34
35
36
# File 'lib/thin_models/struct.rb', line 33

def initialize_copy(other)
  super
  @values = @values.dup
end

#inspectObject Also known as: to_s

Based on Matz’s code for OpenStruct#inspect in the stdlib.

Note the trick with the Thread-local :inspect_key, which ruby internals appear to use but isn’t documented anywhere. If you use it in the same way the stdlib uses it, you can override inspect without breaking its cycle avoidant behaviour



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/thin_models/struct.rb', line 125

def inspect
  str = "#<#{self.class}"

  ids = (Thread.current[:__inspect_key__] ||= [])
  if ids.include?(object_id)
    return str << ' ...>'
  end

  ids << object_id
  begin
    first = true
    for k,v in @values
      str << "," unless first
      first = false
      str << " #{k}=#{v.inspect}"
    end
    if @lazy_values
      str << "," unless first
      str << " ..."
    end
    return str << '>'
  ensure
    ids.pop
  end
end

#loaded_attributesObject Also known as: keys



71
72
73
# File 'lib/thin_models/struct.rb', line 71

def loaded_attributes
  @values.keys
end

#loaded_valuesObject Also known as: to_hash



43
44
45
# File 'lib/thin_models/struct.rb', line 43

def loaded_values
  @values.dup
end

#merge(updated_values) ⇒ Object



108
109
110
# File 'lib/thin_models/struct.rb', line 108

def merge(updated_values)
  dup.merge!(updated_values)
end

#merge!(updated_values) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/thin_models/struct.rb', line 112

def merge!(updated_values)
  updated_values.to_hash.each_key do |attribute|
    check_attribute(attribute)
  end
  @values.merge!(updated_values)
  self
end

#remove_lazy_valuesObject



59
60
61
# File 'lib/thin_models/struct.rb', line 59

def remove_lazy_values
  remove_instance_variable(:@lazy_values) if instance_variable_defined?(:@lazy_values)
end

#to_json(*p) ⇒ Object



152
153
154
# File 'lib/thin_models/struct.rb', line 152

def to_json(*p)
  @values.merge(:json_class => self.class).to_json(*p)
end