tins 1.56.0 → 1.57.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/CHANGES.md +27 -0
- data/lib/tins/ask_and_send.rb +12 -8
- data/lib/tins/expose.rb +23 -17
- data/lib/tins/version.rb +1 -1
- data/lib/tins/xt/full.rb +3 -2
- data/tests/ask_and_send_test.rb +62 -0
- data/tests/blank_full_test.rb +9 -0
- data/tests/expose_test.rb +22 -0
- data/tins.gemspec +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 495d7cdbe014ddf4d784dc67f16d6956a7abc7cacd61519cb9f2e82c1150a6bf
|
|
4
|
+
data.tar.gz: 486eed8c0a2c3cad0927ea935a290dfcf478e820478fc4f49060f8f1c8d170c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a6f0055b6921c6ea2adfe4b99e46f54fc846c1e571f0e94c8bd0af42dbb877b3a5eab1d88f8320c3f78e2766b0344e8c5d2e598b518bb5dcf320dfc0936ff11a
|
|
7
|
+
data.tar.gz: 27e271bdf9858d5924fb56fafef2ae52867cba5e5b9c83c34892a236afac8b0833da040696888e9d029052d406332cc45f5a4123d72fc417ac70132d3b5cdcf5
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-09-15 v1.57.0
|
|
4
|
+
|
|
5
|
+
* Add keyword and block forwarding to `Expose#expose`
|
|
6
|
+
* Add `**kwargs` and `&block` forwarding to `__send__` in
|
|
7
|
+
`lib/tins/expose.rb`
|
|
8
|
+
* Restructure guards so `method_name.nil?` is checked first, preventing
|
|
9
|
+
kwargs from shadowing the method name
|
|
10
|
+
* Update YARD docs to reflect new dispatch order and remove stale `@raise
|
|
11
|
+
[ArgumentError]`
|
|
12
|
+
* Add `with_kw` and `with_block` fixture methods and three new tests in
|
|
13
|
+
`tests/expose_test.rb` covering kwargs, block, and combined forwarding
|
|
14
|
+
* Add keyword argument support to `Full#full?`
|
|
15
|
+
* Add `**kwargs` to `full?` method signature in `lib/tins/xt/full.rb` and
|
|
16
|
+
forward via `__send__`
|
|
17
|
+
* Update YARD documentation with `@param kwargs`
|
|
18
|
+
* Add `test_full_with_kwargs` in `tests/blank_full_test.rb` verifying
|
|
19
|
+
`**kwargs` forwarding and blank result handling
|
|
20
|
+
* Add keyword argument support to `AskAndSend`
|
|
21
|
+
* Add `**kwargs` to all four methods in `lib/tins/ask_and_send.rb`
|
|
22
|
+
(`ask_and_send`, `ask_and_send!`, `ask_and_send_or_self`,
|
|
23
|
+
`ask_and_send_or_self!`) and forward them via `__send__`
|
|
24
|
+
* Update YARD documentation with `@param kwargs` for each method
|
|
25
|
+
* Add test fixtures `foo_kw`, `foo_args`, `bar_kw`, `bar_args` in
|
|
26
|
+
`tests/ask_and_send_test.rb`
|
|
27
|
+
* Add 8 new test cases covering `**kwargs`, `*args`, and `&block`
|
|
28
|
+
forwarding across all four `AskAndSend` variants
|
|
29
|
+
|
|
3
30
|
## 2026-07-25 v1.56.0
|
|
4
31
|
|
|
5
32
|
### Changes
|
data/lib/tins/ask_and_send.rb
CHANGED
|
@@ -7,12 +7,13 @@ module Tins
|
|
|
7
7
|
#
|
|
8
8
|
# @param method_name [ Symbol ] the name of the method to invoke
|
|
9
9
|
# @param args [ Array ] arguments to pass to the method
|
|
10
|
+
# @param kwargs [ Hash ] keyword arguments to pass to the method
|
|
10
11
|
# @yield [ block ] optional block to pass to the method
|
|
11
12
|
# @return [ Object, nil ] the result of the method call or nil if the
|
|
12
13
|
# method doesn't exist
|
|
13
|
-
def ask_and_send(method_name, *args, &block)
|
|
14
|
+
def ask_and_send(method_name, *args, **kwargs, &block)
|
|
14
15
|
if respond_to?(method_name)
|
|
15
|
-
__send__(method_name, *args, &block)
|
|
16
|
+
__send__(method_name, *args, **kwargs, &block)
|
|
16
17
|
end
|
|
17
18
|
end
|
|
18
19
|
|
|
@@ -21,13 +22,14 @@ module Tins
|
|
|
21
22
|
#
|
|
22
23
|
# @param method_name [ Symbol ] the name of the method to call
|
|
23
24
|
# @param args [ Array ] arguments to pass to the method
|
|
25
|
+
# @param kwargs [ Hash ] keyword arguments to pass to the method
|
|
24
26
|
# @param block [ Proc ] optional block to pass to the method
|
|
25
27
|
#
|
|
26
28
|
# @return [ Object, nil ] the result of the method call or nil if the
|
|
27
29
|
# method doesn't exist
|
|
28
|
-
def ask_and_send!(method_name, *args, &block)
|
|
30
|
+
def ask_and_send!(method_name, *args, **kwargs, &block)
|
|
29
31
|
if respond_to?(method_name, true)
|
|
30
|
-
__send__(method_name, *args, &block)
|
|
32
|
+
__send__(method_name, *args, **kwargs, &block)
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
|
|
@@ -38,13 +40,14 @@ module Tins
|
|
|
38
40
|
#
|
|
39
41
|
# @param method_name [ Symbol ] the name of the method to call
|
|
40
42
|
# @param args [ Array ] the arguments to pass to the method
|
|
43
|
+
# @param kwargs [ Hash ] the keyword arguments to pass to the method
|
|
41
44
|
# @param block [ Proc ] the block to pass to the method
|
|
42
45
|
#
|
|
43
46
|
# @return [ Object ] the result of the method call or self if the method
|
|
44
47
|
# doesn't exist
|
|
45
|
-
def ask_and_send_or_self(method_name, *args, &block)
|
|
48
|
+
def ask_and_send_or_self(method_name, *args, **kwargs, &block)
|
|
46
49
|
if respond_to?(method_name)
|
|
47
|
-
__send__(method_name, *args, &block)
|
|
50
|
+
__send__(method_name, *args, **kwargs, &block)
|
|
48
51
|
else
|
|
49
52
|
self
|
|
50
53
|
end
|
|
@@ -57,13 +60,14 @@ module Tins
|
|
|
57
60
|
#
|
|
58
61
|
# @param method_name [ Symbol ] the name of the method to send
|
|
59
62
|
# @param args [ Array ] the arguments to pass to the method
|
|
63
|
+
# @param kwargs [ Hash ] the keyword arguments to pass to the method
|
|
60
64
|
# @param block [ Proc ] the block to pass to the method
|
|
61
65
|
#
|
|
62
66
|
# @return [ Object ] the result of the method call or the object itself if
|
|
63
67
|
# the method is not found
|
|
64
|
-
def ask_and_send_or_self!(method_name, *args, &block)
|
|
68
|
+
def ask_and_send_or_self!(method_name, *args, **kwargs, &block)
|
|
65
69
|
if respond_to?(method_name, true)
|
|
66
|
-
__send__(method_name, *args, &block)
|
|
70
|
+
__send__(method_name, *args, **kwargs, &block)
|
|
67
71
|
else
|
|
68
72
|
self
|
|
69
73
|
end
|
data/lib/tins/expose.rb
CHANGED
|
@@ -40,36 +40,42 @@ module Tins
|
|
|
40
40
|
# This method provides three distinct usage patterns:
|
|
41
41
|
#
|
|
42
42
|
# 1. **Method Call**: When given a method name, directly calls that method
|
|
43
|
-
# and returns its result.
|
|
43
|
+
# and returns its result. Positional arguments, keyword arguments, and
|
|
44
|
+
# a block can be forwarded to the called method.
|
|
44
45
|
#
|
|
45
|
-
# 2. **Block Execution**: When
|
|
46
|
-
# context of the object, allowing
|
|
46
|
+
# 2. **Block Execution**: When called without a method name but with a
|
|
47
|
+
# block, evaluates the block in the context of the object, allowing
|
|
48
|
+
# access to private/protected methods.
|
|
47
49
|
#
|
|
48
|
-
# 3. **Full Exposure**: When called without
|
|
49
|
-
# of the object with all private and
|
|
50
|
+
# 3. **Full Exposure**: When called without a method name and without a
|
|
51
|
+
# block, returns a duplicate of the object with all private and
|
|
52
|
+
# protected methods exposed as public.
|
|
50
53
|
#
|
|
51
54
|
# @param method_name [Symbol, String, nil] name of the method to call,
|
|
52
55
|
# or nil for full exposure
|
|
53
56
|
# @param args [Array] arguments to pass to the method when calling it
|
|
54
|
-
# @param
|
|
57
|
+
# @param kwargs [Hash] keyword arguments to pass to the method when calling it
|
|
58
|
+
# @param block [Proc] block to execute in the context of the object or
|
|
59
|
+
# to forward to the called method
|
|
55
60
|
#
|
|
56
61
|
# @return [Object] result of the method call, block execution, or a new
|
|
57
62
|
# object with exposed methods (when called without args)
|
|
58
63
|
#
|
|
59
64
|
# @raise [NoMethodError] if method_name is given but doesn't exist
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
def expose(method_name = nil, *args, **kwargs, &block)
|
|
66
|
+
if method_name.nil?
|
|
67
|
+
if block
|
|
68
|
+
instance_eval(&block)
|
|
69
|
+
else
|
|
70
|
+
methods = private_methods(true) + protected_methods(true)
|
|
71
|
+
o = dup
|
|
72
|
+
o.singleton_class.class_eval do
|
|
73
|
+
public(*methods)
|
|
74
|
+
end
|
|
75
|
+
o
|
|
69
76
|
end
|
|
70
|
-
o
|
|
71
77
|
elsif method_name
|
|
72
|
-
__send__(method_name, *args)
|
|
78
|
+
__send__(method_name, *args, **kwargs, &block)
|
|
73
79
|
end
|
|
74
80
|
end
|
|
75
81
|
end
|
data/lib/tins/version.rb
CHANGED
data/lib/tins/xt/full.rb
CHANGED
|
@@ -26,6 +26,7 @@ module Tins
|
|
|
26
26
|
#
|
|
27
27
|
# @param dispatch [Symbol, nil] The method to call on the object (optional)
|
|
28
28
|
# @param args [Array] Arguments to pass to the dispatched method (optional)
|
|
29
|
+
# @param kwargs [Hash] Keyword arguments to pass to the dispatched method (optional)
|
|
29
30
|
# @yield [Object] Optional block to execute with the result if result or
|
|
30
31
|
# dispatched result not nil
|
|
31
32
|
# @return [Object, nil] The object itself if not blank, or the result of
|
|
@@ -43,11 +44,11 @@ module Tins
|
|
|
43
44
|
#
|
|
44
45
|
# @example With block execution
|
|
45
46
|
# user.full?(:name) { |name| "Hello #{name}" }
|
|
46
|
-
def full?(dispatch = nil, *args)
|
|
47
|
+
def full?(dispatch = nil, *args, **kwargs)
|
|
47
48
|
if blank?
|
|
48
49
|
obj = nil
|
|
49
50
|
elsif dispatch
|
|
50
|
-
obj = __send__(dispatch, *args)
|
|
51
|
+
obj = __send__(dispatch, *args, **kwargs)
|
|
51
52
|
obj = nil if obj.blank?
|
|
52
53
|
else
|
|
53
54
|
obj = self
|
data/tests/ask_and_send_test.rb
CHANGED
|
@@ -10,11 +10,27 @@ module Tins
|
|
|
10
10
|
:foo
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
def foo_kw(x:)
|
|
14
|
+
[:foo_kw, x]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def foo_args(*args, &block)
|
|
18
|
+
[:foo_args, args, block&.call]
|
|
19
|
+
end
|
|
20
|
+
|
|
13
21
|
private
|
|
14
22
|
|
|
15
23
|
def bar
|
|
16
24
|
:bar
|
|
17
25
|
end
|
|
26
|
+
|
|
27
|
+
def bar_kw(x:)
|
|
28
|
+
[:bar_kw, x]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def bar_args(*args, &block)
|
|
32
|
+
[:bar_args, args, block&.call]
|
|
33
|
+
end
|
|
18
34
|
end
|
|
19
35
|
|
|
20
36
|
def test_asking_publicly
|
|
@@ -42,5 +58,51 @@ module Tins
|
|
|
42
58
|
assert_equal :bar, a.ask_and_send_or_self!(:bar)
|
|
43
59
|
assert_equal a, a.ask_and_send_or_self(:baz)
|
|
44
60
|
end
|
|
61
|
+
|
|
62
|
+
def test_asking_publicly_with_kwargs
|
|
63
|
+
assert_equal [:foo_kw, 42], A.new.ask_and_send(:foo_kw, x: 42)
|
|
64
|
+
assert_nil A.new.ask_and_send(:bar_kw, x: 42)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def test_asking_privately_with_kwargs
|
|
68
|
+
assert_equal [:foo_kw, 42], A.new.ask_and_send!(:foo_kw, x: 42)
|
|
69
|
+
assert_equal [:bar_kw, 42], A.new.ask_and_send!(:bar_kw, x: 42)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_asking_selfy_publicly_with_kwargs
|
|
73
|
+
a = A.new
|
|
74
|
+
assert_equal [:foo_kw, 7], a.ask_and_send_or_self(:foo_kw, x: 7)
|
|
75
|
+
assert_equal a, a.ask_and_send_or_self(:bar_kw, x: 7)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_asking_selfy_privately_with_kwargs
|
|
79
|
+
a = A.new
|
|
80
|
+
assert_equal [:foo_kw, 7], a.ask_and_send_or_self!(:foo_kw, x: 7)
|
|
81
|
+
assert_equal [:bar_kw, 7], a.ask_and_send_or_self!(:bar_kw, x: 7)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def test_asking_publicly_with_args_and_block
|
|
85
|
+
a = A.new
|
|
86
|
+
assert_equal [:foo_args, [1, 2], :hello], a.ask_and_send(:foo_args, 1, 2) { :hello }
|
|
87
|
+
assert_nil a.ask_and_send(:bar_args, 1, 2) { :hello }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_asking_privately_with_args_and_block
|
|
91
|
+
a = A.new
|
|
92
|
+
assert_equal [:foo_args, [1, 2], :hello], a.ask_and_send!(:foo_args, 1, 2) { :hello }
|
|
93
|
+
assert_equal [:bar_args, [3, 4], :world], a.ask_and_send!(:bar_args, 3, 4) { :world }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_asking_selfy_publicly_with_args_and_block
|
|
97
|
+
a = A.new
|
|
98
|
+
assert_equal [:foo_args, [1], :ok], a.ask_and_send_or_self(:foo_args, 1) { :ok }
|
|
99
|
+
assert_equal a, a.ask_and_send_or_self(:bar_args, 1) { :ok }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def test_asking_selfy_privately_with_args_and_block
|
|
103
|
+
a = A.new
|
|
104
|
+
assert_equal [:foo_args, [1], :ok], a.ask_and_send_or_self!(:foo_args, 1) { :ok }
|
|
105
|
+
assert_equal [:bar_args, [2], :ok], a.ask_and_send_or_self!(:bar_args, 2) { :ok }
|
|
106
|
+
end
|
|
45
107
|
end
|
|
46
108
|
end
|
data/tests/blank_full_test.rb
CHANGED
|
@@ -58,6 +58,15 @@ module Tins
|
|
|
58
58
|
assert_equal 3, "foo".full?(:size)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
def test_full_with_kwargs
|
|
62
|
+
obj = Object.new
|
|
63
|
+
def obj.greet(name:)
|
|
64
|
+
"hello #{name}"
|
|
65
|
+
end
|
|
66
|
+
assert_equal 'hello world', obj.full?(:greet, name: 'world')
|
|
67
|
+
assert_nil ''.full?(:greet, name: 'world')
|
|
68
|
+
end
|
|
69
|
+
|
|
61
70
|
def test_all_full
|
|
62
71
|
assert_equal [1, 2], [1, 2].all_full?
|
|
63
72
|
assert_nil [nil, 2].all_full?
|
data/tests/expose_test.rb
CHANGED
|
@@ -13,6 +13,16 @@ module Tins
|
|
|
13
13
|
:prot
|
|
14
14
|
end
|
|
15
15
|
protected :prot
|
|
16
|
+
|
|
17
|
+
def with_kw(x:)
|
|
18
|
+
[:with_kw, x]
|
|
19
|
+
end
|
|
20
|
+
private :with_kw
|
|
21
|
+
|
|
22
|
+
def with_block
|
|
23
|
+
yield :from_block
|
|
24
|
+
end
|
|
25
|
+
private :with_block
|
|
16
26
|
end
|
|
17
27
|
|
|
18
28
|
def setup
|
|
@@ -39,5 +49,17 @@ module Tins
|
|
|
39
49
|
assert_equal :priv, @a.expose(:priv)
|
|
40
50
|
assert_equal :prot, @a.expose(:prot, :any)
|
|
41
51
|
end
|
|
52
|
+
|
|
53
|
+
def test_exposes_method_with_kwargs
|
|
54
|
+
assert_equal [:with_kw, 42], @a.expose(:with_kw, x: 42)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_exposes_method_with_block
|
|
58
|
+
assert_equal :from_block, @a.expose(:with_block) { |v| v }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_exposes_method_with_kwargs_and_block
|
|
62
|
+
assert_equal [:with_kw, 7], @a.expose(:with_kw, x: 7) { :ignored }
|
|
63
|
+
end
|
|
42
64
|
end
|
|
43
65
|
end
|
data/tins.gemspec
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: tins 1.
|
|
2
|
+
# stub: tins 1.57.0 ruby lib
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "tins".freeze
|
|
6
|
-
s.version = "1.
|
|
6
|
+
s.version = "1.57.0".freeze
|
|
7
7
|
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
9
9
|
s.require_paths = ["lib".freeze]
|
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
|
23
23
|
|
|
24
24
|
s.specification_version = 4
|
|
25
25
|
|
|
26
|
-
s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.
|
|
26
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.18.0".freeze])
|
|
27
27
|
s.add_development_dependency(%q<all_images>.freeze, [">= 0".freeze])
|
|
28
28
|
s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
|
|
29
29
|
s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tins
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.57.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 2.
|
|
18
|
+
version: 2.18.0
|
|
19
19
|
type: :development
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 2.
|
|
25
|
+
version: 2.18.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: all_images
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|