Clay Examples
This document contains a number of examples of interacting with Clay using its various tasks. Sections correspond to the general details in the API Reference document.
Most examples will either use |pass to just send a task or the following thread to send a task and take the resulting gift. You can save the following thread to the /ted directory of the %base desk on a fake ship:
send-task-take-gift.hoon
/- spider
/+ strandio
=, strand=strand:spider
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=/ uarg !< (unit task:clay) arg
?~ uarg
(strand-fail:strand %no-arg ~)
=/ =task:clay u.uarg
=/ =card:agent:gall [%pass /foo %arvo %c task]
;< ~ bind:m (send-raw-card:strandio card)
;< res=[wire sign-arvo] bind:m take-sign-arvo:strandio
~& +>:res
(pure:m !>(~))%warp
%warpSee the Read and Subscribe section of the API Reference document for general details.
%sing
%singHere we'll look at reading files by passing Clay a %warp task with a %sing $rave and receiving a %writ gift containing the data in response.
Using the send-task-take-gift.hoon thread, let's try reading gen/hood/hi.hoon:
You should see something like this as the output:
The $cage in the $riot of the %writ contains the file's data due to our use of an %x $care. It needn't be %x though. If we change it to %u, for example, we'll get a ? $cage instead:
Here's a breakdown of the task we sent:

%next
%nextHere we'll look at subscribing to the next version of a file by passing Clay a %warp task with a %next $rave and receiving a %writ gift when the file changes.
Using the send-task-take-gift.hoon thread, let's subscribe to the next version of foo.txt:
Now, in unix, create a file called foo.txt in the root of the $base directory of your ship. In the dojo, hit backspace to disconnect the thread from the dojo prompt and run |commit %base. You should see something like:
As you can see, the $riot in the %writ includes a $cage with the data of /foo/txt due to our use of an %x $care.
Now run the thread again, and this time delete the file in unix and again |commit %base in the dojo. You should see:
You can see the $riot is just ~ due to the file being deleted.
Here's a breakdown of the task we sent:

%mult
%multHere we'll look at subscribing to the next version of multiple files by passing Clay a %warp task with a %mult $rave and receiving a %wris gift when any of the files change.
This thread will subscribe to /foo/txt with an %x $care and /bar/txt with a %u $care. It will print out the %wris it gets back from Clay.
sub-mult.hoon
Save the above to ted/sub-mult.hoon, |commit %base and run with -sub-mult. Now, create foo.txt and bar.txt in your base directory, hit backspace in the dojo to disconnect the thread and run |commit %base. You should see something like:
You'll notice that, unlike a %writ, the %wris doesn't give you the data. It merely tells you the $cares and $paths of the files that changed. If you need to actually get the data, you can just scry or send a request for the files in question.
Now, run the thread again, open bar.txt in an editor, modify its contents, save it and |commit %base. You'll notice you didn't receive a %wris. This is because we subscribed to /bar/txt with %u care and its existence didn't change.
Lastly, delete foo.txt and |commit %base. You should see something like:
As you can see, a relevant change to any of the subscribed files will trigger a response, not just when all of them change.
Here's a breakdown of the task we sent:

%many
%manyHere we'll look at subscribing to a range of changes to a desk by passing Clay a %warp task with a %many $rave and receiving %writ gifts when changes occur.
This thread will subscribe to changes to your %base desk for the next three minutes. The track is %.y so it will only inform you of changes, not send the full $nako. It will only get updates if the specified file exists. It contains a main-loop that will take an arbitrary number of $signs and print them out in the dojo. Since it never ends, you'll need to stop it with the :spider|kill command in the dojo.
sub-many.hoon
Make sure foo.txt doesn't exist in the root of your %base desk. Save this to ted/sub-many.hoon, |commit %base, run it like -sub-many /foo/txt, and hit backspace in the dojo to free up the dojo prompt. Now, add a file called bar.txt to your desk and |commit %base. You should see something like:
Notice you've received no %writ from Clay. This is because /foo/txt doesn't exist. Now, create foo.txt and |commit %base again. You should see:
Now that /foo/txt exists it will inform you of updates. Note that if you delete /foo/txt again it will again stop sending updates.
Now try adding baz.txt:
Now wait until the three minutes is up and try making a change, for example deleting baz.txt:
You can see that along with the normal %writ it's also sent a second %writ with a null $riot to indicate the subscription has ended. This is because it has now passed the end of the range of $cases to which you subscribed.
Run :spider|kill to stop the thread.
Here's a breakdown of the task we sent:

Cancel Subscription
Here we'll look at cancelling a subscription by sending Clay a %warp task with a null (unit rave) in the $riff.
This thread will subscribe to the %next version of /foo/txt, then immediately cancel the subscription and wait for a response to print (which it will never receive).
stop-sub.hoon
Save the above to /ted/stop-sub.hoon, |commit %base, run it with -stop-sub and hit backspace to detach it from the dojo prompt. Now, add foo.txt to the root of your %base desk and |commit %base. You should see:
As you can see we've received no %writ. We can thus conclude the subscription has successfully been cancelled.
Run :spider|kill to stop the thread.
Here's a breakdown of the task we sent:

%info
%infoSee the Write and Modify section of the API Reference document for general details.
%ins
%insHere we'll look at adding a file by sending Clay a %info task containing a %ins $miso.
Let's try adding a foo.txt file with 'foo' as its contents:
If you have a look in the base of your pier you'll see there's now a file called foo.txt with the text foo in it.
We've created the $cage of the content like [%txt !>(~['foo'])], if you want to write something besides a text file you'd just give it the appropriate $mark and $vase.
Here's a breakdown of the task we sent:

%del
%delHere we'll look at deleting a file by sending Clay a %info task containing a %del $miso.
Let's try deleting the foo.txt file created in the previous example:
If you have a look in the base of your pier you'll see the foo.txt file is now gone.
Here's a breakdown of the task we sent:

%mut
%mutIdentical to the %ins example, just replace %ins with %mut.
Multiple Changes
Here we'll look at changing multiple files in one request by sending Clay a %info task containing multiple $miso in the $soba.
Since $soba is just a +list of $miso, you can add a bunch of $miso and they'll all be applied. This thread adds three files and then deletes them. Here there's only one type of $miso in each request but you could mix different types together too.
multi-change.hoon
Save to ted/multi-change.hoon, |commit %base, and run:
Manage Mounts
See the Manage Mounts section of the API Reference document for general details.
%boat
%boatHere we'll look at requesting the list of existing mount points on a ship by sending Clay a %boat task and receiving a %hill gift.
Using the send-task-take-gift.hoon thread, let's make such a request:
%mont
%montHere we'll look at mounting desks, directories and files to unix by sending Clay a %mont task.
Let's first try mounting our %landscape desk:
If you look in your pier, you should now see a /landscape folder which contains the contents of that desk.
If we make a %boat request as detailed in the %boat section, we'll now see the mount point listed:
Note the mount point doesn't need to match a desk, file, or directory. We can also do:
And you'll now see that there's a /wibbly-wobbly folder with the contents of the %base desk. You'll also notice we can mount the same file or directory more than once. There's no problem having %base mounted to both $base and /wibbly-wobbly. The only requirement is that their mount points be unique.
Let's try mounting a subdirectory and a single folder:
If you look in your pier you'll now see a /gen folder with the contents of /gen and a hi.hoon file by itself. Notice how the file extension has been automatically added.
%ogre
%ogreHere we'll look at unmounting desks, directories and files by sending Clay a %ogre task.
Let's unmount what we mounted in the %mont section. First we'll unmount the %landscape desk:
Our custom mount point %wibbly-wobbly:
And the single hi.hoon we previously mounted by specifying its mount point %hi:
If we specify a non-existent mount point it will fail with an error printed to the dojo like:
If we give it an unmounted $beam it will not print an error but still won't work.
%dirk
%dirkHere we'll look at committing changed files by sending Clay a %dirk task.
This task performs the same function as the |commit dojo command.
With your %base desk mounted, try adding a file and send a %dirk to commit the change:
Clay will print the changed files to the dojo with a leading +, - or : to indicate a new file, deleted file and changed file respectively.
If you have the same desk mounted to multiple points, a committed change in one mount will also update the others.
Merge Desks
See the Merge Desks section of the API Reference document for general details.
%merg
%mergHere we'll look at merging desks by sending Clay a %merg task and receiving a %mere gift in response.
First, using the send-task-take-gift.hoon thread, let's try creating a new desk:
Now if we scry for our desks we'll see %foo is there:
Next, we'll create a merge conflict and try a couple of things. Mount %foo with |mount /=foo=, then add a foo.txt to both desks but with different text in each and |commit them.
Now we'll try merging %base into %foo with a %mate strategy:
As you can see, the merge has failed. Let's try again with a %meld strategy:
Now the merge has succeeded and the %mere notes the file with a merge conflict. If we try with a %only-that strategy:
...you can see it's overwritten the /foo/txt in the %foo desk and the %mere now has an empty +set, indicating no merge conflicts.
Next, let's look at subscribing for future changes. Since the $case is specified explicitly in the %merge task, we can set it in the future:
Now change the text in the foo.txt in the %base desk, hit backspace to detach the thread and |commit %base. After the two minutes pass you should see:
You can also specify it by revision number or label.
Permissions
See the Permissions section of the API Reference document for general details.
%perm
%permHere we'll look at setting permissions by sending Clay a %perm task.
First, let's allow ~nes to read /gen/hood/hi/hoon:
...and we'll do a %p scry to see that the permission was set:
You can see that ~nes is now in the read whitelist. Next, let's try a write permission:
You can see ~nes can now write to /ted:
Since we've set it for the whole /ted directory, if we check a file inside it we'll see it also has this permission:
...and you'll notice that src tells us it's inherited the rule from /ted.
Now let's try setting both read and write permissions:
Lastly, let's look at deleting a permission rule we've previously set. To do that, we just send a null (unit rule) in the $rite.
For example, to remove a read permission (or write if you specify %w):
...and to remove both read and write at the same time:
As you can see it's back to the default inherited from /.
Here's a breakdown of a %perm task:

%cred
%credHere we'll look at creating a permission group by sending Clay a %cred task.
Let's create a group called 'foo' with a few ships:
We'll check it with the next kind of task: %crew.
%crew
%crewHere we'll look at retrieving permission groups by sending Clay a %crew task and receiving a %cruz gift in response.
Let's check, using the send-task-take-gift.hoon thread, for the permission group created in the %cred example:
%crow
%crowHere we'll look at retrieving a list of all files and directories in all desks which have permissions set for a group by sending Clay a %crow task and receiving a %croz gift in response.
First we'll set a couple of permissions for the foo group we created in the %cred section:
Notice we use a %.n in the $whom to indicate a group rather than the %.y of a ship.
Now we'll use the send-task-take-gift.hoon thread to try %crow:
Foreign Ships
See the Foreign Ships section of the API Reference document for general details.
%warp - Remote
%warp - RemoteHere we'll look at reading files on a foreign ship by sending Clay a %warp task with a foreign ship in the wer field and receiving a %writ gift in response.
We'll use a fake ~nes as the the foreign ship and a fake ~zod as the local ship.
First we'll set permissions on the foreign ship. Create a file called foo.txt in the %base of ~nes, then send a %perm request to allow ~zod to read and write the file:
If we scry the file for its permissions with a %p $care, we'll see ~zod is now whitelisted:
Back on ~zod: Using the send-task-take-gift.hoon thread, send a %x read request for /foo/txt on ~nes like:
As you can see, we've received a %writ containing the requested data just as we would with a local request. Let's try a %u:
If we send a %d request however, it will crash:
%merg - Remote
%merg - RemoteTo merge a foreign desk into a local one, you just send Clay a %merg task (as you would for a local merge) and specify the foreign ship in the her field. For an example, see the %merg section.
The foreign ship will respond only if correct permissions have been set. See the %perm section for an example.
Last updated