MergedObservable¶
Observables that combine multiple values using the merge operator (+).
FynX MergedObservable - Combined Reactive Values¶
MergedObservable combines multiple observables into a single reactive tuple that updates when any component changes. Like coordinate pairs where both x and y must be known together, merged observables treat multiple related values as a single atomic unit. Change any component, and the entire tuple updates automatically.
MergedObservable creates a read-only computed observable whose value is a tuple containing the current values of all source observables. When any source observable changes, the merged observable automatically recalculates its tuple value and notifies all subscribers. That automatic coordination eliminates manual synchronization—you declare the relationship, and the framework maintains it.
The merge operation uses the + operator between observables. That syntax creates a new MergedObservable containing both values as a tuple:
from fynx import observable
width = observable(10)
height = observable(20)
dimensions = width + height # Creates MergedObservable
print(dimensions.value) # (10, 20)
width.set(15)
print(dimensions.value) # (15, 20)
# Merged observables are read-only
dimensions.set((5, 5)) # Raises ValueError: Computed observables are read-only and cannot be set directly
Result: multiple reactive values that behave as a single atomic unit, updating automatically when any component changes. That pattern enables functions that need multiple related parameters, computed values that depend on several inputs, and coordinated state updates across multiple variables.
MergedObservable ¶
A computed observable that combines multiple observables into a single reactive tuple.
MergedObservable combines multiple observables into a single reactive tuple that updates when any component changes. Change any source value, and the entire tuple recalculates automatically. This enables treating multiple related values as a single atomic unit.
The merged observable creates a read-only computed observable whose value is a tuple containing the current values of all source observables. When any source observable changes, the merged observable automatically recalculates its tuple value and notifies all subscribers. That automatic coordination eliminates manual synchronization—you declare the relationship, and the framework maintains it.
As a computed observable, MergedObservable is read-only and cannot be set directly. Its value always derives from its source observables, ensuring consistency. That constraint prevents breaking reactive relationships—if you could set a merged value, it would diverge from its sources.
This enables treating multiple related reactive values as a single atomic unit. Functions that need multiple related parameters can receive the tuple directly. Computed values that depend on several inputs can derive from the merged observable. Coordinated state updates across multiple variables happen automatically when any component changes.
Example
from fynx import observable
# Individual observables
x = observable(10)
y = observable(20)
# Merge them into a single reactive unit
point = x + y
print(point.value) # (10, 20)
# Computed values can work with the tuple
distance_from_origin = point.then(
lambda px, py: (px**2 + py**2)**0.5
)
print(distance_from_origin.value) # 22.360679774997898
# Changes to either coordinate update everything
x.set(15)
print(point.value) # (15, 20)
print(distance_from_origin.value) # 25.0
The merged observable's value is always a tuple, even when merging just two observables. That consistency provides a uniform interface for computed functions—they always receive a tuple, regardless of how many observables were merged.
See Also
ComputedObservable: Base computed observable class
operator: For creating derived values from merged observables
Create a merged observable from multiple source observables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*observables
|
Observable
|
Variable number of Observable instances to combine. At least one observable must be provided. |
()
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If no observables are provided |
value ¶
Get the current tuple value, using cache when possible.
Returns the current values of all source observables as a tuple. Uses caching to avoid recomputing the tuple on every access.
Returns:
| Type | Description |
|---|---|
|
A tuple containing the current values of all source observables, |
|
|
in the order they were provided to the constructor. |
__add__ ¶
Chain merging with another observable using the + operator.
Enables fluent syntax for building up merged observables incrementally. Each + operation creates a new MergedObservable containing all previous observables plus the new one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
Observable
|
Another Observable to merge with this merged observable |
required |
Returns:
| Type | Description |
|---|---|
MergedObservable
|
A new MergedObservable containing all source observables from this |
MergedObservable
|
merged observable plus the additional observable. |
__enter__ ¶
Context manager entry for reactive blocks.
Enables experimental syntax for defining reactive blocks that execute whenever any of the merged observables change.
Returns:
| Type | Description |
|---|---|
|
A context object that can be called with a function to create reactive behavior. |
Example
Note
This is an experimental feature. The more common approach is to use subscribe() or the @reactive decorator.
__exit__ ¶
Context manager exit.
Currently does nothing, but allows the context manager to work properly.
subscribe ¶
Subscribe a function to react to changes in any of the merged observables.
The subscribed function will be called whenever any source observable changes. This provides a way to react to coordinated changes across multiple observables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable
|
A callable that will receive the current values of all merged observables as separate arguments, in the order they were merged. The function signature should match the number of merged observables. |
required |
Returns:
| Type | Description |
|---|---|
MergedObservable[T]
|
This merged observable instance for method chaining. |
Examples:
from fynx import observable
x = observable(1)
y = observable(2)
coords = x + y
def on_coords_change(x_val, y_val):
print(f"Coordinates: ({x_val}, {y_val})")
coords.subscribe(on_coords_change)
x.set(10) # Prints: "Coordinates: (10, 2)"
y.set(20) # Prints: "Coordinates: (10, 20)"
The function is called only when observables change. It is not called immediately upon subscription—that behavior differs from some reactive frameworks, but ensures that subscriptions don't trigger unnecessary initial executions.
See Also
unsubscribe: Remove a subscription reactive: Decorator-based reactive functions
unsubscribe ¶
Unsubscribe a function from this merged observable.
Removes the subscription for the specified function, preventing it from being called when the merged observable changes. This properly cleans up the reactive context and removes all observers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable
|
The function that was previously subscribed to this merged observable. Must be the same function object that was passed to subscribe(). |
required |
Examples:
from fynx import observable
x = observable(1)
y = observable(2)
def handler(x, y):
print(f"Changed: {x}, {y}")
coords = x + y
coords.subscribe(handler)
# Later, unsubscribe
coords.unsubscribe(handler) # No longer called when coords change
This only removes subscriptions to this specific merged observable. If the same function is subscribed to other observables, those subscriptions remain active. That selective removal enables fine-grained control over reactive behavior—you can unsubscribe from specific merged observables without affecting other subscriptions.
See Also
subscribe: Add a subscription