length() returning 0 for Dynamic object with keys #202

Closed
opened 2025-12-30 01:22:05 +01:00 by adam · 2 comments
Owner

Originally created by @fhalde on GitHub (Sep 10, 2024).

Pkl 0.26.0 (macOS 13.6.6, native)

I have the following json file

cat source.json
{ "topic": "hello" }

and the following pkl file

cat p.pkl
import "pkl:json"

hidden f = read?("file:./source.json") ?? "{}"
hidden p = new json.Parser {}.parse(f)

a = trace(p)
b = trace(p.length())

the output of the trace is

pkl eval p.pkl
pkl: TRACE: p = new Dynamic { topic = "hello" }
pkl: TRACE: p.length() = 0
a {
  topic = "hello"
}
b = 0

What could be going on?
The documentation of length() in Dynamic states

function length(): Int
Returns the number of elements in this object.

Originally created by @fhalde on GitHub (Sep 10, 2024). ``` Pkl 0.26.0 (macOS 13.6.6, native) ``` I have the following json file ``` cat source.json { "topic": "hello" } ``` and the following pkl file ``` cat p.pkl import "pkl:json" hidden f = read?("file:./source.json") ?? "{}" hidden p = new json.Parser {}.parse(f) a = trace(p) b = trace(p.length()) ``` the output of the trace is ``` pkl eval p.pkl pkl: TRACE: p = new Dynamic { topic = "hello" } pkl: TRACE: p.length() = 0 a { topic = "hello" } b = 0 ``` What could be going on? The documentation of length() in Dynamic states > function length(): [Int](https://pkl-lang.org/package-docs/pkl/0.26.3/base/Int.html) Returns the number of elements in this object.
adam closed this issue 2025-12-30 01:22:05 +01:00
Author
Owner

@bioball commented on GitHub (Sep 10, 2024):

Pkl has three types of object members: properties, elements, and entries (see explanation here).

Dynamic.length, as you pointed out, will count the number of elements, and your object there has a property and no elements.

Try parsing into Mapping instead of Dynamic. This will parse JSON objects as Mapping, where Mapping#length counts the number of entries (note, this isn't the same thing as properties). Parsing into Dynamic also has some other issues; for example, it hides any JSON properties called "default".

 import "pkl:json"
 
 hidden f = read?("file:./source.json") ?? "{}"
-hidden p = new json.Parser {}.parse(f)
+hidden p = new json.Parser { useMapping = true }.parse(f)

a = trace(p)
b = trace(p.length())
@bioball commented on GitHub (Sep 10, 2024): Pkl has three types of object members: properties, elements, and entries (see explanation [here](https://pkl-lang.org/main/current/language-tutorial/01_basic_config.html#structure-classes-objects-modules)). `Dynamic.length`, as you pointed out, will count the number of elements, and your object there has a _property_ and no _elements_. Try parsing into `Mapping` instead of `Dynamic`. This will parse JSON objects as `Mapping`, where `Mapping#length` counts the number of _entries_ (note, this isn't the same thing as properties). Parsing into `Dynamic` also has some other issues; for example, it hides any JSON properties called "default". ```diff import "pkl:json" hidden f = read?("file:./source.json") ?? "{}" -hidden p = new json.Parser {}.parse(f) +hidden p = new json.Parser { useMapping = true }.parse(f) a = trace(p) b = trace(p.length()) ```
Author
Owner

@fhalde commented on GitHub (Sep 10, 2024):

this worked ! thank you :)

@fhalde commented on GitHub (Sep 10, 2024): this worked ! thank you :)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/pkl#202