Class: Base

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

Constant Summary collapse

VERSION =
"0.0.2"

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



28
29
30
# File 'lib/base.rb', line 28

def method_missing name, *args, &block
  self.class.call_method(self, name, args, block) { super }
end

Class Method Details

.all_modulesObject



11
12
13
14
15
16
17
# File 'lib/base.rb', line 11

def self.all_modules
  modules = ObjectSpace.each_object(Module).select do |mod|
    should_extract_from?(mod)
  end
  modules << Kernel
  modules
end

.call_instance_method(mod, name, args, block) ⇒ Object



49
50
51
52
53
54
55
56
57
58
# File 'lib/base.rb', line 49

def self.call_instance_method(mod, name, args, block)
  if mod.is_a? Class
    klass = Class.new(mod)
  else
    klass = Class.new { include mod }
  end

  object = self.instantiate_regardless_of_argument_count(klass)
  return object.send name, *args, &block
end

.call_method(object, name, args, block) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/base.rb', line 32

def self.call_method(object, name, args, block)
  name_string = name.to_s

  all_modules.each do |mod|
    if mod.respond_to?(name)
      return mod.send name, *args, &block
    elsif mod.instance_methods.include?(name_string)
      return call_instance_method(mod, name, args, block)
    end
  end

  # 1. The world is all that is the case.
  # 2. We failed to find a method to call.
  #   2.1. call "super" in the context of the method_missing caller
  yield
end

.const_missing(name) ⇒ Object



4
5
6
7
8
9
# File 'lib/base.rb', line 4

def self.const_missing name
  all_modules.each do |mod|
    return mod.const_get(name) if mod.const_defined?(name)
  end
  super
end

.giant_method_list_including_object(object) ⇒ Object

INHERIT ALL THE METHODS!



78
79
80
81
82
83
84
85
86
# File 'lib/base.rb', line 78

def self.giant_method_list_including_object(object)
  methods = []
  all_modules.each do |mod|
    # Don't recurse into other Base objects' "methods" method
    next if mod.is_a?(Base) || mod < Base || mod == Base
    methods.concat(mod.methods).concat(mod.instance_methods)
  end
  methods
end

.instantiate_regardless_of_argument_count(klass) ⇒ Object



60
61
62
63
64
65
66
67
# File 'lib/base.rb', line 60

def self.instantiate_regardless_of_argument_count(klass)
  (0..100).each do |arg_count|
    begin
      return klass.new(*[nil] * arg_count)
    rescue ArgumentError
    end
  end
end

.method_missing(name, *args, &block) ⇒ Object



24
25
26
# File 'lib/base.rb', line 24

def self.method_missing name, *args, &block
  call_method(self, name, args, block) { super }
end

.methodsObject



69
70
71
# File 'lib/base.rb', line 69

def self.methods
  (giant_method_list_including_object(self) + super).uniq
end

.should_extract_from?(mod) ⇒ Boolean

Returns:

  • (Boolean)


19
20
21
22
# File 'lib/base.rb', line 19

def self.should_extract_from?(mod)
  return false if (mod < Base || mod == Base || mod.is_a?(Base))
  return mod.is_a?(Module) && mod != Kernel
end

Instance Method Details

#methodsObject



73
74
75
# File 'lib/base.rb', line 73

def methods
  (self.class.giant_method_list_including_object(self) + super).uniq
end