standard-procedure-signal 0.1.2 → 0.2.0
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/CHANGELOG.md +4 -0
- data/README.md +22 -32
- data/checksums/standard-procedure-signal-0.1.2.1.gem.sha512 +1 -0
- data/checksums/standard-procedure-signal-0.2.0.gem.sha512 +1 -0
- data/lib/standard_procedure/signal/attribute.rb +11 -2
- data/lib/standard_procedure/signal/manager.rb +2 -0
- data/lib/standard_procedure/signal/observable.rb +9 -0
- data/lib/standard_procedure/signal/observer.rb +2 -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 +5 -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
|
+
c5a5dd921fe67d5faa376542bd566d2802d5e0389306f0e149d82a9b55b957f0270d051243e02a5fab2cca43463586408f9d1bfe707659f8135e6b20da609860
|
@@ -0,0 +1 @@
|
|
1
|
+
7ff644775dc25b8168b1ba28d3d0635846efe7aada24bcd95c4299a5e225856f3cd5448dc1d2577a89dd01638504cf9be151d83d2869da1b645fa56c6cee6523
|
@@ -5,7 +5,15 @@ module StandardProcedure
|
|
5
5
|
module Signal
|
6
6
|
class Attribute
|
7
7
|
include Observable
|
8
|
-
|
8
|
+
require_relative "attribute/format_error"
|
9
|
+
require_relative "attribute/array"
|
10
|
+
require_relative "attribute/boolean"
|
11
|
+
require_relative "attribute/date"
|
12
|
+
require_relative "attribute/float"
|
13
|
+
require_relative "attribute/hash"
|
14
|
+
require_relative "attribute/integer"
|
15
|
+
require_relative "attribute/text"
|
16
|
+
require_relative "attribute/time"
|
9
17
|
|
10
18
|
# Create a new, untyped, Attribute, with the given value
|
11
19
|
# Alternatively, you can use the class factory methods to build an attribute that automatically performs type conversions.
|
@@ -14,8 +22,9 @@ module StandardProcedure
|
|
14
22
|
set value
|
15
23
|
end
|
16
24
|
|
25
|
+
TYPES = %i[text integer float date time boolean array hash].freeze
|
17
26
|
class << self
|
18
|
-
|
27
|
+
TYPES.each do |type|
|
19
28
|
class_name = "StandardProcedure::Signal::Attribute::#{type.to_s.capitalize}"
|
20
29
|
define_method type do |value|
|
21
30
|
const_get(class_name).new value
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module StandardProcedure
|
2
4
|
module Signal
|
3
5
|
module Observable
|
@@ -29,6 +31,13 @@ module StandardProcedure
|
|
29
31
|
alias_method :get, :call
|
30
32
|
alias_method :read, :call
|
31
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
|
+
|
32
41
|
# Set the value of this signal and notify any observers
|
33
42
|
#
|
34
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
|
@@ -30,7 +30,9 @@ files:
|
|
30
30
|
- Rakefile
|
31
31
|
- checksums/standard-procedure-signal-0.1.0.gem.sha512
|
32
32
|
- checksums/standard-procedure-signal-0.1.1.gem.sha512
|
33
|
+
- checksums/standard-procedure-signal-0.1.2.1.gem.sha512
|
33
34
|
- checksums/standard-procedure-signal-0.1.2.gem.sha512
|
35
|
+
- checksums/standard-procedure-signal-0.2.0.gem.sha512
|
34
36
|
- lib/standard_procedure/signal.rb
|
35
37
|
- lib/standard_procedure/signal/attribute.rb
|
36
38
|
- lib/standard_procedure/signal/attribute/array.rb
|
@@ -45,6 +47,7 @@ files:
|
|
45
47
|
- lib/standard_procedure/signal/manager.rb
|
46
48
|
- lib/standard_procedure/signal/observable.rb
|
47
49
|
- lib/standard_procedure/signal/observer.rb
|
50
|
+
- lib/standard_procedure/signal/signal_extensions.rb
|
48
51
|
- lib/standard_procedure/signal/version.rb
|
49
52
|
- sig/standard/procedure/attribute.rbs
|
50
53
|
homepage: https://theartandscienceofruby.com
|