README.md in signalize-1.0.0 vs README.md in signalize-1.0.1
- old
+ new
@@ -30,10 +30,12 @@
### `signal(initial_value)`
The first building block is the `Signalize::Signal` class. You can think of this as a reactive value object which wraps an underlying primitive like String, Integer, Array, etc.
```ruby
+require "signalize"
+
counter = Signalize.signal(0)
# Read value from signal, logs: 0
puts counter.value
@@ -42,10 +44,11 @@
```
You can include the `Signalize::API` mixin to access these methods directly in any context:
```ruby
+require "signalize"
include Signalize::API
counter = signal(0)
counter.value += 1
@@ -54,10 +57,11 @@
### `computed { }`
You derive computed state by accessing a signal's value within a `computed` block and returning a new value. Every time that signal value is updated, a computed value will likewise be updated. Actually, that's not quite accurate — the computed value only computes when it's read. In this sense, we can call computed values "lazily-evaluated".
```ruby
+require "signalize"
include Signalize::API
name = signal("Jane")
surname = signal("Doe")
@@ -80,10 +84,11 @@
### `effect { }`
Effects are callbacks which are executed whenever values which the effect has "subscribed" to by referencing them have changed. An effect callback is run immediately when defined, and then again for any future mutations.
```ruby
+require "signalize"
include Signalize::API
name = signal("Jane")
surname = signal("Doe")
full_name = computed { name.value + " " + surname.value }
@@ -97,10 +102,11 @@
```
You can dispose of an effect whenever you want, thereby unsubscribing it from signal notifications.
```ruby
+require "signalize"
include Signalize::API
name = signal("Jane")
surname = signal("Doe")
full_name = computed { name.value + " " + surname.value }
@@ -115,35 +121,87 @@
# Even the computed `full_name` signal won't change, because it knows
# that no one listens to it.
surname.value = "Doe 2"
```
+**IMPORTANT:** you cannot use `return` or `break` within an effect block. Doing so will raise an exception (due to it breaking the underlying execution model).
+
+```ruby
+def my_method(signal_obj)
+ effect do
+ return if signal_obj.value > 5 # DON'T DO THIS!
+
+ puts signal_obj.value
+ end
+
+ # more code here
+end
+```
+
+Instead, try to resolve it using more explicit logic:
+
+```ruby
+def my_method(signal_obj)
+ should_exit = false
+
+ effect do
+ should_exit = true && next if signal_obj.value > 5
+
+ puts signal_obj.value
+ end
+
+ return if should_exit
+
+ # more code here
+end
+```
+
+However, there's no issue if you pass in a method proc directly:
+
+```ruby
+def my_method(signal_obj)
+ @signal_obj = signal_obj
+
+ effect &method(:an_effect_method)
+
+ # more code here
+end
+
+def an_effect_method
+ return if @signal_obj.value > 5
+
+ puts @signal_obj.value
+end
+```
+
### `batch { }`
-You can write to multiple signals within a batch, and flush the updates at all once (thereby notifying computed refreshes and effects).
+You can write to multiple signals within a batch, and flush the updates at all once (thereby notifying computed refreshes and effects).
```ruby
+require "signalize"
include Signalize::API
name = signal("Jane")
surname = signal("Doe")
full_name = computed { name.value + " " + surname.value }
# Logs: "Jane Doe"
dispose = effect { puts full_name.value }
batch do
- name.value = "Foo"
- surname.value = "Bar"
+ name.value = "Foo"
+ surname.value = "Bar"
end
```
### `signal.subscribe { }`
You can explicitly subscribe to a signal signal value and be notified on every change. (Essentially the Observable pattern.) In your block, the new signal value will be supplied as an argument.
```ruby
+require "signalize"
include Signalize::API
counter = signal(0)
counter.subscribe do |new_value|
@@ -156,20 +214,21 @@
### `peek`
If you need to access a signal's value inside an effect without subscribing to that signal's updates, use the `peek` method instead of `value`.
```ruby
+require "signalize"
include Signalize::API
counter = signal(0)
effect_count = signal(0)
effect do
- puts counter.value
+ puts counter.value
- # Whenever this effect is triggered, increase `effect_count`.
- # But we don't want this signal to react to `effect_count`
- effect_count.value = effect_count.peek
+ # Whenever this effect is triggered, increase `effect_count`.
+ # But we don't want this signal to react to `effect_count`
+ effect_count.value = effect_count.peek + 1
end
```
## Development