Skip to content

Instantly share code, notes, and snippets.

@mikeymicrophone
Created April 11, 2009 04:27
Show Gist options
  • Save mikeymicrophone/93458 to your computer and use it in GitHub Desktop.
Save mikeymicrophone/93458 to your computer and use it in GitHub Desktop.
# A sometimes useful development utility
class Nop < BlankSlate
def self.null
new {}
end
def self.void
new {throw :skip}
end
def initialize(&blk)
@run = blk
end
private
def method_missing(method, *args, &blk)
catch(:self) {
catch(:skip) {
@run[method, *args]
if Object.instance_methods.include? method
throw :self, Object.instance_method(method).bind(self).call(*args, &blk)
end
}
self
}
end
end
# A quick spec to verify that this idea works
# Extracted from other code of course so you might have to tweak this.
# It also assumes BlankSlate is in the environment already.
require File.dirname(__FILE__) + '/../../spec_helper'
describe Nop, '.new' do
it 'should create a new Nop object' do
Nop.new {}.should be_a(Nop)
end
it 'should take a block for method handling' do
called = false
n = Nop.new {|*| called = true}
n.anything.you.want
called.should == true
end
it 'should bind and dispatch to Object instance methods indirectly' do
called = false
n = Nop.new {|*| called = true}
n.object_id.should == Object.instance_method(:object_id).bind(n).call
called.should == true
end
it 'should allow throw :skip to skip other methods' do
called = false
n = Nop.new {|*| called = true; throw :skip}
n.object_id.should == n
called.should == true
end
it 'should allow throw :self to override what is returned' do
called = false
n = Nop.new {|*| called = true; throw :self, 42}
n.object_id.should == 42
called.should == true
end
end
describe Nop, '.null' do
it 'should return self except for object methods' do
Nop.null.foo.bar.class.should == Nop
end
end
describe nop, '.void' do
it 'should always return self' do
obj = Nop.void.foo.bar.class
Object.instance_method(:equal?).bind(obj).call(obj).should == true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment