gv(3perl)
πΈ NAME πΈ
gv_perl β graph manipulation in perl π
okay bestie, welcome to the manual page for gv(3perl), aka the perl extension that lets you do graph stuff. yes, that graph stuff. graphviz. in perl. iconic behavior honestly π¦
β¨ SYNOPSIS β¨
the vibe check, in code:
#!/usr/bin/perl
use gv;
that's it. that's the whole ritual. no cap π
π USAGE π
this section is out here living its best minimalist life β it has no body text of its own. all the actual tea is served in INTRODUCTION and COMMANDS right below, so keep scrolling, bestie, don't stop here π«Ά
π INTRODUCTION π
gv_perl</purl> is a dynamically loaded extension for perl that provides access to the graph facilities of graphviz. literally that's the whole pitch. dynamic loading? we love a flexible queen. π
π COMMANDS π
π New graphs π
New empty graph
graph_handle gv::graph (name);
graph_handle gv::digraph (name);
graph_handle gv::strictgraph (name);
graph_handle gv::strictdigraph (name);
four flavors, pick your fighter. graph, digraph, strictgraph, strictdigraph β all of them hand you back a graph_handle and all of them want a name. π
New graph from a dot-syntax string or file
graph_handle gv::readstring (string);
graph_handle gv::read (string filename);
graph_handle gv::read (channel);
readstring takes a string, read takes either a string filename or a channel. two totally different inputs, one function name, and honestly? we respect the range. π¦
Add new subgraph to existing graph
graph_handle gv::graph (graph_handle, name);
pass in an existing graph_handle plus a name and boom, subgraph. nesting era. π
π New nodes π
Add new node to existing graph
node_handle gv::node (graph_handle, name);
give it a graph_handle and a name, get a node_handle back. the circle of life, but for nodes. β¨
π₯ New edges π₯
Add new edge between existing nodes
edge_handle gv::edge (tail_node_handle, head_node_handle);
two real, already-existing node handles walk in, one edge_handle walks out. π
Add a new edge between an existing tail node, and a named head node which will be induced in the graph if it doesn't already exist
edge_handle gv::edge (tail_node_handle, head_name);
real tail node handle + a head_name. and the tea here is that the named head node gets induced in the graph if it doesn't already exist β it just shows up, uninvited but welcome. π
Add a new edge between an existing head node, and a named tail node which will be induced in the graph if it doesn't already exist
edge_handle gv::edge (tail_name, head_node_handle);
mirror image, same energy: real head node handle + a tail_name, and that named tail node will be induced in the graph if it doesn't already exist. π§
Add a new edge between named tail and head nodes which will be induced in the graph if they don't already exist
edge_handle gv::edge (graph_handle, tail_name, head_name);
now we're doing it with a graph_handle, a tail_name and a head_name, and both named nodes get induced if they don't already exist. manifesting nodes fr fr β
π Setting attribute values π
Set value of named attribute of graph/node/edge β creating attribute if necessary
string gv::setv (graph_handle, attr_name, attr_value);
string gv::setv (node_handle, attr_name, attr_value);
string gv::setv (edge_handle, attr_name, attr_value);
works on a graph_handle, a node_handle or an edge_handle, returns a string, and takes attr_name + attr_value. key detail bestie: it creates the attribute if necessary. it does not ask permission. it simply ships. π
Set value of existing attribute of graph/node/edge (using attribute handle)
string gv::setv (graph_handle, attr_handle, attr_value);
string gv::setv (node_handle, attr_handle, attr_value);
string gv::setv (edge_handle, attr_handle, attr_value);
same three targets, same string return, but this time you're passing an attr_handle instead of a name. note the description says existing attribute β this one isn't out here creating anything new. π
π Getting attribute values π
Get value of named attribute of graph/node/edge
string gv::getv (graph_handle, attr_name);
string gv::getv (node_handle, attr_name);
string gv::getv (edge_handle, attr_name);
three targets, one attr_name, and a string coming back at you. retrieval girlies rise. π«Ά
Get value of attribute of graph/node/edge (using attribute handle)
string gv::getv (graph_handle, attr_handle);
string gv::getv (node_handle, attr_handle);
string gv::getv (edge_handle, attr_handle);
same deal but with an attr_handle. still returning a string. still eating. β¨
π¦ Obtain names from handles π¦
string gv::nameof (graph_handle);
string gv::nameof (node_handle);
string gv::nameof (attr_handle);
hand it a graph_handle, node_handle or attr_handle, and it tells you the string name. "who are you?" "here's who i am." π
π Find handles from names π
graph_handle gv::findsubg (graph_handle, name);
node_handle gv::findnode (graph_handle, name);
edge_handle gv::findedge (tail_node_handle, head_node_handle);
attribute_handle gv::findattr (graph_handle, name);
attribute_handle gv::findattr (node_handle, name);
attribute_handle gv::findattr (edge_handle, name);
the reverse maneuver: findsubg gives a graph_handle, findnode gives a node_handle, findedge gives an edge_handle (from a tail_node_handle and a head_node_handle β no name needed, the nodes themselves are the address), and findattr gives an attribute_handle whether you feed it a graph_handle, a node_handle or an edge_handle. equal opportunity attribute hunting. π
π Misc graph navigators returning handles π
node_handle gv::headof (edge_handle);
node_handle gv::tailof (edge_handle);
graph_handle gv::graphof (graph_handle);
graph_handle gv::graphof (edge_handle);
graph_handle gv::graphof (node_handle);
graph_handle gv::rootof (graph_handle);
headof and tailof each take an edge_handle and give you a node_handle. graphof takes a graph_handle, an edge_handle or a node_handle and gives you a graph_handle. rootof takes a graph_handle and gives you a graph_handle. navigators stay navigating. π§
π Obtain handles of proto node/edge for setting default attribute values π
node_handle gv::protonode (graph_handle);
edge_handle gv::protoedge (graph_handle);
want defaults? get the proto. protonode returns a node_handle, protoedge returns an edge_handle, both from a graph_handle. set your default attribute values on these bad boys. π₯
π Iterators π
Iteration termination tests
bool gv::ok (graph_handle);
bool gv::ok (node_handle);
bool gv::ok (edge_handle);
bool gv::ok (attr_handle);
gv::ok takes any of the four handle types and returns a bool. are we still going? yes or no. that's the whole job. π
Iterate over subgraphs of a graph
graph_handle gv::firstsubg (graph_handle);
graph_handle gv::nextsubg (graph_handle, subgraph_handle);
firstsubg kicks it off, nextsubg keeps it going with a graph_handle and a subgraph_handle. both return a graph_handle. π
Iterate over supergraphs of a graph (obscure and rarely useful)
graph_handle gv::firstsupg (graph_handle);
graph_handle gv::nextsupg (graph_handle, subgraph_handle);
and the original page straight up says these are obscure and rarely useful. not me being honest! but they exist, they take what they take, they return a graph_handle, and you deserve to know. π
Iterate over edges of a graph
edge_handle gv::firstedge (graph_handle);
edge_handle gv::nextedge (graph_handle, edge_handle);
firstedge starts you off from a graph_handle, nextedge moves you along with a graph_handle + edge_handle. both hand back an edge_handle. β¨
Iterate over outedges of a graph
edge_handle gv::firstout (graph_handle);
edge_handle gv::nextout (graph_handle, edge_handle);
out-edges only. firstout from a graph_handle, nextout with graph_handle + edge_handle, both returning an edge_handle. outgoing girlies only. π
Iterate over edges of a node
edge_handle gv::firstedge (node_handle);
edge_handle gv::nextedge (node_handle, edge_handle);
same function names, now node-flavored: firstedge from a node_handle, nextedge with node_handle + edge_handle, returning an edge_handle. π
Iterate over out-edges of a node
edge_handle gv::firstout (node_handle);
edge_handle gv::nextout (node_handle, edge_handle);
firstout from a node_handle, nextout with node_handle + edge_handle, edge_handle out the other side. π₯
Iterate over head nodes reachable from out-edges of a node
node_handle gv::firsthead (node_handle);
node_handle gv::nexthead (node_handle, head_node_handle);
you start at a node_handle, you follow the out-edges, and you land on head nodes. firsthead and nexthead (which wants a node_handle and a head_node_handle) both return a node_handle. π¦
Iterate over in-edges of a graph
edge_handle gv::firstin (graph_handle);
edge_handle gv::nextin (node_handle, edge_handle);
okay so this is exactly what the page says, and i am copying it character for character because that is the rule: firstin takes a graph_handle, and nextin takes a node_handle plus an edge_handle. both return an edge_handle. no edits, no "fixes", that's canon. π (same situation right below, bestie, i'm not the one who wrote it, i'm the one who's faithful to it π)
Iterate over in-edges of a node
edge_handle gv::firstin (node_handle);
edge_handle gv::nextin (graph_handle, edge_handle);
as promised: firstin with a node_handle, nextin with a graph_handle plus an edge_handle, both returning an edge_handle. verbatim, bestie, always. π«Ά
Iterate over tail nodes reachable from in-edges of a node
node_handle gv::firsttail (node_handle);
node_handle gv::nexttail (node_handle, tail_node_handle);
firsttail starts from a node_handle, nexttail takes a node_handle and a tail_node_handle, both give you a node_handle. the mirror of the head situation. β
Iterate over nodes of a graph
node_handle gv::firstnode (graph_handle);
node_handle gv::nextnode (graph_handle, node_handle);
firstnode from a graph_handle, nextnode with graph_handle + node_handle, node_handle returned. π
Iterate over nodes of an edge
node_handle gv::firstnode (edge_handle);
node_handle gv::nextnode (edge_handle, node_handle);
now edge-flavored: firstnode from an edge_handle, nextnode with edge_handle + node_handle, node_handle back. π
Iterate over attributes of a graph
attribute_handle gv::firstattr (graph_handle);
attribute_handle gv::nextattr (graph_handle, attr_handle);
firstattr from a graph_handle, nextattr with graph_handle + attr_handle, attribute_handle returned. π
Iterate over attributes of an edge
attribute_handle gv::firstattr (edge_handle);
attribute_handle gv::nextattr (edge_handle, attr_handle);
firstattr from an edge_handle, nextattr with edge_handle + attr_handle, attribute_handle returned. π₯
Iterate over attributes of a node
attribute_handle gv::firstattr (node_handle);
attribute_handle gv::nextattr (node_handle, attr_handle);
firstattr from a node_handle, nextattr with node_handle + attr_handle, attribute_handle returned. three flavors, one gorgeous pattern. β¨
Remove graph objects
bool gv::rm (graph_handle);
bool gv::rm (node_handle);
bool gv::rm (edge_handle);
gv::rm takes a graph_handle, a node_handle or an edge_handle and returns a bool. bye bestie, love you, blocked. π
β Layout β
Annotate a graph with layout attributes and values using a specific layout engine
bool gv::layout (graph_handle, string engine);
give it a graph_handle and a string engine, get a bool back. this is where your graph gets its whole look. main character makeover arc. π
π§ Render π§
Render a layout into attributes of the graph
bool gv::render (graph_handle);
just the graph_handle, bool returned. the layout goes into the attributes of the graph itself. β¨
Render a layout to stdout
bool gv::render (graph_handle, string format);
add a string format and it goes straight to stdout. yes, straight to your terminal, out loud. π«Ά
Render to an open file
bool gv::render (graph_handle, string format, channel fout);
graph_handle, string format, and a channel fout that's already open. you opened it, you own it. π
Render a layout to an unopened file by name
bool gv::render (graph_handle, string format, string filename);
this time the third argument is a string filename β the file is unopened, and it's found by name. π
Render to a string result
string gv::renderresult (graph_handle ing, string format);
gv::renderresult (graph_handle, string format, string outdata);
okay bestie, graph_handle ing β with the space and the ing β is verbatim from the page. i do not touch the sacred texts, i only decorate them. π
the two-argument form returns a string; the three-argument form takes a graph_handle, a string format and a string outdata, and the page gives it no return type at all. take it up with the page, not with me. π
Render to an open channel
bool gv::renderchannel (graph_handle, string format, string channelname);
graph_handle, string format, string channelname, bool returned. open channel energy. π
Render a layout to a malloc'ed string, to be free'd by the caller
deprecated β too easy to leak memory π
string gv::renderdata (graph_handle, string format);
the page also notes it's still needed for "eval [gv::renderdata $G tk]", so like. it's deprecated but it's still doing shifts. we don't make the rules. β
Writing graph back to file
bool gv::write (graph_handle, string filename);
bool gv::write (graph_handle, channel);
gv::write takes a graph_handle plus either a string filename or a channel, and returns a bool. save your work bestie, i am begging. π«Ά
Graph transformation tools
bool gv::tred (graph_handle);
one graph_handle in, one bool out. transformation era. π¦
π KEYWORDS π
graph, dot, neato, fdp, circo, twopi, perl.
that's the whole page, bestie, and you ate it π
go make some graphs. this was gv(3perl), dated 21 March 2026 β mwah, love you, bye! πβ¨ππ¦
π¦ where this page comes from
- fedora 44: graphviz-perl 14.1.4-2.fc44 Β· epl-1.0 AND cpl-1.0 AND bsd-3-clause AND mit AND gpl-3.0-or-later WITH bison-exception-2.2 AND apache-1.1 AND lgpl-2.0-or-later WITH libtool-exception AND smlnj AND hpnd-uc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms