Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'rubygems'
- require 'nakajima'
- if RUBY_VERSION < "1.9"
- require 'builder/blankslate'
- BasicObject = BlankSlate
- end
- class ContextEvaluator < BasicObject
- def initialize(*contexts)
- @contexts = contexts
- end
- def method_missing(sym, *args, &block)
- @contexts.each do |context|
- begin
- return context.send(sym, *args, &block)
- rescue ::NoMethodError => ex
- # next
- end
- end
- super
- end
- end
- class Object
- def context_eval(*contexts, &block)
- outer = eval('self', block.binding)
- ContextEvaluator.new(self, outer, *contexts).instance_eval(&block)
- end
- def context_exec(*args, &block)
- contexts = args.first.is_a?(Array) ? args.shift : []
- contexts << self
- contexts << eval('self', block.binding)
- block.bind(ContextEvaluator.new(*contexts)).call(*args)
- end
- end
- require 'rubygems'
- require 'spec'
- describe "method directors" do
- attr_reader :context, :instance
- before(:each) do
- %w(Foo Bar Fizz).each { |klass| Object.send(:remove_const, klass) rescue nil }
- Object.const_set('Foo', Class.new {
- def foo(arg=:foo); arg end
- })
- Object.const_set('Bar', Class.new {
- def bar(arg=:bar); arg end
- })
- Object.const_set('Fizz', Class.new {
- def fizz(arg=:fizz); arg end
- })
- @instance = Foo.new
- @context = Bar.new
- end
- describe "context_eval" do
- it "occurs in context of instance" do
- instance.context_eval { self }.should == instance
- end
- it "works with instance's methods" do
- instance.context_eval { [foo] }.should == [:foo]
- end
- it "works with a context's methods" do
- instance.context_eval(context) { [foo, bar] }.should == [:foo, :bar]
- end
- it "works with multiple contexts" do
- instance.context_eval(Bar.new, Fizz.new) { [foo, bar, fizz] }.should == [:foo, :bar, :fizz]
- end
- it "works with block binding" do
- def self.buzz; :buzz end
- instance.context_eval { [foo, buzz] }.should == [:foo, :buzz]
- end
- it "blows up when no method is there" do
- proc {
- instance.context_eval { cheese }
- }.should raise_error(NoMethodError)
- end
- end
- describe "context_exec" do
- it "occurs in context of instance" do
- instance.context_exec(:execd) { self }.should == instance
- end
- it "works with instance's methods" do
- instance.context_exec(:execd) { |arg| [foo(arg)] }.should == [:execd]
- end
- it "works with a context's methods" do
- instance.context_exec([context], :execd) do |arg|
- [foo(arg), bar(arg)]
- end.should == [:execd, :execd]
- end
- it "works with multiple contexts" do
- result = instance.context_exec([Bar.new, Fizz.new], :execd) do |arg|
- [foo(arg), bar(arg), fizz(arg)]
- end
- result.should == [:execd, :execd, :execd]
- end
- it "works with block binding" do
- def self.buzz(arg=:buzz); arg end
- instance.context_exec(:execd) { |arg| [foo(arg), buzz(arg)] }.should == [:execd, :execd]
- end
- it "blows up when no method is there" do
- proc {
- instance.context_exec { cheese }
- }.should raise_error(NoMethodError)
- end
- end
- end
Add Comment
Please, Sign In to add comment