super_module 1.2.0 → 1.2.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.
- checksums.yaml +4 -4
- data/README.md +13 -7
- data/VERSION +1 -1
- data/lib/super_module.rb +2 -1
- data/ruby187.Gemfile +2 -1
- data/spec/lib/super_module_spec.rb +11 -1
- data/super_module.gemspec +39 -24
- metadata +75 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 68d5daba9c77fe5ee84f024856002607eaa567fb
|
|
4
|
+
data.tar.gz: 0fdb3c4950a1ffa2fea44970561c2c688a355fb1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad5348c682aa493a0a22196b16c976e8bbeb1708aaf912503408bc4731eba158009ce44100237be0c5843848fcbf85f77a289656a5e686e14990238c98594c09
|
|
7
|
+
data.tar.gz: c5727909276e62bbff1e9ac82399cefb683a089c17b5a017924a66b6b4794555746a3add17b0731f03f3f4c71b358f96b7367c70acfea3a71fa21c217428817e
|
data/README.md
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
# <img src="https://raw.githubusercontent.com/AndyObtiva/super_module/master/SuperModule.jpg" alt="SuperModule" align="left" height="50" /> SuperModule 2 Beta (1.2.
|
|
1
|
+
# <img src="https://raw.githubusercontent.com/AndyObtiva/super_module/master/SuperModule.jpg" alt="SuperModule" align="left" height="50" /> SuperModule 2 Beta (1.2.1)
|
|
2
2
|
[](http://badge.fury.io/rb/super_module)
|
|
3
3
|
[](https://travis-ci.org/AndyObtiva/super_module)
|
|
4
4
|
[](https://coveralls.io/r/AndyObtiva/super_module?branch=master)
|
|
5
5
|
[](https://codeclimate.com/github/AndyObtiva/super_module)
|
|
6
6
|
|
|
7
|
-
Calling [Ruby](https://www.ruby-lang.org/en/)'s [`Module#include`](http://ruby-doc.org/core-2.2.1/Module.html#method-i-include) to mix in a module does not bring in class methods by default. This can come as quite
|
|
7
|
+
Calling [Ruby](https://www.ruby-lang.org/en/)'s [`Module#include`](http://ruby-doc.org/core-2.2.1/Module.html#method-i-include) to mix in a module does not bring in class methods by default. This can come as quite the surprise when attempting to include class methods via a module.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Ruby offers one workaround in the form of implementing the hook method [`Module.included(base)`](http://ruby-doc.org/core-2.2.1/Module.html#method-i-included) [following a certain boilerplate code idiom](http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/). Unfortunately, it hinders code maintainability and productivity with extra unnecessary complexity, especially in production-environment projects employing many [mixins](http://en.wikipedia.org/wiki/Mixin) (e.g. modeling business domain models with composable object [traits](http://en.wikipedia.org/wiki/Trait_(computer_programming))).
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Another workaround is [`ActiveSupport::Concern`](http://api.rubyonrails.org/classes/ActiveSupport/Concern.html), a Rails library that attempts to ease some of the boilerplate pain by offering a [DSL](http://www.infoq.com/news/2007/06/dsl-or-not) layer on top of [`Module.included(base)`](http://ruby-doc.org/core-2.2.1/Module.html#method-i-included). Unfortunately, while it helps improve readability a bit, it adds even more boilerplate idiom cruft, thus feeling no more than putting a band-aid on the problem.
|
|
12
|
+
|
|
13
|
+
But do not fear, [SuperModule](https://rubygems.org/gems/super_module) comes to the rescue! By declaring your module as a `super_module`, it will simply behave as one would expect and automatically include class methods along with instance methods, without any further work needed.
|
|
12
14
|
|
|
13
15
|
## Introductory Comparison
|
|
14
16
|
|
|
15
17
|
To introduce [SuperModule](https://rubygems.org/gems/super_module), here is a comparison of three different approaches for writing a
|
|
16
|
-
<code>UserIdentifiable</code> module.
|
|
18
|
+
<code>UserIdentifiable</code> module, which includes ActiveModel::Model module as an in-memory alternative to ActiveRecord::Base superclass (Side-note: ActiveModel::Model is not needed when extending ActiveRecord::Base to connect to database.)
|
|
17
19
|
|
|
18
20
|
#### 1) [self.included(base)](http://ruby-doc.org/core-2.2.1/Module.html#method-i-included)
|
|
19
21
|
|
|
@@ -21,8 +23,8 @@ To introduce [SuperModule](https://rubygems.org/gems/super_module), here is a co
|
|
|
21
23
|
module UserIdentifiable
|
|
22
24
|
include ActiveModel::Model
|
|
23
25
|
|
|
24
|
-
def self.included(
|
|
25
|
-
|
|
26
|
+
def self.included(base)
|
|
27
|
+
base.extend(ClassMethods)
|
|
26
28
|
base.class_eval do
|
|
27
29
|
belongs_to :user
|
|
28
30
|
validates :user_id, presence: true
|
|
@@ -290,6 +292,10 @@ In the future, [SuperModule](https://rubygems.org/gems/super_module) could perha
|
|
|
290
292
|
|
|
291
293
|
## What's New?
|
|
292
294
|
|
|
295
|
+
### v2 Beta (v1.2.1)
|
|
296
|
+
|
|
297
|
+
* Standalone super module usage (e.g. direct class method invocation)
|
|
298
|
+
|
|
293
299
|
### v2 Beta (v1.2.0)
|
|
294
300
|
|
|
295
301
|
* New `super_module(name)` syntax
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.2.
|
|
1
|
+
1.2.1
|
data/lib/super_module.rb
CHANGED
|
@@ -50,7 +50,8 @@ def super_module(name=nil, &super_module_body)
|
|
|
50
50
|
parent = SuperModule.__super_module_parent(name, initial_ancestor)
|
|
51
51
|
module_name = name.to_s.split('::').last
|
|
52
52
|
parent.const_set(module_name, new_super_module)
|
|
53
|
+
super_module_body = new_super_module.super_module_body
|
|
54
|
+
new_super_module.class_eval(&super_module_body)
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
57
|
end
|
|
56
|
-
|
data/ruby187.Gemfile
CHANGED
|
@@ -7,11 +7,12 @@ group :development do
|
|
|
7
7
|
gem "rdoc", "~> 4.2.0"
|
|
8
8
|
gem "rspec", "~> 3.2.0"
|
|
9
9
|
|
|
10
|
-
# Ruby 1.8.7
|
|
10
|
+
# Ruby 1.8.7 requires some older gems
|
|
11
11
|
gem "mime-types", "~> 1.25.1"
|
|
12
12
|
gem "netrc", "~> 0.9.0"
|
|
13
13
|
gem "rest-client", "~> 1.6.0"
|
|
14
14
|
gem "nokogiri", "~> 1.5.0"
|
|
15
15
|
gem "highline", "~> 1.6.21"
|
|
16
|
+
gem "rake", "< 11.0"
|
|
16
17
|
end
|
|
17
18
|
|
|
@@ -28,9 +28,19 @@ describe SuperModule do
|
|
|
28
28
|
class BazActiveRecord < FakeActiveRecord
|
|
29
29
|
include SupportVersion::Baz
|
|
30
30
|
end
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
context version do
|
|
33
33
|
|
|
34
|
+
context "standalone module usage" do
|
|
35
|
+
subject { Support::V2::FakeActiveModel }
|
|
36
|
+
|
|
37
|
+
it 'allows invoking class methods' do
|
|
38
|
+
subject.validates 'foo', {:presence => true}
|
|
39
|
+
expect(subject.validations).to include(['foo', {:presence => true}])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
34
44
|
context "included by a module (Foo) that is included by a class (FooActiveRecord)" do
|
|
35
45
|
|
|
36
46
|
subject { FooActiveRecord }
|
data/super_module.gemspec
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
|
-
# stub: super_module 1.2.
|
|
5
|
+
# stub: super_module 1.2.1 ruby lib
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
|
-
s.name = "super_module"
|
|
9
|
-
s.version = "1.2.
|
|
8
|
+
s.name = "super_module".freeze
|
|
9
|
+
s.version = "1.2.1"
|
|
10
10
|
|
|
11
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
12
|
-
s.require_paths = ["lib"]
|
|
13
|
-
s.authors = ["Andy Maleh"]
|
|
14
|
-
s.date = "
|
|
15
|
-
s.description = "SuperModule allows defining class methods and method invocations the same way a super class does without using def included(base). This also succeeds ActiveSupport::Concern by offering lighter syntax"
|
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
12
|
+
s.require_paths = ["lib".freeze]
|
|
13
|
+
s.authors = ["Andy Maleh".freeze]
|
|
14
|
+
s.date = "2017-10-23"
|
|
15
|
+
s.description = "SuperModule allows defining class methods and method invocations the same way a super class does without using def included(base). This also succeeds ActiveSupport::Concern by offering lighter syntax".freeze
|
|
16
16
|
s.extra_rdoc_files = [
|
|
17
17
|
"LICENSE.txt",
|
|
18
18
|
"README.md"
|
|
@@ -52,30 +52,45 @@ Gem::Specification.new do |s|
|
|
|
52
52
|
"spec/support/v2_alt/foo.rb",
|
|
53
53
|
"super_module.gemspec"
|
|
54
54
|
]
|
|
55
|
-
s.homepage = "http://github.com/AndyObtiva/super_module"
|
|
56
|
-
s.licenses = ["MIT"]
|
|
57
|
-
s.rubygems_version = "2.
|
|
58
|
-
s.summary = "SuperModule allows defining class methods and method invocations the same way a super class does without using def included(base). This also succeeds ActiveSupport::Concern by offering lighter syntax"
|
|
55
|
+
s.homepage = "http://github.com/AndyObtiva/super_module".freeze
|
|
56
|
+
s.licenses = ["MIT".freeze]
|
|
57
|
+
s.rubygems_version = "2.6.10".freeze
|
|
58
|
+
s.summary = "SuperModule allows defining class methods and method invocations the same way a super class does without using def included(base). This also succeeds ActiveSupport::Concern by offering lighter syntax".freeze
|
|
59
59
|
|
|
60
60
|
if s.respond_to? :specification_version then
|
|
61
61
|
s.specification_version = 4
|
|
62
62
|
|
|
63
63
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
64
|
-
s.add_runtime_dependency(%q<method_source
|
|
65
|
-
s.add_development_dependency(%q<jeweler
|
|
66
|
-
s.add_development_dependency(%q<rdoc
|
|
67
|
-
s.add_development_dependency(%q<rspec
|
|
64
|
+
s.add_runtime_dependency(%q<method_source>.freeze, ["~> 0.8.2"])
|
|
65
|
+
s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
|
|
66
|
+
s.add_development_dependency(%q<rdoc>.freeze, ["~> 4.2.0"])
|
|
67
|
+
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.2.0"])
|
|
68
|
+
s.add_development_dependency(%q<rake>.freeze, ["~> 10.4.2"])
|
|
69
|
+
s.add_development_dependency(%q<rack>.freeze, ["~> 1.6.5"])
|
|
70
|
+
s.add_development_dependency(%q<nokogiri>.freeze, ["~> 1.6.8.1"])
|
|
71
|
+
s.add_development_dependency(%q<tins>.freeze, ["~> 1.6.0"])
|
|
72
|
+
s.add_development_dependency(%q<term-ansicolor>.freeze, ["~> 1.3.2"])
|
|
68
73
|
else
|
|
69
|
-
s.add_dependency(%q<method_source
|
|
70
|
-
s.add_dependency(%q<jeweler
|
|
71
|
-
s.add_dependency(%q<rdoc
|
|
72
|
-
s.add_dependency(%q<rspec
|
|
74
|
+
s.add_dependency(%q<method_source>.freeze, ["~> 0.8.2"])
|
|
75
|
+
s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
|
|
76
|
+
s.add_dependency(%q<rdoc>.freeze, ["~> 4.2.0"])
|
|
77
|
+
s.add_dependency(%q<rspec>.freeze, ["~> 3.2.0"])
|
|
78
|
+
s.add_dependency(%q<rake>.freeze, ["~> 10.4.2"])
|
|
79
|
+
s.add_dependency(%q<rack>.freeze, ["~> 1.6.5"])
|
|
80
|
+
s.add_dependency(%q<nokogiri>.freeze, ["~> 1.6.8.1"])
|
|
81
|
+
s.add_dependency(%q<tins>.freeze, ["~> 1.6.0"])
|
|
82
|
+
s.add_dependency(%q<term-ansicolor>.freeze, ["~> 1.3.2"])
|
|
73
83
|
end
|
|
74
84
|
else
|
|
75
|
-
s.add_dependency(%q<method_source
|
|
76
|
-
s.add_dependency(%q<jeweler
|
|
77
|
-
s.add_dependency(%q<rdoc
|
|
78
|
-
s.add_dependency(%q<rspec
|
|
85
|
+
s.add_dependency(%q<method_source>.freeze, ["~> 0.8.2"])
|
|
86
|
+
s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.0"])
|
|
87
|
+
s.add_dependency(%q<rdoc>.freeze, ["~> 4.2.0"])
|
|
88
|
+
s.add_dependency(%q<rspec>.freeze, ["~> 3.2.0"])
|
|
89
|
+
s.add_dependency(%q<rake>.freeze, ["~> 10.4.2"])
|
|
90
|
+
s.add_dependency(%q<rack>.freeze, ["~> 1.6.5"])
|
|
91
|
+
s.add_dependency(%q<nokogiri>.freeze, ["~> 1.6.8.1"])
|
|
92
|
+
s.add_dependency(%q<tins>.freeze, ["~> 1.6.0"])
|
|
93
|
+
s.add_dependency(%q<term-ansicolor>.freeze, ["~> 1.3.2"])
|
|
79
94
|
end
|
|
80
95
|
end
|
|
81
96
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: super_module
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andy Maleh
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-10-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: method_source
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 2.0
|
|
33
|
+
version: 2.3.0
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 2.0
|
|
40
|
+
version: 2.3.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rdoc
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,6 +66,76 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: 3.2.0
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rake
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 10.4.2
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 10.4.2
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: rack
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: 1.6.5
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: 1.6.5
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: nokogiri
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 1.6.8.1
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 1.6.8.1
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: tins
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: 1.6.0
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: 1.6.0
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: term-ansicolor
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: 1.3.2
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: 1.3.2
|
|
69
139
|
description: SuperModule allows defining class methods and method invocations the
|
|
70
140
|
same way a super class does without using def included(base). This also succeeds
|
|
71
141
|
ActiveSupport::Concern by offering lighter syntax
|
|
@@ -129,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
129
199
|
version: '0'
|
|
130
200
|
requirements: []
|
|
131
201
|
rubyforge_project:
|
|
132
|
-
rubygems_version: 2.
|
|
202
|
+
rubygems_version: 2.6.10
|
|
133
203
|
signing_key:
|
|
134
204
|
specification_version: 4
|
|
135
205
|
summary: SuperModule allows defining class methods and method invocations the same
|