dynamic_methods 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +28 -0
- data/README.md +29 -0
- data/Rakefile +7 -0
- data/dynamic_methods.gemspec +23 -0
- data/lib/dynamic_methods.rb +91 -0
- data/lib/dynamic_methods/version.rb +3 -0
- data/spec/dynamic_methods_spec.rb +67 -0
- data/spec/spec_helper.rb +7 -0
- metadata +110 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
@@ -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,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
|
data/spec/spec_helper.rb
ADDED
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
|
+
|