Module: NRSER::Meta::Props

Included in:
Base
Defined in:
lib/nrser/meta/props.rb,
lib/nrser/meta/props/prop.rb

Overview

Definitions

Defined Under Namespace

Modules: ClassMethods Classes: Base, Prop

Constant Summary collapse

DEFAULT_CLASS_KEY =
'__class__'
PROPS_VARIABLE_NAME =
:@__NRSER_props
PROP_VALUES_VARIABLE_NAME =
:@__NRSER_prop_values

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_props_ref(klass) ⇒ return_type

TODO:

Document get_props_ref method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



36
37
38
39
40
41
42
# File 'lib/nrser/meta/props.rb', line 36

def self.get_props_ref klass
  unless klass.instance_variable_defined? PROPS_VARIABLE_NAME
    klass.instance_variable_set PROPS_VARIABLE_NAME, {}
  end
  
  klass.instance_variable_get PROPS_VARIABLE_NAME
end

.included(base) ⇒ Object

Hook to extend the including class with NRSER::Meta::Props:ClassMethods



118
119
120
# File 'lib/nrser/meta/props.rb', line 118

def self.included base
  base.extend ClassMethods
end

.UNSAFE_load_instance_from_data(data, class_key: DEFAULT_CLASS_KEY) ⇒ NRSER::Meta::Props

Instantiate a class from a data hash. The hash must contain the ‘__class__` key and the target class must be loaded already.

WARNING

I’m sure this is all-sorts of unsafe. Please don’t ever think this is reasonable to use on untrusted data.

Parameters:

  • data (Hash<String, Object>)

    Data hash to load from.

Returns:



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/nrser/meta/props.rb', line 61

def self.UNSAFE_load_instance_from_data data, class_key: DEFAULT_CLASS_KEY
  t.hash_.check data
  
  unless data.key?( class_key )
    raise ArgumentError.new binding.erb <<-ERB
      Data is missing <%= class_key %> key - no idea what class to
      instantiate.
      
      Data:
      
          <%= data.pretty_inspect %>
      
    ERB
  end
  
  # Get the class name from the data hash using the key, checking that it's
  # a non-empty string.
  class_name = t.non_empty_str.check data[class_key]
  
  # Resolve the constant at that name.
  klass = class_name.to_const
  
  # Make sure it's one of ours
  unless klass.included_modules.include?( NRSER::Meta::Props )
    raise ArgumentError.new binding.erb <<-ERB
      Can not load instance from data - bad class name.
      
      Extracted class name
      
          <%= class_name.inspect %>
      
      from class key
      
          <%= class_key.inspect %>
      
      which resolved to constant
      
          <%= klass.inspect %>
      
      but that class does not include the NRSER::Meta::Props mixin, which we
      check for to help protect against executing an unrelated `.from_data`
      class method when attempting to load.
      
      Data:
      
          <%= data.pretty_inspect %>
      
    ERB
  end
  
  # Kick off the restore and return the result
  klass.from_data data
  
end

Instance Method Details

#initialize_props(values) ⇒ return_type

TODO:

Document initialize_props method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



254
255
256
257
258
# File 'lib/nrser/meta/props.rb', line 254

def initialize_props values
  self.class.props(only_primary: true).each { |name, prop|
    prop.set_from_values_hash self, values
  }
end

#merge(overrides = {}) ⇒ Object



261
262
263
264
265
# File 'lib/nrser/meta/props.rb', line 261

def merge overrides = {}
  self.class.new(
    self.to_h(only_primary: true).merge(overrides.symbolize_keys)
  )
end

#to_data(only_own: false, only_primary: false, add_class: true, class_key: NRSER::Meta::Props::DEFAULT_CLASS_KEY) ⇒ Hash<String, Object>

Create a “data” representation suitable for transport, storage, etc.

The result is meant to consist of only basic data types and structures - strings, numbers, arrays, hashes, datetimes, etc… though it depends on any custom objects it encounters correctly responding to ‘#to_data` for this to happen (as is implemented from classes that mix in Props here).

Prop names are converted to strings (from symbols) since though YAML supports symbol values, they have poor portability across languages, and they mean the same thing in this situation.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (Hash<String, Object>)

    @todo Document return value.



300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/nrser/meta/props.rb', line 300

def to_data only_own: false,
            only_primary: false,
            add_class: true,
            class_key: NRSER::Meta::Props::DEFAULT_CLASS_KEY
            
  self.class.props(only_own: false, only_primary: false).
    map { |name, prop|
      [name.to_s, prop.to_data(self)]
    }.
    to_h.
    tap { |hash|
      hash[class_key] = self.class.name if add_class
    }
end

#to_h(only_own: false, only_primary: false) ⇒ Hash<Symbol, Object>

TODO:

Document to_h method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (Hash<Symbol, Object>)

    @todo Document return value.



276
277
278
279
280
# File 'lib/nrser/meta/props.rb', line 276

def to_h only_own: false, only_primary: false
  self.class.
    props(only_own: only_own, only_primary: only_primary).
    map_values { |name, prop| prop.get self }
end

#to_json(*args) ⇒ String

Get a JSON String encoding the instance’s data.

Parameters:

  • *args (Array)

    I really don’t know. ‘#to_json` takes at last one argument, but I’ve had trouble finding a spec for it :/

Returns:

  • (String)


327
328
329
# File 'lib/nrser/meta/props.rb', line 327

def to_json *args
  to_data.to_json *args
end

#to_yaml(*args) ⇒ String

Get a YAML String encoding the instance’s data.

Parameters:

  • *args (Array)

    I really don’t know… whatever YAML.dump sends to it i guess.

Returns:

  • (String)


339
340
341
# File 'lib/nrser/meta/props.rb', line 339

def to_yaml *args
  to_data.to_yaml *args
end