The /lib/dbug.hoon agent wrapper adds support to view the state of a Gall agent. It is applied to an existing Gall agent as a single drop-in line, %- agent:dbug.
Before we look at the code, let's consider the functionality it exposes. By supplying %- agent:dbug, an associated +dbug generator can be invoked against the agent state.
For instance, using the %azimuth agent, we can expose the current state of the agent:
As we examine this code, there are two particularly interesting aspects:
How /lib/dbug.hoon modifies an agent's arms by adding functionality over the top of them.
How /gen/dbug.hoon utilizes the modified arms with an elegant and simple invocation.
There is also extensive use of tank/tang formatted error messaging.
How the library works
By applying this door builder using %- censig, the ++on-poke and ++on-peek arms can be modified. (In fact, all of the arms can be modified but most of the arms are pass-throughs to the modified agent.)
The ++on-poke arm has several branches added to it after a check to see whether it is being used through the +dbug generator. If it isn't (as determined by the associated mark), then the poke is passed through to the base agent.
The following ?- wuthep handles the input arguments: %state is the most interesting code in this library. The code first checks whether the base agent has a /dbug/state peek endpoint already (in which case it passes it through), otherwise it evaluates the requested Hoon expression against the agent's state (obtained via ++on-save:ag).
%state
=? grab.dbug =('' grab.dbug) '-'
=; product=^vase
[(sell product)]~
=/ state=^vase
:: if the underlying app has implemented a /dbug/state scry endpoint,
:: use that vase in place of +on-save's.
::
=/ result=(each ^vase tang)
(mule |.(q:(need (need (on-peek:ag /x/dbug/state)))))
?:(?=(%& -.result) p.result on-save:ag)
%+ slap
(slop state !>([bowl=bowl ..zuse]))
(ream grab.dbug)
This branch includes the use of a rare =? tiswut conditional leg change and the reversed =/ tisfas, =; tismic. There is also some direct compilation of cords taking place:
The generator explicitly injects the %dbug mark in its return cask ([mark noun]). This is a valid if uncommon operation, and it works here because the mark is never used as a transforming gate but only as a marker to see whether the arms need to pass through the values. The no-argument input is routed through the %state with an empty cord.