Skip to content

Instantly share code, notes, and snippets.

@mfdeveloper
Last active August 29, 2015 14:22
Show Gist options
  • Save mfdeveloper/b3cb019389b4f31be2db to your computer and use it in GitHub Desktop.
Save mfdeveloper/b3cb019389b4f31be2db to your computer and use it in GitHub Desktop.
Ruby Meta Programming

Ruby Meta Programming

Here you will see divers code snippets about meta programming with Ruby.

Hook called methods that not exists

The first snippet here shows a example the method callback named method_exists(). This method is trigged when a method that not exists in one class is executed. The implementation here use define_method(name) to create a new method in runtime!!

source 'https://rubygems.org'
gem 'rspec', require: false, group: :test
gem 'simplecov', require: false, group: :test
GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.2.5)
docile (1.1.5)
json (1.8.2)
rspec (3.2.0)
rspec-core (~> 3.2.0)
rspec-expectations (~> 3.2.0)
rspec-mocks (~> 3.2.0)
rspec-core (3.2.3)
rspec-support (~> 3.2.0)
rspec-expectations (3.2.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-mocks (3.2.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-support (3.2.2)
simplecov (0.10.0)
docile (~> 1.1.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
PLATFORMS
ruby
DEPENDENCIES
rspec
simplecov
# This is a meta programming example of usage
# the method_missing feature that intercept
# unexistent methods of a class
class MyClass
def method_missing(name, *args)
method_name = name.to_s
if is_method? method_name
self.class.send(:define_method, method_name) do |value|
field = method_name.gsub(/find_by_/,'')
return "This method find by '#{field}' with value: '#{value}'"
end
self.send(name,args[0])
elsif
super(name, args)
end
end
def respond_to?(symbol, include_private=false)
is_method?(symbol.to_s) ? true : super(symbol, include_private)
end
protected
def is_method?(name)
name.start_with?('find_') ? true : false
end
end
require 'simplecov'
SimpleCov.start
require_relative 'method_missing'
describe 'Verify the method_missing on ruby meta programming' do
before :each do
@obj = MyClass.new
end
it 'Check methods that starts with "find_by_something" exists in MyClass' do
method_exists = @obj.respond_to? 'find_by_name'
expect(method_exists).to be true
end
it 'Check methods that not starts with "find_by_something" exists in MyClass' do
method_exists = @obj.respond_to? 'test'
expect(method_exists).to be false
end
it 'Raise a exception if call a method that not has find_by prefix' do
expect { @obj.test }.to raise_error(NoMethodError)
end
it 'Call a method with prefix "find_by" from a obj of MyClass' do
expect { @obj.find_by_value 'foo' }.not_to raise_error
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment