Re: How to make a static variable dynamic at runtime?

2015-07-22 Thread Yuri Govorushchenko
Hello Alexander, Marc,

Ah, now I get this. Thank you for your responses!

вторник, 21 июля 2015 г., 17:54:42 UTC+3 пользователь Yuri Govorushchenko 
написал:

 The problem I'm trying to solve is how to stub a variable (e.g. a function 
 from a third-party lib) in tests so that the stubbing occurs only in the 
 current thread with other threads continuing using var's root value. It's 
 important because unit tests may be run in parallel. Without thread-local 
 binding two threads stubbing the same function will lead to race conditions:

 (binding [somelib/foo foo-stub] ; throws java.lang.IllegalStateException: 
 Can't dynamically bind non-dynamic var
   ; invoke tested code which depends on foo
   ; assert stuff
   )

 I've tried to use *.setDynamic* (as described in blog post [1]) but it 
 doesn't work without direct *deref*-ing of the var:

 (def static-var 123)
 (defn quz[]
   (.setDynamic #'static-var true)
   (binding [static-var 1000]
 (println static-var = static-var deref = @#'static-var)))

 (quz) ; = static-var = 123 deref = 1000

 This approach seems to be used in a recent *bolth* lib [2]. And The 
 strange thing is that in REPL running this code line by line works:

 user= (def static-var 123)
 #'user/static-var
 user= (.setDynamic #'static-var true)
 #'user/static-var
 user= (binding [static-var 1000] (println static-var = static-var))
 static-var = 1000


 Looking at Var class implementation I couldn't figure out why .
 *setDynamic* call wouldn't work. My guess is that compiler somehow caches 
 initial static Var value for performance reasons?..

 So the questions are:
 1) Is it a bug that *.setDynamic* + *binding* don't work?
 2) Is there any other way to temporally rebind static variable 
 thread-locally? Considering I can't add *^:dynamic* into third-party lib 
 and don't want to write a wrapper or use dependency injection in order to 
 explicitly substitute the dependency in my unit tests.
 3) Is there a Clojure parallel test runner which runs tests in new 
 processes instead of threads? This would eliminate any race conditions. 
 Python's *nose* test runner works this way [3].
 4) Maybe crazy: does Clojure allow dynamically rebinding the symbol to a 
 new Var instance so that I could set *'static-var* to point at *(.setDynamic 
 (Var/create)*?
 5) Even crazier idea: can I change the nature of the var so that it 
 behaves like an InheritedThreadLocal instead of ThreadLocal, but without 
 forcing a user to *deref* it (as it was described in [4])?

 Links:
 [1] http://blog.zolotko.me/2012/06/making-variable-dynamic-in-clojure.html
 [2] 
 https://github.com/yeller/bolth/blob/323532683e3f66ae11566db5423c1e927e51818e/src/bolth/runner.clj#L99
 [3] 
 http://nose.readthedocs.org/en/latest/doc_tests/test_multiprocess/multiprocess.html
 [4] https://aphyr.com/posts/240-configuration-and-scope  - see 
 Thread-inheritable dynamic vars in Clojure



-- 
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.


Re: How to make a static variable dynamic at runtime?

2015-07-22 Thread Yuri Govorushchenko
Thank you for a reply, I totally agree with you on dependency injection. 
Though I'm exercising in writing a mocking framework and thought it would 
be an interesting feature to implement a thread-safe mocking of an implicit 
dependency.

среда, 22 июля 2015 г., 5:03:36 UTC+3 пользователь Surgo написал:

 Not that it's the answer you're looking for, but usually this is when you 
 rewrite the code you're testing to use dependency injection (ie, take the 
 var of interest as an argument instead of a global or in its lexical 
 environment).

 -- Morgon

 On Tuesday, July 21, 2015 at 10:54:42 AM UTC-4, Yuri Govorushchenko wrote:

 The problem I'm trying to solve is how to stub a variable (e.g. a 
 function from a third-party lib) in tests so that the stubbing occurs only 
 in the current thread with other threads continuing using var's root value. 
 It's important because unit tests may be run in parallel. Without 
 thread-local binding two threads stubbing the same function will lead to 
 race conditions:

 (binding [somelib/foo foo-stub] ; throws java.lang.IllegalStateException: 
 Can't dynamically bind non-dynamic var
   ; invoke tested code which depends on foo
   ; assert stuff
   )

 I've tried to use *.setDynamic* (as described in blog post [1]) but it 
 doesn't work without direct *deref*-ing of the var:

 (def static-var 123)
 (defn quz[]
   (.setDynamic #'static-var true)
   (binding [static-var 1000]
 (println static-var = static-var deref = @#'static-var)))

 (quz) ; = static-var = 123 deref = 1000

 This approach seems to be used in a recent *bolth* lib [2]. And The 
 strange thing is that in REPL running this code line by line works:

 user= (def static-var 123)
 #'user/static-var
 user= (.setDynamic #'static-var true)
 #'user/static-var
 user= (binding [static-var 1000] (println static-var = static-var))
 static-var = 1000


 Looking at Var class implementation I couldn't figure out why .
 *setDynamic* call wouldn't work. My guess is that compiler somehow 
 caches initial static Var value for performance reasons?..

 So the questions are:
 1) Is it a bug that *.setDynamic* + *binding* don't work?
 2) Is there any other way to temporally rebind static variable 
 thread-locally? Considering I can't add *^:dynamic* into third-party lib 
 and don't want to write a wrapper or use dependency injection in order to 
 explicitly substitute the dependency in my unit tests.
 3) Is there a Clojure parallel test runner which runs tests in new 
 processes instead of threads? This would eliminate any race conditions. 
 Python's *nose* test runner works this way [3].
 4) Maybe crazy: does Clojure allow dynamically rebinding the symbol to a 
 new Var instance so that I could set *'static-var* to point at *(.setDynamic 
 (Var/create)*?
 5) Even crazier idea: can I change the nature of the var so that it 
 behaves like an InheritedThreadLocal instead of ThreadLocal, but without 
 forcing a user to *deref* it (as it was described in [4])?

 Links:
 [1] 
 http://blog.zolotko.me/2012/06/making-variable-dynamic-in-clojure.html
 [2] 
 https://github.com/yeller/bolth/blob/323532683e3f66ae11566db5423c1e927e51818e/src/bolth/runner.clj#L99
 [3] 
 http://nose.readthedocs.org/en/latest/doc_tests/test_multiprocess/multiprocess.html
 [4] https://aphyr.com/posts/240-configuration-and-scope  - see 
 Thread-inheritable dynamic vars in Clojure



-- 
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.


Re: How to make a static variable dynamic at runtime?

2015-07-22 Thread Alexander Yakushev
Sorry, didn't link to the exact time. The correct link 
is: https://youtu.be/8NUI07y1SlQ?t=217

-- 
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.


Re: How to make a static variable dynamic at runtime?

2015-07-22 Thread Alexander Yakushev
Hello Yuri,

You probably need something like with-redefs[1] to do mocking. Setting a 
var to dynamic at runtime will have impact only on code that was *compiled* 
after 
doing that. See the excerpt from Daniel's talk about this behavior[2].

[1] 
http://conj.io/store/v1/org.clojure/clojure/1.7.0/clj/clojure.core/with-redefs/
[2] https://www.youtube.com/watch?v=8NUI07y1SlQ

Best regards,
Alex

On Tuesday, July 21, 2015 at 5:54:42 PM UTC+3, Yuri Govorushchenko wrote:

 The problem I'm trying to solve is how to stub a variable (e.g. a function 
 from a third-party lib) in tests so that the stubbing occurs only in the 
 current thread with other threads continuing using var's root value. It's 
 important because unit tests may be run in parallel. Without thread-local 
 binding two threads stubbing the same function will lead to race conditions:

 (binding [somelib/foo foo-stub] ; throws java.lang.IllegalStateException: 
 Can't dynamically bind non-dynamic var
   ; invoke tested code which depends on foo
   ; assert stuff
   )

 I've tried to use *.setDynamic* (as described in blog post [1]) but it 
 doesn't work without direct *deref*-ing of the var:

 (def static-var 123)
 (defn quz[]
   (.setDynamic #'static-var true)
   (binding [static-var 1000]
 (println static-var = static-var deref = @#'static-var)))

 (quz) ; = static-var = 123 deref = 1000

 This approach seems to be used in a recent *bolth* lib [2]. And The 
 strange thing is that in REPL running this code line by line works:

 user= (def static-var 123)
 #'user/static-var
 user= (.setDynamic #'static-var true)
 #'user/static-var
 user= (binding [static-var 1000] (println static-var = static-var))
 static-var = 1000


 Looking at Var class implementation I couldn't figure out why .
 *setDynamic* call wouldn't work. My guess is that compiler somehow caches 
 initial static Var value for performance reasons?..

 So the questions are:
 1) Is it a bug that *.setDynamic* + *binding* don't work?
 2) Is there any other way to temporally rebind static variable 
 thread-locally? Considering I can't add *^:dynamic* into third-party lib 
 and don't want to write a wrapper or use dependency injection in order to 
 explicitly substitute the dependency in my unit tests.
 3) Is there a Clojure parallel test runner which runs tests in new 
 processes instead of threads? This would eliminate any race conditions. 
 Python's *nose* test runner works this way [3].
 4) Maybe crazy: does Clojure allow dynamically rebinding the symbol to a 
 new Var instance so that I could set *'static-var* to point at *(.setDynamic 
 (Var/create)*?
 5) Even crazier idea: can I change the nature of the var so that it 
 behaves like an InheritedThreadLocal instead of ThreadLocal, but without 
 forcing a user to *deref* it (as it was described in [4])?

 Links:
 [1] http://blog.zolotko.me/2012/06/making-variable-dynamic-in-clojure.html
 [2] 
 https://github.com/yeller/bolth/blob/323532683e3f66ae11566db5423c1e927e51818e/src/bolth/runner.clj#L99
 [3] 
 http://nose.readthedocs.org/en/latest/doc_tests/test_multiprocess/multiprocess.html
 [4] https://aphyr.com/posts/240-configuration-and-scope  - see 
 Thread-inheritable dynamic vars in Clojure



-- 
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.


Re: How to make a static variable dynamic at runtime?

2015-07-22 Thread Marc O'Morain
Hi Yuri,

You need to call .setDynamic before the access to the var is compiled. In
your test, the call to .setDynamic is invoked when the function is called,
which is after the function has been compiled.  So when compiler sees the
read of static-var the var is still static, and it can emit a read of the
static var (or inline the value, I'm not sure which approach the compiler
takes).

If the var is dynamic when a form is compiled that reads the var, a dynamic
look-up can be emitted. Try this:

(def static-var 123)

(.setDynamic #'static-var true)
(defn quz[]
  (binding [static-var 1000]
(println static-var = static-var deref = @#'static-var)))

(quz) ; = static-var = 1000 deref = 1000
static-var ; = 123

This doesn't help much when the var is defined in a library though, since
the library will be compiled before you get a chance to set the var to be
dynamic. It explains the behaviour that you are seeing though.

Marc

On 22 July 2015 at 13:13, Yuri Govorushchenko yuri.go...@gmail.com wrote:

 Thank you for a reply, I totally agree with you on dependency injection.
 Though I'm exercising in writing a mocking framework and thought it would
be an interesting feature to implement a thread-safe mocking of an implicit
dependency.

 среда, 22 июля 2015 г., 5:03:36 UTC+3 пользователь Surgo написал:

 Not that it's the answer you're looking for, but usually this is when
you rewrite the code you're testing to use dependency injection (ie, take
the var of interest as an argument instead of a global or in its lexical
environment).

 -- Morgon

 On Tuesday, July 21, 2015 at 10:54:42 AM UTC-4, Yuri Govorushchenko
wrote:

 The problem I'm trying to solve is how to stub a variable (e.g. a
function from a third-party lib) in tests so that the stubbing occurs only
in the current thread with other threads continuing using var's root value.
It's important because unit tests may be run in parallel. Without
thread-local binding two threads stubbing the same function will lead to
race conditions:

 (binding [somelib/foo foo-stub] ; throws
java.lang.IllegalStateException: Can't dynamically bind non-dynamic var
   ; invoke tested code which depends on foo
   ; assert stuff
   )

 I've tried to use .setDynamic (as described in blog post [1]) but it
doesn't work without direct deref-ing of the var:

 (def static-var 123)
 (defn quz[]
   (.setDynamic #'static-var true)
   (binding [static-var 1000]
 (println static-var = static-var deref = @#'static-var)))

 (quz) ; = static-var = 123 deref = 1000

 This approach seems to be used in a recent bolth lib [2]. And The
strange thing is that in REPL running this code line by line works:

 user= (def static-var 123)
 #'user/static-var
 user= (.setDynamic #'static-var true)
 #'user/static-var
 user= (binding [static-var 1000] (println static-var = static-var))
 static-var = 1000


 Looking at Var class implementation I couldn't figure out why
.setDynamic call wouldn't work. My guess is that compiler somehow caches
initial static Var value for performance reasons?..

 So the questions are:
 1) Is it a bug that .setDynamic + binding don't work?
 2) Is there any other way to temporally rebind static variable
thread-locally? Considering I can't add ^:dynamic into third-party lib and
don't want to write a wrapper or use dependency injection in order to
explicitly substitute the dependency in my unit tests.
 3) Is there a Clojure parallel test runner which runs tests in new
processes instead of threads? This would eliminate any race conditions.
Python's nose test runner works this way [3].
 4) Maybe crazy: does Clojure allow dynamically rebinding the symbol to
a new Var instance so that I could set 'static-var to point at (.setDynamic
(Var/create)?
 5) Even crazier idea: can I change the nature of the var so that it
behaves like an InheritedThreadLocal instead of ThreadLocal, but without
forcing a user to deref it (as it was described in [4])?

 Links:
 [1]
http://blog.zolotko.me/2012/06/making-variable-dynamic-in-clojure.html
 [2]
https://github.com/yeller/bolth/blob/323532683e3f66ae11566db5423c1e927e51818e/src/bolth/runner.clj#L99
 [3]
http://nose.readthedocs.org/en/latest/doc_tests/test_multiprocess/multiprocess.html
 [4] https://aphyr.com/posts/240-configuration-and-scope  - see
Thread-inheritable dynamic vars in Clojure

 --
 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 

How to make a static variable dynamic at runtime?

2015-07-21 Thread Yuri Govorushchenko
The problem I'm trying to solve is how to stub a variable (e.g. a function 
from a third-party lib) in tests so that the stubbing occurs only in the 
current thread with other threads continuing using var's root value. It's 
important because unit tests may be run in parallel. Without thread-local 
binding two threads stubbing the same function will lead to race conditions:

(binding [somelib/foo foo-stub] ; throws java.lang.IllegalStateException: 
Can't dynamically bind non-dynamic var
  ; invoke tested code which depends on foo
  ; assert stuff
  )

I've tried to use *.setDynamic* (as described in blog post [1]) but it 
doesn't work without direct *deref*-ing of the var:

(def static-var 123)
(defn quz[]
  (.setDynamic #'static-var true)
  (binding [static-var 1000]
(println static-var = static-var deref = @#'static-var)))

(quz) ; = static-var = 123 deref = 1000

This approach seems to be used in a recent *bolth* lib [2]. And The strange 
thing is that in REPL running this code line by line works:

user= (def static-var 123)
 #'user/static-var
 user= (.setDynamic #'static-var true)
 #'user/static-var
 user= (binding [static-var 1000] (println static-var = static-var))
 static-var = 1000


Looking at Var class implementation I couldn't figure out why .*setDynamic* 
call wouldn't work. My guess is that compiler somehow caches initial static 
Var value for performance reasons?..

So the questions are:
1) Is it a bug that *.setDynamic* + *binding* don't work?
2) Is there any other way to temporally rebind static variable 
thread-locally? Considering I can't add *^:dynamic* into third-party lib 
and don't want to write a wrapper or use dependency injection in order to 
explicitly substitute the dependency in my unit tests.
3) Is there a Clojure parallel test runner which runs tests in new 
processes instead of threads? This would eliminate any race conditions. 
Python's *nose* test runner works this way [3].
4) Maybe crazy: does Clojure allow dynamically rebinding the symbol to a 
new Var instance so that I could set *'static-var* to point at *(.setDynamic 
(Var/create)*?
5) Even crazier idea: can I change the nature of the var so that it behaves 
like an InheritedThreadLocal instead of ThreadLocal, but without forcing a 
user to *deref* it (as it was described in [4])?

Links:
[1] http://blog.zolotko.me/2012/06/making-variable-dynamic-in-clojure.html
[2] 
https://github.com/yeller/bolth/blob/323532683e3f66ae11566db5423c1e927e51818e/src/bolth/runner.clj#L99
[3] 
http://nose.readthedocs.org/en/latest/doc_tests/test_multiprocess/multiprocess.html
[4] https://aphyr.com/posts/240-configuration-and-scope  - see 
Thread-inheritable dynamic vars in Clojure

-- 
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.


Re: How to make a static variable dynamic at runtime?

2015-07-21 Thread Surgo
Not that it's the answer you're looking for, but usually this is when you 
rewrite the code you're testing to use dependency injection (ie, take the 
var of interest as an argument instead of a global or in its lexical 
environment).

-- Morgon

On Tuesday, July 21, 2015 at 10:54:42 AM UTC-4, Yuri Govorushchenko wrote:

 The problem I'm trying to solve is how to stub a variable (e.g. a function 
 from a third-party lib) in tests so that the stubbing occurs only in the 
 current thread with other threads continuing using var's root value. It's 
 important because unit tests may be run in parallel. Without thread-local 
 binding two threads stubbing the same function will lead to race conditions:

 (binding [somelib/foo foo-stub] ; throws java.lang.IllegalStateException: 
 Can't dynamically bind non-dynamic var
   ; invoke tested code which depends on foo
   ; assert stuff
   )

 I've tried to use *.setDynamic* (as described in blog post [1]) but it 
 doesn't work without direct *deref*-ing of the var:

 (def static-var 123)
 (defn quz[]
   (.setDynamic #'static-var true)
   (binding [static-var 1000]
 (println static-var = static-var deref = @#'static-var)))

 (quz) ; = static-var = 123 deref = 1000

 This approach seems to be used in a recent *bolth* lib [2]. And The 
 strange thing is that in REPL running this code line by line works:

 user= (def static-var 123)
 #'user/static-var
 user= (.setDynamic #'static-var true)
 #'user/static-var
 user= (binding [static-var 1000] (println static-var = static-var))
 static-var = 1000


 Looking at Var class implementation I couldn't figure out why .
 *setDynamic* call wouldn't work. My guess is that compiler somehow caches 
 initial static Var value for performance reasons?..

 So the questions are:
 1) Is it a bug that *.setDynamic* + *binding* don't work?
 2) Is there any other way to temporally rebind static variable 
 thread-locally? Considering I can't add *^:dynamic* into third-party lib 
 and don't want to write a wrapper or use dependency injection in order to 
 explicitly substitute the dependency in my unit tests.
 3) Is there a Clojure parallel test runner which runs tests in new 
 processes instead of threads? This would eliminate any race conditions. 
 Python's *nose* test runner works this way [3].
 4) Maybe crazy: does Clojure allow dynamically rebinding the symbol to a 
 new Var instance so that I could set *'static-var* to point at *(.setDynamic 
 (Var/create)*?
 5) Even crazier idea: can I change the nature of the var so that it 
 behaves like an InheritedThreadLocal instead of ThreadLocal, but without 
 forcing a user to *deref* it (as it was described in [4])?

 Links:
 [1] http://blog.zolotko.me/2012/06/making-variable-dynamic-in-clojure.html
 [2] 
 https://github.com/yeller/bolth/blob/323532683e3f66ae11566db5423c1e927e51818e/src/bolth/runner.clj#L99
 [3] 
 http://nose.readthedocs.org/en/latest/doc_tests/test_multiprocess/multiprocess.html
 [4] https://aphyr.com/posts/240-configuration-and-scope  - see 
 Thread-inheritable dynamic vars in Clojure



-- 
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.