Регистрация | Войти
Lisp — программируемый язык программирования
RSS
странное поведение хеш-таблицы
anaumov - 05.12.2016 00:44, Сообщений - 10
Всем привет.
Подскажите пожалуйста почему последняя строка выдает NIL?

(defun cmd (param)
  (setf hash (make-hash-table))
  (dolist (p param)
    (if (member (concatenate 'string "-" (subseq p 0 1)) sb-ext:*posix-argv* :test #'equal)
      (setf (gethash p hash)
        (nth (+ (position (concatenate 'string "-" (subseq p 0 1)) sb-ext:*posix-argv* :test #'equal) 1) sb-ext:*posix-argv*)
)

      (format t "ERROR: no ~A parameter set" (concatenate 'string "-" (subseq p 0 1)))
)
)

  hash
)



(setf hash-cmd (cmd (list "HOST" "USERNAME" "PASSWORD")))

(maphash #'(lambda (key value) (format t "~A = ~A~%" key value)) hash-cmd)

(format t "~A~%" (gethash 'HOST hash-cmd))

На предпоследней строке я проверяю пары ключ-значение, и sbcl показывает, что по ключу HOST явно есть значение. Запускаю таким вот образом:

> ./test.lsp -H 127.0.0.1 -P aaaaa -U alex

HOST = 127.0.0.1
USERNAME = alex
PASSWORD = aaaaa
NIL
[#]
>Подскажите пожалуйста почему последняя строка выдает NIL?

Хеш-таблица здесь не причём. Сравни вывод

(format t "asd")

и

(format nil "asd")
zh17 - 05.12.2016 13:54
[#] Ответ на комментарий от zh17 05.12.2016 13:54
Этот параметр указыват куда слать вывод: t - стандартный вывод, nil соответственно никуда. Но причем тут это? Разве у меня есть хоть одна функция format с nil?
anaumov - 05.12.2016 14:13
[#]
> Подскажите пожалуйста почему последняя строка выдает NIL?

format печатет данные и возвращает nil. Поскольку это последняя форма, то её результат и печатается как результат выполнения.

Если хочешь от этого избавиться, то добавь в конец форму (values)

archimag - 05.12.2016 15:10
[#] Ответ на комментарий от archimag 05.12.2016 15:10

(defun cmd (param)
  (setf hash (make-hash-table))
  (dolist (p param)
    (if (member (concatenate 'string "-" (subseq p 0 1)) sb-ext:*posix-argv* :test #'equal)
      (setf (gethash p hash)
        (nth (+ (position (concatenate 'string "-" (subseq p 0 1)) sb-ext:*posix-argv* :test #'equal) 1) sb-ext:*posix-argv*)
)

      (format t "ERROR: no ~A parameter set" (concatenate 'string "-" (subseq p 0 1)))
)
)

  hash
)



(setf hash-cmd (cmd (list "HOST" "USERNAME" "PASSWORD")))

(maphash #'(lambda (key value) (format t "~A = ~A~%" key value)) hash-cmd)

(format t "~A~%" (gethash 'HOST hash-cmd))



(setf hash-aaa (make-hash-table))
(setf (gethash 'aaa hash-aaa) '111)
(format t "~A~%" (gethash 'aaa hash-aaa))
Добавил в конец еще одну хеш таблицу с точно таким же запросом и выводом format. Теперь вывод выглядит вот так:

./test.lsp -H 127.0.0.1 -P aaaaa -U alex

HOST = 127.0.0.1
USERNAME = alex
PASSWORD = aaaaa
NIL
111


Как видете, последний вывод format выдает не nil, а реальное значение. А вот предпоследний по-прежнему nil.
anaumov - 05.12.2016 15:17
[#] Ответ на комментарий от anaumov 05.12.2016 15:17
> Как видете, последний вывод format выдает не nil, а реальное значение. 

Не вижу. Это всего лишь сочетание двух систем вывода, одна от format, другая как результат вычисления формы. В одном случае, вероятно, вывод буферизоцанный, а в другом нет, вот и происходит смешение.  В описании format ясно сказано:  

result---if destination is non-nil, then nil; otherwise, a string.
archimag - 05.12.2016 15:31
[#] Ответ на комментарий от archimag 05.12.2016 15:31
Как я понял, вопрос не в том, почему там nil выдается, а почему не находится значение в hash-table.
Hedin - 05.12.2016 16:20
[#]
Судя по всему, из-за несоответствия типов. В хеш-таблицу кладется строка, а ищется символ. У меня поиск по строке вообще не сработал, даже если такая строка лежит в таблице.
Hedin - 05.12.2016 16:23
[#] Ответ на комментарий от Hedin 05.12.2016 16:23
Для того, чтобы использовать строку в качестве ключа, надо при создании хеш-таблицы указать :test 'equal. Т.е. создавать так (make-hash-table :test 'equal). И потом искать не 'HOST, а "HOST".
Hedin - 05.12.2016 16:26
[#] Ответ на комментарий от Hedin 05.12.2016 16:26
Hedin
Большое спасибо! Теперь заработало. Я догдывался, что что-то не так с типом данных, но не мог сообразить что именно :)
anaumov - 05.12.2016 20:18
[#] Ответ на комментарий от zh17 05.12.2016 13:54
Увы мне, увы. Не обратил внимание на строку запуска. посыпаю голову пеплом. :(

В своё оправдание: Я и представить себе не мог, что разумный человек, пишущий на лиспе, игнорирует отладочные возможности РЕПЛа. Пишущий на лиспе... Не в нотепаде ли, часом?
zh17 - 05.12.2016 20:40
@2009-2013 lisper.ru