class Ripar::Roller
Pass in the original chainable object method calls in block will be applied resulting value will be in riven
Attributes
Public Class Methods
# 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
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
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
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
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
# File lib/ripar/roller.rb, line 79 def pretty_inspect inspect end
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
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
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
# File lib/ripar/roller.rb, line 83 def to_s; inspect; end
Protected Instance Methods
# 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
# File lib/ripar/roller.rb, line 104 def __methods__( include_all = true ) self.__class__.instance_methods include_all end