standard-procedure-signal 0.1.2.1 → 0.2.0
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 -0
- data/README.md +22 -32
- data/checksums/standard-procedure-signal-0.2.0.gem.sha512 +1 -0
- data/lib/standard_procedure/signal/attribute.rb +2 -1
- data/lib/standard_procedure/signal/observable.rb +7 -0
- data/lib/standard_procedure/signal/signal_extensions.rb +3 -0
- data/lib/standard_procedure/signal/version.rb +1 -1
- data/lib/standard_procedure/signal.rb +24 -10
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f6832d51eb537fe7c3fb46ffeddf42c0cace64f77a2caae6499ee85688caf55
|
4
|
+
data.tar.gz: be9c55a822d3d053d176f57b51e21b7e0de1ad8a3817257b096ff9f6b228d82a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bedb9d1523ce359dfafe85fff3865055f48aeb4e8def1e585ba63b7d75de1bdd62e8107b26b2e7277e997f1b7bbf1d5fb41c78f505a5af051e3ffd408afba3a7
|
7
|
+
data.tar.gz: dabbde43de2d4b1a62da7bb7b389a8dcb0b3c8c27136da3cc8f3a0b316fa5ddab4592c87cbb18cf36d3b7160b48fe58bcfc4e3889b747f5181feb33d5ed5fe17
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -15,20 +15,18 @@ Finally, we define an observer (our "name badge") that simply writes the display
|
|
15
15
|
When we update the values stored in those various attributes, our "name badge" redraws itself when it has to but does nothing if it does not need to change.
|
16
16
|
|
17
17
|
```ruby
|
18
|
-
include StandardProcedure::Signal
|
19
|
-
|
20
18
|
# Define the basic attributes
|
21
|
-
first_name =
|
22
|
-
last_name =
|
23
|
-
show_full_name =
|
19
|
+
first_name = Signal.text_attribute "Alice"
|
20
|
+
last_name = Signal.text_attribute "Aardvark"
|
21
|
+
show_full_name = Signal.boolean_attribute true
|
24
22
|
|
25
23
|
# Define the composite attribute
|
26
|
-
display_name = compute do
|
24
|
+
display_name = Signal.compute do
|
27
25
|
show_full_name.get ? "#{first_name.get} #{last_name.get}" : first_name.get
|
28
26
|
end
|
29
27
|
|
30
28
|
# Define the output that the end-user will see
|
31
|
-
observe do
|
29
|
+
Signal.observe do
|
32
30
|
puts "My name is #{display_name.get}"
|
33
31
|
end
|
34
32
|
# => My name is Alice Aardvark
|
@@ -41,7 +39,7 @@ show_full_name.set true
|
|
41
39
|
# => My name is Alice Anteater
|
42
40
|
|
43
41
|
# Perform a batch update, with no notifications until the batch is completed
|
44
|
-
update do
|
42
|
+
Signal.update do
|
45
43
|
first_name.set "Anthony"
|
46
44
|
# no output
|
47
45
|
show_full_name.set false
|
@@ -107,25 +105,23 @@ In addition, there is a concrete implementation of the StandardProcedure::Signal
|
|
107
105
|
And `StandardProcedure::Signal.compute` allows you to build composite observables which depend on multiple other observables.
|
108
106
|
|
109
107
|
```ruby
|
110
|
-
|
111
|
-
|
112
|
-
@
|
113
|
-
@
|
114
|
-
@
|
115
|
-
|
116
|
-
@sum = compute { @a.get + @b.get }
|
117
|
-
observe do
|
108
|
+
@my_object = Signal.attribute MyObject.new
|
109
|
+
@my_text = Signal.text_attribute "The total is: "
|
110
|
+
@a = Signal.integer_attribute 1
|
111
|
+
@b = Signal.integer_attribute 2
|
112
|
+
@sum = Signal.compute { @a.get + @b.get }
|
113
|
+
Signal.observe do
|
118
114
|
puts "#{@my_text.get} #{@sum.get}"
|
119
115
|
end
|
120
116
|
```
|
121
117
|
|
122
|
-
To access the values stored in
|
118
|
+
To access the values stored in an attribute, you can call `StandardProcedure::Signal::Attribute#get`. This is aliased as both `StandardProcedure::Signal::Attribute#read` and `StandardProcedure::Signal::Attribute#call` (which means you can use the short-hand `@my_attribute.()` as well). However, calling `StandardProcedure::Signal::Attribute#get` also incurs the overhead of setting up observers for the attribute, so if you just want to peek at the value without worrying about changes, you can call `StandardProcedure::Signal::Attribute#peek`.
|
123
119
|
|
124
|
-
To place a value into an attribute you call `
|
120
|
+
To place a value into an attribute you call `StandardProcedure::Signal::Attribute#set`, aliased as `StandardProcedure::Signal::Attribute#write`.
|
125
121
|
|
126
122
|
### Extensions
|
127
123
|
|
128
|
-
Because `StandardProcedure::Signal.observe` and `StandardProcedure::Signal::Attribute` are quite long names, you can
|
124
|
+
Because `StandardProcedure::Signal.observe` and `StandardProcedure::Signal::Attribute` are quite long names, you can include the [StandardProcedure::Signal module](lib/standard_procedure/signal.rb) into your own classes. And the module has also been extended into the standard Ruby [Signal](https://docs.ruby-lang.org/en/master/Module.html) so you can refer to them as `Signal.observe`, `Signal.compute` and so on.
|
129
125
|
|
130
126
|
### Triggering updates
|
131
127
|
|
@@ -134,23 +130,19 @@ It's important to note that most observables only trigger updates when the `set`
|
|
134
130
|
For example:
|
135
131
|
|
136
132
|
```ruby
|
137
|
-
include StandardProcedure::Signal
|
138
|
-
|
139
133
|
# This will not trigger any updates
|
140
|
-
@attribute =
|
134
|
+
@attribute = Signal.text_attribute "hello"
|
141
135
|
@attribute.get.upcase!
|
142
136
|
|
143
137
|
# This will trigger updates
|
144
|
-
@attribute =
|
138
|
+
@attribute = Signal.text_attribute "hello"
|
145
139
|
@attribute.set @attribute.get.upcase
|
146
140
|
```
|
147
141
|
|
148
142
|
If necessary, you can manually trigger updates on an observable.
|
149
143
|
```ruby
|
150
|
-
include StandardProcedure::Signal
|
151
|
-
|
152
144
|
# Manually trigger updates
|
153
|
-
@attribute =
|
145
|
+
@attribute = Signal.text_attribute "hello"
|
154
146
|
@attribute.get.upcase!
|
155
147
|
@attribute.update_observers
|
156
148
|
```
|
@@ -160,30 +152,28 @@ However, there are two mutable attributes that you can use - [attribute::Array](
|
|
160
152
|
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.
|
161
153
|
|
162
154
|
```ruby
|
163
|
-
include StandardProcedure::Signal
|
164
|
-
|
165
155
|
# Non-mutable array attribute
|
166
156
|
@array = [1, 2, 3]
|
167
|
-
@attribute =
|
157
|
+
@attribute = Signal.array_attribute @array
|
168
158
|
@new_array = @array.dup
|
169
159
|
@new_array.push 4
|
170
160
|
@attribute.set @new_array
|
171
161
|
|
172
162
|
# Mutable array attribute
|
173
163
|
@array = [1, 2, 3]
|
174
|
-
@attribute =
|
164
|
+
@attribute = Signal.array_attribute @array
|
175
165
|
@attribute << 4
|
176
166
|
|
177
167
|
# Non-mutable hash attribute
|
178
168
|
@hash = { key1: "value1", key2: "value2" }
|
179
|
-
@attribute = attribute
|
169
|
+
@attribute = Signal.attribute @hash
|
180
170
|
@new_hash = @hash.dup
|
181
171
|
@new_hash[:key3] = "value3"
|
182
172
|
@attribute.set @new_hash
|
183
173
|
|
184
174
|
# Mutable hash attribute
|
185
175
|
@hash = { key1: "value1", key2: "value2" }
|
186
|
-
@attribute =
|
176
|
+
@attribute = Signal.array_attribute @hash
|
187
177
|
@attribute[:key3] = "value3"
|
188
178
|
```
|
189
179
|
|
@@ -0,0 +1 @@
|
|
1
|
+
7ff644775dc25b8168b1ba28d3d0635846efe7aada24bcd95c4299a5e225856f3cd5448dc1d2577a89dd01638504cf9be151d83d2869da1b645fa56c6cee6523
|
@@ -22,8 +22,9 @@ module StandardProcedure
|
|
22
22
|
set value
|
23
23
|
end
|
24
24
|
|
25
|
+
TYPES = %i[text integer float date time boolean array hash].freeze
|
25
26
|
class << self
|
26
|
-
|
27
|
+
TYPES.each do |type|
|
27
28
|
class_name = "StandardProcedure::Signal::Attribute::#{type.to_s.capitalize}"
|
28
29
|
define_method type do |value|
|
29
30
|
const_get(class_name).new value
|
@@ -31,6 +31,13 @@ module StandardProcedure
|
|
31
31
|
alias_method :get, :call
|
32
32
|
alias_method :read, :call
|
33
33
|
|
34
|
+
# Peek at the value of this signal without registering as an observer
|
35
|
+
#
|
36
|
+
# This is useful if you just want to access the value but don't care if it changes
|
37
|
+
def peek
|
38
|
+
@value
|
39
|
+
end
|
40
|
+
|
34
41
|
# Set the value of this signal and notify any observers
|
35
42
|
#
|
36
43
|
# This method is aliased as `write` it can be used in whichever way makes most sense to you
|
@@ -7,6 +7,7 @@ module StandardProcedure
|
|
7
7
|
require_relative "signal/observer"
|
8
8
|
require_relative "signal/observable"
|
9
9
|
require_relative "signal/attribute"
|
10
|
+
require_relative "signal/signal_extensions"
|
10
11
|
|
11
12
|
# Build a "computed" attribute that automatically updates based upon its dependents
|
12
13
|
#
|
@@ -21,8 +22,8 @@ module StandardProcedure
|
|
21
22
|
# "#{first_line.get}\n#{second_line.get}\n#{city.get}\n#{region.get}"
|
22
23
|
# end
|
23
24
|
def compute(&block)
|
24
|
-
|
25
|
-
observe {
|
25
|
+
attribute(nil).tap do |a|
|
26
|
+
observe { a.set block.call }
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
@@ -59,16 +60,29 @@ module StandardProcedure
|
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
62
|
-
#
|
63
|
-
#
|
63
|
+
# Shortcut method to build an attribute that signals its changes to dependents
|
64
|
+
#
|
65
|
+
# There are also helpers for the various types of Attribute - see StandardProcedure::Signal::Attribute::TYPES
|
64
66
|
#
|
65
67
|
# include StandardProcedure::Signal
|
66
|
-
# @
|
67
|
-
# @
|
68
|
-
# @
|
69
|
-
# @
|
70
|
-
def attribute
|
71
|
-
StandardProcedure::Signal::Attribute
|
68
|
+
# @object = attribute @some_object
|
69
|
+
# @name = text_attribute "Alice"
|
70
|
+
# @age = integer_attribute 23
|
71
|
+
# @colours = array_attribute %w[red green blue]
|
72
|
+
def attribute value
|
73
|
+
StandardProcedure::Signal::Attribute.new value
|
74
|
+
end
|
75
|
+
|
76
|
+
class_eval do
|
77
|
+
StandardProcedure::Signal::Attribute::TYPES.each do |type|
|
78
|
+
define_method :"#{type}_attribute" do |value|
|
79
|
+
StandardProcedure::Signal::Attribute.send type, value
|
80
|
+
end
|
81
|
+
end
|
72
82
|
end
|
73
83
|
end
|
74
84
|
end
|
85
|
+
|
86
|
+
def Signal
|
87
|
+
StandardProcedure::Signal
|
88
|
+
end
|
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.
|
4
|
+
version: 0.2.0
|
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-14 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
|
@@ -32,6 +32,7 @@ files:
|
|
32
32
|
- checksums/standard-procedure-signal-0.1.1.gem.sha512
|
33
33
|
- checksums/standard-procedure-signal-0.1.2.1.gem.sha512
|
34
34
|
- checksums/standard-procedure-signal-0.1.2.gem.sha512
|
35
|
+
- checksums/standard-procedure-signal-0.2.0.gem.sha512
|
35
36
|
- lib/standard_procedure/signal.rb
|
36
37
|
- lib/standard_procedure/signal/attribute.rb
|
37
38
|
- lib/standard_procedure/signal/attribute/array.rb
|
@@ -46,6 +47,7 @@ files:
|
|
46
47
|
- lib/standard_procedure/signal/manager.rb
|
47
48
|
- lib/standard_procedure/signal/observable.rb
|
48
49
|
- lib/standard_procedure/signal/observer.rb
|
50
|
+
- lib/standard_procedure/signal/signal_extensions.rb
|
49
51
|
- lib/standard_procedure/signal/version.rb
|
50
52
|
- sig/standard/procedure/attribute.rbs
|
51
53
|
homepage: https://theartandscienceofruby.com
|