penetrator 0.1.6 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +37 -12
- data/lib/penetrator.rb +16 -4
- data/lib/penetrator/version.rb +1 -1
- data/spec/concern_spec.rb +56 -26
- metadata +2 -2
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Penetrator
|
2
2
|
|
3
|
-
This gem aimed to help
|
4
|
-
Highly inspired
|
3
|
+
This gem aimed to help improving code reuse in ruby projects.
|
4
|
+
Highly inspired by http://github.com/makandra/modularity gem but slightly modified for supporting
|
5
5
|
conventional *super* inheritance methods chaining.
|
6
|
-
Also much of code was shamelessly borrowed from `ActiveSupport::Concern`
|
7
|
-
All what left to do for me -
|
6
|
+
Also much of code was shamelessly borrowed from `ActiveSupport::Concern` so I should say thanks that Ruby Hackers, who wrote it.
|
7
|
+
All that what left to do for me - just to take the best from both worlds.
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -16,7 +16,7 @@ And then execute:
|
|
16
16
|
|
17
17
|
$ bundle
|
18
18
|
|
19
|
-
Or install it yourself
|
19
|
+
Or install it yourself:
|
20
20
|
|
21
21
|
$ gem install penetrator
|
22
22
|
|
@@ -70,6 +70,7 @@ File: *app/controllers/traits/crudable_trait.rb*
|
|
70
70
|
@_resources ||= resource_class.order(default_order).all
|
71
71
|
end
|
72
72
|
end
|
73
|
+
|
73
74
|
```
|
74
75
|
|
75
76
|
File: *app/controllers/accomodations_controller.rb*
|
@@ -136,13 +137,13 @@ File: *app/models/my_model.rb*
|
|
136
137
|
```ruby
|
137
138
|
|
138
139
|
class Victim
|
139
|
-
behaves_like :CanHaveArgs, '
|
140
|
+
behaves_like :CanHaveArgs, 'first', 'second'
|
140
141
|
end
|
141
142
|
|
142
143
|
obj = Victim.new
|
143
144
|
|
144
|
-
obj.
|
145
|
-
obj.
|
145
|
+
obj.first # => first-chunked!
|
146
|
+
obj.second # => second-chunked!
|
146
147
|
|
147
148
|
```
|
148
149
|
|
@@ -154,7 +155,7 @@ Also you can freely utilize `ClassMethods` internal module as you usually do wit
|
|
154
155
|
extend Penetrator::Concern
|
155
156
|
module ClassMethods
|
156
157
|
def class_method
|
157
|
-
... add what you want ...
|
158
|
+
# ... add what you want ...
|
158
159
|
end
|
159
160
|
end
|
160
161
|
|
@@ -164,7 +165,7 @@ Also you can freely utilize `ClassMethods` internal module as you usually do wit
|
|
164
165
|
|
165
166
|
```
|
166
167
|
|
167
|
-
You can
|
168
|
+
You can even extend arbitrary instance of any class with your trait:
|
168
169
|
|
169
170
|
```ruby
|
170
171
|
|
@@ -172,15 +173,39 @@ You can ever extend arbitrary instance of any class with your trait:
|
|
172
173
|
extend Penetrator::Concern
|
173
174
|
|
174
175
|
def cleanup
|
175
|
-
|
176
|
+
# ...
|
176
177
|
end
|
177
178
|
end
|
178
179
|
|
179
|
-
string_of_dirty_html = "Something <span>dirty</span> and even <marquee>fearing ugly</marquee>
|
180
|
+
string_of_dirty_html = "Something <span>dirty</span> and even <marquee>fearing ugly</marquee>"
|
180
181
|
string_of_dirty_html.behave_like 'html_sanitizer'
|
181
182
|
|
182
183
|
```
|
183
184
|
|
185
|
+
`behave_like` also accepts block which can be used in `included` section.
|
186
|
+
I have no idea whom need that, but decided to make it possible.
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
|
190
|
+
module HtmlSanitizerTrait
|
191
|
+
included do |*args, block|
|
192
|
+
args.each do |method_name|
|
193
|
+
define_method(method_name) do
|
194
|
+
method_name.to_s
|
195
|
+
end
|
196
|
+
end
|
197
|
+
block.call if block
|
198
|
+
end # included
|
199
|
+
|
200
|
+
class VictimWithBlock
|
201
|
+
behaves_like :HtmlSanitizerTrait, 'cleanup_processor' do
|
202
|
+
class_variable_set(:@@foo, "I'm set")
|
203
|
+
# ... something useful
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
```
|
208
|
+
|
184
209
|
|
185
210
|
## Contributing
|
186
211
|
|
data/lib/penetrator.rb
CHANGED
@@ -18,13 +18,23 @@ module Penetrator
|
|
18
18
|
@_dependencies.each { |dep| base.send(:include, dep) }
|
19
19
|
super
|
20
20
|
base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
|
21
|
-
|
21
|
+
return unless instance_variable_defined?("@_included_block")
|
22
|
+
if @_trait_block
|
23
|
+
base.class_exec(*@_trait_args, @_trait_block, &@_included_block)
|
24
|
+
else
|
25
|
+
base.class_exec(*@_trait_args, &@_included_block)
|
26
|
+
end
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
30
|
def extend_object(obj)
|
26
31
|
super
|
27
|
-
|
32
|
+
return unless instance_variable_defined?("@_included_block")
|
33
|
+
if @_trait_block
|
34
|
+
(class << obj; self; end).instance_exec(*@_trait_args, @_trait_block, &@_included_block)
|
35
|
+
else
|
36
|
+
(class << obj; self; end).instance_exec(*@_trait_args, &@_included_block)
|
37
|
+
end
|
28
38
|
end
|
29
39
|
|
30
40
|
def included(base = nil, &block)
|
@@ -42,18 +52,20 @@ module Penetrator
|
|
42
52
|
end
|
43
53
|
|
44
54
|
module ClassMethods
|
45
|
-
def behaves_like(trait_name, *args)
|
55
|
+
def behaves_like(trait_name, *args, &block)
|
46
56
|
full_name = "#{Penetrator::Inflector.camelize(trait_name.to_s)}Trait"
|
47
57
|
trait = Penetrator::Inflector.constantize(full_name)
|
48
58
|
trait.instance_variable_set(:@_trait_args, args)
|
59
|
+
trait.instance_variable_set(:@_trait_block, block)
|
49
60
|
include trait
|
50
61
|
end
|
51
62
|
end # ClassMethods
|
52
63
|
|
53
|
-
def behaves_like(trait_name, *args)
|
64
|
+
def behaves_like(trait_name, *args, &block)
|
54
65
|
full_name = "#{Penetrator::Inflector.camelize(trait_name.to_s)}Trait"
|
55
66
|
trait = Penetrator::Inflector.constantize(full_name)
|
56
67
|
trait.instance_variable_set(:@_trait_args, args)
|
68
|
+
trait.instance_variable_set(:@_trait_block, block)
|
57
69
|
extend trait
|
58
70
|
end
|
59
71
|
end # Behavior
|
data/lib/penetrator/version.rb
CHANGED
data/spec/concern_spec.rb
CHANGED
@@ -58,35 +58,65 @@ describe 'behavior when trait add ClassMethods and Instance methods' do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
61
|
+
describe 'behavior when trait add ClassMethods and Instance methods alongside with existing' do
|
62
|
+
module SuperRichTrait
|
63
|
+
extend Penetrator::Concern
|
64
|
+
module ClassMethods
|
65
|
+
def class_method(arg)
|
66
|
+
"From Trait with chaining"
|
67
|
+
end
|
68
|
+
end
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
def instance_method(arg)
|
71
|
+
"From Trait with chaining"
|
72
|
+
end
|
73
|
+
end
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
75
|
+
it 'add class and instance methods from traits' do
|
76
|
+
class Innocent
|
77
|
+
def self.class_method arg
|
78
|
+
"This is class argument: #{arg} " + super
|
79
|
+
end
|
80
|
+
def instance_method arg
|
81
|
+
"This is instance argument: #{arg} " + super
|
82
|
+
end
|
83
83
|
|
84
|
-
|
85
|
-
|
84
|
+
behaves_like 'super_rich'
|
85
|
+
end
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
87
|
+
obj = Innocent.new
|
88
|
+
obj.instance_method('iarg').must_be :==, 'This is instance argument: iarg From Trait with chaining'
|
89
|
+
Innocent.class_method('carg').must_be :==, 'This is class argument: carg From Trait with chaining'
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
describe 'behavior when trait utilize arguments and block' do
|
97
|
+
module WithArgsAndBlockTrait
|
98
|
+
extend Penetrator::Concern
|
99
|
+
included do |*args, block|
|
100
|
+
args.each do |method_name|
|
101
|
+
define_method(method_name) do
|
102
|
+
method_name.to_s
|
103
|
+
end
|
104
|
+
end
|
105
|
+
block.call if block
|
106
|
+
end # included
|
107
|
+
|
108
|
+
end # WithArgsAndBlockTrait
|
109
|
+
|
110
|
+
it 'receive trait block' do
|
111
|
+
class VictimWithBlock
|
112
|
+
behaves_like :WithArgsAndBlock, 'arg1' do
|
113
|
+
class_variable_set(:@@foo, "I'm set")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
obj = VictimWithBlock.new
|
117
|
+
obj.must_respond_to :arg1
|
118
|
+
obj.arg1.must_be :==, 'arg1'
|
119
|
+
VictimWithBlock.class_variable_get(:@@foo).must_be :==, "I'm set"
|
120
|
+
end
|
91
121
|
|
92
122
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: penetrator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|