If you've spent any time working with modern web APIs, Large Language Models (LLMs), or configuration files, you know that JSON is the undisputed king of data interchange. But if your weapon of choice is Tcl, you might have hit a stumbling block: Tcl doesn't have native, built-in JSON parsing capabilities in its core language without pulling in external packages like tcllib.
Even with tcllib, parsing deeply nested JSON or safely constructing complex JSON strings from Tcl variables can sometimes feel clunky. What if there was a way to bypass the complexity by leaning on the power of the Linux shell?
Enter json_shell_utils.tcl—a lightweight, general-purpose Tcl module that elegantly solves this problem by wrapping two incredible command-line tools: jo and jq.
The Problem
Imagine you are writing a Tcl script to interact with an AI API (like Gemini or OpenAI). You need to construct a JSON payload to send, and you need to parse the JSON response you get back.
Trying to manually escape quotes and newlines in bash or Tcl is a recipe for disaster:
tcl# DON'T DO THIS! It breaks if $my_prompt has quotes or newlines.set payload "{\"text\": \"$my_prompt\"}"
Parsing the response manually using regular expressions is even worse.
The Solution
Our new module acts as a bridge between your native Tcl dictionaries and the shell. Let's look at how it works.
1. Creating JSON safely with jo
jo is a small utility that creates JSON objects directly from the shell. It automatically handles type inference and, most importantly, securely escapes all strings.
With json_shell::create, you simply pass a standard Tcl dictionary, and the module uses jo to spit out perfectly formatted, 100% valid JSON:
tclsource "json_shell_utils.tcl"set myData [dict create name "Jane Doe" role "Engineer" active true]set jsonString [json_shell::create $myData]puts $jsonString# Output: {"name":"Jane Doe","role":"Engineer","active":true}
No more string concatenation. No more quote escaping nightmares.
2. Parsing JSON flawlessly with jq
jq is the legendary command-line JSON processor. It's incredibly fast and flexible.
But how do we get jq's output back into a native Tcl dictionary? We use a clever trick with the NULL byte (\u0000). Our module's json_shell::parse function pipes your raw JSON into jq and formats the output so that keys and values are separated by NULL bytes. Tcl then splits this string perfectly into a flat list, which casts directly into a dictionary!
tclset raw_api_response {{"title": "The Quest", "chapters": 5, "author": "John Smith"}}# Parse it directly into a Tcl dict!set parsedDict [json_shell::parse $raw_api_response]puts [dict get $parsedDict "author"]# Output: John Smith
Because it uses the NULL byte delimiter, this method is virtually bulletproof against embedded spaces, newlines, or quotes inside your JSON values.
Why This Matters
By delegating the heavy lifting of serialization and deserialization to jo and jq, json_shell_utils.tcl keeps your Tcl codebase incredibly light, fast, and free of complex third-party dependencies. It allows you to focus on the logic of your scripts rather than fighting with string escaping.
If you're building bots, automating API calls, or just need to wrangle JSON in Tcl on a Linux system, give this approach a try!
No comments:
Post a Comment