Class: AttrExtras::AttrInitialize

Inherits:
Object
  • Object
show all
Defined in:
lib/attr_extras/attr_initialize.rb

Instance Method Summary collapse

Constructor Details

#initialize(klass, names, block) ⇒ AttrInitialize

Returns a new instance of AttrInitialize.



2
3
4
# File 'lib/attr_extras/attr_initialize.rb', line 2

def initialize(klass, names, block)
  @klass, @names, @block = klass, names, block
end

Instance Method Details

#applyObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/attr_extras/attr_initialize.rb', line 9

def apply
  # The define_method block can't call our methods, so we need to make
  # things available via local variables.
  names = @names
  block = @block
  validate_arity = method(:validate_arity)
  set_ivar_from_hash = method(:set_ivar_from_hash)

  klass.send(:define_method, :initialize) do |*values|
    validate_arity.call(values.length, self.class)

    names.zip(values).each do |name_or_names, value|
      if name_or_names.is_a?(Array)
        hash = value || {}

        known_keys = name_or_names.map { |name| name.to_s.sub(/!\z/, "").to_sym }
        unknown_keys = hash.keys - known_keys
        if unknown_keys.any?
          raise ArgumentError, "Got unknown keys: #{unknown_keys.inspect}; allowed keys: #{known_keys.inspect}"
        end

        name_or_names.each do |name|
          set_ivar_from_hash.call(self, name, hash)
        end
      else
        name = name_or_names
        instance_variable_set("@#{name}", value)
      end
    end

    if block
      instance_eval(&block)
    end
  end
end