Class: NRSER::Meta::Props::Prop

Inherits:
Object
  • Object
show all
Defined in:
lib/nrser/meta/props/prop.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(defined_in, name, type: t.any, default: NRSER::NO_ARG, source: nil, to_data: nil) ⇒ Prop

Returns a new instance of Prop.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/nrser/meta/props/prop.rb', line 20

def initialize  defined_in,
                name,
                type: t.any,
                default: NRSER::NO_ARG,
                source: nil,
                to_data: nil
  
  @defined_in = defined_in
  @name = name
  @type = t.make type
  @source = source
  @default = default
  @to_data = to_data
  
  if @source.nil?
    @instance_variable_source = false
  else
    source_str = source.to_s
    @instance_variable_source = source_str[0] == '@'
  end
end

Instance Attribute Details

#defined_inObject

Returns the value of attribute defined_in.



14
15
16
# File 'lib/nrser/meta/props/prop.rb', line 14

def defined_in
  @defined_in
end

#nameObject

Returns the value of attribute name.



14
15
16
# File 'lib/nrser/meta/props/prop.rb', line 14

def name
  @name
end

#sourceObject

Returns the value of attribute source.



14
15
16
# File 'lib/nrser/meta/props/prop.rb', line 14

def source
  @source
end

#typeObject

Returns the value of attribute type.



14
15
16
# File 'lib/nrser/meta/props/prop.rb', line 14

def type
  @type
end

Instance Method Details

#defaultObject



56
57
58
59
60
61
62
63
64
# File 'lib/nrser/meta/props/prop.rb', line 56

def default
  if default?
    @default
  else
    raise NameError.new NRSER.squish <<-END
      Prop #{ self } has no default value.
    END
  end
end

#default?return_type

TODO:

Document default? method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



51
52
53
# File 'lib/nrser/meta/props/prop.rb', line 51

def default?
  @default != NRSER::NO_ARG
end

#get(instance) ⇒ return_type

TODO:

Document get method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/nrser/meta/props/prop.rb', line 114

def get instance
  if source?
    if instance_variable_source?
      instance.instance_variable_get source
    else
      case source
      when String, Symbol
        instance.send source
      when Proc
        instance.instance_exec &source
      else
        raise TypeError.squished <<-END
          Expected `Prop#source` to be a String, Symbol or Proc;
          found #{ source.inspect }
        END
      end
    end
  else
    values(instance)[name]
  end
end

#instance_variable_source?return_type

TODO:

Document instance_variable_source? method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



88
89
90
# File 'lib/nrser/meta/props/prop.rb', line 88

def instance_variable_source?
  @instance_variable_source
end

#primary?return_type

TODO:

Document primary? method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



101
102
103
# File 'lib/nrser/meta/props/prop.rb', line 101

def primary?
  !source?
end

#set(instance, value) ⇒ return_type

TODO:

Document set method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



145
146
147
148
149
150
151
152
153
154
# File 'lib/nrser/meta/props/prop.rb', line 145

def set instance, value
  unless type.test value
    raise TypeError.new NRSER.squish <<-END
      #{ defined_in }##{ name } must be of type #{ type };
      found #{ value.inspect }
    END
  end
  
  values(instance)[name] = value
end

#set_from_values_hash(instance, **values) ⇒ return_type

TODO:

Document set_from_hash method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/nrser/meta/props/prop.rb', line 165

def set_from_values_hash instance, **values
  if values.key? name
    set instance, values[name]
  else
    if default?
      set instance, if !default.nil? && default.respond_to?( :dup )
        default.dup
      else
        default
      end
    else
      raise TypeError.new NRSER.squish <<-END
        Prop #{ name } has no default value and no value was provided in
        values #{ values.inspect }.
      END
    end
  end
end

#source?return_type

TODO:

Document source? method.

Returns @todo Document return value.

Parameters:

  • arg_name (type)

    @todo Add name param description.

Returns:

  • (return_type)

    @todo Document return value.



75
76
77
# File 'lib/nrser/meta/props/prop.rb', line 75

def source?
  !@source.nil?
end

#to_data(instance) ⇒ Object

Get the “data” value - a basic scalar or structure of hashes, arrays and scalars, suitable for JSON encoding, etc. - for the property from an instance.

The process depends on the ‘to_data:` keyword provided at property declaration:

  1. nil default

    • If the property value responds to ‘#to_data`, the result of invoking that method will be returned.

      WARNING

      This can cause infinite recursion if an instance has a property value that is also an instance of the same class (as as other more complicated scenarios that boil down to the same problem), but, really, what else would it do in this situation?

      This problem can be avoided by by providing a ‘to_data:` keyword when declaring the property that dictates how to handle it’s value. In fact, that was the motivation for adding ‘to_data:`.

    • Otherwise, the value itself is returned, under the assumption that it is already suitable as data.

  2. Symbol | String

    • The ‘to_data:` string or symbol is sent to the property value (the method with this name is called via Object#send).

  3. Proc

    • The ‘to_data:` proc is called with the property value as the sole argument and the result is returned as the data.

Parameters:

Returns:

  • (Object)

    Data representation of the property value (hopefully - the value itself is returned if we don’t have any better options, see above).

Raises:

  • (TypeError)

    If @to_data (provided via the ‘to_data:` keyword at property declaration) is anything other than nil, String, Symbol or Proc.



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/nrser/meta/props/prop.rb', line 229

def to_data instance
  value = get instance
  
  case @to_data
  when nil
    if value.respond_to? :to_data
      value.to_data
    elsif type.respond_to? :to_data
      type.to_data value
    else
      value
    end
  when Symbol, String
    value.send @to_data
  when Proc
    @to_data.call value
  else
    raise TypeError.squished <<-END
      Expected `@to_data` to be Symbol, String or Proc;
      found #{ @to_data.inspect }
    END
  end
end

#to_sString

Returns a short string describing the instance.

Returns:

  • (String)

    a short string describing the instance.



257
258
259
260
261
262
# File 'lib/nrser/meta/props/prop.rb', line 257

def to_s
  <<-END.squish
    #<#{ self.class.name }
      #{ @defined_in.name }##{ @name }:#{ @type }>
  END
end