type_wrapper 1.1.0 → 1.2.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 +29 -3
- data/lib/type_wrapper/module.rb +51 -0
- data/lib/type_wrapper/version.rb +1 -1
- data/lib/type_wrapper.rb +8 -6
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69d54edce7635369ec8d00ab82bd42a96c9a7394
|
4
|
+
data.tar.gz: b64a288d3a8ead6d044efe8d4882df5189e4e341
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cf9f7abf54087cf97bd05633590fe0660ea9f066c8875254fc9fce47f19e3486f9f3a208ed884d891763c87118386ca1010c816f3331f31551dfa7a5c18eb5b
|
7
|
+
data.tar.gz: 198d91a0c3a5ad32434559cd5a16323ea342b03202f64cfeb40655310d22fd3087281e941485a9e71efcbe414e83db8362290a4b15ec4fedfaa0fc6ff2f53070
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# TypeWrapper
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/type_wrapper)
|
4
|
+
[](https://travis-ci.org/RichOrElse/type-wrapper)
|
4
5
|
|
5
6
|
Delegator pattern in Ruby without object schizophrenia. Because Object#extend at runtime is evil.
|
6
7
|
|
@@ -22,6 +23,10 @@ Or install it yourself as:
|
|
22
23
|
|
23
24
|
## Usage
|
24
25
|
|
26
|
+
### TypeWrapper
|
27
|
+
|
28
|
+
Construct a delegator class using square brackets '[]' method with type as the first argument followed by mixins.
|
29
|
+
|
25
30
|
```ruby
|
26
31
|
module ToArray
|
27
32
|
def to_a
|
@@ -43,18 +48,39 @@ peter = PersonPresenter.new(Person.new('Peter'))
|
|
43
48
|
peter.to_a
|
44
49
|
```
|
45
50
|
|
51
|
+
### TypeWrapper::Module
|
52
|
+
|
53
|
+
Define a block with the 'new' method and pass the 'mod' parameter to 'using' keyword.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
AwesomeSinging = TypeWrapper::Module.new do |mod| using mod
|
57
|
+
def sing
|
58
|
+
"#{name} sings #{song}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def song
|
62
|
+
"Everything is AWESOME!!!"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
Lego = Struct.new(:name)
|
67
|
+
|
68
|
+
using AwesomeSinging[Lego]
|
69
|
+
Lego.new("Emmet").sing
|
70
|
+
```
|
71
|
+
|
46
72
|
## Pros
|
47
73
|
|
48
74
|
* Five (5) times faster than [Object#extend](https://apidock.com/ruby/Object/extend).
|
49
75
|
* Delegation without [self schizophrenia](https://en.wikipedia.org/wiki/Schizophrenia_(object-oriented_programming)).
|
50
76
|
* [Decorator Pattern](https://en.wikipedia.org/wiki/Decorator_pattern) with multiple traits.
|
51
|
-
* Allows [DCI](
|
77
|
+
* Allows [DCI](https://github.com/RichOrElse/wrapper-based/) in Ruby without [blowing the method cache at run time](https://tonyarcieri.com/dci-in-ruby-is-completely-broken).
|
52
78
|
|
53
79
|
## Cons
|
54
80
|
|
81
|
+
* Must use TypeWrapper::Module to allow procedural code in mixins.
|
55
82
|
* Three (3) times slower than calling class method. [See benchmark.](https://github.com/RichOrElse/wrapper-based/tree/master/examples/benchmark.rb)
|
56
|
-
* [
|
57
|
-
* Methods applied by [Object#extend](https://apidock.com/ruby/Object/extend) takes precedence over Mixin methods.
|
83
|
+
* Methods applied with [Object#extend](https://apidock.com/ruby/Object/extend) takes precedence over Mixin methods.
|
58
84
|
|
59
85
|
## Development
|
60
86
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module TypeWrapper
|
2
|
+
# == Basic Usage
|
3
|
+
#
|
4
|
+
# === Define a block with the 'new' method and pass the 'mod' parameter to 'using' keyword.
|
5
|
+
#
|
6
|
+
# AwesomeSinging = TypeWrapper::Module.new do |mod| using mod
|
7
|
+
# def sing
|
8
|
+
# "#{name} sings #{song}"
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# def song
|
12
|
+
# "Everything is AWESOME!!!"
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# === Use as refinement module by passing the 'refines' method with types.
|
17
|
+
#
|
18
|
+
# Lego = Struct.new(:name)
|
19
|
+
# using AwesomeSinging[Lego]
|
20
|
+
# Lego.new("Emmette").sing
|
21
|
+
#
|
22
|
+
|
23
|
+
class Module < ::Module
|
24
|
+
def initialize(default = Object, *types, &blk)
|
25
|
+
mod, @block = self, blk
|
26
|
+
types.unshift(default).each do |type|
|
27
|
+
refine(type) { module_exec mod, &blk }
|
28
|
+
end
|
29
|
+
super(&blk)
|
30
|
+
end
|
31
|
+
|
32
|
+
def refines(*types)
|
33
|
+
self.class.new(*types, &@block)
|
34
|
+
end
|
35
|
+
|
36
|
+
alias_method :[], :refines
|
37
|
+
|
38
|
+
module Refines
|
39
|
+
refine ::Module do
|
40
|
+
def refines(*types)
|
41
|
+
mod = self
|
42
|
+
Module.new do
|
43
|
+
types.each do |type|
|
44
|
+
refine(type) { prepend mod }
|
45
|
+
end
|
46
|
+
end # new Module
|
47
|
+
end # refines method
|
48
|
+
end # ::Module refinements
|
49
|
+
end # Refinements module
|
50
|
+
end # Module class
|
51
|
+
end # TypeWrapper module
|
data/lib/type_wrapper/version.rb
CHANGED
data/lib/type_wrapper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "type_wrapper/version"
|
2
|
+
require "type_wrapper/module"
|
2
3
|
require 'delegate'
|
3
4
|
|
4
5
|
module TypeWrapper
|
@@ -10,20 +11,21 @@ module TypeWrapper
|
|
10
11
|
@delegate_tw_obj # return object we are delegating to
|
11
12
|
end
|
12
13
|
|
13
|
-
def self.[](
|
14
|
-
raise TypeError, "wrong argument type (expected
|
15
|
-
raise
|
16
|
-
raise ArgumentError, "wrong number of arguments (given 1, expected 2+)" if modules.empty?
|
14
|
+
def self.[](*types)
|
15
|
+
raise TypeError, "wrong argument type (expected Module(s))" if types.include?(nil)
|
16
|
+
raise ArgumentError, "wrong number of arguments (given #{types.size}, expected 2+)" if types.size < 2
|
17
17
|
|
18
|
-
FOR[
|
18
|
+
FOR[*types]
|
19
19
|
end
|
20
|
+
|
21
|
+
using Module::Refines
|
20
22
|
|
21
23
|
FOR = -> type, *behaviors do
|
22
24
|
Class.new(Delegator) do
|
23
25
|
include TypeWrapper
|
24
26
|
const_set :Type, type
|
25
27
|
const_set :BEHAVIORS, behaviors
|
26
|
-
const_set :Trait, Module.new {
|
28
|
+
const_set :Trait, Module.new { behaviors.each { |mod| include mod.refines(type) } }
|
27
29
|
forwarding = behaviors.flat_map(&:public_instance_methods) - public_instance_methods
|
28
30
|
code = forwarding.uniq.map { |meth| "def %{meth}(*args, &block) __getobj__.%{meth}(*args, &block) end" % { meth: meth } }
|
29
31
|
class_eval code.unshift("using Trait").join("\n")
|
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.2.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-
|
11
|
+
date: 2017-07-19 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/module.rb
|
72
73
|
- lib/type_wrapper/version.rb
|
73
74
|
- type_wrapper.gemspec
|
74
75
|
homepage: https://github.com/RichOrElse/type-wrapper/
|
@@ -91,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
92
|
version: '0'
|
92
93
|
requirements: []
|
93
94
|
rubyforge_project:
|
94
|
-
rubygems_version: 2.
|
95
|
+
rubygems_version: 2.2.2
|
95
96
|
signing_key:
|
96
97
|
specification_version: 4
|
97
98
|
summary: Delegator pattern in Ruby without object schizophrenia. Because Object#extend
|