简体   繁体   English

REPL 的试剂/原子行为?

[英]reagent/atom behaviour at REPL?

Looking for clarification of behaviour of reagent/atom .寻找对reagent/atom行为的澄清。

This is code from the book Professional Clojure, Chapter 5, with figwheel running:这是来自 Professional Clojure 一书第 5 章的代码,运行 figwheel:

reagent version in deps is 0.8.1 deps 中的试剂版本是 0.8.1

(ns whip.core
    (:require [reagent.core :as reagent :refer [atom]]))

(defonce app-state                                          
  (reagent/atom
    {:projects                
     {"aaa"                   
      {:title "Build Whip"
       :stories
       {1 {:title "Design a data model for projects and stories"    
           :status "done"                                           
           :order 1}                                                
        2 {:title "Create a story title entry form"                 
           :order 2}                                                
        3 {:title "Implement a way to finish stories"
           :order 3}}}}}))

(defn project-board [app-state project-id]                          
  (into [:ul]
    (for [[id {:keys [title]}] (get-in @app-state [:projects project-id :stories])]
      [:li title])))

At the REPL, If I pass deref'd app-state to project-board I get an error:在 REPL 中,如果我将 deref'd app-state传递给 project-board,我会收到一个错误:

dev:whip.core=> (project-board @app-state "aaa")
#object[Error Error: No protocol method IDeref.-deref defined for type cljs.core/PersistentArrayMap: {:projects {"aaa" {:title "Build Whip", :stories {1 {:title "Design a data model for projects and stories", :status "done", :order 1}, 2 {:title "Create a story title entry form", :order 2}, 3 {:title "Implement a way to finish stories", :order 3}}}}}]
   cljs.core/missing-protocol (jar:file:/Users/m/.m2/repository/org/clojure/clojurescript/1.10.520/clojurescript-1.10.520.jar!/cljs/core.cljs:316:4)
   cljs.core/-deref (jar:file:/Users/m/.m2/repository/org/clojure/clojurescript/1.10.520/clojurescript-1.10.520.jar!/cljs/core.cljs:671:1)
   cljs$core$deref (jar:file:/Users/m/.m2/repository/org/clojure/clojurescript/1.10.520/clojurescript-1.10.520.jar!/cljs/core.cljs:1452:4)
   whip.core.project_board_reagentRender (file:/Users/m/clj-pro-clojure/code-and-notes/whip/src/whip/core.cljs:62:3)

But If I pass ordinary var app-state :但是如果我通过普通的 var app-state

dev:whip.core=> (project-board app-state "aaa")
[:ul
 [:li "Design a data model for projects and stories"]
 [:li "Create a story title entry form"]
 [:li "Implement a way to finish stories"]]

If I print out ordinary var app-state at repl it prints out:如果我在 repl 打印出普通的 var app-state ,它会打印出:

dev:whip.core=> app-state
#<Atom: {:projects {"aaa" {:title "Build Whip", :stories {1 {:title "Design a data model for projects and stories", :status "done", :order 1}, 2 {:title "Create a story title entry form", :order 2}, 3 {:title "Implement a way to finish stories", :order 3}}}}}>

If I print out deref'd var app-state at repl it also prints out, but now syntax indented:如果我在 repl 处打印出 deref'd var app-state它也会打印出来,但现在语法缩进了:

dev:whip.core=> @app-state
{:projects
 {"aaa"
  {:title "Build Whip",
   :stories
   {1
    {:title "Design a data model for projects and stories",
     :status "done",
     :order 1},
    2 {:title "Create a story title entry form", :order 2},
    3 {:title "Implement a way to finish stories", :order 3}}}}}

Why does the first case fail?为什么第一种情况会失败? (if something is an atom should I not expect always to deref it?) (如果某物是一个原子,我不应该期望总是取消它吗?)

In the first case you are trying to deref twice, which is why it fails.在第一种情况下,您尝试deref两次,这就是它失败的原因。

(project-board @app-state "aaa")

means that the project-board fn now received a map as an argument, not the atom.意味着project-board fn 现在收到一个映射作为参数,而不是原子。 So the (get-in @app-state ...) fails since maps to not implement the deref protocol.因此(get-in @app-state ...)失败,因为映射未实现deref协议。

No protocol method IDeref.-deref defined for type cljs.core/PersistentArrayMap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM