When getting and setting information into the Time State, it’s possible to use more complex keys than basic symbols such as :foo
and :bar
. You can also use URL style strings called paths such as "/foo/bar/baz"
. Once we start working with paths, we can then start taking advantage of Sonic Pi’s sophisticated pattern matching system to get
and sync
with ‘similar’ rather than ‘identical’ paths. Let’s take a look.
Let’s assume we want to wait for the next event that has three path segments:
sync "/*/*/*"
This will match any Time State event with exactly three path segments, regardless of their names. For example:
cue "/foo/bar/baz"
cue "/foo/baz/quux"
cue "/eggs/beans/toast"
cue "/moog/synths/rule"
However, it will not match paths with fewer or more path segments. The following will not match:
cue "/foo/bar"
cue "/foo/baz/quux/quaax"
cue "/eggs"
Each *
means any content. So we could match paths with just one segment with /*
or paths with five segments with /*/*/*/*/*
If we know what the segment is going to start or finish with, we can use a *
in addition to a partial segment name. For example: "/foo/b*/baz"
will match any path that has three segments, the first of which is foo
, the last baz
and the middle segment can be anything that starts with b
. So, it would match:
cue "/foo/bar/baz"
cue "/foo/baz/baz"
cue "/foo/beans/baz"
However, it wouldn’t match the following:
cue "/foo/flibble/baz"
cue "/foo/abaz/baz"
cue "/foo/beans/baz/eggs"
You can also place the *
at the start of the segment to specify the last characters of a segment: "/foo/*zz/baz"
which will match any 3 segment cue
or set
where the first segment is foo
, the last is baz
and the middle segment ends with zz
such as "cue "/foo/whizz/baz"
.
Sometimes you don’t know how many path segments you want to match. In these cases you can use the powerful double star: **
such as "/foo/**/baz"
which will match:
cue "/foo/bar/baz"
cue "/foo/bar/beans/baz"
cue "/foo/baz"
cue "/foo/a/b/c/d/e/f/baz"
You can use the ?
character to match against a single char such as "/?oo/bar/baz"
which will match:
cue "/foo/bar/baz"
cue "/goo/bar/baz"
cue "/too/bar/baz"
cue "/woo/bar/baz"
If you know that a segment may be one of a select number of words, you can use the {
and }
matchers to specify a list of choices such as "/foo/{bar,beans,eggs}/quux"
which will only match the following:
cue "/foo/bar/quux"
cue "/foo/beans/quux"
cue "/foo/eggs/quux"
Finally, you can match against a selection of letters if you use the [
and ]
matchers to specify a list of choices such as "/foo/[abc]ux/baz"
which will match only:
cue "/foo/aux/baz"
cue "/foo/bux/baz"
cue "/foo/cux/baz"
You can also use the -
character to specify ranges of letters. For example "/foo/[a-e]ux/baz"
which will match only:
cue "/foo/aux/baz"
cue "/foo/bux/baz"
cue "/foo/cux/baz"
cue "/foo/dux/baz"
cue "/foo/eux/baz"
When calling sync
or get
you are free to combine matchers in any order you see fit to powerfully match any Time State event created by cue
or set
. Let’s look at a crazy example:
in_thread do
sync "/?oo/[a-z]*/**/ba*/{quux,quaax}/"
sample :loop_amen
end
sleep 1
cue "/foo/beans/a/b/c/d/e/bark/quux/"
For those curious, these matching rules are based on the Open Sound Control pattern matching specification which is explained in detail here: http://opensoundcontrol.org/spec-1_0