>
> Why does `alter-var-root` here seem to succeed, but have no effect?


What you want is:

(set! *print-level* 2)

But, this will not work 100% of the time, and sometimes you might want 
alter-var-root.

Here's the trick. *print-level* is a dynamic Var. Alter-var-root only 
changes the root value of a Var, it can not change a dynamically binded 
value:

(def ^:dynamic x "I am root!")
x ; => "I am root!"
(binding [x "I am dynamically binded!"] x) ; => "I am dynamically binded!"
(alter-var-root #'x (constantly "I've had my root altered!"))
x ; => "I've had my root altered!"
(binding [x "I am dynamically binded!"] x) ; => "I am dynamically binded!"

So where is *print-level* binded you ask? Well, that depends on how you 
bootstrapped Clojure. Most of the time, such as when using lein, or 
clojure.main, those things will wrap your entire code in a binding, and 
they will bind a certain number of default dynamic var such as 
*print-level*. You can see the code for clojure.main here: 
https://github.com/clojure/clojure/blob/master/src/clj/clojure/main.clj#L76

So in your case, you're probably bootstrapping Clojure using a mechanism 
that binds *print-level*, thus changing its root has no effect in your 
code, you have to change its binding, and the function to do that is set!.

On Monday, 24 July 2017 07:12:05 UTC-7, Rob Nikander wrote:
>
> I think in my case here the easiest thing will be to remove the cycles, 
> but still I'd like to understand a couple things...
>
> On Sunday, July 23, 2017 at 10:12:46 PM UTC-4, Didier wrote:
>>
>> I'm not sure I can fully help without you explaining more what you're 
>> doing. It sounds like you've got a collection or container type which has 
>> an implementation of print that loops over its elements, and calls print on 
>> them. So if you have a cycle, the print will go on forever until memory 
>> runs out.
>>
>
> My container type (the tree node) is simply the standard clojure map. 
>
> If you're using a standard type, you might be able to limit *print-level* 
>> <https://clojuredocs.org/clojure.core/*print-level*>. Most Clojure 
>> collections will limit how deep they print based on the value of this 
>> global dynamic Var.
>>
>
> Okay, *print-level* works but it looks like I have to call print myself. I 
> can't rely on the REPL to print it. 
>
>     (binding [*print-level* 2] (println (find-route "/reports")))   ; okay
>
> Why does `alter-var-root` here seem to succeed, but have no effect?
>
>     (alter-var-root #'*print-level* (constantly 2))
>     => 2
>     *print-level*
>     => nil
>     (find-route "/reports")
>     stack overflow
>
>  
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to