type_wrapper 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69d54edce7635369ec8d00ab82bd42a96c9a7394
4
- data.tar.gz: b64a288d3a8ead6d044efe8d4882df5189e4e341
3
+ metadata.gz: 58f7ba6011b57c1a7e2c036ca846eb83340f16dc
4
+ data.tar.gz: 9a5e7768db72b7f850e7f5161cc676133f221de3
5
5
  SHA512:
6
- metadata.gz: 3cf9f7abf54087cf97bd05633590fe0660ea9f066c8875254fc9fce47f19e3486f9f3a208ed884d891763c87118386ca1010c816f3331f31551dfa7a5c18eb5b
7
- data.tar.gz: 198d91a0c3a5ad32434559cd5a16323ea342b03202f64cfeb40655310d22fd3087281e941485a9e71efcbe414e83db8362290a4b15ec4fedfaa0fc6ff2f53070
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
- alias_method :initialize, def __setobj__(obj)
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
- FOR[*types]
19
- end
20
-
21
- using Module::Refines
13
+ type, *behaviors = *types
22
14
 
23
- FOR = -> type, *behaviors do
24
- Class.new(Delegator) do
25
- include TypeWrapper
26
- const_set :Type, type
27
- const_set :BEHAVIORS, behaviors
28
- const_set :Trait, Module.new { behaviors.each { |mod| include mod.refines(type) } }
29
- forwarding = behaviors.flat_map(&:public_instance_methods) - public_instance_methods
30
- code = forwarding.uniq.map { |meth| "def %{meth}(*args, &block) __getobj__.%{meth}(*args, &block) end" % { meth: meth } }
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
@@ -1,3 +1,3 @@
1
1
  module TypeWrapper
2
- VERSION = "1.2.0".freeze
2
+ VERSION = "1.3.0".freeze
3
3
  end
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.2.0
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-19 00:00:00.000000000 Z
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