openhab-jrubyscripting 5.0.0.rc1 → 5.0.0.rc3
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/core/entity_lookup.rb +1 -12
- data/lib/openhab/core/items/generic_item.rb +15 -7
- data/lib/openhab/core/items/metadata/hash.rb +81 -39
- data/lib/openhab/core/items/metadata/namespace_hash.rb +17 -19
- data/lib/openhab/core/items/metadata/provider.rb +48 -0
- data/lib/openhab/core/items/persistence.rb +2 -0
- data/lib/openhab/core/items/provider.rb +40 -0
- data/lib/openhab/core/items/proxy.rb +10 -0
- data/lib/openhab/core/items/registry.rb +16 -7
- data/lib/openhab/core/items/semantics/enumerable.rb +6 -4
- data/lib/openhab/core/items/state_storage.rb +3 -3
- data/lib/openhab/core/profile_factory.rb +3 -1
- data/lib/openhab/core/provider.rb +223 -0
- data/lib/openhab/core/registry.rb +30 -0
- data/lib/openhab/core/rules/provider.rb +25 -0
- data/lib/openhab/core/rules/registry.rb +76 -0
- data/lib/openhab/core/rules/rule.rb +150 -0
- data/lib/openhab/core/rules.rb +25 -0
- data/lib/openhab/core/script_handling.rb +50 -0
- data/lib/openhab/core/things/links/provider.rb +40 -0
- data/lib/openhab/core/things/provider.rb +25 -0
- data/lib/openhab/core/things/proxy.rb +10 -0
- data/lib/openhab/core/things/registry.rb +25 -2
- data/lib/openhab/core/timer.rb +17 -7
- data/lib/openhab/core/types/quantity_type.rb +5 -2
- data/lib/openhab/core/types.rb +1 -1
- data/lib/openhab/core.rb +3 -30
- data/lib/openhab/core_ext/java/class.rb +34 -0
- data/lib/openhab/core_ext/java/list.rb +436 -0
- data/lib/openhab/core_ext/java/local_time.rb +2 -1
- data/lib/openhab/core_ext/java/map.rb +66 -0
- data/lib/openhab/core_ext/java/month.rb +2 -1
- data/lib/openhab/core_ext/java/zoned_date_time.rb +1 -2
- data/lib/openhab/core_ext/ruby/date.rb +2 -0
- data/lib/openhab/core_ext/ruby/date_time.rb +53 -0
- data/lib/openhab/core_ext/ruby/time.rb +88 -86
- data/lib/openhab/dsl/events/watch_event.rb +1 -1
- data/lib/openhab/dsl/items/builder.rb +38 -100
- data/lib/openhab/dsl/items/ensure.rb +6 -2
- data/lib/openhab/dsl/items/timed_command.rb +10 -11
- data/lib/openhab/dsl/rules/automation_rule.rb +36 -13
- data/lib/openhab/dsl/rules/builder.rb +126 -8
- data/lib/openhab/dsl/rules/name_inference.rb +0 -5
- data/lib/openhab/dsl/rules/terse.rb +1 -2
- data/lib/openhab/dsl/rules/triggers/changed.rb +7 -4
- data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +17 -53
- data/lib/openhab/dsl/rules/triggers/conditions/proc.rb +0 -3
- data/lib/openhab/dsl/rules/triggers/cron/cron.rb +1 -1
- data/lib/openhab/dsl/rules/triggers/trigger.rb +1 -1
- data/lib/openhab/dsl/rules/triggers/updated.rb +7 -3
- data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +1 -1
- data/lib/openhab/dsl/rules.rb +0 -21
- data/lib/openhab/dsl/script_handling.rb +0 -49
- data/lib/openhab/dsl/things/builder.rb +8 -31
- data/lib/openhab/dsl/thread_local.rb +3 -2
- data/lib/openhab/dsl/timer_manager.rb +16 -8
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +137 -120
- data/lib/openhab/log.rb +3 -3
- data/lib/openhab/rspec/example_group.rb +42 -0
- data/lib/openhab/rspec/helpers.rb +33 -27
- data/lib/openhab/rspec/hooks.rb +17 -23
- data/lib/openhab/rspec/karaf.rb +45 -27
- data/lib/openhab/rspec/mocks/synchronous_executor.rb +11 -4
- data/lib/openhab/rspec/mocks/timer.rb +7 -1
- data/lib/openhab/rspec/suspend_rules.rb +4 -2
- metadata +30 -3
- data/lib/openhab/rspec/mocks/metadata_provider.rb +0 -75
@@ -24,6 +24,8 @@ module OpenHAB
|
|
24
24
|
end
|
25
25
|
alias_method :include?, :[]
|
26
26
|
alias_method :key?, :[]
|
27
|
+
# @deprecated
|
28
|
+
alias_method :has_key?, :[]
|
27
29
|
|
28
30
|
#
|
29
31
|
# Explicit conversion to array
|
@@ -34,11 +36,32 @@ module OpenHAB
|
|
34
36
|
$things.all.map { |thing| Proxy.new(thing) }
|
35
37
|
end
|
36
38
|
|
39
|
+
#
|
37
40
|
# Enter the Thing Builder DSL.
|
41
|
+
# @param (see Core::Provider.current)
|
38
42
|
# @yield Block executed in the context of a {DSL::Things::Builder}.
|
39
43
|
# @return [Object] The result of the block.
|
40
|
-
|
41
|
-
|
44
|
+
#
|
45
|
+
def build(preferred_provider = nil, &block)
|
46
|
+
DSL::Things::Builder.new(preferred_provider).instance_eval(&block)
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Remove a Thing.
|
51
|
+
#
|
52
|
+
# The thing must be a managed thing (typically created by Ruby or in the UI).
|
53
|
+
#
|
54
|
+
# @param [String, Thing, ThingUID] thing_uid
|
55
|
+
# @return [Thing, nil] The removed item, if found.
|
56
|
+
def remove(thing_uid)
|
57
|
+
thing_uid = thing.uid if thing_uid.is_a?(Thing)
|
58
|
+
thing_uid = ThingUID.new(thing_uid) if thing_uid.is_a?(String)
|
59
|
+
provider = Provider.registry.provider_for(thing_uid)
|
60
|
+
unless provider.is_a?(org.openhab.core.common.registry.ManagedProvider)
|
61
|
+
raise "Cannot remove thing #{thing_uid} from non-managed provider #{provider.inspect}"
|
62
|
+
end
|
63
|
+
|
64
|
+
provider.remove(thing_uid)
|
42
65
|
end
|
43
66
|
end
|
44
67
|
end
|
data/lib/openhab/core/timer.rb
CHANGED
@@ -35,7 +35,6 @@ module OpenHAB
|
|
35
35
|
# @return [Object, nil]
|
36
36
|
attr_accessor :id
|
37
37
|
|
38
|
-
# @!visibility private
|
39
38
|
# @!visibility private
|
40
39
|
attr_reader :block
|
41
40
|
|
@@ -84,6 +83,7 @@ module OpenHAB
|
|
84
83
|
# @return [self]
|
85
84
|
#
|
86
85
|
def reschedule(time = nil)
|
86
|
+
Thread.current[:openhab_rescheduled_timer] = true if Thread.current[:openhab_rescheduled_timer] == self
|
87
87
|
DSL.timers.add(self)
|
88
88
|
@timer.reschedule(new_execution_time(time || @time))
|
89
89
|
self
|
@@ -96,6 +96,18 @@ module OpenHAB
|
|
96
96
|
#
|
97
97
|
def cancel
|
98
98
|
DSL.timers.delete(self)
|
99
|
+
cancel!
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Cancel the timer but do not remove self from the timer manager
|
104
|
+
#
|
105
|
+
# To be used internally by {TimerManager} from inside ConcurrentHashMap's compute blocks
|
106
|
+
#
|
107
|
+
# @return [true,false] True if cancel was successful, false otherwise
|
108
|
+
#
|
109
|
+
# @!visibility private
|
110
|
+
def cancel!
|
99
111
|
@timer.cancel
|
100
112
|
end
|
101
113
|
|
@@ -107,12 +119,10 @@ module OpenHAB
|
|
107
119
|
# @return [void]
|
108
120
|
#
|
109
121
|
def execute
|
110
|
-
|
111
|
-
DSL::ThreadLocal.thread_local(**@thread_locals)
|
112
|
-
|
113
|
-
|
114
|
-
# don't remove ourselves if we were rescheduled in the block
|
115
|
-
DSL.timers.delete(self) if execution_time == last_execution_time
|
122
|
+
Thread.current[:openhab_rescheduled_timer] = self
|
123
|
+
DSL::ThreadLocal.thread_local(**@thread_locals) { @block.call(self) }
|
124
|
+
DSL.timers.delete(self) unless Thread.current[:openhab_rescheduled_timer] == true
|
125
|
+
Thread.current[:openhab_rescheduled_timer] = nil
|
116
126
|
end
|
117
127
|
|
118
128
|
#
|
@@ -15,6 +15,9 @@ module OpenHAB
|
|
15
15
|
# framework in OpenHAB. It is represented as a decimal number with a unit.
|
16
16
|
# You can construct a {QuantityType} object by using the pipe operator with any Numeric.
|
17
17
|
#
|
18
|
+
# @see OpenHAB::DSL.unit unit: Implicit unit conversions
|
19
|
+
# @see OpenHAB::CoreExt::Ruby::QuantityTypeConversion Convert Numeric to QuantityType
|
20
|
+
#
|
18
21
|
# @example QuantityTypes can perform math operations between them.
|
19
22
|
# (50 | "°F") + (-25 | "°F") # => 25.0 °F
|
20
23
|
# (100 | "°F") / (2 | "°F") # => 50
|
@@ -141,7 +144,7 @@ module OpenHAB
|
|
141
144
|
return compare_to(QuantityType.new(other, unit))
|
142
145
|
end
|
143
146
|
|
144
|
-
return nil # don
|
147
|
+
return nil # don't allow comparison with numeric outside a unit block
|
145
148
|
end
|
146
149
|
|
147
150
|
return nil unless other.respond_to?(:coerce)
|
@@ -308,7 +311,7 @@ module OpenHAB
|
|
308
311
|
def multiply_quantity(other)
|
309
312
|
lhs = deunitize
|
310
313
|
rhs = other.deunitize
|
311
|
-
# reverse the arguments if it's multiplication and the LHS isn
|
314
|
+
# reverse the arguments if it's multiplication and the LHS isn't a QuantityType
|
312
315
|
lhs, rhs = rhs, lhs if lhs.is_a?(java.math.BigDecimal)
|
313
316
|
# what a waste... using a QuantityType to multiply two dimensionless quantities
|
314
317
|
# have to make sure lhs is still a QuantityType in order to return a new
|
data/lib/openhab/core/types.rb
CHANGED
@@ -13,7 +13,7 @@ module OpenHAB
|
|
13
13
|
# Types are the specific data types that commands and states are. They can be
|
14
14
|
# sent to items, be the current state of an item, or be the `command`, `state`,
|
15
15
|
# and `was` field of various
|
16
|
-
# {group::OpenHAB::DSL::Rules::
|
16
|
+
# {group::OpenHAB::DSL::Rules::BuilderDSL::Triggers triggers}.
|
17
17
|
# Some types have additional useful methods.
|
18
18
|
#
|
19
19
|
module Types
|
data/lib/openhab/core.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# several classes rely on this, so force it to load earlier
|
4
|
+
require_relative "core/provider"
|
5
|
+
|
3
6
|
Dir[File.expand_path("core/**/*.rb", __dir__)].sort.each do |f|
|
4
7
|
require f
|
5
8
|
end
|
@@ -42,20 +45,6 @@ module OpenHAB
|
|
42
45
|
Pathname.new(org.openhab.core.OpenHAB.config_folder)
|
43
46
|
end
|
44
47
|
|
45
|
-
#
|
46
|
-
# JRuby isn't respecting $RUBYLIB when run embedded inside of OpenHAB, so do it manually
|
47
|
-
#
|
48
|
-
# @return [void]
|
49
|
-
#
|
50
|
-
# @!visibility private
|
51
|
-
def add_rubylib_to_load_path
|
52
|
-
ENV["RUBYLIB"]&.split(File::PATH_SEPARATOR)&.each do |path|
|
53
|
-
next if path.empty?
|
54
|
-
|
55
|
-
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
48
|
#
|
60
49
|
# @!attribute [r] automation_manager
|
61
50
|
# @return [org.openhab.core.automation.module.script.rulesupport.shared.ScriptedAutomationManager]
|
@@ -64,22 +53,6 @@ module OpenHAB
|
|
64
53
|
def automation_manager
|
65
54
|
$scriptExtension.get("automationManager")
|
66
55
|
end
|
67
|
-
|
68
|
-
#
|
69
|
-
# @!attribute [r] rule_registry
|
70
|
-
# @return [org.openhab.core.automation.RuleRegistry] The OpenHAB rule registry
|
71
|
-
#
|
72
|
-
def rule_registry
|
73
|
-
$scriptExtension.get("ruleRegistry")
|
74
|
-
end
|
75
|
-
|
76
|
-
#
|
77
|
-
# @!attribute [r] rule_manager
|
78
|
-
# @return [org.openhab.core.automation.RuleManager] The OpenHAB rule manager/engine
|
79
|
-
#
|
80
|
-
def rule_manager
|
81
|
-
@rule_manager ||= OSGi.service("org.openhab.core.automation.RuleManager")
|
82
|
-
end
|
83
56
|
end
|
84
57
|
end
|
85
58
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module CoreExt
|
5
|
+
module Java
|
6
|
+
Class = java.lang.Class
|
7
|
+
|
8
|
+
# Extensions to Class
|
9
|
+
class Class
|
10
|
+
#
|
11
|
+
# `self`, all superclasses and interfaces, recursively.
|
12
|
+
#
|
13
|
+
# @return [Array<Class>]
|
14
|
+
#
|
15
|
+
def ancestors
|
16
|
+
([self] +
|
17
|
+
Array(superclass&.ancestors) +
|
18
|
+
interfaces.flat_map(&:ancestors)).uniq
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# `self`, all superclasses and interfaces, recursively.
|
23
|
+
#
|
24
|
+
# @return [Array<java.reflect.Type>]
|
25
|
+
#
|
26
|
+
def generic_ancestors
|
27
|
+
ancestors.flat_map do |klass|
|
28
|
+
Array(klass.generic_superclass) + klass.generic_interfaces
|
29
|
+
end.uniq
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,436 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
module Java::JavaUtil::List # rubocop:disable Style/ClassAndModuleChildren
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_delegators :to_a,
|
8
|
+
:&,
|
9
|
+
:*,
|
10
|
+
:|,
|
11
|
+
:bsearch_index,
|
12
|
+
:difference,
|
13
|
+
:flatten,
|
14
|
+
:intersection,
|
15
|
+
:pack,
|
16
|
+
:product,
|
17
|
+
:repeated_combination,
|
18
|
+
:repeated_permutation,
|
19
|
+
:reverse,
|
20
|
+
:rotate,
|
21
|
+
:sample,
|
22
|
+
:shelljoin,
|
23
|
+
:shuffle,
|
24
|
+
:transpose,
|
25
|
+
:union
|
26
|
+
|
27
|
+
def assoc(obj)
|
28
|
+
find { |v| (v.is_a?(Array) || v.is_a?(self.class)) && v[0] == obj }
|
29
|
+
end
|
30
|
+
|
31
|
+
def at(index)
|
32
|
+
self[index]
|
33
|
+
end
|
34
|
+
|
35
|
+
def bsearch(&block)
|
36
|
+
raise NotImplementedError unless block
|
37
|
+
|
38
|
+
r = bsearch_index(&block)
|
39
|
+
self[r] if r
|
40
|
+
end
|
41
|
+
|
42
|
+
def combination(n, &block) # rubocop:disable Naming/MethodParameterName
|
43
|
+
r = to_a.combination(n, &block)
|
44
|
+
block ? self : r
|
45
|
+
end
|
46
|
+
|
47
|
+
def compact
|
48
|
+
reject(&:nil?)
|
49
|
+
end
|
50
|
+
|
51
|
+
def compact!
|
52
|
+
reject!(&:nil?)
|
53
|
+
end
|
54
|
+
|
55
|
+
def concat(*other_arrays)
|
56
|
+
other_arrays.each { |array| add_all(array) }
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def deconstruct
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def delete(obj)
|
65
|
+
last = nil
|
66
|
+
found = false
|
67
|
+
loop do
|
68
|
+
i = index(obj)
|
69
|
+
break if i.nil?
|
70
|
+
|
71
|
+
found = true
|
72
|
+
last = remove(i)
|
73
|
+
end
|
74
|
+
|
75
|
+
return yield(obj) if !found && block_given?
|
76
|
+
|
77
|
+
last
|
78
|
+
end
|
79
|
+
|
80
|
+
def delete_at(index)
|
81
|
+
index = length + index if index.negative?
|
82
|
+
return if index.negative? || index >= length
|
83
|
+
|
84
|
+
remove(index)
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete_if
|
88
|
+
raise NotImplementedError unless block_given?
|
89
|
+
|
90
|
+
it = list_iterator
|
91
|
+
while it.has_next? # rubocop:disable Style/WhileUntilModifier
|
92
|
+
it.remove if yield(it.next)
|
93
|
+
end
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
def dig(index, *identifiers)
|
98
|
+
return self[index] if identifiers.empty?
|
99
|
+
|
100
|
+
self[index]&.dig(*identifiers)
|
101
|
+
end
|
102
|
+
|
103
|
+
def each_index(&block)
|
104
|
+
r = (0...length)
|
105
|
+
return r.each unless block
|
106
|
+
|
107
|
+
r.each(&block)
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
def fetch(index, *default_value)
|
112
|
+
if default_value.length > 1
|
113
|
+
raise ArgumentError,
|
114
|
+
"wrong number of arguments calling `fetch` (given #{default_value.length - 1}, expected 1..2)"
|
115
|
+
end
|
116
|
+
|
117
|
+
original_index = index
|
118
|
+
index = length + index if index.negative?
|
119
|
+
return self[index] if index >= 0 && index < length
|
120
|
+
|
121
|
+
return default_value.first unless default_value.empty?
|
122
|
+
return yield(original_index) if block_given?
|
123
|
+
|
124
|
+
raise IndexError, "index #{index} out of list"
|
125
|
+
end
|
126
|
+
|
127
|
+
def fill(*args)
|
128
|
+
if block_given?
|
129
|
+
unless (0..2).cover?(args.length)
|
130
|
+
raise ArgumentError,
|
131
|
+
"wrong number of arguments calling `fill` (given #{args.length}, expected 1..3)"
|
132
|
+
end
|
133
|
+
else
|
134
|
+
unless (1..3).cover?(args.length)
|
135
|
+
raise ArgumentError,
|
136
|
+
"wrong number of arguments calling `fill` (given #{args.length}, expected 1..2)"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
obj = args.shift unless block_given?
|
141
|
+
|
142
|
+
if args.length == 1 && args.first.is_a?(Range)
|
143
|
+
range = args.first
|
144
|
+
|
145
|
+
range = Range.new(length + range.begin, range.end, range.exclude_end?) if range.begin.negative?
|
146
|
+
range = Range.new(range.begin, length + range.end, range.exclude_end?) if range.end&.negative?
|
147
|
+
return self if range.begin.negative? || (range.end && range.end < range.begin)
|
148
|
+
else
|
149
|
+
first, count = *args
|
150
|
+
return self if count&.negative?
|
151
|
+
|
152
|
+
first ||= 0
|
153
|
+
|
154
|
+
first = length + first if first.negative?
|
155
|
+
range = count ? first...(first + count) : first..
|
156
|
+
end
|
157
|
+
|
158
|
+
add(nil) while length < range.begin && count
|
159
|
+
|
160
|
+
start = range.begin
|
161
|
+
start = 0 if start.negative?
|
162
|
+
start = length if start > length
|
163
|
+
it = list_iterator(start)
|
164
|
+
|
165
|
+
while range.cover?(it.next_index)
|
166
|
+
break if range.end.nil? && !it.has_next?
|
167
|
+
|
168
|
+
obj = yield(it.next_index) if block_given?
|
169
|
+
if it.has_next?
|
170
|
+
it.next
|
171
|
+
it.set(obj)
|
172
|
+
else
|
173
|
+
it.add(obj)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
self
|
178
|
+
end
|
179
|
+
|
180
|
+
def flatten!(*args)
|
181
|
+
if args.length > 1
|
182
|
+
raise ArgumentError,
|
183
|
+
"wrong number of arguments calling `flatten` (given #{args.length}, expect 0..1)"
|
184
|
+
end
|
185
|
+
|
186
|
+
it = list_iterator
|
187
|
+
|
188
|
+
args = [args.first - 1] unless args.empty?
|
189
|
+
done = args.first == 0 # rubocop:disable Style/NumericPredicate
|
190
|
+
|
191
|
+
changed = false
|
192
|
+
while it.has_next?
|
193
|
+
element = it.next
|
194
|
+
next unless element.respond_to?(:to_ary)
|
195
|
+
|
196
|
+
changed = true
|
197
|
+
it.remove
|
198
|
+
arr = element.to_ary
|
199
|
+
arr = arr.flatten(*args) unless done
|
200
|
+
arr.each do |e|
|
201
|
+
it.add(e)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
changed ? self : nil
|
205
|
+
end
|
206
|
+
|
207
|
+
def insert(index, *objects)
|
208
|
+
return self if objects.empty?
|
209
|
+
|
210
|
+
raise IndexError, "index #{index} too small for list, minimum: #{-length}" if index < -length
|
211
|
+
|
212
|
+
index = length + index + 1 if index.negative?
|
213
|
+
|
214
|
+
add(nil) while length < index
|
215
|
+
add_all(index, objects)
|
216
|
+
self
|
217
|
+
end
|
218
|
+
|
219
|
+
def intersect?(other_ary)
|
220
|
+
!(self & other_ary).empty?
|
221
|
+
end
|
222
|
+
|
223
|
+
def keep_if?
|
224
|
+
raise NotImplementedError unless block_given?
|
225
|
+
|
226
|
+
it = list_iterator
|
227
|
+
while it.has_next? # rubocop:disable Style/WhileUntilModifier
|
228
|
+
it.remove unless yield(it.next)
|
229
|
+
end
|
230
|
+
self
|
231
|
+
end
|
232
|
+
|
233
|
+
def map!(&block)
|
234
|
+
raise NotImplementedError unless block
|
235
|
+
|
236
|
+
replace_all(&block)
|
237
|
+
self
|
238
|
+
end
|
239
|
+
|
240
|
+
def permutation(n, &block) # rubocop:disable Naming/MethodParameterName
|
241
|
+
r = to_a.permutation(n, &block)
|
242
|
+
block ? self : r
|
243
|
+
end
|
244
|
+
|
245
|
+
def pop(*args)
|
246
|
+
if args.length > 1
|
247
|
+
raise ArgumentError,
|
248
|
+
"wrong number of arguments calling `pop` (given #{args.length}, expected 0..1)"
|
249
|
+
end
|
250
|
+
|
251
|
+
if args.empty?
|
252
|
+
return if empty?
|
253
|
+
|
254
|
+
return remove(length - 1)
|
255
|
+
end
|
256
|
+
|
257
|
+
count = args.first
|
258
|
+
start = [length - count, 0].max
|
259
|
+
result = self[start..-1].to_a # rubocop:disable Style/SlicingWithRange
|
260
|
+
it = list_iterator(start)
|
261
|
+
while it.has_next?
|
262
|
+
it.next
|
263
|
+
it.remove
|
264
|
+
end
|
265
|
+
result
|
266
|
+
end
|
267
|
+
|
268
|
+
def push(*objects)
|
269
|
+
add_all(objects)
|
270
|
+
self
|
271
|
+
end
|
272
|
+
alias_method :append, :push
|
273
|
+
|
274
|
+
def rassoc(obj)
|
275
|
+
find { |v| (v.is_a?(Array) || v.is_a?(self.class)) && v[1] == obj }
|
276
|
+
end
|
277
|
+
|
278
|
+
def reject!
|
279
|
+
raise NotImplementedError unless block_given?
|
280
|
+
|
281
|
+
it = list_iterator
|
282
|
+
changed = false
|
283
|
+
while it.has_next
|
284
|
+
if yield(it.next)
|
285
|
+
changed = true
|
286
|
+
it.remove
|
287
|
+
end
|
288
|
+
end
|
289
|
+
self if changed
|
290
|
+
end
|
291
|
+
|
292
|
+
def repeated_combination(n, &block) # rubocop:disable Naming/MethodParameterName
|
293
|
+
r = to_a.repeated_combination(n, &block)
|
294
|
+
block ? self : r
|
295
|
+
end
|
296
|
+
|
297
|
+
def repeated_permutation(n, &block) # rubocop:disable Naming/MethodParameterName
|
298
|
+
r = to_a.repeated_permutation(n, &block)
|
299
|
+
block ? self : r
|
300
|
+
end
|
301
|
+
|
302
|
+
def replace(other_array)
|
303
|
+
clear
|
304
|
+
add_all(other_array)
|
305
|
+
self
|
306
|
+
end
|
307
|
+
|
308
|
+
def reverse!
|
309
|
+
replace(reverse)
|
310
|
+
self
|
311
|
+
end
|
312
|
+
|
313
|
+
def rotate!(count = 1)
|
314
|
+
count = count % length
|
315
|
+
push(*shift(count))
|
316
|
+
self
|
317
|
+
end
|
318
|
+
|
319
|
+
def select!
|
320
|
+
raise NotImplementedError unless block_given?
|
321
|
+
|
322
|
+
it = list_iterator
|
323
|
+
changed = false
|
324
|
+
while it.has_next?
|
325
|
+
unless yield(it.next)
|
326
|
+
changed = true
|
327
|
+
it.remove
|
328
|
+
end
|
329
|
+
end
|
330
|
+
self if changed
|
331
|
+
end
|
332
|
+
|
333
|
+
def shift(*args)
|
334
|
+
if args.length > 1
|
335
|
+
raise ArgumentError,
|
336
|
+
"wrong number of arguments calling `shift` (given #{args.length}, expected 0..1)"
|
337
|
+
end
|
338
|
+
|
339
|
+
if args.empty?
|
340
|
+
return if empty?
|
341
|
+
|
342
|
+
return remove(0)
|
343
|
+
end
|
344
|
+
|
345
|
+
count = args.first
|
346
|
+
result = self[0...count].to_a
|
347
|
+
it = list_iterator
|
348
|
+
count.times do
|
349
|
+
break unless it.has_next?
|
350
|
+
|
351
|
+
it.next
|
352
|
+
it.remove
|
353
|
+
end
|
354
|
+
result
|
355
|
+
end
|
356
|
+
|
357
|
+
def shuffle!(*args)
|
358
|
+
replace(shuffle(*args))
|
359
|
+
end
|
360
|
+
|
361
|
+
def slice(*args)
|
362
|
+
self[*args]
|
363
|
+
end
|
364
|
+
|
365
|
+
def slice!(*args)
|
366
|
+
unless (1..2).cover?(args.length)
|
367
|
+
raise ArgumentError,
|
368
|
+
"wrong number of arguments calling `slice!` (given #{args.length}, expected 1..2)"
|
369
|
+
end
|
370
|
+
|
371
|
+
return delete_at(args.first) if args.length == 1 && !args.first.is_a?(Range)
|
372
|
+
|
373
|
+
start = args.first
|
374
|
+
start = start.begin if start.is_a?(Range)
|
375
|
+
start = length + start if start.negative?
|
376
|
+
return nil if start.negative? || start >= length
|
377
|
+
|
378
|
+
result = slice(*args).to_a
|
379
|
+
|
380
|
+
it = list_iterator(start)
|
381
|
+
result.length.times do
|
382
|
+
it.next
|
383
|
+
it.remove
|
384
|
+
end
|
385
|
+
result
|
386
|
+
end
|
387
|
+
|
388
|
+
def sort_by!
|
389
|
+
raise NotImplementedError unless block_given?
|
390
|
+
|
391
|
+
sort { |a, b| (yield a) <=> (yield b) }
|
392
|
+
self
|
393
|
+
end
|
394
|
+
|
395
|
+
def uniq!
|
396
|
+
seen = Set.new
|
397
|
+
|
398
|
+
it = list_iterator
|
399
|
+
changed = false
|
400
|
+
while it.has_next?
|
401
|
+
n = it.next
|
402
|
+
n = yield(n) if block_given?
|
403
|
+
if seen.include?(n)
|
404
|
+
changed = true
|
405
|
+
it.remove
|
406
|
+
end
|
407
|
+
seen << n
|
408
|
+
end
|
409
|
+
self if changed
|
410
|
+
end
|
411
|
+
|
412
|
+
def unshift(*objects)
|
413
|
+
add_all(0, objects)
|
414
|
+
self
|
415
|
+
end
|
416
|
+
alias_method :prepend, :unshift
|
417
|
+
|
418
|
+
def values_at(*indexes)
|
419
|
+
result = []
|
420
|
+
indexes.each do |index|
|
421
|
+
if index.is_a?(Range)
|
422
|
+
partial_result = self[index]
|
423
|
+
result.concat(partial_result)
|
424
|
+
result.fill(nil, result.length, index.count - partial_result.length)
|
425
|
+
else
|
426
|
+
index = length + index if index.negative?
|
427
|
+
result << if index.negative? || index >= length
|
428
|
+
nil
|
429
|
+
else
|
430
|
+
self[index]
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
result
|
435
|
+
end
|
436
|
+
end
|
@@ -33,7 +33,7 @@ module OpenHAB
|
|
33
33
|
# end
|
34
34
|
#
|
35
35
|
class LocalTime
|
36
|
-
include Time
|
36
|
+
# @!parse include Time
|
37
37
|
|
38
38
|
# @!visibility private
|
39
39
|
class << self
|
@@ -104,3 +104,4 @@ module OpenHAB
|
|
104
104
|
end
|
105
105
|
|
106
106
|
LocalTime = OpenHAB::CoreExt::Java::LocalTime unless Object.const_defined?(:LocalTime)
|
107
|
+
java.time.LocalTime.include(OpenHAB::CoreExt::Java::Time)
|