I'm having trouble understanding what is wrong with this Raku code.
I want to fetch JSON from a website, and print out a field from each item in an array within the JSON (in this case the titles of latest topics from any Discourse forum).
This is code that I expected to work, but it failed:
use HTTP::UserAgent; use JSON::Tiny; my $client = HTTP::UserAgent.new; $client.timeout = 10; my $url = 'https://meta.discourse.org/latest.json'; my $resp = $client.get($url); my %data = from-json($resp.content); # I think the problem starts here. my @topics = %data<topic_list><topics>; say @topics.WHAT; #=> (Array) for @topics -> $topic { say $topic<fancy_title>; } The error message is from the say $topic<fancy_title> line:
Type Array does not support associative indexing. in block <unit> at http-clients/http.raku line 18 I would have expected that $topic should be written as %topic, because it's an array of hashes, but this doesn't work:
for @topics -> %topic { say %topic<fancy_title>; } The error message for that is:
Type check failed in binding to parameter '%topic'; expected Associative but got Array ([{:archetype("regula...) in block <unit> at http-clients/http.raku line 17 If you inspect the data, it should be a hash, not an array. I tried @array but I know that isn't correct, so I changed %topic to $topic.
I finally got it to work by adding .list to the line that defines @topics but I don't understand why that fixes it, because @topics is an (Array) whether that is added or not.
This is the working code:
use HTTP::UserAgent; use JSON::Tiny; my $client = HTTP::UserAgent.new; $client.timeout = 10; my $url = 'https://meta.discourse.org/latest.json'; my $resp = $client.get($url); my %data = from-json($resp.content); # Adding `.list` here makes it work, but the type doesn't change. # Why is `.list` needed? my @topics = %data<topic_list><topics>.list; say @topics.WHAT; #=> (Array) # Why is it `$topic` instead of `%topic`? for @topics -> $topic { say $topic<fancy_title>; } Does anyone know why it's failing and the correct way to perform this task?
$topicinstead of%topic? , I tried%topicin the same position and got the same result.