openhab-scripting 2.14.1 → 2.14.2
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/lib/openhab.rb +3 -0
- data/lib/openhab/core/dsl/actions.rb +1 -1
- data/lib/openhab/core/dsl/entities.rb +41 -4
- data/lib/openhab/core/dsl/gems.rb +1 -1
- data/lib/openhab/core/dsl/group.rb +3 -1
- data/lib/openhab/core/dsl/items/items.rb +3 -1
- data/lib/openhab/core/dsl/items/number_item.rb +151 -50
- data/lib/openhab/core/dsl/items/string_item.rb +21 -3
- data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +66 -42
- data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +2 -1
- data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +2 -1
- data/lib/openhab/core/dsl/property.rb +15 -4
- data/lib/openhab/core/dsl/rule/automation_rule.rb +348 -0
- data/lib/openhab/core/dsl/rule/guard.rb +43 -6
- data/lib/openhab/core/dsl/rule/rule.rb +80 -367
- data/lib/openhab/core/dsl/rule/rule_config.rb +153 -0
- data/lib/openhab/core/dsl/rule/triggers/changed.rb +145 -0
- data/lib/openhab/core/dsl/rule/{channel.rb → triggers/channel.rb} +22 -8
- data/lib/openhab/core/dsl/rule/triggers/command.rb +106 -0
- data/lib/openhab/core/dsl/rule/{cron.rb → triggers/cron.rb} +36 -14
- data/lib/openhab/core/dsl/rule/triggers/trigger.rb +126 -0
- data/lib/openhab/core/dsl/rule/triggers/updated.rb +100 -0
- data/lib/openhab/core/dsl/time_of_day.rb +50 -24
- data/lib/openhab/core/dsl/timers.rb +2 -6
- data/lib/openhab/core/dsl/types/quantity.rb +106 -69
- data/lib/openhab/core/log.rb +3 -8
- data/lib/openhab/core/startup_delay.rb +1 -0
- data/lib/openhab/osgi.rb +7 -0
- data/lib/openhab/version.rb +1 -1
- metadata +10 -6
- data/lib/openhab/core/dsl/rule/item.rb +0 -203
- data/lib/openhab/core/dsl/rule/triggers.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf896ff53247e4170a9d3c09ebd3b337114bcc8509963001f4ccea9a4c81d52f
|
4
|
+
data.tar.gz: 974c4e5175053de2818fa725de5376458f21a01bc45fb444ac4a6b82e84685bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3d966995bcf7d4d6ae5ff5a6567af8e47e57355d7ac438b46b236755205a6dbc955520f28734901f8e49b8d415b6a0497f82f1a89a698cc90d61363621d9396
|
7
|
+
data.tar.gz: 0a76fe6c623432d7203ddbac268690be10ff7c9bcdcd1a2b56ace1cda3ead34f036ee70cd7f66c695c284faba921f37b3e5bbf6a091b616b31a2ca94e1c4cb89
|
data/lib/openhab.rb
CHANGED
@@ -46,7 +46,7 @@ module OpenHAB
|
|
46
46
|
# rubocop: disable Style/GlobalVars
|
47
47
|
action_keys = $actions.action_keys
|
48
48
|
# rubocop: enable Style/GlobalVars
|
49
|
-
logger.trace(
|
49
|
+
logger.trace("Registered actions: '#{action_keys}' for thing '#{thing_uid}'")
|
50
50
|
action_keys.map { |action_key| action_key.split('-', 2) }
|
51
51
|
.select { |action_pair| action_pair.last == thing_uid }
|
52
52
|
.map(&:first)
|
@@ -4,6 +4,7 @@ require 'pp'
|
|
4
4
|
require 'java'
|
5
5
|
require 'set'
|
6
6
|
require 'core/dsl/group'
|
7
|
+
require 'core/log'
|
7
8
|
require 'core/dsl/items/number_item'
|
8
9
|
require 'core/dsl/items/string_item'
|
9
10
|
|
@@ -25,6 +26,7 @@ end
|
|
25
26
|
# Manages access to OpenHAB entities
|
26
27
|
#
|
27
28
|
module EntityLookup
|
29
|
+
include Logging
|
28
30
|
#
|
29
31
|
# Decorate items with Ruby wrappers
|
30
32
|
#
|
@@ -32,14 +34,13 @@ module EntityLookup
|
|
32
34
|
#
|
33
35
|
# @return [Array] Array of decorated items
|
34
36
|
#
|
37
|
+
# rubocop: disable Metrics/MethodLength
|
38
|
+
# Disabled line length - case dispatch pattern
|
35
39
|
def self.decorate_items(*items)
|
36
40
|
items.flatten.map do |item|
|
37
41
|
case item
|
38
42
|
when GroupItem
|
39
|
-
|
40
|
-
item = OpenHAB::Core::DSL::Groups::Group.new(Set.new(EntityLookup.decorate_items(item.all_members.to_a)))
|
41
|
-
item.group = group
|
42
|
-
item
|
43
|
+
decorate_group(item)
|
43
44
|
when Java::Org.openhab.core.library.items::NumberItem
|
44
45
|
OpenHAB::Core::DSL::Items::NumberItem.new(item)
|
45
46
|
when Java::Org.openhab.core.library.items::StringItem
|
@@ -49,6 +50,7 @@ module EntityLookup
|
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
53
|
+
# rubocop: enable Metrics/MethodLength
|
52
54
|
|
53
55
|
#
|
54
56
|
# Loops up a Thing in the OpenHAB registry replacing '_' with ':'
|
@@ -58,6 +60,7 @@ module EntityLookup
|
|
58
60
|
# @return [Thing] if found, nil otherwise
|
59
61
|
#
|
60
62
|
def self.lookup_thing(name)
|
63
|
+
logger.trace("Looking up thing(#{name})")
|
61
64
|
# Convert from : syntax to underscore
|
62
65
|
name = name.to_s if name.is_a? Symbol
|
63
66
|
|
@@ -78,6 +81,7 @@ module EntityLookup
|
|
78
81
|
# @return [Item] OpenHAB item if registry contains a matching item, nil othewise
|
79
82
|
#
|
80
83
|
def self.lookup_item(name)
|
84
|
+
logger.trace("Looking up item(#{name})")
|
81
85
|
name = name.to_s if name.is_a? Symbol
|
82
86
|
# rubocop: disable Style/GlobalVars
|
83
87
|
item = $ir.get(name)
|
@@ -98,6 +102,39 @@ module EntityLookup
|
|
98
102
|
return if method.to_s == 'scriptLoaded'
|
99
103
|
return if method.to_s == 'scriptUnloaded'
|
100
104
|
|
105
|
+
logger.trace("method missing, performing OpenHab Lookup for: #{method}")
|
101
106
|
EntityLookup.lookup_item(method) || EntityLookup.lookup_thing(method) || super
|
102
107
|
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Checks if this method responds to the missing method
|
111
|
+
#
|
112
|
+
# @param [String] method_name Name of the method to check
|
113
|
+
# @param [Boolean] _include_private boolean if private methods should be checked
|
114
|
+
#
|
115
|
+
# @return [Boolean] true if this object will respond to the supplied method, false otherwise
|
116
|
+
#
|
117
|
+
def respond_to_missing?(method_name, _include_private = false)
|
118
|
+
logger.trace("Checking if OpenHAB entites exist for #{method_name}")
|
119
|
+
method_name = method_name.to_s if method_name.is_a? Symbol
|
120
|
+
|
121
|
+
method_name == 'scriptLoaded' ||
|
122
|
+
method_name == 'scriptUnloaded' ||
|
123
|
+
EntityLookup.lookup_item(method_name) ||
|
124
|
+
EntityLookup.lookup_thing(method_name) ||
|
125
|
+
super
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Decorate a group from an item base
|
130
|
+
#
|
131
|
+
# @param [OpenHAB item] item item to convert to a group item
|
132
|
+
#
|
133
|
+
# @return [OpenHAB::Core::DSL::Groups::Group] Group created from supplied item
|
134
|
+
#
|
135
|
+
def self.decorate_group(item)
|
136
|
+
group = OpenHAB::Core::DSL::Groups::Group.new(Set.new(EntityLookup.decorate_items(item.all_members.to_a)))
|
137
|
+
group.group = item
|
138
|
+
group
|
139
|
+
end
|
103
140
|
end
|
@@ -28,7 +28,7 @@ module OpenHAB
|
|
28
28
|
#
|
29
29
|
def[](name)
|
30
30
|
group = EntityLookup.lookup_item(name)
|
31
|
-
|
31
|
+
group.is_a?(Group) ? group : nil
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -38,7 +38,9 @@ module OpenHAB
|
|
38
38
|
# @return [Set] of OpenHAB Groups
|
39
39
|
#
|
40
40
|
def groups
|
41
|
+
# rubocop: disable Style/GlobalVars
|
41
42
|
Groups.new(EntityLookup.decorate_items($ir.items.select { |item| item.is_a? GroupItem }))
|
43
|
+
# rubocop: enable Style/GlobalVars
|
42
44
|
end
|
43
45
|
|
44
46
|
# Group class that provides access to OpenHAB group object and delegates other methods to
|
@@ -21,7 +21,7 @@ module OpenHAB
|
|
21
21
|
# rubocop: disable Style/GlobalVars
|
22
22
|
item = $ir.getItem(name)
|
23
23
|
# rubocop: enable Style/GlobalVars
|
24
|
-
|
24
|
+
item.is_a?(GroupItem) ? nil : item
|
25
25
|
rescue Java::OrgOpenhabCoreItems::ItemNotFoundException
|
26
26
|
nil
|
27
27
|
end
|
@@ -30,7 +30,9 @@ module OpenHAB
|
|
30
30
|
# @param name [String] Item name to check
|
31
31
|
# @return [Boolean] true if the item exists, false otherwise
|
32
32
|
def include?(name)
|
33
|
+
# rubocop: disable Style/GlobalVars
|
33
34
|
!$ir.getItems(name).empty?
|
35
|
+
# rubocop: enable Style/GlobalVars
|
34
36
|
end
|
35
37
|
alias key? include?
|
36
38
|
end
|
@@ -12,6 +12,9 @@ module OpenHAB
|
|
12
12
|
#
|
13
13
|
# Delegation to OpenHAB Number Item
|
14
14
|
#
|
15
|
+
# rubocop: disable Metrics/ClassLength
|
16
|
+
# Disabled because this class has a single responsibility, there does not appear a logical
|
17
|
+
# way of breaking it up into multiple classes
|
15
18
|
class NumberItem < Numeric
|
16
19
|
extend Forwardable
|
17
20
|
|
@@ -46,21 +49,14 @@ module OpenHAB
|
|
46
49
|
#
|
47
50
|
# @param [Object] other object to coerce to a NumberItem if possible
|
48
51
|
#
|
49
|
-
# @return [Object] NumberItem, QuantityTypes, BigDecimal or nil depending on NumberItem configuration
|
52
|
+
# @return [Object] NumberItem, QuantityTypes, BigDecimal or nil depending on NumberItem configuration
|
53
|
+
# and/or supplied object
|
50
54
|
#
|
51
55
|
def coerce(other)
|
52
56
|
logger.trace("Coercing #{self} as a request from #{other.class}")
|
53
57
|
case other
|
54
|
-
when Quantity
|
55
|
-
|
56
|
-
logger.trace("Converted #{self} to a Quantity #{as_qt}")
|
57
|
-
[other, as_qt]
|
58
|
-
when Numeric
|
59
|
-
if dimension
|
60
|
-
[Quantity.new(other), to_qt]
|
61
|
-
elsif @number_item.state?
|
62
|
-
[other.to_d, @number_item.state.to_big_decimal.to_d]
|
63
|
-
end
|
58
|
+
when Quantity then coerce_from_quantity(other)
|
59
|
+
when Numeric then coerce_from_numeric(other)
|
64
60
|
else
|
65
61
|
logger.trace("#{self} cannot be coereced to #{other.class}")
|
66
62
|
nil
|
@@ -72,22 +68,15 @@ module OpenHAB
|
|
72
68
|
#
|
73
69
|
# @param [Object] other object to compare to
|
74
70
|
#
|
75
|
-
# @return [Integer] -1,0,1 or nil depending on value supplied,
|
71
|
+
# @return [Integer] -1,0,1 or nil depending on value supplied,
|
72
|
+
# nil comparison to supplied object is not possible.
|
76
73
|
#
|
77
74
|
def <=>(other)
|
78
75
|
logger.trace("Comparing #{self} to #{other}")
|
79
76
|
case other
|
80
|
-
when NumberItem
|
81
|
-
|
82
|
-
|
83
|
-
to_qt <=> other.to_qt
|
84
|
-
else
|
85
|
-
@number_item.state <=> other.state
|
86
|
-
end
|
87
|
-
when Numeric
|
88
|
-
@number_item.state.to_big_decimal.to_d <=> other.to_d
|
89
|
-
when String
|
90
|
-
@number_item.state <=> QuantityType.new(other) if dimension
|
77
|
+
when NumberItem then number_item_compare(other)
|
78
|
+
when Numeric then @number_item.state.to_big_decimal.to_d <=> other.to_d
|
79
|
+
when String then @number_item.state <=> QuantityType.new(other) if dimension
|
91
80
|
end
|
92
81
|
end
|
93
82
|
|
@@ -167,6 +156,7 @@ module OpenHAB
|
|
167
156
|
# @return [Object] Value from delegated method in OpenHAB NumberItem
|
168
157
|
#
|
169
158
|
def method_missing(meth, *args, &block)
|
159
|
+
logger.trace("Method missing, performing dynamic lookup for: #{meth}")
|
170
160
|
if @number_item.respond_to?(meth)
|
171
161
|
@number_item.__send__(meth, *args, &block)
|
172
162
|
elsif ::Kernel.method_defined?(meth) || ::Kernel.private_method_defined?(meth)
|
@@ -176,42 +166,153 @@ module OpenHAB
|
|
176
166
|
end
|
177
167
|
end
|
178
168
|
|
169
|
+
#
|
170
|
+
# Checks if this method responds to the missing method
|
171
|
+
#
|
172
|
+
# @param [String] method_name Name of the method to check
|
173
|
+
# @param [Boolean] _include_private boolean if private methods should be checked
|
174
|
+
#
|
175
|
+
# @return [Boolean] true if this object will respond to the supplied method, false otherwise
|
176
|
+
#
|
177
|
+
def respond_to_missing?(method_name, _include_private = false)
|
178
|
+
@number_item.respond_to?(method_name) ||
|
179
|
+
::Kernel.method_defined?(method_name) ||
|
180
|
+
::Kernel.private_method_defined?(method_name)
|
181
|
+
end
|
182
|
+
|
179
183
|
%w[+ - * /].each do |operation|
|
180
184
|
define_method(operation) do |other|
|
181
185
|
logger.trace("Execution math operation '#{operation}' on #{inspect} with #{other.inspect}")
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
186
|
+
left_operand, right_operand = operands_for_operation(other)
|
187
|
+
left_operand.public_send(operation, right_operand)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
private
|
192
|
+
|
193
|
+
#
|
194
|
+
# Get the operands for any operation
|
195
|
+
#
|
196
|
+
# @param [Object] other object to convert to a compatible operand
|
197
|
+
#
|
198
|
+
# @return [Array[Object,Object]] of operands where the first value is the left operand
|
199
|
+
# and the second value is the right operand
|
200
|
+
#
|
201
|
+
def operands_for_operation(other)
|
202
|
+
case other
|
203
|
+
when NumberItem then number_item_operands(other)
|
204
|
+
when Numeric then [to_d, other.to_d]
|
205
|
+
when String then string_operands(other)
|
206
|
+
else
|
207
|
+
return other.coerce(to_d) if other.respond_to? :coerce
|
208
|
+
|
209
|
+
raise ArgumentError, "#{other.class} can't be coerced into a NumberItem"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
#
|
214
|
+
# Get operands for an operation when the right operand is provided as a string
|
215
|
+
#
|
216
|
+
# @param [String] other right operand
|
217
|
+
#
|
218
|
+
# @return [Array[QuantityType,QuantiyType]] of operands where the first value is the left operand
|
219
|
+
# and the second value is the right operand
|
220
|
+
#
|
221
|
+
def string_operands(other)
|
222
|
+
return [to_qt, Quantity.new(other)] if dimension
|
223
|
+
|
224
|
+
raise ArgumentError, 'Strings are only valid operands if NumberItem is dimensions=ed.'
|
225
|
+
end
|
226
|
+
|
227
|
+
#
|
228
|
+
# Get operands for an operation when the right operand is provided is another number item
|
229
|
+
#
|
230
|
+
# @param [NumberItem] other right operand
|
231
|
+
#
|
232
|
+
# @return [Array<QuantityType,QuantityType>,Array<BigDecimal,BigDecimal>] of operands depending on
|
233
|
+
# if the left or right operand has a dimensions
|
234
|
+
#
|
235
|
+
def number_item_operands(other)
|
236
|
+
if dimension || other.dimension
|
237
|
+
dimensioned_operands(other)
|
238
|
+
else
|
239
|
+
logger.trace("Both objects lack dimension, self='#{self}' other='#{other}'")
|
240
|
+
# If nothing has a dimension, just use BigDecimals
|
241
|
+
[to_d, other.to_d]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
#
|
246
|
+
# Get operands for an operation when the left or right operand has a dimension
|
247
|
+
#
|
248
|
+
# @param [NumberItem] other right operand
|
249
|
+
#
|
250
|
+
# @return [Array<QuantityType,QuantityType>] of operands
|
251
|
+
#
|
252
|
+
def dimensioned_operands(other)
|
253
|
+
logger.trace("Dimensions self='#{dimension}' other='#{other.dimension}'")
|
254
|
+
if dimension
|
255
|
+
if other.dimension
|
256
|
+
# If both numbers have dimensions, do the math on the quantity types.
|
257
|
+
[to_qt, other.to_qt]
|
208
258
|
else
|
209
|
-
|
259
|
+
# If this number has dimension and the other does not,
|
260
|
+
# do math with this quantity type and the other as a big decimal
|
261
|
+
[to_qt, other]
|
210
262
|
end
|
263
|
+
else
|
264
|
+
# If this number has no dimension and the other does, convert this into a dimensionless quantity
|
265
|
+
[to_qt, other]
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
#
|
270
|
+
# Compare two number items, taking into account any dimensions
|
271
|
+
#
|
272
|
+
# @param [NumberItem] other number item
|
273
|
+
#
|
274
|
+
# @return [-1,0,1] depending on if other object is less than, equal to or greater than self
|
275
|
+
#
|
276
|
+
def number_item_compare(other)
|
277
|
+
if other.dimension
|
278
|
+
logger.trace('Other is dimensioned, converting self and other to QuantityTypes to compare')
|
279
|
+
to_qt <=> other.to_qt
|
280
|
+
else
|
281
|
+
@number_item.state <=> other.state
|
211
282
|
end
|
212
283
|
end
|
284
|
+
|
285
|
+
#
|
286
|
+
# Coerce from a numberic object depnding on dimension and state
|
287
|
+
#
|
288
|
+
# @param [Numeric] other numeric object to convert
|
289
|
+
#
|
290
|
+
# @return [Array<QuantityType,QuantityType>,Array<BigDecimal,BigDecimal>,nil] depending on
|
291
|
+
# if this object has a dimension or state
|
292
|
+
#
|
293
|
+
def coerce_from_numeric(other)
|
294
|
+
if dimension
|
295
|
+
[Quantity.new(other), to_qt]
|
296
|
+
elsif @number_item.state?
|
297
|
+
[other.to_d, @number_item.state.to_big_decimal.to_d]
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
#
|
302
|
+
# Coerce when other is a quantity
|
303
|
+
#
|
304
|
+
# @param [QuantityType] other
|
305
|
+
#
|
306
|
+
# @return [Array<QuanityType,QuantityType] other and self as a quantity type
|
307
|
+
#
|
308
|
+
def coerce_from_quantity(other)
|
309
|
+
as_qt = to_qt
|
310
|
+
logger.trace("Converted #{self} to a Quantity #{as_qt}")
|
311
|
+
[other, as_qt]
|
312
|
+
end
|
213
313
|
end
|
214
314
|
end
|
215
315
|
end
|
216
316
|
end
|
217
317
|
end
|
318
|
+
# rubocop: enable Metrics/ClassLength
|
@@ -15,6 +15,7 @@ module OpenHAB
|
|
15
15
|
extend Forwardable
|
16
16
|
include Comparable
|
17
17
|
|
18
|
+
# @return [Regex] Regular expression matching blank strings
|
18
19
|
BLANK_RE = /\A[[:space:]]*\z/.freeze
|
19
20
|
private_constant :BLANK_RE
|
20
21
|
|
@@ -33,7 +34,8 @@ module OpenHAB
|
|
33
34
|
#
|
34
35
|
# Convert the StringItem into a String
|
35
36
|
#
|
36
|
-
# @return [String] String representation of the StringItem or
|
37
|
+
# @return [String] String representation of the StringItem or
|
38
|
+
# nil if underlying OpenHAB StringItem does not have a state
|
37
39
|
#
|
38
40
|
def to_str
|
39
41
|
@string_item.state&.to_full_string&.to_s
|
@@ -64,7 +66,8 @@ module OpenHAB
|
|
64
66
|
#
|
65
67
|
# @param [Object] other object to compare to
|
66
68
|
#
|
67
|
-
# @return [Integer] -1,0,1 or nil depending on value supplied,
|
69
|
+
# @return [Integer] -1,0,1 or nil depending on value supplied,
|
70
|
+
# nil comparison to supplied object is not possible.
|
68
71
|
#
|
69
72
|
def <=>(other)
|
70
73
|
case other
|
@@ -87,7 +90,7 @@ module OpenHAB
|
|
87
90
|
def method_missing(meth, *args, &block)
|
88
91
|
if @string_item.respond_to?(meth)
|
89
92
|
@string_item.__send__(meth, *args, &block)
|
90
|
-
elsif @string_item.state
|
93
|
+
elsif @string_item.state&.to_full_string&.to_s.respond_to?(meth)
|
91
94
|
@string_item.state.to_full_string.to_s.__send__(meth, *args, &block)
|
92
95
|
elsif ::Kernel.method_defined?(meth) || ::Kernel.private_method_defined?(meth)
|
93
96
|
::Kernel.instance_method(meth).bind_call(self, *args, &block)
|
@@ -95,6 +98,21 @@ module OpenHAB
|
|
95
98
|
super(meth, *args, &block)
|
96
99
|
end
|
97
100
|
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Checks if this method responds to the missing method
|
104
|
+
#
|
105
|
+
# @param [String] method_name Name of the method to check
|
106
|
+
# @param [Boolean] _include_private boolean if private methods should be checked
|
107
|
+
#
|
108
|
+
# @return [Boolean] true if this object will respond to the supplied method, false otherwise
|
109
|
+
#
|
110
|
+
def respond_to_missing?(method_name, _include_private = false)
|
111
|
+
@string_item.respond_to?(method_name) ||
|
112
|
+
@string_item.state&.to_full_string&.to_s.respond_to?(method_name) ||
|
113
|
+
::Kernel.method_defined?(method_name) ||
|
114
|
+
::Kernel.private_method_defined?(method_name)
|
115
|
+
end
|
98
116
|
end
|
99
117
|
end
|
100
118
|
end
|