absorb 0.0.2

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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/absorb.rb +53 -0
  3. data/test/test_absorb.rb +91 -0
  4. metadata +46 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 638cbacbd4bc5b6f49a180bc22b742da1a6533cb
4
+ data.tar.gz: 5e36bd4eb9356a917126a707ed5813aee09a6bbf
5
+ SHA512:
6
+ metadata.gz: 832a9df3c37fccccac55f0bd28fda4906df5172ac070437fab5258cd2dc56315215efafc483feca62814edc011a822ffb267019585e115184dfbd536a6335fcd
7
+ data.tar.gz: b55edee932d4c53ef673ba95e0d2b3c83545f75a319edd51fa43e6df33dcb0057e3656bfe8da8b7b54abc4b83113953f29a3ba92aeb588464cfdc04219f5f31b
@@ -0,0 +1,53 @@
1
+ # Pickup -- The Object extension that gives us pickups
2
+ class Object
3
+ @@local_extensions = []
4
+
5
+ def method_missing(name, *args, &block)
6
+ klass = self
7
+ @@local_extensions.each { |mod|
8
+ if mod.instance_methods.include? name
9
+ return mod
10
+ .instance_method(name)
11
+ .bind(klass)
12
+ .call(*args, &block)
13
+ end
14
+ }
15
+
16
+ super
17
+ end
18
+
19
+ def respond_to?(method_name, include_all=false)
20
+ klass = self
21
+ result = super method_name, include_all
22
+
23
+ if result then return result end
24
+
25
+ @@local_extensions.each { |mod|
26
+ if mod.instance_methods.include? method_name
27
+ result = true
28
+ return result
29
+ end
30
+ }
31
+
32
+ result
33
+ end
34
+
35
+ # Absorb lets you locally extend a class with a module
36
+ #
37
+ # Example:
38
+ # >> Array.absorb(MyArrayExtension) do
39
+ # >> [1,2,3].nowHasThisMethodFromModule #=> Works!
40
+ # >> end
41
+ # >> [1,2,3].nowHasThisMethodFromModule #=> NoMethodError
42
+ #
43
+ # Arguments:
44
+ # module_name: (String)
45
+ # block: (Block)
46
+ #
47
+ def absorb(name, &block)
48
+ @@local_extensions.push(name)
49
+ result = block.call
50
+ @@local_extensions.pop
51
+ result
52
+ end
53
+ end
@@ -0,0 +1,91 @@
1
+ require 'test/unit'
2
+ require 'absorb'
3
+
4
+ # we'll be testing these two modules
5
+
6
+ module ArrayPowerups
7
+ # return an array of only the even elements
8
+ def even
9
+ select { |x| x.even? }
10
+ end
11
+
12
+ # return an array of elements strictly between
13
+ # the two numbers passed as arguments
14
+ def between(a, b)
15
+ select { |x| x > a and x < b }
16
+ end
17
+ end
18
+
19
+ module NumberPowerups
20
+ # return the number squared
21
+ def powerup
22
+ self * self
23
+ end
24
+ end
25
+
26
+ class PickupTest < Test::Unit::TestCase
27
+ def test_one_module_pickup
28
+ Array.absorb(ArrayPowerups) do
29
+ assert_equal [1,2,3,4,5].even(), [2,4]
30
+ end
31
+ end
32
+
33
+ def test_nested_module_pickup
34
+ Array.absorb(ArrayPowerups) do
35
+ Numeric.absorb(NumberPowerups) do
36
+ even_nums = [1,2,3,4,5].even().map { |x| x.powerup }
37
+ assert_equal even_nums.length, 2
38
+ assert_equal even_nums[0], 4
39
+ assert_equal even_nums[1], 16
40
+ end
41
+ end
42
+ end
43
+
44
+ def test_respond_to_works_correctly
45
+ mock = [1,2,3,4]
46
+ assert_equal mock.respond_to?(:even), false
47
+ assert_equal mock.respond_to?(:between), false
48
+ Array.absorb(ArrayPowerups) do
49
+ assert_respond_to mock, :even
50
+ assert_respond_to mock, :between
51
+ end
52
+ assert_equal mock.respond_to?(:even), false
53
+ assert_equal mock.respond_to?(:between), false
54
+ end
55
+
56
+ def test_method_is_missing_outside_pickup
57
+ mock = [1,2,3,4]
58
+ assert_raise NoMethodError do
59
+ mock.even
60
+ end
61
+
62
+ assert_raise NoMethodError do
63
+ mock.between(1, 3)
64
+ end
65
+
66
+ Array.absorb(ArrayPowerups) do
67
+ assert_nothing_raised NoMethodError do
68
+ assert_equal mock.even, [2,4]
69
+ assert_equal mock.between(1, 3), [2]
70
+ end
71
+
72
+ assert_raise NoMethodError do
73
+ mock.even[0].powerup
74
+ end
75
+
76
+ Numeric.absorb(NumberPowerups) do
77
+ assert_nothing_raised NoMethodError do
78
+ assert_equal mock.even[0].powerup, 4
79
+ end
80
+ end
81
+ end
82
+
83
+ assert_raise NoMethodError do
84
+ mock.even
85
+ end
86
+
87
+ assert_raise NoMethodError do
88
+ mock.between(1, 3)
89
+ end
90
+ end
91
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: absorb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Miroslav Gavrilov
8
+ - Igor Sarcevic
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-04-29 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Use this module to enable local, in-method class extensions.
15
+ email: gavrilov.miroslav@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/absorb.rb
21
+ - test/test_absorb.rb
22
+ homepage: http://www.pixelablaze.com
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '2.0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.0.14
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Locally pick up and extend a class with a module.
46
+ test_files: []