defi 2.0.7 → 3.0.1
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/LICENSE.md +1 -1
- data/README.md +35 -21
- data/lib/defi/method.rb +105 -0
- data/lib/defi/value.rb +47 -30
- data/lib/defi.rb +27 -15
- data/lib/kernel.rb +45 -0
- metadata +10 -135
- data/lib/defi/challenge.rb +0 -99
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbd2a5befa5ac9808bfe1c121549311dfed58c0a48070b9708ec46621a101255
|
4
|
+
data.tar.gz: b1f16e2e70d07e377e7f662a807afb1afbe9cc971535cb683d5000b19b0306de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a673ab6344aa7f6ebe0b04ff7556b0f3d5524cec97f26810613858afe874f96362081a293cabadcdcf8a09da1c10c75ef8fa0e5a3efc39fc3f075660febc6a9a
|
7
|
+
data.tar.gz: a8c78c9725743ba1efeb8e3ac12afb5dca6403d8a7d6b714142814db42d7d60b075b5a3d5431a2145b33319f2c6d08742e50fe91d4e7ea5916579a8185b4bcdd
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
# Defi
|
2
2
|
|
3
|
-
[](https://github.com/fixrb/defi/
|
3
|
+
[](https://github.com/fixrb/defi/tags)
|
4
4
|
[](https://rubydoc.info/github/fixrb/defi/main)
|
5
|
-
[](https://github.com/fixrb/defi/actions?query=workflow%3Aci+branch%3Amain)
|
6
|
-
[](https://github.com/fixrb/defi/actions?query=workflow%3Arubocop+branch%3Amain)
|
7
5
|
[](https://github.com/fixrb/defi/raw/main/LICENSE.md)
|
8
6
|
|
9
|
-
|
7
|
+
**Defi** is a streamlined Ruby library designed for the specification of method arguments while respecting their signatures.
|
8
|
+
Rather than representing method signatures themselves, Defi focuses on providing a way to furnish methods with appropriate arguments, thereby preparing them for invocation.
|
9
|
+
|
10
|
+
This approach serves as an alternative to traditional methods like `Object#method` and `UnboundMethod`.
|
11
|
+
Where `Object#method` is bound to a specific object and `UnboundMethod` requires compatibility with the method’s originating class, Defi offers a more flexible and universal way to prepare method calls.
|
12
|
+
It allows method arguments to be specified in advance and then applied to any compatible object – those equipped with corresponding methods.
|
13
|
+
|
14
|
+
Defi is particularly useful in scenarios where you need to apply a set of method arguments across different objects to observe the varying outcomes, whether they be returned values or exceptions.
|
15
|
+
This makes it an ideal tool for testing, method comparison across different implementations, or any situation where method behavior needs to be assessed dynamically across various objects.
|
10
16
|
|
11
17
|
## Installation
|
12
18
|
|
@@ -30,26 +36,39 @@ gem install defi
|
|
30
36
|
|
31
37
|
## Usage
|
32
38
|
|
33
|
-
|
39
|
+
The `Defi` library simplifies the task of applying method signatures to various objects, regardless of their type (instances, modules, etc.).
|
40
|
+
Below are some detailed examples to demonstrate its versatility and ease of use:
|
34
41
|
|
35
|
-
|
36
|
-
Defi.send(:*, 7).to(6).call # => 42
|
37
|
-
```
|
42
|
+
### Example 1: Multiplying Numbers
|
38
43
|
|
39
|
-
|
44
|
+
Suppose you want to multiply the number `6` by `7`.
|
45
|
+
With `Defi`, this can be elegantly done as follows:
|
40
46
|
|
41
47
|
```ruby
|
42
|
-
Defi
|
48
|
+
result = Defi(:*, 7).to(6).call
|
49
|
+
puts result # Output: 42
|
43
50
|
```
|
44
51
|
|
45
|
-
|
52
|
+
Here, `Defi(:*, 7)` creates a challenge with the multiplication method (`:*`) and the argument `7`.
|
53
|
+
The `.to(6)` method specifies that this challenge should be applied to the number `6`.
|
54
|
+
Finally, `.call` executes the challenge, yielding the result `42`.
|
55
|
+
|
56
|
+
### Example 2: Invoking an Undefined Method
|
57
|
+
|
58
|
+
`Defi` also elegantly handles cases where the method might not exist on the target object.
|
59
|
+
For instance:
|
46
60
|
|
47
61
|
```ruby
|
48
|
-
|
49
|
-
Defi
|
50
|
-
|
62
|
+
begin
|
63
|
+
Defi(:boom).to("foo").call
|
64
|
+
rescue NoMethodError => e
|
65
|
+
puts e.message # Output: undefined method `boom' for "foo":String
|
66
|
+
end
|
51
67
|
```
|
52
68
|
|
69
|
+
In this example, we attempt to call the non-existent method `boom` on the string `"foo"`.
|
70
|
+
`Defi` correctly raises a `NoMethodError`, showing that the method `boom` is undefined for a `String` object.
|
71
|
+
|
53
72
|
## Contact
|
54
73
|
|
55
74
|
* Source code: https://github.com/fixrb/defi/issues
|
@@ -62,11 +81,6 @@ __Defi__ follows [Semantic Versioning 2.0](https://semver.org/).
|
|
62
81
|
|
63
82
|
The [gem](https://rubygems.org/gems/defi) is available as open source under the terms of the [MIT License](https://github.com/fixrb/defi/raw/main/LICENSE.md).
|
64
83
|
|
65
|
-
|
84
|
+
## Sponsors
|
66
85
|
|
67
|
-
|
68
|
-
This project is sponsored by:<br />
|
69
|
-
<a href="https://sashite.com/"><img
|
70
|
-
src="https://github.com/fixrb/defi/raw/main/img/sashite.png"
|
71
|
-
alt="Sashite" /></a>
|
72
|
-
</p>
|
86
|
+
This project is sponsored by [Sashité](https://sashite.com/)
|
data/lib/defi/method.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Defi
|
4
|
+
# Represents a method to be applied against an object.
|
5
|
+
# Encapsulates method name, arguments, keyword arguments and blocks
|
6
|
+
# for dynamic method invocation with proper error handling.
|
7
|
+
class Method < ::BasicObject
|
8
|
+
# Initialize a new Method object.
|
9
|
+
#
|
10
|
+
# @param name [Symbol] The method name
|
11
|
+
# @param args [Array] Positional arguments
|
12
|
+
# @param opts [Hash] Keyword arguments
|
13
|
+
# @param block [Proc] Optional block
|
14
|
+
#
|
15
|
+
# @raise [ArgumentError] If name is not a Symbol, raises with the actual class received
|
16
|
+
def initialize(name, *args, **opts, &block)
|
17
|
+
raise ::ArgumentError, "Method name must be a Symbol, got: #{name.class}" unless name.is_a?(::Symbol)
|
18
|
+
|
19
|
+
@name = name
|
20
|
+
@args = args
|
21
|
+
@opts = opts
|
22
|
+
@block = block
|
23
|
+
end
|
24
|
+
|
25
|
+
# Applies the method to the given object.
|
26
|
+
#
|
27
|
+
# @param object [#object_id] Target object for method invocation
|
28
|
+
# @return [Defi::Value] Result wrapper containing return value or exception
|
29
|
+
#
|
30
|
+
# @example Basic arithmetic
|
31
|
+
# Defi::Method.new(:+, 1).to(2).call # => 3
|
32
|
+
#
|
33
|
+
# @example Block usage
|
34
|
+
# Defi::Method.new(:map) { |x| x * 2 }.to([1, 2, 3]).call # => [2, 4, 6]
|
35
|
+
#
|
36
|
+
# @example Error handling
|
37
|
+
# result = Defi::Method.new(:undefined).to(42)
|
38
|
+
# result.raised? # => true
|
39
|
+
def to(object)
|
40
|
+
Value.new { object.public_send(@name, *@args, **@opts, &@block) }
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Hash] Method properties
|
44
|
+
def to_h
|
45
|
+
{
|
46
|
+
name: @name,
|
47
|
+
args: @args,
|
48
|
+
opts: @opts,
|
49
|
+
block: @block
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [String] Human-readable representation
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# Defi::Method.new(:+, 1).inspect
|
57
|
+
# # => "Defi(name: :+, args: [1], opts: {}, block: nil)"
|
58
|
+
def inspect
|
59
|
+
"Defi(" \
|
60
|
+
"name: #{@name.inspect}, " \
|
61
|
+
"args: #{@args.inspect}, " \
|
62
|
+
"opts: #{@opts.inspect}, " \
|
63
|
+
"block: #{@block.nil? ? "nil" : "<Proc>"})"
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [String] String representation of the method call
|
67
|
+
#
|
68
|
+
# @example
|
69
|
+
# Defi::Method.new(:+, 1).to_s # => ".+(1)"
|
70
|
+
# Defi::Method.new(:map) { |x| x }.to_s # => ".map(<Proc>)"
|
71
|
+
def to_s
|
72
|
+
return ".#{@name}" if no_arguments?
|
73
|
+
|
74
|
+
".#{@name}(#{stringified_arguments})"
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def no_arguments?
|
80
|
+
@args.empty? && @opts.empty? && @block.nil?
|
81
|
+
end
|
82
|
+
|
83
|
+
def stringified_arguments
|
84
|
+
[
|
85
|
+
args_string,
|
86
|
+
opts_string,
|
87
|
+
block_string
|
88
|
+
].compact.join(", ")
|
89
|
+
end
|
90
|
+
|
91
|
+
def args_string
|
92
|
+
@args.inspect[1..-2] unless @args.empty?
|
93
|
+
end
|
94
|
+
|
95
|
+
def opts_string
|
96
|
+
@opts.inspect[1..-2] unless @opts.empty?
|
97
|
+
end
|
98
|
+
|
99
|
+
def block_string
|
100
|
+
"<Proc>" if @block
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
require_relative "value"
|
data/lib/defi/value.rb
CHANGED
@@ -1,68 +1,85 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Defi
|
4
|
-
#
|
5
|
-
#
|
4
|
+
# Represents a result of an operation, encapsulating both successful returns
|
5
|
+
# and exceptions. This class intentionally catches all exceptions (Exception)
|
6
|
+
# instead of StandardError to maintain complete control over method execution
|
7
|
+
# outcomes, particularly in testing contexts. This ensures that system-level
|
8
|
+
# exceptions like SystemExit cannot prematurely terminate test execution with
|
9
|
+
# potentially false positive results.
|
6
10
|
class Value
|
7
|
-
|
11
|
+
RAISE = "raise"
|
12
|
+
RETURN = "return"
|
13
|
+
|
14
|
+
# @return [#object_id] The returned value or caught exception
|
8
15
|
attr_reader :object
|
9
16
|
|
10
|
-
#
|
17
|
+
# Initializes a Value object by executing the provided block.
|
18
|
+
#
|
19
|
+
# @example Successful execution
|
20
|
+
# value = Defi::Value.new { 1 + 1 }
|
21
|
+
# value.call # => 2
|
22
|
+
# value.raised? # => false
|
23
|
+
#
|
24
|
+
# @example Exception handling
|
25
|
+
# value = Defi::Value.new { raise TypeError, "Invalid type" }
|
26
|
+
# value.raised? # => true
|
27
|
+
# value.object # => #<TypeError: Invalid type>
|
11
28
|
#
|
12
|
-
# @
|
13
|
-
#
|
29
|
+
# @note This implementation catches Exception instead of StandardError
|
30
|
+
# to provide complete control over method execution outcomes,
|
31
|
+
# including system-level exceptions when needed.
|
32
|
+
#
|
33
|
+
# @yieldreturn [#object_id] Result or exception from block execution
|
14
34
|
def initialize
|
15
35
|
@object = yield
|
16
36
|
@raised = false
|
17
|
-
rescue ::Exception => e
|
37
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
18
38
|
@object = e
|
19
39
|
@raised = true
|
20
40
|
end
|
21
|
-
# rubocop:enable Lint/RescueException
|
22
41
|
|
23
|
-
#
|
42
|
+
# Returns the result or raises the captured exception.
|
43
|
+
#
|
44
|
+
# @example With successful result
|
45
|
+
# Value.new { "success" }.call # => "success"
|
24
46
|
#
|
25
|
-
# @
|
47
|
+
# @example With exception
|
48
|
+
# Value.new { raise "error" }.call # raises RuntimeError: error
|
49
|
+
#
|
50
|
+
# @return [#object_id] The operation result
|
51
|
+
# @raise [Exception] The captured exception if raised? is true
|
26
52
|
def call
|
27
53
|
raise object if raised?
|
28
54
|
|
29
55
|
object
|
30
56
|
end
|
31
57
|
|
32
|
-
# @return [Boolean]
|
58
|
+
# @return [Boolean] true if execution raised an exception
|
33
59
|
def raised?
|
34
60
|
@raised
|
35
61
|
end
|
36
62
|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
63
|
+
# @return [String] Human-readable representation
|
64
|
+
def inspect
|
65
|
+
"Value(object: #{object}, raised: #{raised?})"
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Hash] Value properties
|
40
69
|
def to_h
|
41
|
-
{
|
42
|
-
raised: raised?,
|
43
|
-
object: object
|
44
|
-
}
|
70
|
+
{ raised: raised?, object: }
|
45
71
|
end
|
46
72
|
|
47
|
-
# String
|
48
|
-
#
|
49
|
-
# @return [String] The string representation of the value.
|
73
|
+
# @return [String] String representation showing outcome type and value
|
50
74
|
def to_s
|
51
75
|
"#{raise_or_return} #{object}"
|
52
76
|
end
|
53
77
|
|
54
|
-
# A string containing a human-readable representation of the value.
|
55
|
-
#
|
56
|
-
# @return [String] The human-readable representation of the value.
|
57
|
-
def inspect
|
58
|
-
"Value(object: #{object}, raised: #{raised?})"
|
59
|
-
end
|
60
|
-
|
61
78
|
private
|
62
79
|
|
63
|
-
# @return [String]
|
80
|
+
# @return [String] Execution outcome type
|
64
81
|
def raise_or_return
|
65
|
-
raised? ?
|
82
|
+
raised? ? RAISE : RETURN
|
66
83
|
end
|
67
84
|
end
|
68
85
|
end
|
data/lib/defi.rb
CHANGED
@@ -2,21 +2,33 @@
|
|
2
2
|
|
3
3
|
# Namespace for the Defi library.
|
4
4
|
#
|
5
|
+
# Defi provides a flexible way to specify method calls with arguments
|
6
|
+
# for later execution. It supports method chaining, exception handling,
|
7
|
+
# and value inspection.
|
8
|
+
#
|
9
|
+
# @example Basic arithmetic operation
|
10
|
+
# addition = Defi(:+, 2)
|
11
|
+
# addition.to(1).call # => 3
|
12
|
+
#
|
13
|
+
# @example String manipulation
|
14
|
+
# upcase = Defi(:upcase)
|
15
|
+
# upcase.to("hello").call # => "HELLO"
|
16
|
+
#
|
17
|
+
# @example Method with keyword arguments
|
18
|
+
# format = Defi(:format, precision: 2)
|
19
|
+
# format.to(3.14159).call # => "3.14"
|
20
|
+
#
|
21
|
+
# @example Block usage
|
22
|
+
# map_double = Defi(:map) { |x| x * 2 }
|
23
|
+
# map_double.to([1, 2, 3]).call # => [2, 4, 6]
|
24
|
+
#
|
25
|
+
# @example Error handling
|
26
|
+
# result = Defi(:undefined_method).to(42)
|
27
|
+
# result.raised? # => true
|
28
|
+
# result.object # => #<NoMethodError: ...>
|
29
|
+
#
|
5
30
|
module Defi
|
6
|
-
# Expectations are built with this method.
|
7
|
-
#
|
8
|
-
# @example A :foo challenge
|
9
|
-
# send(:foo) # => #<Defi::Challenge:0x007f96a40925f8 @method=:foo, @args=[]>
|
10
|
-
#
|
11
|
-
# @param method [#to_sym] The method to send to an object.
|
12
|
-
# @param args [Array] Any arguments of the method.
|
13
|
-
# @param kwargs [Hash] Any keyword arguments of the method.
|
14
|
-
# @param block [Proc] Any block argument of the method.
|
15
|
-
#
|
16
|
-
# @return [Challenge] The challenge instance.
|
17
|
-
def self.send(method, *args, **kwargs, &block)
|
18
|
-
Challenge.new(method, *args, **kwargs, &block)
|
19
|
-
end
|
20
31
|
end
|
21
32
|
|
22
|
-
|
33
|
+
# Load core components
|
34
|
+
require_relative "kernel"
|
data/lib/kernel.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative File.join("defi", "method")
|
4
|
+
|
5
|
+
# Core Ruby module extended to provide the Defi method globally.
|
6
|
+
# This extension allows for convenient method encapsulation and
|
7
|
+
# delayed execution through the Defi method, accessible anywhere
|
8
|
+
# in the Ruby environment.
|
9
|
+
module Kernel
|
10
|
+
# rubocop:disable Naming/MethodName
|
11
|
+
|
12
|
+
# Creates a new Defi::Method instance.
|
13
|
+
# This method provides a flexible way to encapsulate a method name along with its
|
14
|
+
# arguments, keyword arguments, and an optional block for later invocation.
|
15
|
+
#
|
16
|
+
# @param method_name [Symbol] The method name to be sent to an object
|
17
|
+
# @param args [Array] Positional arguments to be passed to the method
|
18
|
+
# @param opts [Hash] Keyword arguments to be passed to the method
|
19
|
+
# @param block [Proc] Optional block to be passed to the method
|
20
|
+
#
|
21
|
+
# @example Basic method without arguments
|
22
|
+
# Defi(:to_s)
|
23
|
+
#
|
24
|
+
# @example Method with positional arguments
|
25
|
+
# Defi(:+, 2)
|
26
|
+
# Defi(:[], 0, 2) # For array/string slicing
|
27
|
+
#
|
28
|
+
# @example Method with keyword arguments
|
29
|
+
# Defi(:transform, x: 1, y: 2)
|
30
|
+
#
|
31
|
+
# @example Method with a block
|
32
|
+
# Defi(:map) { |x| x * 2 }
|
33
|
+
#
|
34
|
+
# @example Complex method call
|
35
|
+
# Defi(:reduce, 0, &:+) # Sum an array
|
36
|
+
#
|
37
|
+
# @raise [ArgumentError] If method_name is not a Symbol
|
38
|
+
#
|
39
|
+
# @return [Defi::Method] An instance of Defi::Method encapsulating the method call
|
40
|
+
def Defi(method_name, *args, **opts, &block)
|
41
|
+
::Defi::Method.new(method_name, *args, **opts, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
# rubocop:enable Naming/MethodName
|
45
|
+
end
|
metadata
CHANGED
@@ -1,141 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: defi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Kato
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: aw
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 0.2.0
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 0.2.0
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rake
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rubocop-md
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rubocop-performance
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rubocop-rake
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop-thread_safety
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: simplecov
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: yard
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
11
|
+
date: 2024-12-31 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
139
13
|
description: Challenge library.
|
140
14
|
email: contact@cyril.email
|
141
15
|
executables: []
|
@@ -145,14 +19,15 @@ files:
|
|
145
19
|
- LICENSE.md
|
146
20
|
- README.md
|
147
21
|
- lib/defi.rb
|
148
|
-
- lib/defi/
|
22
|
+
- lib/defi/method.rb
|
149
23
|
- lib/defi/value.rb
|
24
|
+
- lib/kernel.rb
|
150
25
|
homepage: https://github.com/fixrb/defi
|
151
26
|
licenses:
|
152
27
|
- MIT
|
153
28
|
metadata:
|
154
29
|
rubygems_mfa_required: 'true'
|
155
|
-
post_install_message:
|
30
|
+
post_install_message:
|
156
31
|
rdoc_options: []
|
157
32
|
require_paths:
|
158
33
|
- lib
|
@@ -160,15 +35,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
35
|
requirements:
|
161
36
|
- - ">="
|
162
37
|
- !ruby/object:Gem::Version
|
163
|
-
version:
|
38
|
+
version: 3.1.0
|
164
39
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
40
|
requirements:
|
166
41
|
- - ">="
|
167
42
|
- !ruby/object:Gem::Version
|
168
43
|
version: '0'
|
169
44
|
requirements: []
|
170
|
-
rubygems_version: 3.
|
171
|
-
signing_key:
|
45
|
+
rubygems_version: 3.3.27
|
46
|
+
signing_key:
|
172
47
|
specification_version: 4
|
173
48
|
summary: Challenge library.
|
174
49
|
test_files: []
|
data/lib/defi/challenge.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "aw"
|
4
|
-
|
5
|
-
module Defi
|
6
|
-
# This class contains a challenge to apply against an object.
|
7
|
-
class Challenge < ::BasicObject
|
8
|
-
# Initialize the challenge class.
|
9
|
-
#
|
10
|
-
# @param method [#to_sym] The method to send to an object.
|
11
|
-
# @param args [Array] Any arguments of the method.
|
12
|
-
# @param opts [Hash] Any keyword arguments of the method.
|
13
|
-
# @param block [Proc] Any block argument of the method.
|
14
|
-
def initialize(method, *args, **opts, &block)
|
15
|
-
@method = method.to_sym
|
16
|
-
@args = args
|
17
|
-
@opts = opts
|
18
|
-
@block = block
|
19
|
-
end
|
20
|
-
|
21
|
-
# @param object [#object_id] The object to challenge.
|
22
|
-
#
|
23
|
-
# @return [Defi::Value] The actual value, to raise or to return.
|
24
|
-
def to(object)
|
25
|
-
Value.new { object.public_send(@method, *@args, **@opts, &@block) }
|
26
|
-
end
|
27
|
-
|
28
|
-
# @param object [#object_id] The object to challenge in code isolation.
|
29
|
-
#
|
30
|
-
# @return [Defi::Value] The actual value, to raise or to return.
|
31
|
-
#
|
32
|
-
# @see to
|
33
|
-
def to!(object)
|
34
|
-
::Aw.fork! { to(object) }
|
35
|
-
end
|
36
|
-
|
37
|
-
# Properties of the challenge.
|
38
|
-
#
|
39
|
-
# @return [Hash] The properties of the challenge.
|
40
|
-
def to_h
|
41
|
-
{
|
42
|
-
method: @method,
|
43
|
-
args: @args,
|
44
|
-
opts: @opts,
|
45
|
-
block: @block
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
# rubocop:disable Metrics/AbcSize
|
50
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
51
|
-
# rubocop:disable Metrics/MethodLength
|
52
|
-
|
53
|
-
# String of the challenge.
|
54
|
-
#
|
55
|
-
# @return [String] The string representation of the challenge.
|
56
|
-
def to_s
|
57
|
-
string = ".#{@method}"
|
58
|
-
|
59
|
-
return string if @args.empty? && @opts.empty? && @block.nil?
|
60
|
-
|
61
|
-
stringified_args = @args.inspect[1..-2]
|
62
|
-
stringified_opts = @opts.inspect[1..-2]
|
63
|
-
stringified_block = "<Proc>" unless @block.nil?
|
64
|
-
|
65
|
-
string += "("
|
66
|
-
|
67
|
-
stringified_items = []
|
68
|
-
|
69
|
-
stringified_items << stringified_args unless @args.empty?
|
70
|
-
stringified_items << stringified_opts unless @opts.empty?
|
71
|
-
stringified_items << stringified_block unless @block.nil?
|
72
|
-
|
73
|
-
"#{string}#{stringified_items.join(", ")})"
|
74
|
-
end
|
75
|
-
|
76
|
-
# rubocop:enable Metrics/AbcSize
|
77
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
78
|
-
# rubocop:enable Metrics/MethodLength
|
79
|
-
|
80
|
-
# A string containing a human-readable representation of the challenge.
|
81
|
-
#
|
82
|
-
# @return [String] The human-readable representation of the challenge.
|
83
|
-
def inspect
|
84
|
-
inspected_method = @method.inspect
|
85
|
-
inspected_args = @args.inspect
|
86
|
-
inspected_opts = @opts.inspect
|
87
|
-
inspected_block = @block.nil? ? "nil" : "<Proc>"
|
88
|
-
|
89
|
-
"Defi(" \
|
90
|
-
"method: #{inspected_method}, " \
|
91
|
-
"args: #{inspected_args}, " \
|
92
|
-
"opts: #{inspected_opts}, " \
|
93
|
-
"block: #{inspected_block}" \
|
94
|
-
")"
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
require_relative "value"
|