Module: JInterface::InterfaceClassMethods

Defined in:
lib/jinterface/interface_class_methods.rb

Instance Method Summary collapse

Instance Method Details

#extend(*args) ⇒ Object

Raises:

  • (SyntaxError)


86
87
88
89
90
91
# File 'lib/jinterface/interface_class_methods.rb', line 86

def extend(*args)
  raise SyntaxError.new(
    "Interface '#{self.name}' cannot extend,"\
    " only include other interfaces."
  )
end

#extended(obj) ⇒ Object

Raises:

  • (SyntaxError)


92
93
94
95
96
97
# File 'lib/jinterface/interface_class_methods.rb', line 92

def extended(obj)
  raise SyntaxError.new(
    "Interface '#{self.name}' cannot be "\
    " extended, only included, in '#{obj.name}'."
  )
end

#include(*args) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/jinterface/interface_class_methods.rb', line 5

def include(*args)
  #For each inclusion

  args.each do |mod|
    #Make sure it is an interface

    raise TypeError.new(
      "Cannot include non-interface module"\
      " '#{mod.name}' in interface '#{self.name}'."
    ) unless JInterface.interface? mod
    #Add the method arrays together

    arg_ranges = mod.instance_variable_get(:@arg_ranges)
    arg_ranges.each do |method_name, range|
      @arg_ranges[method_name] = range + @arg_ranges[method_name]
    end
    #Include it

    super mod
  end
end

#included(obj) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
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
# File 'lib/jinterface/interface_class_methods.rb', line 22

def included(obj)
  #Ignore if included in an interface,

  #include method will take care of checks

  return if JInterface.interface?(obj)
  #Cache public obj method names

  obj_methods = Hash[obj.public_instance_methods.map.with_index.to_a]
  #Check interface methods are implemented in obj

  act_range = JInterface::ArgRange.new(nil)
  self.public_instance_methods.each do |method_name|
    #If method does not exist

    if not obj_methods.key? method_name
      #Raise error if under a different scope

      [:private, :protected].each do |scope|
        raise NameError.new(
          "Method '#{method_name}' in class '#{obj.name}'"\
          " must be declared as public, not #{scope},"\
          " as declared in interface '#{self.name}'."
        ) if obj.send("#{scope}_method_defined?", method_name)
      end
      #If here, method does not exist. This is possible

      #if the method was removed or made undefined

      raise NotImplementedError.new(
        "Method '#{method_name}' must be implemented in class"\
        " '#{obj.name}' as declared in interface '#{self.name}'."
      )
    end
    #Make sure method was overriden (implemented)

    meth = obj.public_instance_method method_name
    raise NotImplementedError.new(
      "Method '#{method_name}' must be implemented in class"\
      " '#{obj.name}' as declared in interface '#{meth.owner.name}'."
    ) if JInterface.interface? meth.owner
    #Make sure method can handle number of args defined

    act_range.reset(meth)
    exp_range = @arg_ranges[method_name]
    raise ArgumentError.new(
      "Method '#{method_name}' in class '#{obj.name}'"\
      " must handle #{exp_range} arguments, not #{act_range},"\
      " as declared in included interface(s)."
    ) unless act_range.cover? exp_range
  end
end

#method_added(method_name) ⇒ Object



64
65
66
67
# File 'lib/jinterface/interface_class_methods.rb', line 64

def method_added(method_name)
  meth = self.public_instance_method(method_name)
  @arg_ranges[method_name] = JInterface::ArgRange.new(meth) + @arg_ranges[method_name]
end

#prepend(*args) ⇒ Object

Raises:

  • (SyntaxError)


98
99
100
101
102
103
# File 'lib/jinterface/interface_class_methods.rb', line 98

def prepend(*args)
  raise SyntaxError.new(
    "Interface '#{self.name}' cannot prepend,"\
    " only include other interfaces."
  )
end

#prepended(obj) ⇒ Object

Raises:

  • (SyntaxError)


104
105
106
107
108
109
# File 'lib/jinterface/interface_class_methods.rb', line 104

def prepended(obj)
  raise SyntaxError.new(
    "Interface '#{self.name}' cannot be "\
    " prepended, only included, in '#{obj.name}'."
  )
end

#private(*args) ⇒ Object

Raises:

  • (SyntaxError)


68
69
70
71
72
73
# File 'lib/jinterface/interface_class_methods.rb', line 68

def private(*args)
  raise SyntaxError.new(
    "Interface '#{self.name}' cannot declare"\
    " private methods, only public methods."
  )
end

#protected(*args) ⇒ Object

Raises:

  • (SyntaxError)


74
75
76
77
78
79
# File 'lib/jinterface/interface_class_methods.rb', line 74

def protected(*args)
  raise SyntaxError.new(
    "Interface '#{self.name}' cannot declare"\
    " protected methods, only public methods."
  )
end

#singleton_method_added(*args) ⇒ Object

Raises:

  • (SyntaxError)


80
81
82
83
84
85
# File 'lib/jinterface/interface_class_methods.rb', line 80

def singleton_method_added(*args)
  raise SyntaxError.new(
    "Interface '#{self.name}' cannot declare"\
    " class methods, only instance methods."
  )
end