Module: Cube::Trait
- Defined in:
- lib/cube/traits.rb
Defined Under Namespace
Classes: IncludeError, MethodConflict
Instance Method Summary
collapse
Instance Method Details
#append_features(mod) ⇒ Object
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/cube/traits.rb', line 16
def append_features(mod)
if mod.is_a?(Class) && !mod.is_a?(CubeMethods)
raise IncludeError, "Traits can only be mixed into cube classes"
end
unless mod.instance_variable_defined?(:@__trait_allow_include) &&
mod.instance_variable_get(:@__trait_allow_include)
raise IncludeError, "Traits can only be mixed in using method `with_trait`"
end
conflicts = public_instance_methods & mod.public_instance_methods
errors = conflicts.map { |c|
meth = mod.instance_method(c)
{ meth: meth, owner: meth.owner } unless meth.owner.is_a?(Class)
}.compact
unless errors.empty?
message = "\n" + errors.map { |e| e[:meth].to_s }.join("\n")
raise MethodConflict, message
end
if @__interface_trait_required_interface && mod.is_a?(Class)
intf = @__interface_trait_required_interface
mod.include?(intf) || mod.as_interface(intf, runtime_checks: false)
end
super
end
|
#assert_match(intf) ⇒ Object
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# File 'lib/cube/traits.rb', line 55
def assert_match(intf)
self_methods = instance_methods
inherited = self.ancestors.select{ |x| Trait === x }
required_interface_spec = inherited.inject({}) { |acc, x|
req = x.instance_variable_get('@__interface_trait_required_interface')
if req
acc.merge(req.to_spec)
else
acc
end
}
self_methods.each do |sm|
required_interface_spec.delete(sm)
end
Interface.match_specs(required_interface_spec, intf.to_spec)
end
|
#requires_interface(intf) ⇒ Object
9
10
11
12
13
14
|
# File 'lib/cube/traits.rb', line 9
def requires_interface(intf)
unless intf.is_a? Cube::Interface
raise ArgumentError, "#{intf} is not a Cube::Interface"
end
@__interface_trait_required_interface = intf
end
|
#wrap(intf) ⇒ Object
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# File 'lib/cube/traits.rb', line 40
def wrap(intf)
assert_match(intf)
cls = Class.new(SimpleDelegator) do
define_method(:initialize) do |obj|
$stderr.puts "Checking with #{intf}"
Cube.check_type(intf, obj)
super(obj)
end
end
inc_trait = clone
inc_trait.instance_variable_set(:@__interface_trait_required_interface, nil)
inc_trait.instance_variable_set(:@__trait_cloned_from, self)
Cube[cls].with_trait(inc_trait)
end
|