Class: MethodObject

Inherits:
Object
  • Object
show all
Defined in:
lib/method_object.rb,
lib/method_object/version.rb

Overview

See gemspec for description

Defined Under Namespace

Classes: AmbigousMethodError, PotentialDelegator, PotentialDelegatorWithPrefix, Setup

Constant Summary collapse

VERSION =
'2.1.4'

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(_) ⇒ MethodObject

Returns a new instance of MethodObject.



24
# File 'lib/method_object.rb', line 24

def initialize(_); end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/method_object.rb', line 30

def method_missing(name, *args, &block)
  candidates = candidates_for_method_missing(name)
  case candidates.length
  when 0
    super
  when 1
    delegate = candidates.first
    define_delegated_method(delegate)
    public_send(delegate.delegated_method, *args, &block)
  else
    handle_ambiguous_missing_method(candidates, name)
  end
end

Class Attribute Details

.attributesObject (readonly)

Returns the value of attribute attributes.



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

def attributes
  @attributes
end

Class Method Details

.attrs(*attributes) ⇒ Object



10
11
12
13
# File 'lib/method_object.rb', line 10

def attrs(*attributes)
  @attributes = attributes
  Setup.call(attributes: attributes, subclass: self)
end

.call(**args) ⇒ Object



15
16
17
# File 'lib/method_object.rb', line 15

def call(**args)
  new(args).call
end

Instance Method Details

#callObject

Raises:

  • (NotImplementedError)


26
27
28
# File 'lib/method_object.rb', line 26

def call
  raise NotImplementedError, 'Define the call method'
end

#candidates_for_method_missing(method_name) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/method_object.rb', line 48

def candidates_for_method_missing(method_name)
  potential_candidates =
    self.class.attributes.map do |attribute|
      PotentialDelegator.new(
        attribute,
        public_send(attribute),
        method_name,
      )
    end +
    self.class.attributes.map do |attribute|
      PotentialDelegatorWithPrefix.new(
        attribute,
        public_send(attribute),
        method_name,
      )
    end
  potential_candidates.select(&:candidate?)
end

#define_delegated_method(delegate) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/method_object.rb', line 67

def define_delegated_method(delegate)
  self.class.class_eval(
    if delegate.method_to_call_on_delegate.to_s.end_with?('=')
      <<-RUBY
        def #{delegate.delegated_method}(arg)
          #{delegate.attribute}.#{delegate.method_to_call_on_delegate}(arg)
        end
      RUBY
    else
      <<-RUBY
        def #{delegate.delegated_method}(*args, &block)
          #{delegate.attribute}
            .#{delegate.method_to_call_on_delegate}(*args, &block)
        end
      RUBY
    end
  )
end

#handle_ambiguous_missing_method(candidates, method_name) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/method_object.rb', line 86

def handle_ambiguous_missing_method(candidates, method_name)
  raise(
    AmbigousMethodError,
    "#{method_name} is ambiguous: " +
    candidates
      .map do |candidate|
        "#{candidate.attribute}.#{candidate.method_to_call_on_delegate}"
      end
      .join(', '),
  )
end

#respond_to_missing?(name) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/method_object.rb', line 44

def respond_to_missing?(name)
  candidates_for_method_missing(name).length == 1
end