method_repository 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7d0710a19c282ef8e641f042d15563f5498602bc
4
+ data.tar.gz: c9a9f0bc218b5f5fc95feb03aa5b37045f5e718b
5
+ SHA512:
6
+ metadata.gz: 78d801a95aee6810a5f18836587fe6d4a5b77d11e5c599fd429e6a2be16841a5a2e3d2a57e0d5df4084aa4dbe690c47f64310e3de0e9e6136b22f34f29fa2d2c
7
+ data.tar.gz: d9ba6041bfafbb1315a028dfdd2ccb5dbbe5d6ab14373eb14de5cc9b97248887210bdc7fff4667842c24a7be37dfdaa12fa2174d4199a73926fe17cb69ce03c9
data/README.md CHANGED
@@ -8,7 +8,7 @@ To extract redundant codes into a method to commonalize them is a usual strategy
8
8
 
9
9
  I don't like when highly commonalized OOP structure disturbes me from quick tracing where such methods are defined. It's OOP's natural defect, I think. Once classes/modules are defined, it's inevitable that the classes/modules are inherited/included at anywhere we don't know.
10
10
 
11
- In that way, inheritance/inclusion-based OOP resembles `goto` programming; There's no clear reason why some classes/modules are inherited/included by another classes/modules. Even though there's some structural thought in your classes/modules design, such an excessively free inheritance/inclusion prevent us from grasping the whole code quickily.
11
+ In that way, inheritance/inclusion-based OOP resembles `goto` programming; There's no clear reason why some classes/modules are inherited/included by another classes/modules. Even though there's some structural thought in your classes/modules design, such an excessively free inheritance/inclusion prevents us from grasping the whole code quickily.
12
12
 
13
13
  ## Solution
14
14
 
@@ -38,6 +38,43 @@ class Qux; end
38
38
  * `method2` is declared it can be inserted in only `Baz`
39
39
  * No method is declared it can be inserted in `Qux`
40
40
 
41
+ ### Limit Extending/Including in a Lump
42
+
43
+ You can also limit extending/including in a lump, not designating classes using `insert` method at method definitions, like below:
44
+
45
+ ```
46
+ module Extendable
47
+ include MethodRepository
48
+
49
+ extendable_by 'Hoge'
50
+ end
51
+
52
+ module Includable
53
+ include MethodRepository
54
+
55
+ includable_by 'Hoge'
56
+ end
57
+
58
+ class Hoge; end
59
+ class Fuga; end
60
+ ```
61
+
62
+ In this way:
63
+
64
+ ```
65
+ Hoge.extend(Extendable)
66
+ Hoge.send(:include, Includable)
67
+ ```
68
+
69
+ works as you see, however:
70
+
71
+ ```
72
+ Fuga.extend(Extendable)
73
+ Fuga.send(:include, Includable)
74
+ ```
75
+
76
+ raises `MethodRepository::NotPermittedError`.
77
+
41
78
  ### Extending
42
79
 
43
80
  When the classes/objects are extended by `Repository` module:
@@ -2,14 +2,22 @@ require_relative "method_repository/version"
2
2
 
3
3
  module MethodRepository
4
4
  def self.included(base)
5
- base.instance_variable_set(:@targets, {})
5
+ base.instance_variable_set(:@targets, {})
6
+ base.instance_variable_set(:@extendable, [])
7
+ base.instance_variable_set(:@includable, [])
6
8
  base.extend(ModuleMethods)
7
9
  end
8
10
 
11
+ class NotPermittedError < RuntimeError; end
12
+
9
13
  module ModuleMethods
10
14
  def extended(base)
11
15
  klass_name = base.class.to_s == 'Class' ? base.to_s : base.class.to_s
12
16
 
17
+ if !@extendable.empty? && !@extendable.include?(klass_name)
18
+ raise MethodRepository::NotPermittedError.new("Extending #{klass_name} by this module is not permitted")
19
+ end
20
+
13
21
  if (methods = @targets[klass_name])
14
22
  base.singleton_class.class_eval do
15
23
  methods.each do |method|
@@ -20,7 +28,13 @@ module MethodRepository
20
28
  end
21
29
 
22
30
  def included(base)
23
- if (methods = @targets[base.to_s])
31
+ klass_name = base.to_s
32
+
33
+ if !@includable.empty? && !@includable.include?(klass_name)
34
+ raise MethodRepository::NotPermittedError.new("Including #{klass_name} by this module is not permitted")
35
+ end
36
+
37
+ if (methods = @targets[klass_name])
24
38
  base.class_eval do
25
39
  methods.each do |method|
26
40
  define_method method[:name], method[:block]
@@ -29,6 +43,14 @@ module MethodRepository
29
43
  end
30
44
  end
31
45
 
46
+ def extendable_by(*klasses)
47
+ @extendable.push(*klasses)
48
+ end
49
+
50
+ def includable_by(*klasses)
51
+ @includable.push(*klasses)
52
+ end
53
+
32
54
  def insert(name, klasses = {}, &block)
33
55
  if !klasses[:in]
34
56
  raise ArgumentError.new("`:in' parameter is required")
@@ -1,3 +1,3 @@
1
1
  module MethodRepository
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -1,6 +1,18 @@
1
1
  require_relative '../spec_helper'
2
2
 
3
3
  describe MethodRepository do
4
+ module Extendable
5
+ include MethodRepository
6
+
7
+ extendable_by 'Hoge', 'Piyo'
8
+ end
9
+
10
+ module Includable
11
+ include MethodRepository
12
+
13
+ includable_by 'Hoge', 'Piyo'
14
+ end
15
+
4
16
  module Repository
5
17
  include MethodRepository
6
18
 
@@ -8,11 +20,59 @@ describe MethodRepository do
8
20
  insert :method2, in: %w[Baz] do; end
9
21
  end
10
22
 
23
+ class Hoge; end
24
+ class Fuga; end
25
+ class Piyo; end
26
+
11
27
  class Foo; end
12
28
  class Bar; end
13
29
  class Baz; end
14
30
  class Qux; end
15
31
 
32
+ describe '.extendable_by' do
33
+ context 'when classes are permitted as extendable' do
34
+ before {
35
+ Hoge.extend(Extendable)
36
+ Piyo.extend(Extendable)
37
+ }
38
+
39
+ it {
40
+ expect(Hoge).to be_a_kind_of Extendable
41
+ expect(Piyo).to be_a_kind_of Extendable
42
+ }
43
+ end
44
+
45
+ context 'when classes are not permitted as extendable' do
46
+ it {
47
+ expect {
48
+ Fuga.extend(Extendable)
49
+ }.to raise_error(MethodRepository::NotPermittedError)
50
+ }
51
+ end
52
+ end
53
+
54
+ describe '.includable_by' do
55
+ context 'when classes are permitted as includable' do
56
+ before {
57
+ Hoge.send(:include, Includable)
58
+ Piyo.send(:include, Includable)
59
+ }
60
+
61
+ it {
62
+ expect(Hoge.new).to be_a_kind_of Includable
63
+ expect(Piyo.new).to be_a_kind_of Includable
64
+ }
65
+ end
66
+
67
+ context 'when classes are not permitted as includable' do
68
+ it {
69
+ expect {
70
+ Fuga.send(:include, Includable)
71
+ }.to raise_error(MethodRepository::NotPermittedError)
72
+ }
73
+ end
74
+ end
75
+
16
76
  describe '.insert' do
17
77
  it {
18
78
  expect {
@@ -95,4 +155,8 @@ describe MethodRepository do
95
155
  expect(Qux.new.respond_to?(:method2)).to be false
96
156
  }
97
157
  end
158
+
159
+ describe '.includable_by' do
160
+ context 'when classes'
161
+ end
98
162
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: method_repository
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
5
- prerelease:
4
+ version: 0.0.5
6
5
  platform: ruby
7
6
  authors:
8
7
  - Kentaro Kuribayashi
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-03 00:00:00.000000000 Z
11
+ date: 2013-03-08 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rspec
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,17 +27,15 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  description: Extracting redundant code and commonalizing it in a different way.
@@ -63,29 +58,27 @@ files:
63
58
  - spec/spec_helper.rb
64
59
  homepage: https://github.com/kentaro/method_repository
65
60
  licenses: []
61
+ metadata: {}
66
62
  post_install_message:
67
63
  rdoc_options: []
68
64
  require_paths:
69
65
  - lib
70
66
  required_ruby_version: !ruby/object:Gem::Requirement
71
- none: false
72
67
  requirements:
73
- - - ! '>='
68
+ - - '>='
74
69
  - !ruby/object:Gem::Version
75
70
  version: 1.9.2
76
71
  required_rubygems_version: !ruby/object:Gem::Requirement
77
- none: false
78
72
  requirements:
79
- - - ! '>='
73
+ - - '>='
80
74
  - !ruby/object:Gem::Version
81
75
  version: '0'
82
76
  requirements: []
83
77
  rubyforge_project:
84
- rubygems_version: 1.8.23
78
+ rubygems_version: 2.0.0
85
79
  signing_key:
86
- specification_version: 3
80
+ specification_version: 4
87
81
  summary: Extracting redundant code and commonalizing it in a different way
88
82
  test_files:
89
83
  - spec/lib/method_repository_spec.rb
90
84
  - spec/spec_helper.rb
91
- has_rdoc: