super_module 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: def423de958bb4f6b3d2c6b3edb60908d42bbe86
4
+ data.tar.gz: 962866a97336aaeeebd16386e1cf37417e1d2aa9
5
+ SHA512:
6
+ metadata.gz: 99668ddec0c2e332493f7cda830428e4915d65eaf35bde9b5a0336233396425c458746734082917028a310b8fa0e4a01d0b430f0f3a78a31b7cd5afdd541e5c1
7
+ data.tar.gz: fb848a9f6979fe0f079ddc9d3967eb600b85186659ce6457d220ec5ce55be0c460928fe09e5403cfe0689009a4c93ae9a3ce4102e1b07ac27785027f525e7b02
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 Andy Maleh
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # SuperModule
2
+ [![Gem Version](https://badge.fury.io/rb/super_module.png)](http://badge.fury.io/rb/super_module)
3
+ [![Build Status](https://api.travis-ci.org/AndyObtiva/super_module.png?branch=master)](https://travis-ci.org/AndyObtiva/super_module)
4
+ [![Coverage Status](https://coveralls.io/repos/AndyObtiva/super_module/badge.png?branch=master)](https://coveralls.io/r/AndyObtiva/super_module?branch=master)
5
+ [![Code Climate](https://codeclimate.com/github/AndyObtiva/super_module.png)](https://codeclimate.com/github/AndyObtiva/super_module)
6
+
7
+ Tired of Ruby's modules not allowing you to mix in class methods easily?
8
+ Tired of writing complex code and using complex libraries like ActiveSupport::Concern to accomplish that goal?
9
+
10
+ Well, worry no more! SuperModule comes to the rescue!
11
+
12
+ ![SuperModule](https://raw.githubusercontent.com/AndyObtiva/super_module/master/SuperModule.jpg)
13
+
14
+ SuperModule allows defining class methods and method invocations the same way a super class does without using def included(base).
15
+
16
+ This succeeds ActiveSupport::Concern by offering lighter syntax and simpler module dependency support.
17
+
18
+ ## Instructions
19
+
20
+ ### 1) Install and require gem
21
+
22
+ <b>Using Bundler</b>
23
+
24
+ Add the following to Gemfile: <pre>gem 'super_module', '1.0.0'</pre>
25
+ Run: <code>bundle</code>
26
+
27
+ It will automatically get required in the application when loading with bundler (e.g. in a Rails application)
28
+
29
+ <b>Using RubyGem Directly</b>
30
+
31
+ Run: <pre>gem install super_module</pre>
32
+ (add <code>--no-ri --no-rdoc</code> if you wish to skip downloading them for a faster install)
33
+
34
+ Add <code>require 'super_module'</code> at the top of your Ruby file
35
+
36
+ ### 2) Include SuperModule at the top of the module
37
+
38
+ > module UserIdentifiable
39
+ > include SuperModule
40
+ >
41
+ > belongs_to :user
42
+ > validates :user_id, presence: true
43
+ >
44
+ > def self.most_active_user
45
+ > User.find_by_id(select('count(id) as head_count, user_id').group('user_id').order('count(id) desc').first.user_id)
46
+ > end
47
+ >
48
+ > def slug
49
+ > "#{self.class.name}_#{user_id}"
50
+ > end
51
+ > end
52
+
53
+ ### 3) Mix newly defined module into a class or another super module
54
+
55
+ > class ClubParticipation < ActiveRecord::Base
56
+ > include UserIdentifiable
57
+ > end
58
+ > class CourseEnrollment < ActiveRecord::Base
59
+ > include UserIdentifiable
60
+ > end
61
+ > module Accountable
62
+ > include SuperModule
63
+ > include UserIdentifiable
64
+ > end
65
+ > class Activity < ActiveRecord::Base
66
+ > include Accountable
67
+ > end
68
+
69
+ ### 4) Start using by invoking class methods or instance methods
70
+
71
+ > CourseEnrollment.most_active_user
72
+ > ClubParticipation.most_active_user
73
+ > Activity.last.slug
74
+ > ClubParticipation.create(club_id: club.id, user_id: user.id).slug
75
+ > CourseEnrollment.new(course_id: course.id).valid?
76
+
77
+ ## Example
78
+
79
+ > require 'super_module'
80
+ >
81
+ > module Foo
82
+ > include SuperModule
83
+ >
84
+ > validates :credit_card_id, presence: true
85
+ >
86
+ > def foo
87
+ > puts 'foo'
88
+ > 'foo'
89
+ > end
90
+ >
91
+ > def self.foo
92
+ > puts 'self.foo'
93
+ > 'self.foo'
94
+ > end
95
+ > end
96
+ >
97
+ > module Bar
98
+ > include SuperModule
99
+ > include Foo
100
+ >
101
+ > validates :user_id, presence: true
102
+ >
103
+ > def bar
104
+ > puts 'bar'
105
+ > 'bar'
106
+ > end
107
+ >
108
+ > def self.bar
109
+ > puts 'self.bar'
110
+ > 'self.bar'
111
+ > end
112
+ > end
113
+ >
114
+ > class MediaAuthorization < ActiveRecord::Base
115
+ > include Bar
116
+ > end
117
+ >
118
+ > MediaAuthorization.create.errors.messages.inspect
119
+
120
+ => "{:credit_card_id=>[\"can't be blank\"], :user_id=>[\"can't be blank\"]}"
121
+
122
+ > MediaAuthorization.new.foo
123
+
124
+ => "foo"
125
+
126
+ > MediaAuthorization.new.bar
127
+
128
+ => "bar"
129
+
130
+ > MediaAuthorization.foo
131
+
132
+ => "self.foo"
133
+
134
+ > MediaAuthorization.bar
135
+
136
+ => "self.bar"
137
+
138
+ ## Design Limitations
139
+
140
+ This has been designed to be used only in the code definition of a module.
141
+
142
+ ## Copyright
143
+
144
+ Copyright (c) 2014 Andy Maleh. See LICENSE.txt for
145
+ further details.
146
+
data/SuperModule.jpg ADDED
Binary file
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,66 @@
1
+ # SuperModule allows defining class methods and method invocations the same way a super class does without using def included(base).
2
+ #
3
+ # Author:: Andy Maleh
4
+ # Copyright:: Copyright (c) 2014 Andy Maleh
5
+ # License:: MIT License
6
+
7
+ # This module allows defining class methods and method invocations the same way a super class does without using def included(base).
8
+
9
+ module SuperModule
10
+ EXCLUDED_SINGLETON_METHODS = [
11
+ :__super_module_class_methods,
12
+ :__invoke_super_module_class_method_calls,
13
+ :__define_super_module_class_methods,
14
+ :__restore_original_method_missing,
15
+ :included, :method_missing,
16
+ :singleton_method_added
17
+ ]
18
+ def self.included(base)
19
+ base.class_eval do
20
+ class << self
21
+
22
+ def include(base, &block)
23
+ method_missing('include', base, &block)
24
+ end
25
+
26
+ def __super_module_class_method_calls
27
+ @__super_module_class_method_calls ||= []
28
+ end
29
+
30
+ def __super_module_class_methods
31
+ @__super_module_class_methods ||= []
32
+ end
33
+
34
+ def singleton_method_added(method_name)
35
+ __super_module_class_methods << [method_name, method(method_name)] unless EXCLUDED_SINGLETON_METHODS.include?(method_name)
36
+ super
37
+ end
38
+
39
+ def method_missing(method_name, *args, &block)
40
+ __super_module_class_method_calls << [method_name, args, block]
41
+ end
42
+
43
+ def __invoke_super_module_class_method_calls(base)
44
+ __super_module_class_method_calls.each do |method_name, args, block|
45
+ base.class_eval do
46
+ send(method_name, *args, &block)
47
+ end
48
+ end
49
+ end
50
+
51
+ def __define_super_module_class_methods(base)
52
+ __super_module_class_methods.each do |method_name, method|
53
+ base.class_eval do
54
+ self.class.send(:define_method, method_name, &method)
55
+ end
56
+ end
57
+ end
58
+
59
+ def included(base)
60
+ __invoke_super_module_class_method_calls(base)
61
+ __define_super_module_class_methods(base)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe SuperModule do
4
+ module Foo
5
+ include SuperModule
6
+ validates 'foo', presence: true
7
+
8
+ def self.foo
9
+ 'self.foo'
10
+ end
11
+
12
+ def foo
13
+ 'foo'
14
+ end
15
+ end
16
+ module Bar
17
+ include SuperModule
18
+ validates 'bar', presence: true
19
+
20
+ class << self
21
+ def bar
22
+ 'self.bar'
23
+ end
24
+ end
25
+
26
+ def bar
27
+ 'bar'
28
+ end
29
+ end
30
+ class FakeActiveRecord
31
+ class << self
32
+ def validates(attribute, options)
33
+ validations << [attribute, options]
34
+ end
35
+ def validations
36
+ @validations ||= []
37
+ end
38
+ end
39
+ end
40
+
41
+ context "a base class includes a module enhanced as a super module" do
42
+ before do
43
+ FakeActiveRecord.send(:include, Foo)
44
+ end
45
+
46
+ it 'allows invoking class methods in the including base class body' do
47
+ FakeActiveRecord.validations.should include(['foo', {presence: true}])
48
+ end
49
+ it 'includes instance methods in the including base class' do
50
+ instance = FakeActiveRecord.new
51
+
52
+ instance.foo.should == 'foo'
53
+ end
54
+ it 'includes class methods in the including base class' do
55
+ FakeActiveRecord.foo.should == 'self.foo'
56
+ end
57
+ end
58
+
59
+ context "a base class includes a base module enhanced as a super module that includes another module enhanced as a super module" do
60
+ before do
61
+ Bar.send(:include, Foo)
62
+ FakeActiveRecord.send(:include, Bar)
63
+ end
64
+
65
+ it 'allows invoking class methods in the including base class body' do
66
+ FakeActiveRecord.validations.should include(['foo', {presence: true}])
67
+ FakeActiveRecord.validations.should include(['bar', {presence: true}])
68
+ end
69
+ it 'includes instance methods in the including base class' do
70
+ instance = FakeActiveRecord.new
71
+
72
+ instance.foo.should == 'foo'
73
+ instance.bar.should == 'bar'
74
+ end
75
+ it 'includes class methods in the including base class' do
76
+ FakeActiveRecord.foo.should == 'self.foo'
77
+ FakeActiveRecord.bar.should == 'self.bar'
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,50 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: super_module 1.0.0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "super_module"
9
+ s.version = "1.0.0"
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 = "2014-03-27"
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"
16
+ s.extra_rdoc_files = [
17
+ "LICENSE.txt",
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "SuperModule.jpg",
25
+ "VERSION",
26
+ "lib/super_module.rb",
27
+ "spec/lib/super_module_spec.rb",
28
+ "super_module.gemspec"
29
+ ]
30
+ s.homepage = "http://github.com/AndyObtiva/super_module"
31
+ s.licenses = ["MIT"]
32
+ s.rubygems_version = "2.2.2"
33
+ 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"
34
+
35
+ if s.respond_to? :specification_version then
36
+ s.specification_version = 4
37
+
38
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
39
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0"])
40
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
41
+ else
42
+ s.add_dependency(%q<jeweler>, ["~> 2.0"])
43
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
44
+ end
45
+ else
46
+ s.add_dependency(%q<jeweler>, ["~> 2.0"])
47
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
48
+ end
49
+ end
50
+
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: super_module
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andy Maleh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jeweler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rdoc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.12'
41
+ description: SuperModule allows defining class methods and method invocations the
42
+ same way a super class does without using def included(base). This also succeeds
43
+ ActiveSupport::Concern by offering lighter syntax
44
+ email:
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files:
48
+ - LICENSE.txt
49
+ - README.md
50
+ files:
51
+ - ".document"
52
+ - LICENSE.txt
53
+ - README.md
54
+ - SuperModule.jpg
55
+ - VERSION
56
+ - lib/super_module.rb
57
+ - spec/lib/super_module_spec.rb
58
+ - super_module.gemspec
59
+ homepage: http://github.com/AndyObtiva/super_module
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.2.2
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: SuperModule allows defining class methods and method invocations the same
83
+ way a super class does without using def included(base). This also succeeds ActiveSupport::Concern
84
+ by offering lighter syntax
85
+ test_files: []