dynamic_methods 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in dynamic_methods.gemspec
4
+ gemspec
5
+ gem 'rspec'
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dynamic_methods (0.0.1)
5
+ activesupport (>= 3.0.0)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ activesupport (3.0.3)
11
+ diff-lcs (1.1.2)
12
+ rspec (2.4.0)
13
+ rspec-core (~> 2.4.0)
14
+ rspec-expectations (~> 2.4.0)
15
+ rspec-mocks (~> 2.4.0)
16
+ rspec-core (2.4.0)
17
+ rspec-expectations (2.4.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.4.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ activesupport (>= 3.0.0)
26
+ bundler (>= 1.0.0)
27
+ dynamic_methods!
28
+ rspec
@@ -0,0 +1,29 @@
1
+ DynamicMethods
2
+ ==============
3
+
4
+ Define dynamic instance methods with captures and arguments:
5
+
6
+ require 'rubygems'
7
+ require 'dynamic_methods'
8
+
9
+ class FriendlyGuy
10
+ include DynamicMethods
11
+
12
+ dynamic_method /say_hello_to_(.*)/ do |person|
13
+ puts "Hello #{person}"
14
+ end
15
+
16
+ dynamic_method /say_(.*)_to/ do |word, person|
17
+ puts "#{word} #{person}"
18
+ end
19
+ end
20
+
21
+ guy = FriendlyGuy.new
22
+
23
+ guy.say_hello_to_bob
24
+ # => Hello bob
25
+
26
+ guy.say_bye_to 'bob'
27
+ # => bye bob
28
+
29
+ The block should expect enough arguments to receive the patterns captures plus additional arguments.
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ task :default => :spec
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/dynamic_methods/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "dynamic_methods"
6
+ s.version = DynamicMethods::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Marian Theisen"]
9
+ s.email = ["marian@cice-online.net"]
10
+ s.homepage = "http://rubygems.org/gems/dynamic_methods"
11
+ s.summary = "dynamics_methods is a simple gem to easily define ... dynamic methods"
12
+ s.description = "dynamics_methods is a simple gem to easily define ... dynamic methods"
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+ # s.rubyforge_project = "dynamic_methods"
16
+
17
+ s.add_dependency 'activesupport', ">= 3.0.0"
18
+ s.add_development_dependency "bundler", ">= 1.0.0"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
22
+ s.require_path = 'lib'
23
+ end
@@ -0,0 +1,91 @@
1
+ require 'active_support/core_ext/class/inheritable_attributes'
2
+
3
+ module DynamicMethods
4
+ class DynamicMethod
5
+ attr_accessor :pattern, :definition, :receiver
6
+
7
+ # Create new DynamicMethod. Excepts a RegEx pattern as first argument
8
+ # and the method definition as block argument.
9
+ def initialize receiver, pattern, &definition
10
+ @receiver, @pattern, @definition = receiver, pattern, definition
11
+ end
12
+
13
+ # If method hasn't been defined, define method in receiver's class
14
+ def define name, captures
15
+ return if receiver.method_defined? name
16
+
17
+ method_definition = @definition
18
+ receiver.send :define_method, name do |*args|
19
+ instance_exec *(captures + args), &method_definition
20
+ end
21
+ end
22
+
23
+ # Define and call method.
24
+ def define_and_call object, name, captures, *args, &block
25
+ define name, captures
26
+ object.send name, *args, &block
27
+ end
28
+
29
+ # Match name against this DynamicMethods pattern
30
+ def match name
31
+ pattern.match name.to_s
32
+ end
33
+ end
34
+
35
+
36
+ module ClassMethods
37
+ # Define a dynamic method, accepts a RegEx pattern (optionally with captures)
38
+ # and a block which defines the method body. The block should expect at least
39
+ # as many arguments as capture groups are in the RegEx.
40
+ # e.g.
41
+ #
42
+ # dynamic_method /render_(\w+)_(\w+) do |capture1, capture2, argument1, argument2|
43
+ # # do something
44
+ # end
45
+ #
46
+ def dynamic_method pattern, &method_definition
47
+ DynamicMethod.new(self, pattern, &method_definition).tap do |dynamic_method|
48
+ dynamic_methods << dynamic_method
49
+ end
50
+ end
51
+ end
52
+
53
+ module InstanceMethods
54
+ def respond_to? name, include_private = false #:nodoc:
55
+ !!lookup_dynamic_method(name) || super
56
+ end
57
+
58
+ protected
59
+ def method_missing name, *args, &block #:nodoc:
60
+ matching_method, captures = lookup_dynamic_method name
61
+
62
+ if matching_method
63
+ matching_method.define_and_call self, name, captures, *args, &block
64
+ else
65
+ super
66
+ end
67
+ end
68
+
69
+ private
70
+ def lookup_dynamic_method name #:nodoc:
71
+ match = nil
72
+ matching_method = dynamic_methods.find do |dynamic_method|
73
+ match = dynamic_method.match(name)
74
+ end
75
+
76
+ if matching_method
77
+ [matching_method, match.captures]
78
+ else
79
+ nil
80
+ end
81
+ end
82
+ end
83
+
84
+ def self.included receiver #:nodoc:
85
+ receiver.extend ClassMethods
86
+ receiver.send :include, InstanceMethods
87
+
88
+ receiver.send :class_inheritable_array, :dynamic_methods
89
+ receiver.dynamic_methods = []
90
+ end
91
+ end
@@ -0,0 +1,3 @@
1
+ module DynamicMethods
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ class ATestClass
4
+ include DynamicMethods
5
+ end
6
+
7
+ describe DynamicMethods do
8
+ it 'allows definition of dynamic methods' do
9
+ ATestClass.dynamic_method /some_thing/ do
10
+ end
11
+
12
+ test_object = ATestClass.new
13
+ test_object.should respond_to('some_thing')
14
+ ATestClass.method_defined?(:some_thing).should be(false)
15
+
16
+ proc do
17
+ test_object.some_thing
18
+ end.should_not raise_error(NoMethodError)
19
+
20
+ ATestClass.method_defined?(:some_thing).should be(true)
21
+ end
22
+
23
+ it 'allows definition of dynamic methods with captures' do
24
+ ATestClass.dynamic_method /some_(.*)_(.*)/ do |a, b|
25
+ [a, b]
26
+ end
27
+
28
+ test_object = ATestClass.new
29
+ test_object.should respond_to('some_a_b')
30
+
31
+ proc do
32
+ test_object.some_a_b
33
+ end.should_not raise_error(NoMethodError)
34
+
35
+ test_object.some_a_b.should == ['a', 'b']
36
+ end
37
+
38
+ it 'allows definition of dynamic methods with arguments' do
39
+ ATestClass.dynamic_method /another_method/ do |a, b|
40
+ [a, b]
41
+ end
42
+
43
+ test_object = ATestClass.new
44
+ test_object.should respond_to('another_method')
45
+
46
+ proc do
47
+ test_object.another_method 'a', 'b'
48
+ end.should_not raise_error(NoMethodError)
49
+
50
+ test_object.another_method('a', 'b').should == ['a', 'b']
51
+ end
52
+
53
+ it 'allows definition of dynamic methods with captures and arguments' do
54
+ ATestClass.dynamic_method /another_(.*)_(.*)/ do |a, b, c, d|
55
+ [a, b, c, d]
56
+ end
57
+
58
+ test_object = ATestClass.new
59
+ test_object.should respond_to('another_a_b')
60
+
61
+ proc do
62
+ test_object.another_a_b 'c', 'd'
63
+ end.should_not raise_error(NoMethodError)
64
+
65
+ test_object.another_a_b('c', 'd').should == ['a', 'b', 'c', 'd']
66
+ end
67
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'dynamic_methods'
5
+
6
+ RSpec.configure do |config|
7
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dynamic_methods
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Marian Theisen
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-23 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activesupport
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 0
34
+ version: 3.0.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: bundler
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 23
46
+ segments:
47
+ - 1
48
+ - 0
49
+ - 0
50
+ version: 1.0.0
51
+ type: :development
52
+ version_requirements: *id002
53
+ description: dynamics_methods is a simple gem to easily define ... dynamic methods
54
+ email:
55
+ - marian@cice-online.net
56
+ executables: []
57
+
58
+ extensions: []
59
+
60
+ extra_rdoc_files: []
61
+
62
+ files:
63
+ - .gitignore
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - README.md
67
+ - Rakefile
68
+ - dynamic_methods.gemspec
69
+ - lib/dynamic_methods.rb
70
+ - lib/dynamic_methods/version.rb
71
+ - spec/dynamic_methods_spec.rb
72
+ - spec/spec_helper.rb
73
+ has_rdoc: true
74
+ homepage: http://rubygems.org/gems/dynamic_methods
75
+ licenses: []
76
+
77
+ post_install_message:
78
+ rdoc_options: []
79
+
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ hash: 23
97
+ segments:
98
+ - 1
99
+ - 3
100
+ - 6
101
+ version: 1.3.6
102
+ requirements: []
103
+
104
+ rubyforge_project:
105
+ rubygems_version: 1.3.7
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: dynamics_methods is a simple gem to easily define ... dynamic methods
109
+ test_files: []
110
+