magic-decorator 1.1.1 → 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/CHANGELOG.md +14 -6
- data/README.md +32 -0
- data/lib/enumerable_decorator.rb +5 -0
- data/lib/magic/decoratable.rb +4 -0
- data/lib/magic/decorator/base.rb +12 -0
- data/lib/magic/decorator/core_ext/module.rb +55 -0
- data/lib/magic/decorator/version.rb +1 -1
- data/lib/magic/decorator.rb +5 -1
- data/sig/module.rbs +10 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d922af068afa4289fc270fe9b007de813cff5b8855fc12ff925cfcbe0831d018
|
|
4
|
+
data.tar.gz: 0d95e22503c504847815bad194faf699614840be21fb2aadc231d47c107823a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a3c8d64bbf55a1a9aac586f3489b9ccead69dfb734d1352d44f908e5a8c6973de230d1a498615cef92ac59c4f0727f30c38ded0ed61072dcaf1ce78d0612485
|
|
7
|
+
data.tar.gz: ef85e806210c58a398d43f0bf558482ee62e94632757cb7de3e0e9c5c96ff1c56ff81ef069f88ddaef4c1b2154b1932f753d180f8b709ebddcd9659f346025a3
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [1.2.0] — 2026-10-28
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- `Module#decorated_method`
|
|
6
|
+
to decorate method return values.
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
## [1.1.1] — 2026-10-27
|
|
2
10
|
|
|
3
11
|
### Fixed
|
|
@@ -46,7 +54,7 @@ This release marks the gem to be stable enough.
|
|
|
46
54
|
|
|
47
55
|
- Improved extendability: one may override `Magic::Decoratable#decorator_base` to be used for lookups.
|
|
48
56
|
- `Magic::Decoratable.classes`
|
|
49
|
-
|
|
57
|
+
for all the decoratables.
|
|
50
58
|
|
|
51
59
|
### Fixed
|
|
52
60
|
|
|
@@ -58,7 +66,7 @@ This release marks the gem to be stable enough.
|
|
|
58
66
|
### Changed
|
|
59
67
|
|
|
60
68
|
- For almost any method called on a decorated object, both its result and `yield`ed arguments get decorated.
|
|
61
|
-
|
|
69
|
+
Some methods aren’t meant to be decorated though:
|
|
62
70
|
- `deconstruct` & `deconstruct_keys` for _pattern matching_,
|
|
63
71
|
- _converting_ methods: those starting with `to_`,
|
|
64
72
|
- _system_ methods: those starting with `_`.
|
|
@@ -66,12 +74,12 @@ This release marks the gem to be stable enough.
|
|
|
66
74
|
### Added
|
|
67
75
|
|
|
68
76
|
- `Magic::Decorator::Base.undecorated`
|
|
69
|
-
|
|
77
|
+
to exclude methods from being decorated automagically.
|
|
70
78
|
|
|
71
79
|
#### Default decorators
|
|
72
80
|
|
|
73
81
|
- `EnumerableDecorator`
|
|
74
|
-
|
|
82
|
+
to decorate `Enumerable`s.
|
|
75
83
|
- enables _splat_ operator: `*decorated` ,
|
|
76
84
|
- enables _double-splat_ operator: `**decorated`,
|
|
77
85
|
- enumerating methods yield decorated items.
|
|
@@ -82,9 +90,9 @@ This release marks the gem to be stable enough.
|
|
|
82
90
|
### Added
|
|
83
91
|
|
|
84
92
|
- `Magic::Decorator::Base`
|
|
85
|
-
|
|
93
|
+
— a basic decorator class.
|
|
86
94
|
- `Magic::Decoratable`
|
|
87
|
-
|
|
95
|
+
to be included in decoratable classes.
|
|
88
96
|
- `#decorate`,
|
|
89
97
|
- `#decorate!`,
|
|
90
98
|
- `#decorated`,
|
data/README.md
CHANGED
|
@@ -93,6 +93,38 @@ end
|
|
|
93
93
|
Special::Model.new.decorate # looks for Special::Decorator descendants
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
+
### Decorating methods
|
|
97
|
+
|
|
98
|
+
`Module#decorated_method` decorates the return value of one or more existing instance methods by calling `#decorated` on it.
|
|
99
|
+
It accepts method names as symbols or strings, either separately or in one array, and returns those names as `Module#private` does:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
class Account
|
|
103
|
+
decorated_method attr_reader :owner
|
|
104
|
+
decorated_method def address = owner.address
|
|
105
|
+
decorated_method :method_missing
|
|
106
|
+
end
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Calling it without arguments decorates instance methods defined afterward:
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
class Account
|
|
113
|
+
decorated_method
|
|
114
|
+
|
|
115
|
+
attr_reader :owner
|
|
116
|
+
def address = owner.address
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Method arguments, keyword arguments, blocks, and visibility are preserved.
|
|
121
|
+
|
|
122
|
+
> [!IMPORTANT]
|
|
123
|
+
> This core class extension is not loaded by default and should be required explicitly if needed:
|
|
124
|
+
> ```ruby
|
|
125
|
+
> require 'magic/decorator/core_ext/module'
|
|
126
|
+
> ```
|
|
127
|
+
|
|
96
128
|
## 🪄 Magic
|
|
97
129
|
|
|
98
130
|
### Decoratable scope
|
data/lib/enumerable_decorator.rb
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# = Enumerable Decorator
|
|
4
|
+
#
|
|
5
|
+
# As the name suggests, it’s used automatically to decorate any
|
|
6
|
+
# `Enumerable` collection. The collection itself doesn’t get decorated,
|
|
7
|
+
# while its items do.
|
|
3
8
|
class EnumerableDecorator < Magic::Decorator::Base
|
|
4
9
|
def to_a(...) = super.map &:decorated
|
|
5
10
|
def to_ary(...) = super.map &:decorated
|
data/lib/magic/decoratable.rb
CHANGED
data/lib/magic/decorator/base.rb
CHANGED
|
@@ -4,6 +4,18 @@ require 'delegate'
|
|
|
4
4
|
|
|
5
5
|
module Magic
|
|
6
6
|
module Decorator
|
|
7
|
+
# = Magic Decorator
|
|
8
|
+
#
|
|
9
|
+
# Any decorator should inherit `Magic::Decorator::Base`.
|
|
10
|
+
# It further inherits from `SimpleDelegator` and behaves like that.
|
|
11
|
+
#
|
|
12
|
+
# == Decorator class inference
|
|
13
|
+
#
|
|
14
|
+
# Decorators provide automatic class inference for any class based
|
|
15
|
+
# on its name powered by Magic Lookup.
|
|
16
|
+
# For example, `MyObject.new` looks for `MyObjectDecorator` first.
|
|
17
|
+
# If not found, it looks for decorators of its ancestor classes,
|
|
18
|
+
# up to `ObjectDecorator`.
|
|
7
19
|
class Base < SimpleDelegator
|
|
8
20
|
extend Lookup
|
|
9
21
|
include Decoratable
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rubocop:disable Lint/EmptyInPattern
|
|
4
|
+
|
|
5
|
+
require 'active_support/core_ext/module/redefine_method'
|
|
6
|
+
|
|
7
|
+
# Extends Module with method return-value decoration.
|
|
8
|
+
class Module
|
|
9
|
+
# Prepend it to decorate all subsequently defined instance methods.
|
|
10
|
+
module DecorateAllMethods
|
|
11
|
+
def method_added name
|
|
12
|
+
super
|
|
13
|
+
|
|
14
|
+
decorated_method name
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Decorates the return values of named instance methods.
|
|
19
|
+
#
|
|
20
|
+
# Like Module#private, names can be passed individually or as a single array.
|
|
21
|
+
# With no arguments, subsequently defined instance methods are decorated.
|
|
22
|
+
def decorated_method *methods
|
|
23
|
+
case methods
|
|
24
|
+
in []
|
|
25
|
+
singleton_class.prepend DecorateAllMethods
|
|
26
|
+
|
|
27
|
+
return
|
|
28
|
+
in [ Symbol | String => method ]
|
|
29
|
+
in [ (Symbol | String), * ]
|
|
30
|
+
in [ [ (Symbol | String), * ] | [] => methods ]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
location = caller_locations(1, 1).first
|
|
34
|
+
|
|
35
|
+
methods.map do |method|
|
|
36
|
+
decorated_methods_module.module_eval <<~RUBY.strip, location.path, location.lineno
|
|
37
|
+
#{method_visibility method} def #{method}(...) = super.decorated
|
|
38
|
+
RUBY
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
method || methods
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def decorated_methods_module
|
|
47
|
+
if const_defined? :DecoratedMethods, false
|
|
48
|
+
const_get :DecoratedMethods
|
|
49
|
+
else
|
|
50
|
+
const_set :DecoratedMethods, Module.new
|
|
51
|
+
.tap { it.include const_get :DecoratedMethods if const_defined? :DecoratedMethods } # inheritance
|
|
52
|
+
.tap { prepend it }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/magic/decorator.rb
CHANGED
|
@@ -4,11 +4,15 @@ require 'magic/lookup'
|
|
|
4
4
|
|
|
5
5
|
require_relative 'decorator/version'
|
|
6
6
|
|
|
7
|
-
module Magic
|
|
7
|
+
module Magic # :nodoc:
|
|
8
8
|
autoload :Decoratable, 'magic/decoratable'
|
|
9
9
|
|
|
10
10
|
Object.include Decoratable
|
|
11
11
|
|
|
12
|
+
# = Magic Decorator
|
|
13
|
+
#
|
|
14
|
+
# It implements a general decorator logic. It is not meant to be a
|
|
15
|
+
# presenter.
|
|
12
16
|
module Decorator
|
|
13
17
|
autoload :Base, 'magic/decorator/base'
|
|
14
18
|
|
data/sig/module.rbs
ADDED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: magic-decorator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexander Senko
|
|
@@ -42,18 +42,20 @@ files:
|
|
|
42
42
|
- lib/magic/decorator.rb
|
|
43
43
|
- lib/magic/decorator/authors.rb
|
|
44
44
|
- lib/magic/decorator/base.rb
|
|
45
|
+
- lib/magic/decorator/core_ext/module.rb
|
|
45
46
|
- lib/magic/decorator/version.rb
|
|
46
47
|
- sig/enumerable_decorator.rbs
|
|
47
48
|
- sig/magic/decoratable.rbs
|
|
48
49
|
- sig/magic/decorator.rbs
|
|
49
50
|
- sig/magic/decorator/base.rbs
|
|
51
|
+
- sig/module.rbs
|
|
50
52
|
homepage: "https://github.com/Alexander-Senko/magic-decorator"
|
|
51
53
|
licenses:
|
|
52
54
|
- MIT
|
|
53
55
|
metadata:
|
|
54
56
|
homepage_uri: "https://github.com/Alexander-Senko/magic-decorator"
|
|
55
57
|
source_code_uri: "https://github.com/Alexander-Senko/magic-decorator"
|
|
56
|
-
changelog_uri: "https://github.com/Alexander-Senko/magic-decorator/blob/v1.
|
|
58
|
+
changelog_uri: "https://github.com/Alexander-Senko/magic-decorator/blob/v1.2.0/CHANGELOG.md"
|
|
57
59
|
rdoc_options: []
|
|
58
60
|
require_paths:
|
|
59
61
|
- lib
|