2016-01-23 2 views
4

Clojure beginner здесь, не уверен, что терминология в вопросе даже правильная.Clojure lazy seq потребление от разных положений в теле функции

Я строю веб-скребок, используя такси api для clj-webdriver. Есть несколько сайтов, которые нужно очистить. Ниже на самом деле не код из проекта, но я проверил его и проверить, что он иллюстрирует мой вопрос:

(def gh-un "my-username") 
(def gh-pw "my-password") 

;; print the first five "starred" alerts from my github feed 
(defn get-info [url] 
    (to url) 
    (click "a[href='/login']") 
    (input-text "input#login_field" gh-un) 
    (input-text "input#password" gh-pw) 
    (click "input.btn") 
    (pprint (map text (take 5 (find-elements {:css "div.alert.watch_started"})))) 
    (click "img.avatar") 
    (click "button.dropdown-signout")) 

(defn github-wrapper [] 
    (map get-info (repeat 3 "http://www.github.com")) 
    (quit)) 

Если я называю (github-wrapper) как есть, окно браузера будет закрыто почти сразу, из-за (quit) звонок. Обертка вызова map с doall, т. Е. (doall (map get-info (repeat 3 "http://www.github.com"))), решает эту проблему, что говорит о том, что проблема в том, что эта карта создает ленивую последовательность, которая не потребляется, и поэтому я не вижу побочных эффектов вызовов get-info.

Однако, если я удалю (quit) звонок в конце get-info, github-wrapper делает то, что я хочу.

Вопрос в том, почему ленивая последовательность потребляется в последнем случае, но не в первом?

+6

Возможно, это потому, что вы используете свой код в REPL, поэтому ваша ленивая последовательность возвращается из 'github-wrapper', а затем оценивается и печатается REPL. –

+0

Я действительно запускал код в REPL. У меня нет этого скрипта, настроенного для запуска из командной строки, но я обязательно проверю это, как только я это сделаю. Спасибо! –

ответ

1

Это потому, что вы, вероятно, печатаете возвращенную карту, когда звоните github-wrapper. Печать ленивой последовательности - это один способ (вместе с doall), чтобы использовать его. Когда вы положили quit в конце github-wrapper, это то, что возвращается, и карта просто предполагает, что ничто не требует своих значений.

Вы также можете использовать mapv вместо map, если хотите, чтобы ваша карта была немедленно реализована.