Module: TypedAttr::ModuleMethods

Defined in:
lib/typed_attr.rb

Constant Summary collapse

OPTIONS =
{ }

Instance Method Summary collapse

Instance Method Details

#typed_attr(*types_and_names) ⇒ Object

typed_attr name: Type, … typed_attr Type, :name, …

Generates an initialize method that will accept each :name as a typechecked positional argument. Unspecified arguments are undefined and not typechecked. Additional arguments are ignored.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/typed_attr.rb', line 35

def typed_attr *types_and_names
  if h = types_and_names.first and Hash === h and types_and_names.size == 1
    names = h.keys
    name_to_type = h
  else
    name_to_type = Hash[*types_and_names.reverse]
    names =
      (0 .. types_and_names.size).to_a.
      keep_if(&:odd?).
      map { | i | types_and_names[i] }
  end
  expr = <<"END"
def initialize *__args
  initialize_typed_attrs *__args
end

def initialize_typed_attrs *__args
  #{names.map_with_index do | name, i |
  "@#{name} = __args[#{i}] if __args.size > #{i}"
  end * "\n  "}
  #{"binding.pry if #{OPTIONS[:pry_if] || true}" if OPTIONS[:pry]}
  #{names.map_with_index do | name, i |
type = name_to_type[name]
"typecheck @#{name}, #{type} if __args.size > #{i}"
  end * "\n  "}
end
attr_reader #{names.map(&:to_sym).map(&:inspect) * ', '}
END
  $stderr.puts "#{self}\n#{expr}" if OPTIONS[:debug]
  class_eval expr
end

#typed_attr_option(opts) ⇒ Object



25
26
27
# File 'lib/typed_attr.rb', line 25

def typed_attr_option opts
  OPTIONS.update(opts)
end