casting 1.0.2 → 1.0.3
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 +4 -5
- data/Rakefile +7 -0
- data/lib/casting/context.rb +2 -1
- data/lib/casting/missing_method_client.rb +2 -2
- data/lib/casting/super_delegate.rb +31 -6
- data/lib/casting/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e9ce2a6479f584071216d9aa62c7f076525325295cbd4df491dd6cbf4ffad39
|
4
|
+
data.tar.gz: 3c1475f0c68d62ac2ba37c542b5c7d0a8c6fddad91a88a7097c03dcdaa02f5d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4942f847d1219c074e2794e8079a22c37bccfb0f011502944835c2b4b1aa1413f957fba526545fc66ea3d53f35e0cad5de206ec2560be51e2b4123624161f42f
|
7
|
+
data.tar.gz: c8b62a94bade49af44f49c49fdf1bca3075dfc68a7b65d57f31f4e6cd201fa32915ad1e5f7c6491806119000e3d350233331fcf5bfca94e8567c1c46b319f388
|
data/README.md
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# Casting
|
2
2
|
|
3
|
-
[](https://codeclimate.com/github/saturnflyer/casting)
|
4
|
-
[](https://codeclimate.com/github/saturnflyer/casting/coverage)
|
5
3
|
[](http://badge.fury.io/rb/casting)
|
6
4
|
|
7
5
|
## Add behavior to your objects without using extend
|
6
|
+
|
8
7
|
Do it for the life of the object or only for the life of a block of code.
|
9
8
|
|
10
9
|
Casting gives you real delegation that flattens your object structure compared to libraries
|
@@ -53,7 +52,7 @@ end
|
|
53
52
|
actor = Actor.new
|
54
53
|
```
|
55
54
|
|
56
|
-
Your objects will have a few additional methods: `delegation`, `cast`, and if you do not
|
55
|
+
Your objects will have a few additional methods: `delegation`, `cast`, and if you do not _already_ have it defined (from another library, for example): `delegate`. The `delegate` method is aliased to `cast`.
|
57
56
|
|
58
57
|
Then you may delegate a method to an attendant object:
|
59
58
|
|
@@ -327,11 +326,11 @@ module Special
|
|
327
326
|
def self.cast_object(obj)
|
328
327
|
obj.instance_variable_set(:@special_value, 'this is special!')
|
329
328
|
end
|
330
|
-
|
329
|
+
|
331
330
|
def self.uncast_object(obj)
|
332
331
|
obj.remove_instance_variable(:@special_value)
|
333
332
|
end
|
334
|
-
|
333
|
+
|
335
334
|
def special_behavior
|
336
335
|
"#{self.name} thinks... #{@special_value}"
|
337
336
|
end
|
data/Rakefile
CHANGED
data/lib/casting/context.rb
CHANGED
@@ -98,7 +98,8 @@ module Casting
|
|
98
98
|
# Get the behavior module for the named role.
|
99
99
|
# This role constant for special_person is SpecialPerson.
|
100
100
|
def role_for(name)
|
101
|
-
|
101
|
+
# Convert snake_case to CamelCase
|
102
|
+
role_name = name.to_s.split('_').map(&:capitalize).join
|
102
103
|
self.class.const_get(role_name)
|
103
104
|
rescue NameError
|
104
105
|
Module.new
|
@@ -53,7 +53,7 @@ module Casting
|
|
53
53
|
|
54
54
|
def method_missing(meth, ...)
|
55
55
|
attendant = method_delegate(meth)
|
56
|
-
if
|
56
|
+
if attendant
|
57
57
|
cast(meth, attendant, ...)
|
58
58
|
else
|
59
59
|
super
|
@@ -61,7 +61,7 @@ module Casting
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def respond_to_missing?(meth, *)
|
64
|
-
|
64
|
+
method_delegate(meth) ? true : super
|
65
65
|
end
|
66
66
|
|
67
67
|
def method_delegate(meth)
|
@@ -1,5 +1,13 @@
|
|
1
1
|
module Casting
|
2
2
|
module SuperDelegate
|
3
|
+
# Cache regex matchers at module level for better performance
|
4
|
+
@casting_library_matcher = nil
|
5
|
+
@gem_home_matcher = nil
|
6
|
+
@debugging_matcher = /internal:trace_point/
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :casting_library_matcher, :gem_home_matcher, :debugging_matcher
|
10
|
+
end
|
3
11
|
# Call the method of the same name defined in the next delegate stored in your object
|
4
12
|
#
|
5
13
|
# Because Casting creates an alternative method lookup path using a collection of delegates,
|
@@ -28,13 +36,15 @@ module Casting
|
|
28
36
|
# some_object.greet #=> 'Hello, how do you do?'
|
29
37
|
#
|
30
38
|
def super_delegate(mod = :none, *args, **kwargs, &block)
|
31
|
-
method_name =
|
39
|
+
method_name, method_owner = name_and_owner_of_calling_method(caller_locations)
|
32
40
|
owner = (mod unless mod == :none) || method_delegate(method_name)
|
33
41
|
|
34
42
|
super_delegate_method = unbound_method_from_next_delegate(method_name, owner)
|
35
43
|
super_delegate_method.bind_call(self, *args, **kwargs, &block)
|
36
44
|
rescue NameError
|
37
|
-
|
45
|
+
# Use the method_owner from the call stack for consistent error messages
|
46
|
+
owner_name = method_owner || owner
|
47
|
+
raise NoMethodError.new("super_delegate: no delegate method `#{owner_name}##{method_name}' for #{inspect} from ")
|
38
48
|
end
|
39
49
|
|
40
50
|
def unbound_method_from_next_delegate(method_name, *skipped)
|
@@ -55,19 +65,34 @@ module Casting
|
|
55
65
|
end
|
56
66
|
|
57
67
|
def name_of_calling_method(call_stack)
|
58
|
-
|
68
|
+
method_name, _owner = name_and_owner_of_calling_method(call_stack)
|
69
|
+
method_name
|
70
|
+
end
|
71
|
+
|
72
|
+
def name_and_owner_of_calling_method(call_stack)
|
73
|
+
label = calling_location(call_stack).label
|
74
|
+
# Ruby 3.4.7+ includes module name in label (e.g., "ModuleName#method_name")
|
75
|
+
# Ruby 3.3 and earlier just has method name
|
76
|
+
parts = label.split("#")
|
77
|
+
if parts.length > 1
|
78
|
+
# Ruby 3.4.7+: has owner prefix
|
79
|
+
[parts.last.to_sym, parts.first]
|
80
|
+
else
|
81
|
+
# Ruby 3.3 and earlier: no owner prefix
|
82
|
+
[parts.first.to_sym, nil]
|
83
|
+
end
|
59
84
|
end
|
60
85
|
|
61
86
|
def casting_library_matcher
|
62
|
-
Regexp.new(Dir.pwd.to_s + "/lib")
|
87
|
+
SuperDelegate.casting_library_matcher ||= Regexp.new(Dir.pwd.to_s + "/lib")
|
63
88
|
end
|
64
89
|
|
65
90
|
def gem_home_matcher
|
66
|
-
Regexp.new(ENV["GEM_HOME"])
|
91
|
+
SuperDelegate.gem_home_matcher ||= Regexp.new(ENV["GEM_HOME"])
|
67
92
|
end
|
68
93
|
|
69
94
|
def debugging_matcher
|
70
|
-
|
95
|
+
SuperDelegate.debugging_matcher
|
71
96
|
end
|
72
97
|
end
|
73
98
|
end
|
data/lib/casting/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: casting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Gay
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
12
|
description: |-
|
14
13
|
Casting assists in method delegation which preserves the binding of 'self' to the object receiving a message.
|
@@ -38,7 +37,6 @@ homepage: http://github.com/saturnflyer/casting
|
|
38
37
|
licenses:
|
39
38
|
- MIT
|
40
39
|
metadata: {}
|
41
|
-
post_install_message:
|
42
40
|
rdoc_options: []
|
43
41
|
require_paths:
|
44
42
|
- lib
|
@@ -53,8 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
51
|
- !ruby/object:Gem::Version
|
54
52
|
version: '0'
|
55
53
|
requirements: []
|
56
|
-
rubygems_version: 3.2
|
57
|
-
signing_key:
|
54
|
+
rubygems_version: 3.7.2
|
58
55
|
specification_version: 4
|
59
56
|
summary: Proper method delegation.
|
60
57
|
test_files: []
|