standard-procedure-signal 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -3
- data/README.md +39 -31
- data/checksums/standard-procedure-signal-0.1.1.gem.sha512 +1 -0
- data/lib/signal/attribute/array.rb +51 -0
- data/lib/signal/attribute/hash.rb +87 -0
- data/lib/signal/attribute.rb +5 -1
- data/lib/signal/observable.rb +1 -1
- data/lib/signal/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c347178dc2149032ef830dc559022331c72955415a2bf989e12460a0f3114460
|
4
|
+
data.tar.gz: '09db2d1f954710ce4f4eb277dd950f231d93db17ba660d3d95861c7c68bb9c74'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0ad515217b9f1c5db1c179fb3b0ae9ff7320299e56d1eec1cb038ddd44f2fd31b96d60318af1c39a6a1155764633ebc03d0e2ae6471b0da86ef386fc4e78d0c
|
7
|
+
data.tar.gz: 604b0ed2905965347e560071cd171b817f3a75882da9ad81f518f8e86038cb676da1f2263fa07bfda8f7958567ed1a62080d7a2406949cca716392f6446beb40
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
## [0.1.1] - 2023-09-13
|
2
|
+
|
3
|
+
- Added in [Signal::Attribute::Array](/lib/signal/attribute/array.rb) and [Signal::Attribute::Hash](/lib/signal/attribute/hash.rb)
|
4
|
+
|
1
5
|
## [0.1.0] - 2023-09-08
|
2
6
|
|
3
7
|
- Initial release
|
4
8
|
|
5
9
|
Things to do:
|
6
10
|
|
7
|
-
- Add proper rspec
|
8
|
-
- Add in simple types - string, integer, float, date, datetime, boolean
|
9
|
-
- Add array and hash types
|
10
11
|
- Add compound types
|
data/README.md
CHANGED
@@ -121,48 +121,56 @@ To place a value into an attribute you call `Signal::Attribute#set`, aliased as
|
|
121
121
|
|
122
122
|
### Triggering updates
|
123
123
|
|
124
|
-
It's important to note that observables only trigger updates when the `set` method is called with a new value. This
|
124
|
+
It's important to note that most observables only trigger updates when the `set` method is called with a new value. This means that, in most cases, you cannot _mutate_ a value stored in an observable. Instead, you should replace the value by calling `set`.
|
125
125
|
|
126
|
-
For example
|
126
|
+
For example:
|
127
127
|
|
128
128
|
```ruby
|
129
|
-
|
129
|
+
# This will not trigger any updates
|
130
|
+
@attribute = Signal::Attribute.string "hello"
|
131
|
+
@attribute.get.upcase!
|
130
132
|
|
131
|
-
#
|
132
|
-
@attribute
|
133
|
-
@attribute.get
|
134
|
-
@attribute.get.transform_values! { |v| v.capitalize }
|
133
|
+
# This will trigger updates
|
134
|
+
@attribute = Signal::Attribute.string "hello"
|
135
|
+
@attribute.set @attribute.get.upcase
|
135
136
|
```
|
136
137
|
|
137
|
-
|
138
|
-
|
139
|
-
Option One: manually triggering updates
|
140
|
-
|
138
|
+
If necessary, you can manually trigger updates on an observable.
|
141
139
|
```ruby
|
142
|
-
|
143
|
-
|
144
|
-
@attribute.get
|
145
|
-
@attribute.update_observers
|
146
|
-
@attribute.get[:key_1] = "some other value"
|
147
|
-
@attribute.update_observers
|
148
|
-
@attribute.get.transform_values! { |v| v.capitalize }
|
149
|
-
@attribute.update_observers
|
140
|
+
# Manually trigger updates
|
141
|
+
@attribute = Signal::Attribute.string "hello"
|
142
|
+
@attribute.get.upcase!
|
143
|
+
@attribute.update_observers
|
150
144
|
```
|
151
145
|
|
152
|
-
|
153
|
-
|
154
|
-
```ruby
|
155
|
-
@attribute = Signal::Attribute.new { key_1: "value_1", key_2: "value_2" }
|
156
|
-
|
157
|
-
data = @attribute.get.dup
|
158
|
-
data[:key_3] = "value_3"
|
159
|
-
@attribute.set data
|
146
|
+
However, there are two mutable attributes that you can use - [Signal::Attribute::Array](/lib/signal/attribute/array.rb) and [Signal::Attribute::Hash](/lib/signal/attribute/hash.rb).
|
160
147
|
|
161
|
-
|
162
|
-
data[:key_1] = "some other value"
|
163
|
-
@attribute.set data
|
148
|
+
These are partial implementations of the ruby Array and Hash classes that are convenience wrappers when it comes to updates. They implement Enumerable, so you can use `each`, `map` and your other favourites, plus they include a subset of the mutation methods to make it easier to manipulate the contents without repeatedly copying, changing and then setting your attributes contents.
|
164
149
|
|
165
|
-
|
150
|
+
```ruby
|
151
|
+
# Non-mutable array attribute
|
152
|
+
@array = [1, 2, 3]
|
153
|
+
@attribute = Signal::Attribute.new @array
|
154
|
+
@new_array = @array.dup
|
155
|
+
@new_array.push 4
|
156
|
+
@attribute.set @new_array
|
157
|
+
|
158
|
+
# Mutable array attribute
|
159
|
+
@array = [1, 2, 3]
|
160
|
+
@attribute = Signal::Attribute.array @array
|
161
|
+
@attribute << 4
|
162
|
+
|
163
|
+
# Non-mutable hash attribute
|
164
|
+
@hash = { key1: "value1", key2: "value2" }
|
165
|
+
@attribute = Signal::Attribute.new @hash
|
166
|
+
@new_hash = @hash.dup
|
167
|
+
@new_hash[:key3] = "value3"
|
168
|
+
@attribute.set @new_hash
|
169
|
+
|
170
|
+
# Mutable hash attribute
|
171
|
+
@hash = { key1: "value1", key2: "value2" }
|
172
|
+
@attribute = Signal::Attribute.array @hash
|
173
|
+
@attribute[:key3] = "value3"
|
166
174
|
```
|
167
175
|
|
168
176
|
## Installation
|
@@ -0,0 +1 @@
|
|
1
|
+
87fb50047e2f2b4e14e0a4b48caed00445b344719ca0ea17a8dd82ec92cd48db5ab7a1f1ea87f00da81865045b9f313260b61f34c112f8ba136999a51ae517be
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Signal
|
2
|
+
class Attribute
|
3
|
+
class Array < Attribute
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def set(new_value)
|
7
|
+
new_value = if new_value.nil?
|
8
|
+
nil
|
9
|
+
elsif new_value.respond_to? :map
|
10
|
+
new_value.map { |i| Attribute.for i }
|
11
|
+
else
|
12
|
+
[Attribute.new(new_value)]
|
13
|
+
end
|
14
|
+
super new_value
|
15
|
+
end
|
16
|
+
|
17
|
+
def push item
|
18
|
+
@value.push item
|
19
|
+
update_observers
|
20
|
+
self
|
21
|
+
end
|
22
|
+
alias_method :<<, :push
|
23
|
+
|
24
|
+
def pop
|
25
|
+
item = @value.pop
|
26
|
+
update_observers
|
27
|
+
item
|
28
|
+
end
|
29
|
+
|
30
|
+
def shift
|
31
|
+
item = @value.shift
|
32
|
+
update_observers
|
33
|
+
item
|
34
|
+
end
|
35
|
+
|
36
|
+
def unshift item
|
37
|
+
@value.unshift Attribute.for(item)
|
38
|
+
update_observers
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def last
|
43
|
+
@value.last
|
44
|
+
end
|
45
|
+
|
46
|
+
def each &block
|
47
|
+
@value.each(&block)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Signal
|
2
|
+
class Attribute
|
3
|
+
class Hash < Attribute
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def set(new_value)
|
7
|
+
new_value = if new_value.nil?
|
8
|
+
nil
|
9
|
+
elsif new_value.respond_to? :transform_values
|
10
|
+
new_value.transform_values { |value| Attribute.for value }
|
11
|
+
else
|
12
|
+
raise ArgumentError.new "#{new_value.inspect} is not recognised as a Hash"
|
13
|
+
end
|
14
|
+
super new_value
|
15
|
+
end
|
16
|
+
|
17
|
+
def each &block
|
18
|
+
@value.each(&block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def keys
|
22
|
+
@value.keys
|
23
|
+
end
|
24
|
+
|
25
|
+
def include? key
|
26
|
+
@value.include? key
|
27
|
+
end
|
28
|
+
|
29
|
+
def has_key? key
|
30
|
+
@value.has_key? key
|
31
|
+
end
|
32
|
+
|
33
|
+
def has_value? value, attribute: false
|
34
|
+
if attribute
|
35
|
+
@value.has_value? value
|
36
|
+
else
|
37
|
+
@value.values.map(&:get).include? value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def values
|
42
|
+
@value.values
|
43
|
+
end
|
44
|
+
|
45
|
+
def size
|
46
|
+
@value.size
|
47
|
+
end
|
48
|
+
alias_method :length, :size
|
49
|
+
|
50
|
+
def any?
|
51
|
+
@value.any?
|
52
|
+
end
|
53
|
+
|
54
|
+
def empty?
|
55
|
+
@value.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
def [] key
|
59
|
+
@value[key]
|
60
|
+
end
|
61
|
+
|
62
|
+
def fetch key
|
63
|
+
@value.fetch key
|
64
|
+
end
|
65
|
+
|
66
|
+
def []= key, value
|
67
|
+
@value[key] = value
|
68
|
+
update_observers
|
69
|
+
end
|
70
|
+
|
71
|
+
def store key, value
|
72
|
+
@value.store key, value
|
73
|
+
update_observers
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete key
|
77
|
+
@value.delete key
|
78
|
+
update_observers
|
79
|
+
end
|
80
|
+
|
81
|
+
def clear
|
82
|
+
@value.clear
|
83
|
+
update_observers
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/signal/attribute.rb
CHANGED
@@ -15,12 +15,16 @@ module Signal
|
|
15
15
|
end
|
16
16
|
|
17
17
|
class << self
|
18
|
-
%i[text integer float date time boolean].each do |type|
|
18
|
+
%i[text integer float date time boolean array hash].each do |type|
|
19
19
|
class_name = "Signal::Attribute::#{type.to_s.capitalize}"
|
20
20
|
define_method type do |value|
|
21
21
|
const_get(class_name).new value
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
def for item
|
26
|
+
item.is_a?(Signal::Observable) ? item : Attribute.new(item)
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
data/lib/signal/observable.rb
CHANGED
@@ -49,7 +49,7 @@ module Signal
|
|
49
49
|
# The block will be called whenever this signal or its dependents is updated.
|
50
50
|
# The block handler does not require any parameters, simply access the signal, or any other signals and act accordingly. If you access any dependents outside of this signal, they will be tracked and you will be notified again when they update.
|
51
51
|
def observe(&block)
|
52
|
-
Signal
|
52
|
+
Signal.observe(&block)
|
53
53
|
end
|
54
54
|
|
55
55
|
# Notify all observers that this signal has changed
|
data/lib/signal/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: standard-procedure-signal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rahoul Baruah
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Observable attributes which adapt based upon their dependencies so we
|
14
14
|
avoid unecessary updates
|
@@ -29,12 +29,15 @@ files:
|
|
29
29
|
- README.md
|
30
30
|
- Rakefile
|
31
31
|
- checksums/standard-procedure-signal-0.1.0.gem.sha512
|
32
|
+
- checksums/standard-procedure-signal-0.1.1.gem.sha512
|
32
33
|
- lib/signal.rb
|
33
34
|
- lib/signal/attribute.rb
|
35
|
+
- lib/signal/attribute/array.rb
|
34
36
|
- lib/signal/attribute/boolean.rb
|
35
37
|
- lib/signal/attribute/date.rb
|
36
38
|
- lib/signal/attribute/float.rb
|
37
39
|
- lib/signal/attribute/format_error.rb
|
40
|
+
- lib/signal/attribute/hash.rb
|
38
41
|
- lib/signal/attribute/integer.rb
|
39
42
|
- lib/signal/attribute/text.rb
|
40
43
|
- lib/signal/attribute/time.rb
|