penetrator 0.1.0 → 0.1.6
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/README.md +136 -59
- data/lib/penetrator/version.rb +16 -1
- data/lib/penetrator.rb +14 -1
- data/penetrator.gemspec +1 -1
- data/spec/{coerce_spec.rb → concern_spec.rb} +1 -1
- data/spec/object_spec.rb +54 -0
- metadata +6 -4
data/README.md
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
This gem aimed to help with reuse code in ruby projects.
|
4
4
|
Highly inspired from http://github.com/makandra/modularity gem but slightly modified for supporting
|
5
|
-
conventional *super* inheritance chaining
|
6
|
-
Also
|
5
|
+
conventional *super* inheritance methods chaining.
|
6
|
+
Also much of code was shamelessly borrowed from `ActiveSupport::Concern` and I should say thanks that Ruby Hackers, who wrote it.
|
7
|
+
All what left to do for me - it's just take the best from both worlds.
|
7
8
|
|
8
9
|
## Installation
|
9
10
|
|
@@ -24,85 +25,161 @@ Or install it yourself as:
|
|
24
25
|
|
25
26
|
*config/application.rb*
|
26
27
|
```ruby
|
27
|
-
config.autoload_paths += Rails.root.join( 'app', 'traits' )
|
28
|
+
config.autoload_paths += Rails.root.join( 'app', 'traits' )
|
28
29
|
```
|
29
30
|
|
30
|
-
*app/controllers/traits/crudable_trait.rb*
|
31
|
+
File: *app/controllers/traits/crudable_trait.rb*
|
31
32
|
```ruby
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
33
|
+
|
34
|
+
module CrudableTrait
|
35
|
+
included do
|
36
|
+
helper_method :resource, :resources # they are will be used in views
|
37
|
+
end
|
38
|
+
#
|
39
|
+
# Implementation
|
40
|
+
public
|
41
|
+
|
42
|
+
def index
|
43
|
+
respond_to do |format|
|
44
|
+
format.html { render layout: take_layout }
|
45
|
+
format.json { render json: resources }
|
46
|
+
format.js
|
44
47
|
end
|
48
|
+
end
|
45
49
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
50
|
+
def show
|
51
|
+
respond_to do |format|
|
52
|
+
format.html { render layout: take_layout }
|
53
|
+
format.json { render json: resource }
|
54
|
+
format.js
|
52
55
|
end
|
56
|
+
end
|
53
57
|
|
54
|
-
|
58
|
+
# ... and so on ...
|
55
59
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
+
private
|
61
|
+
def take_layout
|
62
|
+
# ...
|
63
|
+
end
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
+
def resource
|
66
|
+
@_resource ||= resource_class.find(params[:id])
|
67
|
+
end
|
68
|
+
|
69
|
+
def resources
|
70
|
+
@_resources ||= resource_class.order(default_order).all
|
71
|
+
end
|
72
|
+
end
|
65
73
|
```
|
66
74
|
|
67
|
-
*app/controllers/accomodations_controller.rb*
|
75
|
+
File: *app/controllers/accomodations_controller.rb*
|
68
76
|
```ruby
|
69
|
-
class AccomodationsController < ApplicationController
|
70
|
-
#
|
71
|
-
# CrudableTrait required this mehod
|
72
|
-
private
|
73
|
-
def resource_class
|
74
|
-
Accomodation
|
75
|
-
end
|
76
77
|
|
77
|
-
|
78
|
+
class AccomodationsController < ApplicationController
|
79
|
+
#
|
80
|
+
# CrudableTrait assumes that this mehod exists
|
81
|
+
private
|
82
|
+
def resource_class
|
83
|
+
Accomodation
|
84
|
+
end
|
78
85
|
|
79
|
-
|
80
|
-
def index
|
81
|
-
if current_user.is_admin?
|
82
|
-
# ...
|
83
|
-
else
|
84
|
-
super
|
85
|
-
end
|
86
|
-
end
|
86
|
+
behave_like "crudable"
|
87
87
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
88
|
+
# Override public traits method
|
89
|
+
def index
|
90
|
+
if current_user.is_admin?
|
91
|
+
# ...
|
92
|
+
else
|
93
|
+
super
|
93
94
|
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
# Override traits methods
|
100
|
+
#
|
101
|
+
def default_order
|
102
|
+
"accomodations.name desc"
|
103
|
+
end
|
104
|
+
|
105
|
+
public
|
94
106
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
107
|
+
# Override traits methods
|
108
|
+
# with respecting call chaining
|
109
|
+
#
|
110
|
+
def kill_all_humans
|
111
|
+
"Yes" or super
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
What makes this gem different from `ActiveSupport::Concern` ?
|
118
|
+
Well, here you can _parameterize_ your included modules-traits!
|
119
|
+
(Extracted from `spec/coerce_spec.rb` )
|
120
|
+
|
121
|
+
File: *app/traits/can_have_args_trait.rb*
|
122
|
+
```ruby
|
123
|
+
module CanHaveArgsTrait
|
124
|
+
extend Penetrator::Concern
|
125
|
+
included do |*args|
|
126
|
+
args.each do |method_name|
|
127
|
+
define_method(method_name) do
|
128
|
+
method_name.to_s + "-chunked!"
|
101
129
|
end
|
130
|
+
end
|
131
|
+
end # included
|
132
|
+
end # CanHaveArgs
|
133
|
+
```
|
134
|
+
|
135
|
+
File: *app/models/my_model.rb*
|
136
|
+
```ruby
|
137
|
+
|
138
|
+
class Victim
|
139
|
+
behaves_like :CanHaveArgs, 'arg1', 'arg2'
|
140
|
+
end
|
141
|
+
|
142
|
+
obj = Victim.new
|
102
143
|
|
144
|
+
obj.arg1 # => 'arg1-chunked!'
|
145
|
+
obj.arg2 # => 'arg2-chunked!'
|
146
|
+
|
147
|
+
```
|
148
|
+
|
149
|
+
Also you can freely utilize `ClassMethods` internal module as you usually do with `ActiveSupport::Concern`
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
|
153
|
+
module RichTrait
|
154
|
+
extend Penetrator::Concern
|
155
|
+
module ClassMethods
|
156
|
+
def class_method
|
157
|
+
... add what you want ...
|
103
158
|
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def instance_method
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
104
165
|
```
|
105
166
|
|
167
|
+
You can ever extend arbitrary instance of any class with your trait:
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
|
171
|
+
module HtmlSanitizerTrait
|
172
|
+
extend Penetrator::Concern
|
173
|
+
|
174
|
+
def cleanup
|
175
|
+
....
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
string_of_dirty_html = "Something <span>dirty</span> and even <marquee>fearing ugly</marquee>
|
180
|
+
string_of_dirty_html.behave_like 'html_sanitizer'
|
181
|
+
|
182
|
+
```
|
106
183
|
|
107
184
|
|
108
185
|
## Contributing
|
data/lib/penetrator/version.rb
CHANGED
@@ -1,4 +1,19 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
|
2
3
|
module Penetrator
|
3
|
-
|
4
|
+
# Contains information about this gem's version
|
5
|
+
module Version
|
6
|
+
MAJOR = 0
|
7
|
+
MINOR = 1
|
8
|
+
PATCH = 6
|
9
|
+
|
10
|
+
# Returns a version string by joining <tt>MAJOR</tt>, <tt>MINOR</tt>, and <tt>PATCH</tt> with <tt>'.'</tt>
|
11
|
+
#
|
12
|
+
# Example
|
13
|
+
#
|
14
|
+
# Version.to_s # '1.0.2'
|
15
|
+
def self.to_s
|
16
|
+
[MAJOR, MINOR, PATCH].join('.')
|
17
|
+
end
|
18
|
+
end
|
4
19
|
end
|
data/lib/penetrator.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require "penetrator/inflector"
|
3
|
-
require "penetrator/version"
|
4
3
|
|
5
4
|
module Penetrator
|
5
|
+
autoload :Version, 'penetrator/version'
|
6
|
+
|
6
7
|
module Concern
|
7
8
|
def self.extended(base) #:nodoc:
|
8
9
|
base.instance_variable_set("@_dependencies", [])
|
@@ -21,6 +22,11 @@ module Penetrator
|
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
25
|
+
def extend_object(obj)
|
26
|
+
super
|
27
|
+
(class << obj; self; end).instance_exec(*@_trait_args, &@_included_block) if instance_variable_defined?("@_included_block")
|
28
|
+
end
|
29
|
+
|
24
30
|
def included(base = nil, &block)
|
25
31
|
if base.nil?
|
26
32
|
@_included_block = block
|
@@ -43,6 +49,13 @@ module Penetrator
|
|
43
49
|
include trait
|
44
50
|
end
|
45
51
|
end # ClassMethods
|
52
|
+
|
53
|
+
def behaves_like(trait_name, *args)
|
54
|
+
full_name = "#{Penetrator::Inflector.camelize(trait_name.to_s)}Trait"
|
55
|
+
trait = Penetrator::Inflector.constantize(full_name)
|
56
|
+
trait.instance_variable_set(:@_trait_args, args)
|
57
|
+
extend trait
|
58
|
+
end
|
46
59
|
end # Behavior
|
47
60
|
|
48
61
|
end
|
data/penetrator.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
14
|
gem.name = "penetrator"
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.version = Penetrator::
|
16
|
+
gem.version = Penetrator::Version.to_s
|
17
17
|
if RUBY_VERSION < '1.9.0'
|
18
18
|
gem.add_development_dependency "minitest"
|
19
19
|
end
|
@@ -3,7 +3,7 @@ require 'penetrator'
|
|
3
3
|
require 'minitest/spec'
|
4
4
|
require 'minitest/autorun'
|
5
5
|
|
6
|
-
describe 'behavior when trait
|
6
|
+
describe 'behavior when trait parameterized by arguments passed into included module' do
|
7
7
|
module CanHaveArgsTrait
|
8
8
|
extend Penetrator::Concern
|
9
9
|
included do |*args|
|
data/spec/object_spec.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'penetrator'
|
3
|
+
require 'minitest/spec'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
describe 'when object of any class extended by trait' do
|
7
|
+
module ObjectRelatedTrait
|
8
|
+
extend Penetrator::Concern
|
9
|
+
def testing_method
|
10
|
+
"It Works!"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'could extend particular object' do
|
15
|
+
object = Object.new
|
16
|
+
object.behaves_like "object_related"
|
17
|
+
|
18
|
+
object.must_respond_to :testing_method
|
19
|
+
object.testing_method.must_be :==, 'It Works!'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'not extend others objects the same class' do
|
23
|
+
object = Object.new
|
24
|
+
object.behaves_like "object_related"
|
25
|
+
|
26
|
+
second_object = Object.new
|
27
|
+
second_object.wont_respond_to :testing_method
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'behavior when trait parameterized by arguments passed into included module' do
|
33
|
+
module CanHaveArgsTrait
|
34
|
+
extend Penetrator::Concern
|
35
|
+
included do |*args|
|
36
|
+
args.each do |method_name|
|
37
|
+
define_method(method_name) do
|
38
|
+
method_name.to_s
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end # included
|
42
|
+
end # CanHaveArgs
|
43
|
+
|
44
|
+
it 'receive trait arguments' do
|
45
|
+
object = Object.new
|
46
|
+
object.behaves_like :CanHaveArgs, 'arg1', 'arg2'
|
47
|
+
|
48
|
+
object.must_respond_to :arg1
|
49
|
+
object.arg1.must_be :==, 'arg1'
|
50
|
+
object.must_respond_to :arg2
|
51
|
+
object.arg2.must_be :==, 'arg2'
|
52
|
+
end
|
53
|
+
|
54
|
+
end # trait argument
|
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.6
|
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-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -59,8 +59,9 @@ files:
|
|
59
59
|
- lib/penetrator/inflector.rb
|
60
60
|
- lib/penetrator/version.rb
|
61
61
|
- penetrator.gemspec
|
62
|
-
- spec/
|
62
|
+
- spec/concern_spec.rb
|
63
63
|
- spec/core_spec.rb
|
64
|
+
- spec/object_spec.rb
|
64
65
|
homepage: https://github.com/svenyurgensson/penetrator
|
65
66
|
licenses: []
|
66
67
|
post_install_message:
|
@@ -86,5 +87,6 @@ signing_key:
|
|
86
87
|
specification_version: 3
|
87
88
|
summary: Implement traits behavior to get rid of code repetition
|
88
89
|
test_files:
|
89
|
-
- spec/
|
90
|
+
- spec/concern_spec.rb
|
90
91
|
- spec/core_spec.rb
|
92
|
+
- spec/object_spec.rb
|