Renardo's `Ring` cycles through its elements indefinitely when called, unlike a one-shot list
The Ring class is a cyclic container: each call to ring() returns the next element and wraps back to index 0 after the last. It is instantiated with R[a, b, c] syntax (using RingIndexer). Unlike Pattern, Ring is called imperatively rather than being consumed by the player scheduler. It is useful for cycling through values in event-driven or callback contexts: a function called repeatedly can step through a Ring of states without explicit index management. Ring differs from Pattern primarily in invocation style (call syntax vs. player iteration) and in being mutable via .reset().
Examples
r = R[0, 3, 5, 7] # create a Ring
print(r()) # 0
print(r()) # 3
print(r()) # 5
print(r()) # 7
print(r()) # 0 — wraps
Assessment
When would you use a Ring instead of a Pattern as a source of cycling values? How does Ring.__getitem__ handle indices beyond the length of the data?