Class: I8::Struct::Vector

Inherits:
Vector show all
Includes:
I8::Struct, NRSER::Props::Immutable::Vector
Defined in:
lib/nrser/labs/i8/struct/vector.rb

Overview

Base class for Vector-based “propertied” (NRSER::Props) structs created by new.

Constant Summary

Constants included from NRSER::Props::Immutable::Vector

NRSER::Props::Immutable::Vector::STORAGE

Class Method Summary collapse

Methods included from NRSER::Props::Immutable::Vector

included, #initialize

Methods inherited from Hamster::Vector

#as_json, #to_mutable, #to_yaml

Methods included from NRSER::Ext::Tree

#each_branch, #leaves, #map_branches, #map_leaves, #map_tree

Class Method Details

.self.new(*prop_defs, &class_body) ⇒ Object .self.new(*args, **kwds, &block) ⇒ I8::Struct::Vector

Check out Hash for a general idea of how this method works, I don’t want to duplicate the explanation.

@param [Array] prop_defs
  Each entry must be a pair; the first entry must be the name as a
  symbol, the second is either the prop's type or a hash of options
  for creating the prop.

  Look at the examples.

@param [Proc?] class_body
  Optional block to evaluate as the new class's body.

@return [Class<I8::Struct::Vector>]
  New structure class.

Examples:

Providing additional prop options

Point = I8::Struct::Vector.new \
  [x: {type: t.int, default: 0}],
  [y: {type: t.int, default: 0}]
# => Point

Overloads:

  • .self.new(*prop_defs, &class_body) ⇒ Object

    Create a new struct class.

    Examples:

    Using array-wrapping for prop defs

    Point = I8::Struct::Vector.new [x: t.int], [y: t.int]
    # => Point

    Using hashes for prop defs

    Point = I8::Struct::Vector.new( {x: t.int}, {y: t.int} )
    # => Point
  • .self.new(*args, **kwds, &block) ⇒ I8::Struct::Vector

    Create a new instance.

    Returns:



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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/nrser/labs/i8/struct/vector.rb', line 81

def self.new *args, **kwds, &block
  # Are we {I8::Struct::Vector}? (See method doc).
  if self == I8::Struct::Vector
    unless kwds.empty?
      raise NRSER::ArgumentError.new \
        "Can not supply keyword args",
        args: args,
        kwds: kwds
    end

    # Unwrap `[name: type]` format
    prop_defs = args.map { |prop_def|
      if  ::Array === prop_def &&
          prop_def.length == 1 &&
          ::Hash === prop_def[0]
        prop_def[0]
      else
        prop_def
      end
    }
    
    # Check we have a list of pairs with label keys
    t.array( t.pair( key: t.label ) ).check! prop_defs
    
    Class.new( I8::Struct::Vector ) do
      prop_defs.each_with_index do |pair, index|
        name, value = pair.first
        
        kwds = t.match value,
          t.type, ->( type ) {{ type: type }},
          t.hash_, value
        
        prop name, **kwds, index: index
      end
      
      class_exec &block if block
    end

  else
    # No, we are a built struct. Defer up to `super` to create an instance.

    # NOTE  This is... weird. Just doing the normal
    #       
    #           super( *args, **kwds, &block )
    #       
    #       results in `*args` becoming `[*args, {}]` up the super chain
    #       when `kwds` is empty.
    #       
    #       I can't say I can understand it, but I seem to be able to fix
    #       it.
    # 
    if kwds.empty?
      super( *args, &block )
    else
      super( *args, **kwds, &block )
    end

  end
end