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.
- checksums.yaml +7 -0
- data/lib/absorb.rb +53 -0
- data/test/test_absorb.rb +91 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -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
|
data/lib/absorb.rb
ADDED
@@ -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
|
data/test/test_absorb.rb
ADDED
@@ -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: []
|