class Ripar::Roller

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

Attributes

original[RW]
riven[RW]

Public Class Methods

new( original, &block ) click to toggle source
# 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
rive( original, &block ) click to toggle source

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

# File lib/ripar/roller.rb, line 53
def self.rive( original, &block )
  new( original, &block ).riven
end

Public Instance Methods

__ambiguous_method__( binding_self, meth, *args, &blk ) click to toggle source

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.

# 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
inspect() click to toggle source

make sure this BasicObject plays nicely in pry

# File lib/ripar/roller.rb, line 75
def inspect
  %Q{#<#{self.__class__} original: #{@original.inspect}, riven: #{@riven.inspect}>}
end
method_missing(meth, *args, &block) click to toggle source

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

# File lib/ripar/roller.rb, line 58
def method_missing(meth, *args, &block)
  @riven = @riven.send( meth, *args, &block )
end
pretty_inspect() click to toggle source
# File lib/ripar/roller.rb, line 79
def pretty_inspect
  inspect
end
respond_to?( meth, include_all = false ) click to toggle source

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

# 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 ) click to toggle source

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

# File lib/ripar/roller.rb, line 43
def roller( &block )
  if block
    roll_block &block
  else
    self
  end
end
send( meth, *args, &block ) click to toggle source

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

# File lib/ripar/roller.rb, line 63
def send( meth, *args, &block )
  method_missing meth, *args, &block
end
to_s() click to toggle source
# File lib/ripar/roller.rb, line 83
def to_s; inspect; end

Protected Instance Methods

roll_block( ) { |self| ... } click to toggle source
# File lib/ripar/roller.rb, line 92
def roll_block( &block )
  case block.arity
  when 0
    ::Ripar::Combinder.new( self, block.binding ).instance_eval &block
  when 1
    yield self
  else
    ::Kernel.raise "Don't know how to handle arity #{block.arity}"
  end
end

Private Instance Methods

__methods__( include_all = true ) click to toggle source
# File lib/ripar/roller.rb, line 104
def __methods__( include_all = true )
  self.__class__.instance_methods include_all
end