Created
August 16, 2012 21:47
-
-
Save stackdump/3373898 to your computer and use it in GitHub Desktop.
sample illustration of meta-programming with method_missing & respond_to
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Foo | |
TEST=[:foo, :bar] | |
def self.count_foo | |
TEST.find_index(:foo) | |
end | |
#TODO try to reuse method missing code between class & instance methods | |
def self.method_missing(sym, *args, &block) | |
if respond_to?(sym) | |
send(sym, args){ yield block } #TODO should branch based on block_given? | |
else | |
super(sym, args, block) | |
end | |
end | |
def self.respond_to?(sym) | |
super(sym) || add_count_method(sym) | |
end | |
private | |
def self.add_count_method(sym) | |
return false unless /^count_(?<key>[a-zA-Z]\w*)$/ =~ sym | |
instance_eval <<METHOD | |
def self.#{sym}(args=[], &block) | |
TEST.find_index(:"#{key}") | |
end | |
METHOD | |
return true | |
end | |
end | |
describe Foo do | |
context 'using class method' do | |
it 'should allow seemless :respond_to calls' do | |
Foo.should respond_to :count_foo #pre-defined method | |
Foo.should respond_to :count_bar | |
Foo.should respond_to :count_baz | |
Foo.should respond_to :count_a1 | |
Foo.should_not respond_to :count_1 | |
Foo.should_not respond_to :count_ | |
Foo.should_not respond_to :baz | |
end | |
it 'should allow dynamic method creation' do | |
Foo.count_foo.should == 0 | |
Foo.count_bar.should == 1 | |
Foo.count_baz.should be_nil | |
Foo.count_a1.should be_nil | |
end | |
it 'should still raise normal method_missing error' do | |
lambda { Foo.baz }.should raise_error(NoMethodError) | |
end | |
it 'should still allow passing of blocks' do | |
pending 'rewrite test to use blocks' | |
end | |
end | |
context 'using instance methods' do | |
it 'should not create instance methods' do | |
f = Foo.new | |
f.should_not respond_to :count_bar | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment