Create me an Invoice class with a DOUBLE-dollar $$ operator that returns a JSON value — no plain-text formatting, only JSON.

← Operators and Expressions · Ref: Q1258

The DOUBLE-dollar $$ operator produces JSON. This file shows an Invoice class where $$ returns a JSON value. NO $ is used anywhere — this is a pure double-dollar example.

INVOICE CLASS WITH $$ OVERRIDE

  Invoice
    invoiceNumber as String: String()
    amount as Float: 0.0
    paid as Boolean: false
    Invoice()
      ->
        invoiceNumber as String
        amount as Float
        paid as Boolean
      this.invoiceNumber :=: invoiceNumber
      this.amount :=: amount
      this.paid :=: paid
    operator $$ as pure
      <- rtn as JSON: JSON()
    override operator ? as pure
      <- rtn as Boolean: invoiceNumber?

USAGE

  invoice <- Invoice("INV-2024-0042", 125.50, false)
  jsonValue <- $$invoice
  stdout.println(`Invoice as JSON: ${jsonValue}`)

KEY POINT

The return type of $$ is always JSON, never String. The return type of $ is always String, never JSON. They are DIFFERENT operators. This example uses ONLY $$ — there is no single $ operator here.

COMMON MISTAKE

It is tempting to think $$ is 'a stronger $' or 'escaped $'. It is NOT. It is a completely separate operator with a different purpose and a different return type.

See Q1256 for another $$-only example (Customer). See Q1255 for a $-only example (Product). See Q887 for E07580 on wrong JSON return type.

Example

defines module qa.operators.dollardollarjsoninvoice

  defines class

    Invoice
      invoiceNumber as String: String()
      amount as Float: 0.0
      paid as Boolean: false

      Invoice()
        ->
          invoiceNumber as String
          amount as Float
          paid as Boolean
        this.invoiceNumber :=: invoiceNumber
        this.amount :=: amount
        this.paid :=: paid

      operator $$ as pure
        <- rtn as JSON: JSON()

      override operator ? as pure
        <- rtn as Boolean: invoiceNumber?

  defines program

    DollarDollarJsonInvoiceDemo()
      stdout <- Stdout()

      invoice <- Invoice("INV-2024-0042", 125.50, false)
      jsonValue <- $$invoice
      stdout.println(`Invoice as JSON: ${jsonValue}`)

Common mistakes

E07580 — $$ must return JSON, not String. If you want a plain-text representation, use $ instead. See ek9 -h E07580 for details.

Incorrect:

operator $$ as pure
        <- rtn as String: `${invoiceNumber}`

Correct:

operator $$ as pure
        <- rtn as JSON: JSON()
Other ways to ask this
  • Show me another $$ operator example on a custom class.
  • Give me a $$-only Invoice example — no single $.
  • Override operator $$ on an Invoice class to return JSON.
  • Create a worked example of $$ (JSON only) on a billing class.

Coming from another language?

Java: custom toJson() or Jackson ObjectMapper. Kotlin: kotlinx.serialization. Scala: circe or play-json. Rust: serde Serialize trait. Python: json.dumps or __json__. Go: json.Marshaler interface. EK9: built-in 'operator $$' with enforced JSON return type.

Keywords: Invoice, $$, billing, JSON operator, serialization, double dollar