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