Class: Ripar::Roller

Inherits:
BasicObject
Defined in:
lib/ripar/roller.rb

Overview

Pass in the original chainable object method calls in block will be applied resulting value will be in riven

Defined Under Namespace

Classes: Undispatchable

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(original, &block) ⇒ Roller

Returns a new instance of Roller.



8
9
10
11
12
13
# File 'lib/ripar/roller.rb', line 8

def initialize( original, &block )
  @original = original
  # clone is for protection of original - not strictly necessary?
  @riven = original.clone
  roll_block( &block ) if block
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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

Forward to riven, let it raise a method missing exception if necessary



58
59
60
# File 'lib/ripar/roller.rb', line 58

def method_missing(meth, *args, &block)
  @riven = @riven.send( meth, *args, &block )
end

Instance Attribute Details

#originalObject

Returns the value of attribute original.



38
39
40
# File 'lib/ripar/roller.rb', line 38

def original
  @original
end

#rivenObject

Returns the value of attribute riven.



38
39
40
# File 'lib/ripar/roller.rb', line 38

def riven
  @riven
end

Class Method Details

.rive(original, &block) ⇒ Object

instantiate the roller, pass it the block and immediately return the modified copy



53
54
55
# File 'lib/ripar/roller.rb', line 53

def self.rive( original, &block )
  new( original, &block ).riven
end

Instance Method Details

#__ambiguous_method__(binding_self, meth, *args, &blk) ⇒ Object

Callback from Combinder.

This happens when the outside self is_a?(original.class) already, and inside is the roller, which will both respond to the same set of methods. So we want the method calls to go to the roller inside the roller block, otherwise the current value of riven in the roller will end up being constantly reset to original. Which is exactly not the point.



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/ripar/roller.rb', line 25

def __ambiguous_method__( binding_self, meth, *args, &blk )
  # TODO maybe this should just always default to the roller? I don't see much point
  #   in being fancier than that.
  # ::Kernel.puts "__ambiguous_method__ #{meth} for #{binding_self.inspect} and #{@obj.inspect}"
  if binding_self == @original
    # send it to the roller
    send meth, *args, &blk
  else
    # don't know what to do with it
    raise Undispatchable, "don't know how to dispatch #{meth}"
  end
end

#inspectObject

make sure this BasicObject plays nicely in pry



75
76
77
# File 'lib/ripar/roller.rb', line 75

def inspect
  %Q{#<#{self.__class__} original: #{@original.inspect}, riven: #{@riven.inspect}>}
end

#pretty_inspectObject



79
80
81
# File 'lib/ripar/roller.rb', line 79

def pretty_inspect
  inspect
end

#respond_to?(meth, include_all = false) ⇒ Boolean

used by combinder, so must be defined, otherwise it perturbs method_missing no point in using respond_to_missing?, because that’s part of Object#respond_to, not BasicObject

Returns:

  • (Boolean)


70
71
72
# File 'lib/ripar/roller.rb', line 70

def respond_to?( meth, include_all = false )
  @riven.respond_to?(meth, include_all) || __methods__(include_all).include?(meth) || __singleton_methods__(include_all).include?(meth)
end

#roller(&block) ⇒ Object

this is so that we a roller is returned from a call, you can call roller on it again, and keep things rolling along.



43
44
45
46
47
48
49
# File 'lib/ripar/roller.rb', line 43

def roller( &block )
  if block
    roll_block &block
  else
    self
  end
end

#send(meth, *args, &block) ⇒ Object

used by combinder, so must be defined, otherwise it perturbs method_missing



63
64
65
# File 'lib/ripar/roller.rb', line 63

def send( meth, *args, &block )
  method_missing meth, *args, &block
end

#to_sObject



83
# File 'lib/ripar/roller.rb', line 83

def to_s; inspect; end