Module: Squib::Args::ArgLoader

Overview

Intended to be used a a mix-in, For example use see Box as an example

Instance Method Summary collapse

Instance Method Details

#[](i) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Access an individual arg for a given card

Returns:

  • an OpenStruct that looks just like the mixed-in class



105
106
107
108
109
110
111
112
# File 'lib/squib/args/arg_loader.rb', line 105

def [](i)
  card_arg = OpenStruct.new
  self.class.expanding_parameters.each do |p|
    p_val = instance_variable_get("@#{p}")
    card_arg[p] = p_val[i]
  end
  card_arg
end

#convert_units(dpi: 300, cell_px: 37.5) ⇒ Object

Convert units



115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/squib/args/arg_loader.rb', line 115

def convert_units(dpi: 300, cell_px: 37.5)
  self.class.params_with_units.each do |p|
    p_str = "@#{p}"
    p_val = instance_variable_get(p_str)
    if p_val.respond_to? :each
      arr = p_val.map { |x| Squib::Args::UnitConversion.parse(x, dpi, cell_px) }
      instance_variable_set p_str, arr
    else
      instance_variable_set p_str, Squib::Args::UnitConversion.parse(p_val, dpi, cell_px)
    end
  end
  self
end

#deck_confObject

Return the deck’s configuration This keeps the @deck local to this mixin instead of forcing args classes to “know” that @deck works.

It also makes unit testing easier. Sue me.



134
135
136
# File 'lib/squib/args/arg_loader.rb', line 134

def deck_conf
  @deck.conf
end

#defaultify(p, args, layout) ⇒ Object

Incorporate defaults and layouts

(1) Use whatever is specified if it is
(2) Go over all layout specifications (if any) and look them up
   - Use layout when it's specified for that card
   - Use "default" if no layout was specified, or the layout itself did not specify
         Defaut can be overriden for a given dsl method (@dsl_method_defaults)
         (e.g stroke width is 0.0 for text, non-zero everywhere else)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/squib/args/arg_loader.rb', line 59

def defaultify(p, args, layout)
  return args[p] if args.key? p # arg was specified, no defaults used
  defaults = self.class.parameters.merge(@dsl_method_defaults || {})
  args[:layout].map do |layout_arg|
    return defaults[p] if layout_arg.nil?  # no layout specified, use default
    unless layout.key? layout_arg.to_s     # specified a layout, but it doesn't exist in layout. Oops!
      Squib.logger.warn("Layout \"#{layout_arg.to_s}\" does not exist in layout file - using default instead")
      return defaults[p]
    end
    if layout[layout_arg.to_s].key?(p.to_s)
      layout[layout_arg.to_s][p.to_s]     # param specified in layout
    else
      defaults[p]                         # layout specified, but not this param
    end
  end
end

#expand_and_set_and_defaultify(args: {}, by: 1, layout: {}) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/squib/args/arg_loader.rb', line 30

def expand_and_set_and_defaultify(args: {}, by: 1, layout: {})
  attributes = self.class.parameters.keys
  attributes.each do |p|
    args[p] = defaultify(p, args, layout)
    val = if expandable_singleton?(p, args[p])
            [args[p]] * by
          else
            args[p] # not an expanding parameter
          end
    instance_variable_set "@#{p}", val
  end
  self.class.class_eval { attr_reader *(attributes) }
end

#expandable_singleton?(p, arg) ⇒ Boolean

Must be:

(a) an expanding parameter, and
(b) a singleton already (i.e. doesn't respond to :each)

Returns:

  • (Boolean)


47
48
49
# File 'lib/squib/args/arg_loader.rb', line 47

def expandable_singleton?(p, arg)
  self.class.expanding_parameters.include?(p) && !arg.respond_to?(:each)
end

#extract!(args, deck) ⇒ Object

wrapper for compatibility



10
11
12
13
14
15
16
17
# File 'lib/squib/args/arg_loader.rb', line 10

def extract!(args, deck)
  @deck = deck
  load!(args,
        expand_by: deck.size,
        layout: deck.layout,
        dpi: deck.dpi,
        cell_px: deck.cell_px)
end

#load!(args, expand_by: 1, layout: {}, dpi: 300, cell_px: 37.5) ⇒ Object

Main class invoked by the client (i.e. dsl/ methods)



20
21
22
23
24
25
26
27
28
# File 'lib/squib/args/arg_loader.rb', line 20

def load!(args, expand_by: 1, layout: {}, dpi: 300, cell_px: 37.5)
  @dpi = dpi
  @cell_px = cell_px
  args[:layout] = prep_layout_args(args[:layout], expand_by: expand_by)
  expand_and_set_and_defaultify(args: args, by: expand_by, layout: layout)
  validate
  convert_units dpi: dpi, cell_px: cell_px
  self
end

#prep_layout_args(layout_args, expand_by: 1) ⇒ Object

Do singleton expansion on the layout argument as well Treated differently since layout is not always specified



78
79
80
81
82
83
# File 'lib/squib/args/arg_loader.rb', line 78

def prep_layout_args(layout_args, expand_by: 1)
  unless layout_args.respond_to?(:each)
    layout_args = [layout_args] * expand_by
  end
  layout_args || []
end

#validateObject

For each parameter/attribute foo we try to invoke a validate_foo



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/squib/args/arg_loader.rb', line 86

def validate
  self.class.parameters.each do |param, default|
    method = "validate_#{param}"
    if self.respond_to? method
      attribute = "@#{param}"
      val = instance_variable_get(attribute)
      if val.respond_to? :each
        new_val = val.map.with_index{ |v, i| send(method, v, i) }
        instance_variable_set(attribute, new_val)
      else
        instance_variable_set(attribute, send(method, val))
      end
    end
  end
end