method_wrapper 0.1.0
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 +3 -0
- data/Gemfile.lock +27 -0
- data/README.rdoc +74 -0
- data/Rakefile +2 -0
- data/lib/method_wrapper/version.rb +4 -0
- data/lib/method_wrapper.rb +52 -0
- data/method_wrapper.gemspec +24 -0
- data/spec/class_builder.rb +83 -0
- data/spec/method_wrapper_spec.rb +58 -0
- data/spec/spec_helper.rb +5 -0
- metadata +108 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
method_wrapper (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.1.2)
|
10
|
+
rspec (2.0.1)
|
11
|
+
rspec-core (~> 2.0.1)
|
12
|
+
rspec-expectations (~> 2.0.1)
|
13
|
+
rspec-mocks (~> 2.0.1)
|
14
|
+
rspec-core (2.0.1)
|
15
|
+
rspec-expectations (2.0.1)
|
16
|
+
diff-lcs (>= 1.1.2)
|
17
|
+
rspec-mocks (2.0.1)
|
18
|
+
rspec-core (~> 2.0.1)
|
19
|
+
rspec-expectations (~> 2.0.1)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
bundler (>= 1.0.0.rc.5)
|
26
|
+
method_wrapper!
|
27
|
+
rspec (>= 2.0.0)
|
data/README.rdoc
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
= Method Wrapper
|
2
|
+
|
3
|
+
<em>Lightweight method wrapper in Ruby.</em>
|
4
|
+
|
5
|
+
== Introduction
|
6
|
+
|
7
|
+
This gem help you to to wrap new features around (before and after) existing methods call on Any classes.
|
8
|
+
|
9
|
+
The before_ and after_ callbacks will run as soon as you call wrapped method.
|
10
|
+
|
11
|
+
== Installation
|
12
|
+
|
13
|
+
gem install method_wrapper
|
14
|
+
|
15
|
+
== Examples
|
16
|
+
require 'method_wrapper'
|
17
|
+
|
18
|
+
class Klass
|
19
|
+
include MethodWrapper
|
20
|
+
wrap_methods :method_name
|
21
|
+
|
22
|
+
def method_name
|
23
|
+
puts 'hi'
|
24
|
+
end
|
25
|
+
|
26
|
+
def before_method_name
|
27
|
+
puts "calls before method name"
|
28
|
+
end
|
29
|
+
|
30
|
+
def after_method_name
|
31
|
+
puts "calls after method name"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
You can also has partial callback
|
36
|
+
require 'method_wrapper'
|
37
|
+
|
38
|
+
class Klass
|
39
|
+
include MethodWrapper
|
40
|
+
wrap_methods :method_name, :second_method_name
|
41
|
+
|
42
|
+
def method_name
|
43
|
+
puts 'hi'
|
44
|
+
end
|
45
|
+
|
46
|
+
def second_method_name
|
47
|
+
puts 'hello'
|
48
|
+
end
|
49
|
+
|
50
|
+
def before_method_name
|
51
|
+
puts "calls before method name"
|
52
|
+
end
|
53
|
+
|
54
|
+
def after_method_name
|
55
|
+
puts "calls after method name"
|
56
|
+
end
|
57
|
+
|
58
|
+
def after_second_method_name
|
59
|
+
puts "calls after second method name"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
You can also open the existing classes to wrap methods
|
64
|
+
require 'method_wrapper'
|
65
|
+
|
66
|
+
class String
|
67
|
+
include MethodWrapper
|
68
|
+
wrap_methods :reverse
|
69
|
+
|
70
|
+
def before_reverse
|
71
|
+
puts "calls before string reverse"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module MethodWrapper
|
2
|
+
def self.included(base)
|
3
|
+
base.instance_variable_set(:@_wrapped_methods, [])
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
def invoke_method(name)
|
9
|
+
send(name) if respond_to? name, true
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def method_added(name)
|
14
|
+
return if @_disable_hook_method_added
|
15
|
+
|
16
|
+
_wrap_method!(name) if @_wrapped_methods.include? name
|
17
|
+
end
|
18
|
+
|
19
|
+
def wrap_methods(*args)
|
20
|
+
@_wrapped_methods = args
|
21
|
+
|
22
|
+
@_wrapped_methods.each do |name|
|
23
|
+
_wrap_method!(name) if instance_method_defined? name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def _wrap_method!(name)
|
29
|
+
@_disable_hook_method_added = true
|
30
|
+
|
31
|
+
origin_method_name = "origin_#{name}"
|
32
|
+
origin_method = instance_method(name)
|
33
|
+
|
34
|
+
alias_method origin_method_name, name
|
35
|
+
|
36
|
+
define_method(name) do |*args, &block|
|
37
|
+
invoke_method("before_#{name}")
|
38
|
+
return_result = origin_method.bind(self).call(*args, &block)
|
39
|
+
invoke_method("after_#{name}")
|
40
|
+
|
41
|
+
return_result
|
42
|
+
end
|
43
|
+
|
44
|
+
@_disable_hook_method_added = false
|
45
|
+
end
|
46
|
+
|
47
|
+
def instance_method_defined?(name)
|
48
|
+
instance_methods.include? name.to_sym
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
3
|
+
require 'method_wrapper/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "method_wrapper"
|
7
|
+
s.version = MethodWrapper::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Samnang Chhun"]
|
10
|
+
s.email = ["samnang.chhun@gmail.com"]
|
11
|
+
s.homepage = "http://github.com/samnang/method_wrapper"
|
12
|
+
s.summary = "How easy to wrap new features around (before and after) existing methods call with method_wrapper."
|
13
|
+
s.description = "This gem help you to to wrap new features around (before and after) existing methods call on Any classes. The before_ and after_ callbacks will run as soon as you call wrapped method."
|
14
|
+
|
15
|
+
s.required_rubygems_version = ">= 1.3.6"
|
16
|
+
s.rubyforge_project = "[none]"
|
17
|
+
|
18
|
+
s.add_development_dependency "bundler", ">= 1.0.0.rc.5"
|
19
|
+
s.add_development_dependency "rspec", ">= 2.0.0"
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.require_path = 'lib'
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
class ClassBuilder
|
2
|
+
class << self
|
3
|
+
def a_class_has_methods_and_calls_after_methods_defined
|
4
|
+
Class.new do
|
5
|
+
include MethodWrapper
|
6
|
+
|
7
|
+
def method_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def second_method_name
|
11
|
+
end
|
12
|
+
|
13
|
+
wrap_methods :method_name, :second_method_name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def a_class_has_methods_and_calls_before_methods_defined
|
18
|
+
Class.new do
|
19
|
+
include MethodWrapper
|
20
|
+
wrap_methods :method_name, :second_method_name
|
21
|
+
|
22
|
+
def method_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def second_method_name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def a_class_has_before_and_after_wrap_methods
|
31
|
+
Class.new do
|
32
|
+
include MethodWrapper
|
33
|
+
wrap_methods :method_name
|
34
|
+
|
35
|
+
def method_name
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def before_method_name
|
40
|
+
@has_called_before_callback = true
|
41
|
+
end
|
42
|
+
|
43
|
+
def after_method_name
|
44
|
+
@has_called_after_callback = true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def a_class_has_partial_callback
|
50
|
+
Class.new do
|
51
|
+
include MethodWrapper
|
52
|
+
|
53
|
+
def method_name
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def before_method_name
|
58
|
+
@has_called_before_callback = true
|
59
|
+
end
|
60
|
+
|
61
|
+
wrap_methods :method_name
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def a_class_has_method_with_args_and_block
|
66
|
+
Class.new do
|
67
|
+
include MethodWrapper
|
68
|
+
wrap_methods :method_name
|
69
|
+
|
70
|
+
def method_name(param)
|
71
|
+
@param = param
|
72
|
+
yield
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
def after_method_name
|
77
|
+
@has_called_after_callback = true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MethodWrapper do
|
4
|
+
describe ".wrap_methods, stores methods that want to wrap" do
|
5
|
+
it "calls after method defined" do
|
6
|
+
klass = ClassBuilder.a_class_has_methods_and_calls_after_methods_defined
|
7
|
+
|
8
|
+
verify_wrapped_methods(klass)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "calls before method defined" do
|
12
|
+
klass = ClassBuilder.a_class_has_methods_and_calls_before_methods_defined
|
13
|
+
|
14
|
+
verify_wrapped_methods(klass)
|
15
|
+
end
|
16
|
+
|
17
|
+
def verify_wrapped_methods(klass)
|
18
|
+
klass.instance_variable_get(:@_wrapped_methods).should ==
|
19
|
+
[:method_name, :second_method_name]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "invoke the wrapped methods" do
|
24
|
+
it "should invoke _before_method_name and after_method_name" do
|
25
|
+
klass = ClassBuilder.a_class_has_before_and_after_wrap_methods
|
26
|
+
obj = klass.new
|
27
|
+
|
28
|
+
obj.method_name
|
29
|
+
|
30
|
+
obj.instance_variable_get(:@has_called_before_callback).should eql(true)
|
31
|
+
obj.instance_variable_get(:@has_called_after_callback).should eql(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should ignore callbacks if user hasn't defined" do
|
35
|
+
klass = ClassBuilder.a_class_has_partial_callback
|
36
|
+
obj = klass.new
|
37
|
+
|
38
|
+
obj.method_name
|
39
|
+
|
40
|
+
obj.instance_variable_get(:@has_called_before_callback).should eql(true)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be able to invoke the method with args and block" do
|
44
|
+
klass = ClassBuilder.a_class_has_method_with_args_and_block
|
45
|
+
obj = klass.new
|
46
|
+
has_called = false
|
47
|
+
|
48
|
+
obj.method_name("value") do
|
49
|
+
has_called = true
|
50
|
+
end
|
51
|
+
|
52
|
+
obj.instance_variable_get(:@param).should eql("value")
|
53
|
+
has_called.should eql(true)
|
54
|
+
obj.instance_variable_get(:@has_called_after_callback).should eql(true)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: method_wrapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Samnang Chhun
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-10-30 00:00:00 +07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: bundler
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
- rc
|
33
|
+
- 5
|
34
|
+
version: 1.0.0.rc.5
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rspec
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
segments:
|
46
|
+
- 2
|
47
|
+
- 0
|
48
|
+
- 0
|
49
|
+
version: 2.0.0
|
50
|
+
type: :development
|
51
|
+
version_requirements: *id002
|
52
|
+
description: This gem help you to to wrap new features around (before and after) existing methods call on Any classes. The before_ and after_ callbacks will run as soon as you call wrapped method.
|
53
|
+
email:
|
54
|
+
- samnang.chhun@gmail.com
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files: []
|
60
|
+
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- Gemfile.lock
|
65
|
+
- README.rdoc
|
66
|
+
- Rakefile
|
67
|
+
- lib/method_wrapper.rb
|
68
|
+
- lib/method_wrapper/version.rb
|
69
|
+
- method_wrapper.gemspec
|
70
|
+
- spec/class_builder.rb
|
71
|
+
- spec/method_wrapper_spec.rb
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
has_rdoc: true
|
74
|
+
homepage: http://github.com/samnang/method_wrapper
|
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
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
segments:
|
96
|
+
- 1
|
97
|
+
- 3
|
98
|
+
- 6
|
99
|
+
version: 1.3.6
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project: "[none]"
|
103
|
+
rubygems_version: 1.3.7
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: How easy to wrap new features around (before and after) existing methods call with method_wrapper.
|
107
|
+
test_files: []
|
108
|
+
|