Проблемы с использованием hashq-get-handle в Guile

У меня возникли проблемы с получением значения, связанного с ключом в хеш-таблице, и я совершенно не понимаю, что я делаю неправильно. Код, который я использую, показан ниже:

(use-modules (curl))
(use-modules (json))

;; use curl to hit the site's api to get results of query as json:                                                                   
(define handle (curl-easy-init))
(curl-easy-setopt handle 'url
              "http://api.data.gov:80/regulations/v3/documents.json?api_key=mySecKey&countsOnly=0&encoded=1&dktid=EPA-HQ-OAR-2013-0602&dkt=R&cp=C&rpp=25&po=0")
(define s (curl-easy-perform handle))

;; parse the json in the string into guile scheme:                                                                                   
(define queryResults (json-string->scm s))

;; use this to see the keys and values in the resulting hash table:                                                                  
(define print-hash (lambda (my-hash)
                     (hash-for-each (lambda (key value)
                                      (format #t "~a => ~a~%" key value))
                                    my-hash)))

;; now let's take a look at the keys and values:                                                                                     
(print-hash queryResults)

;; now let's get the value associated with the documents key:                                                                        
(hashq-get-handle queryResults 'documents)

Он основан на guile-curl и guile-json для связи с веб-сервером и анализа ответа. Все кажется довольно простым, пока я не побегу. Я вижу ответ сервера в формате json (очень длинный и не опубликованный здесь) и изнутри Emacs (используя geiser для поиска) я вижу:

scheme@(guile-user)> (hash-table? queryResults)
$25 = #t

поэтому я знаю, что queryResults действительно является хэш-таблицей. Когда я смотрю на ключи и связанные значения с помощью print-hash, я вижу, что:

scheme@(guile-user)> (print-hash queryResults)
totalNumRecords => 23318
documents => (#<hash-table 2ad7c60 17/31> #<hash-table 2afdbc0 17/31> #<hash-table 2b0ab60 17/31> #<hash-table 2b0eb00 17/31> #<hash-table 2b10aa0 17/31> #<hash-table 2b13a40 17/31> #<hash-table 2b189e0 17/31> #<hash-table 2b1b980 17/31> #<hash-table 2b1e920 17/31> #<hash-table 2b228c0 17/31> #<hash-table 2b25860 17/31> #<hash-table 2b29800 17/31> #<hash-table 2b2d7a0 17/31> #<hash-table 2b30740 17/31> #<hash-table 2b336e0 17/31> #<hash-table 2b38680 17/31> #<hash-table 2b3b620 17/31> #<hash-table 2b3f5c0 17/31> #<hash-table 2b44560 17/31> #<hash-table 2b48500 17/31> #<hash-table 2b4c4a0 17/31> #<hash-table 2b50440 17/31> #<hash-table 2b533e0 17/31> #<hash-table 2b57380 17/31> #<hash-table 2b5c320 17/31>)

так что это хорошо, и это то, что я ожидал. Но когда я пытаюсь использовать hashq-get-handle, чтобы посмотреть значение для totalNumRecords или документов, я получаю:

scheme@(guile-user)> (hashq-get-handle queryResults 'totalNumRecords)
$24 = #f

scheme@(guile-user)> (hashq-get-handle queryResults 'documents)
$24 = #f

что, по-видимому, указывает на то, что ключ не существует в хеш-таблице queryResults. Я пробовал всю ночь с кавычками, без кавычек, возился с реализациями хэш-таблиц SRFI-69 (во время которых я обнаружил разницу между нативными хэш-таблицами хитрости и хэш-таблицами SRFI-69) и прошел через примеры хеш-таблиц в справочном руководстве guile (все они работали нормально). У меня нет идей.

Если бы кто-нибудь помог мне понять, почему мои вызовы hashq-get-handle не работают должным образом, я был бы очень признателен.

ОБНОВЛЕНИЕ: следуя предложению ttn из списка рассылки guile-user:

scheme@(guile-user)> (hash-get-handle queryResults 'totalNumRecords)
$27 = #f
scheme@(guile-user)> (hashv-get-handle queryResults 'totalNumRecords)
$28 = #f

Так вроде результат тот же. Нет любви.


person unclejamil    schedule 07.12.2014    source источник
comment
Я обновляю комментарии из обсуждения в списке рассылки [email protected]: (от ttn): IIUC, объект хэш-таблицы 'queryResults' создан: github.com/aconchillo/guile-json/blob/master/json/parser.scm proc 'read -объект'. Для взаимодействия с «make-hash-table», который он вызывает, вы можете попробовать некоторые варианты «hashq-get-handle», а именно «hash-get-handle» или «hashv-get-handle».   -  person unclejamil    schedule 08.12.2014


Ответы (1)


Это обсуждение в списке рассылки guile-user (как от Thien-Thi Nguyen, так и от Mark H Weaver) дал решение, обобщенное здесь:

Основываясь на беглом взгляде на код json, я подозреваю, что вы хотите этого:

(hash-get-handle queryResults "документы")

т. е. измените «hashq-get-handle» на «hash-get-handle» и передайте строку в качестве ключа, а не символ.

Что в итоге получается:

scheme@(guile-user)> (hash-get-handle queryResults "documents")
$29 = ("documents" #<hash-table 297f820 17/31> #<hash-table 2982700
17/31> #<hash-table 29896a0 17/31> #<hash-table 298f640 17/31> #\
<hash-table 29915e0 17/31> #<hash-table 299d580 17/31> #<hash-table
29a1520 17/31> #<hash-table 29a34c0 17/31> #<hash-table 29a6460 \
17/31> #<hash-table 29f7400 17/31> #<hash-table 29fd3a0 17/31>
#<hash-table 2a08340 17/31> #<hash-table 2a1c2e0 17/31> #<hash-table \
2a4b280 17/31> #<hash-table 2a96220 17/31> #<hash-table 2aa31c0 17/31>
#<hash-table 2aa5160 17/31> #<hash-table 2aaa100 17/31> #<has\
h-table 2ab10a0 17/31> #<hash-table 2abb040 17/31> #<hash-table
2accfe0 17/31> #<hash-table 2acef80 17/31> #<hash-table 2ad1f20 17/3\
1> #<hash-table 2af1ec0 17/31> #<hash-table 2af4e60 17/31>)

И еще одно предложение Марка, которое имеет смысл:

Если вы используете «~s» вместо «~a» в «print-hash», будет ясно, являются ли ключи строками или символами, потому что строки будут напечатаны в двойных кавычках.

person unclejamil    schedule 08.12.2014