{ } jq-lite

Design principles

On this pagePurpose1. Why Lightweight Matters2. A Common Interface for Structured Data3. Design Philosophy4. Type Semantics and Numeric Coercion5. Open and Reproducible Workflows6. Structured Data as Text7. Ecosystem CompatibilitySummaryConclusion8. Internal Query Architecture
このページの目次目的軽量性が重要な理由構造化データの共通インターフェース設計の考え方型の意味論と数値変換開かれた再現可能な作業テキストとしての構造化データ他の道具との連携内部クエリの構造組み込み関数の登録

目的

JQ::Liteは、多様な環境で構造化データを簡単に絞り込み・変換・再利用するための軽量JSONクエリエンジンです。

JSON処理を、どこでも信頼でき、移植しやすく、人間が読みやすいものにすることを目指します。

軽量性が重要な理由

JSONはAPI・サービス連携、監視・テレメトリー、設定・自動化、機械同士の通信に広く使われています。一方、制限された実行環境、古い長期運用システム、最小構成のイメージ、オフライン環境には制約があります。

重い道具が利用できない、または導入しにくい場所でも、小さく依存の少ないJSONプロセッサーを使えるようにします。

構造化データの共通インターフェース

JSONをシステム間の主要なインターフェースとして扱います。

  • JSONを入力しJSONを出力する処理。
  • UNIXパイプラインとの互換性。
  • CLIとライブラリで同じ処理の振る舞いを提供すること。

スクリプト、サービス、自動化ツール、人間の間で構造化データが流れる作業に適しています。CLIの出力書式とLibrary APIの返り値の契約は、それぞれの仕様を参照してください。

設計の考え方

  • 巧妙さより明快さを選ぶ。
  • 性能上の技巧より移植性を重視する。
  • 不要な依存を避ける。
  • バージョンをまたいで予測できる動作を維持する。

流行を追うより、時間と環境を越えて使い続けられる安定した道具を目指します。

型の意味論と数値変換

現在はPerlのスカラーフラグでJSON型を区別します。type()は指数表記を含む実際の数値だけを"number"とし、数値に見える文字列は"string"とします。

算術演算ではPerl形式の数値変換を行い、"1e3" + 1は1001になります。そのため型の分類と算術の動作は完全には揃っていません。

これは明示的な設計上の検討項目です。互換性のため寛容な変換を維持するか、将来の破壊的変更でjqに近い厳密なエラーへ移るかを検討します。

開かれた再現可能な作業

独自のプラットフォームや強く結合した環境への依存を避けます。

  • 完全なオープンソース。
  • ベンダーへの固定をしない。
  • クラウド依存なし。
  • 制限・オフライン環境で使用可能。

データ変換を再現し、調べ、バージョン管理し、監査・共有できるようにします。

テキストとしての構造化データ

インフラ、監視、自動化で構造化データが増えても、テキスト中心の作業は重要です。JSON変換をテキストで表現し、設定や処理をGitで扱いやすくし、自動化ツールやスクリプトへ組み込みやすくします。

処理を見通せて、レビュー・自動化できることを重視します。

他の道具との連携

JSONを生成する処理の後にjq-liteで絞り込み・変換し、その結果をスクリプト、CLI、自動化へ渡します。データの用途を制限せず、抽出と整形を簡単で信頼できるものにします。

観点 重視する内容
範囲 軽量なJSONクエリと変換
方針 移植性・明快さ・長期安定性
利用方法 CLIとライブラリ
環境 オフライン・制限環境・古い環境・現在の環境
継続性 プラットフォームと年月を越えて利用できる設計

内部クエリの構造

処理を以下の順に分離します。

  1. ソーステキスト。
  2. JQ::Lite::Tokenizer:字句解析。
  3. JQ::Lite::Parser:構文解析。
  4. JQ::Lite::AST:抽象構文木。
  5. JQ::Lite::Evaluator:評価。
  6. JQ::Lite::Runtime:実行処理。

Tokenizerはソースの境界を扱い、現在は最上位のフィルター、パイプ、入力終端のトークンを出します。文字列・配列・オブジェクト・括弧内の区切りはフィルタートークン内に残します。この狭い境界により、2.xの動作を変えずに段階的に構文を移せます。

Parserはトークンを検証し、互換性を維持する形へ正規化して型付きのパイプラインASTを作ります。EvaluatorはASTを辿り結果列の伝播を制御します。RuntimeはJSONのデコードと既存の組み込み・探索処理への振り分けを担います。構文判断と最上位の評価ループが混ざるのを防ぐ構成です。

Tokenizer、AST、Evaluator、Runtimeは内部実装で、安定したLibrary APIの対象外です。フィルター内の構文が専用のASTノードへ移るにつれて変更され得ます。公開の入口は引き続きnewとrun_queryです。

JQ::Lite::Valueは3.0評価器の共通の値意味論を担います。真偽値・数値・文字列を混同せずに分類し、複合値の再帰的な等値と全順序を提供します。安定した2.xのフィルター実装はまだこの層を呼ばず、準備作業で2.xの結果が変わるのを防ぎます。

組み込み関数の登録

JQ::Lite::Filtersは式・制御フロー・構築・代入・探索などの言語要素を扱います。組み込みフィルターは、名前の完全一致と引数付き呼び出しのパターンを扱う内部レジストリーJQ::Lite::Builtinで解決します。

内部モジュール 分類
JQ::Lite::Builtin::Array 配列
JQ::Lite::Builtin::Object オブジェクト
JQ::Lite::Builtin::String 文字列
JQ::Lite::Builtin::Math 数値計算
JQ::Lite::Builtin::Aggregate 集計
JQ::Lite::Builtin::Encoding 符号化
JQ::Lite::Builtin::Type 型

分類モジュールは評価器の所有者と現在の入力列を受け取り、構文解析器や最上位のフィルターループに依存せず、逐次処理とエラーの動作を維持します。レジストリーと各分類も内部実装です。新しい関数はFiltersへ分岐を追加するより、該当する最小の分類へ登録してください。

Purpose

JQ::Lite is a lightweight JSON query engine designed to make structured data easy to filter, transform, and reuse across diverse environments.

Its goal is simple:

Make JSON processing reliable, portable, and human-readable — everywhere.


1. Why Lightweight Matters

JSON has become the universal format for:

  • APIs and service integration
  • Observability and telemetry
  • Configuration and automation
  • Machine-to-machine communication

However, many environments still face practical constraints:

  • Limited or restricted runtime environments
  • Legacy or long-lived systems
  • Minimal base images and offline deployments

JQ::Lite is built to operate reliably under these constraints, providing a small, dependency-minimal JSON processor that can be used where heavier tools are unavailable or impractical.


2. A Common Interface for Structured Data

JQ::Lite treats JSON as a first-class interface between systems.

Key design principles:

  • JSON-in / JSON-out processing
  • Compatibility with UNIX pipelines
  • Identical behavior as a CLI tool and as a library

This makes it suitable for workflows where structured data flows between scripts, services, automation tools, and humans.


3. Design Philosophy

JQ::Lite follows a conservative and long-term design approach:

  • Prefer clarity over cleverness
  • Favor portability over performance tricks
  • Avoid unnecessary dependencies
  • Maintain predictable behavior across versions

The goal is not to chase trends, but to provide a stable, dependable utility that continues to work across time and platforms.


4. Type Semantics and Numeric Coercion

jq-lite currently distinguishes JSON types using Perl scalar flags, so type() reports "number" only for true numeric values (including scientific notation) and reports "string" for numeric-looking strings.

Arithmetic operators, however, follow Perl-style numeric coercion and will implicitly coerce numeric-looking strings into numbers (for example, "1e3" + 1 evaluates to 1001). This means type classification and arithmetic behavior are not strictly aligned today.

This behavior is an explicit design discussion item: we may keep the permissive coercion for compatibility, or move toward stricter jq-style runtime errors for string arithmetic in a future breaking change.


5. Open and Reproducible Workflows

Modern data pipelines often depend on proprietary platforms or tightly coupled ecosystems.

JQ::Lite intentionally avoids this:

  • Fully open source
  • No vendor lock-in
  • No cloud dependency
  • Usable in restricted or offline environments

This allows users to build reproducible, inspectable data transformations that can be versioned, audited, and shared.


6. Structured Data as Text

As infrastructure, observability, and automation increasingly rely on structured data, text-based workflows remain essential.

JQ::Lite supports this by enabling:

  • Text-based JSON transformations
  • Git-friendly configuration and processing logic
  • Simple integration with automation systems and scripts

This keeps data processing transparent, reviewable, and automatable.


7. Ecosystem Compatibility

JQ::Lite is designed to integrate naturally with other tools and workflows.

JSON producer
    ↓
jq-lite (filter / transform)
    ↓
script / CLI / automation

The tool does not prescribe how data should be used — it simply ensures that extracting and shaping JSON remains easy and reliable.


Summary

Aspect Focus
Scope Lightweight JSON querying and transformation
Philosophy Portability, clarity, long-term stability
Usage CLI and library
Environment Offline, restricted, legacy, and modern systems
Longevity Designed to remain usable across platforms/years

Conclusion

JQ::Lite aims to be a small, dependable building block in the broader ecosystem of structured data processing.

By keeping JSON handling simple, portable, and transparent, it helps ensure that data remains usable — regardless of environment or scale.


© 2025 Shingo Kawamura

8. Internal Query Architecture

Query execution has an explicit internal pipeline:

source text
    ↓
JQ::Lite::Tokenizer
    ↓
JQ::Lite::Parser
    ↓
JQ::Lite::AST
    ↓
JQ::Lite::Evaluator
    ↓
JQ::Lite::Runtime

The tokenizer owns source boundaries and currently emits top-level filter, pipe, and end-of-input tokens. Delimiters inside strings, arrays, objects, and parenthesized expressions remain within a filter token. This narrow lexer boundary allows syntax to move incrementally without changing 2.x behavior.

The parser validates and compatibility-normalizes those filter tokens and builds a typed pipeline AST. The evaluator only walks AST nodes and controls stream propagation. The runtime owns JSON decoding and dispatch to the existing built-in and traversal implementations. This separation prevents parsing decisions from being mixed into the top-level evaluation loop.

JQ::Lite::Tokenizer, JQ::Lite::AST, JQ::Lite::Evaluator, and JQ::Lite::Runtime are implementation details. They are intentionally outside the stable Library API and may evolve as more filter-local syntax is represented by dedicated AST node types. JQ::Lite->new and run_query remain the public entry points.

JQ::Lite::Value is the shared value-semantics layer for the 3.0 evaluator. It classifies JSON values without conflating booleans, numbers, and strings, and provides recursive jq-style equality and total ordering for compound values. The stable 2.x filter implementation does not call this layer yet; that separation prevents preparatory 3.0 work from changing 2.x results.

Built-in registry

JQ::Lite::Filters owns language constructs such as expressions, control flow, constructors, assignment, and traversal. Built-in filters are resolved through JQ::Lite::Builtin, whose internal registry supports both exact names and parameterized-call patterns. Implementations are grouped by responsibility under JQ::Lite::Builtin::{Array,Object,String,Math,Aggregate,Encoding,Type}. Category modules receive the evaluator owner and current input stream, so they can preserve streaming and error behaviour without depending on the parser or the top-level filter loop.

The registry and all category packages are internal implementation details, like the tokenizer and evaluator layers. New built-ins should be registered in the narrowest applicable category rather than adding another branch to JQ::Lite::Filters.