type_wrapper 1.2.0 → 1.3.0
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 +34 -0
- data/lib/type_wrapper.rb +13 -21
- data/lib/type_wrapper/forwarding.rb +32 -0
- data/lib/type_wrapper/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58f7ba6011b57c1a7e2c036ca846eb83340f16dc
|
4
|
+
data.tar.gz: 9a5e7768db72b7f850e7f5161cc676133f221de3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c1f1db9b45f45e1bce94982ec5fc69c3bee9edf6409766610af660627eb5a96a24d49cabf643b09dab9d31da92dabf9a7db75f15836c665ea9333832ffa834d
|
7
|
+
data.tar.gz: 6dbd5824a161cf924f0c2d4bc49a371881d41aa32a21dd19f2844acdecfbdcd39d39afbde8dd004050d5ebe6e9ccafc8c2303a4e4f7dce570730ecf4344c6b18
|
data/README.md
CHANGED
@@ -69,6 +69,40 @@ using AwesomeSinging[Lego]
|
|
69
69
|
Lego.new("Emmet").sing
|
70
70
|
```
|
71
71
|
|
72
|
+
### TypeWrapper::Forwarding
|
73
|
+
|
74
|
+
Creates a Module that delegates Refinements methods (forwarding) to a target object.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
Lego = Struct.new(:name)
|
78
|
+
|
79
|
+
module LoudSpeaking
|
80
|
+
def speak(words)
|
81
|
+
"#{name}: #{words.upcase}!!!"
|
82
|
+
end
|
83
|
+
|
84
|
+
def say(words)
|
85
|
+
"#{name}: #{words.upcase}!!!"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Refinements
|
90
|
+
module LoudSpeakingLego
|
91
|
+
refine Lego do
|
92
|
+
include LoudSpeaking
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# target: speaker
|
97
|
+
class LoudLego < Struct.new(:speaker)
|
98
|
+
include TypeWrapper::Forwarding[LoudSpeakingLego, :speak, :say, to: :speaker]
|
99
|
+
end
|
100
|
+
|
101
|
+
batman = Lego.new('Batman')
|
102
|
+
loud_lego = LoudLego.new(batman)
|
103
|
+
loud_lego.speak("I'm Batman") # => "Batman: I'M BATMAN!!!"
|
104
|
+
```
|
105
|
+
|
72
106
|
## Pros
|
73
107
|
|
74
108
|
* Five (5) times faster than [Object#extend](https://apidock.com/ruby/Object/extend).
|
data/lib/type_wrapper.rb
CHANGED
@@ -1,34 +1,26 @@
|
|
1
1
|
require "type_wrapper/version"
|
2
2
|
require "type_wrapper/module"
|
3
|
+
require "type_wrapper/forwarding"
|
3
4
|
require 'delegate'
|
4
5
|
|
5
6
|
module TypeWrapper
|
6
|
-
|
7
|
-
@delegate_tw_obj = obj # change delegation object
|
8
|
-
end
|
9
|
-
|
10
|
-
alias_method :~@, def __getobj__
|
11
|
-
@delegate_tw_obj # return object we are delegating to
|
12
|
-
end
|
7
|
+
using Module::Refines
|
13
8
|
|
14
9
|
def self.[](*types)
|
15
10
|
raise TypeError, "wrong argument type (expected Module(s))" if types.include?(nil)
|
16
11
|
raise ArgumentError, "wrong number of arguments (given #{types.size}, expected 2+)" if types.size < 2
|
17
12
|
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
using Module::Refines
|
13
|
+
type, *behaviors = *types
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
class_eval code.unshift("using Trait").join("\n")
|
32
|
-
end
|
15
|
+
raise ArgumentError, "Module(s) has no public methods defined" if behaviors.flat_map(&:public_instance_methods).empty?
|
16
|
+
|
17
|
+
Class.new DelegateClass(type) do
|
18
|
+
alias_method :~@, :__getobj__
|
19
|
+
define_method(:inspect) { "#< #{self.class.name || behaviors} #{__getobj__} #>" }
|
20
|
+
|
21
|
+
behaviors.each do |mod|
|
22
|
+
include Forwarding.new mod.refines(type), *mod.public_instance_methods, to: :__getobj__
|
33
23
|
end
|
24
|
+
end
|
25
|
+
end
|
34
26
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module TypeWrapper
|
2
|
+
class Forwarding < Module
|
3
|
+
def initialize(refinements, *forward, to:)
|
4
|
+
raise ArgumentError, "No List of Methods specified.", caller if forward.empty?
|
5
|
+
raise ArgumentError, "Can't convert #{to}:#{to.class} to Symbol", caller unless to.respond_to? :to_sym
|
6
|
+
const_set :Refinements, refinements
|
7
|
+
DefineMethods[forward, to.to_sym, self]
|
8
|
+
@forward = forward
|
9
|
+
@target = to
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
refinements = const_get :Refinements
|
14
|
+
name || "Forwarding[#{refinements} #{@forward.join(' ')} to: #{@target}]"
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.[](*args)
|
18
|
+
new *args
|
19
|
+
end
|
20
|
+
|
21
|
+
DefineMethods = -> forward, target, base do
|
22
|
+
code = forward.uniq.map do |forwarding|
|
23
|
+
<<-EOS
|
24
|
+
def #{forwarding}(*args, &block)
|
25
|
+
#{target}.#{forwarding}(*args, &block)
|
26
|
+
end
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
base.module_eval code.unshift("using Refinements").join("\n")
|
30
|
+
end # DefineMethods proc
|
31
|
+
end # Forwarding class
|
32
|
+
end
|
data/lib/type_wrapper/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: type_wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ritchie Paul Buitre
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- bin/setup
|
70
70
|
- examples/benchmark.rb
|
71
71
|
- lib/type_wrapper.rb
|
72
|
+
- lib/type_wrapper/forwarding.rb
|
72
73
|
- lib/type_wrapper/module.rb
|
73
74
|
- lib/type_wrapper/version.rb
|
74
75
|
- type_wrapper.gemspec
|