In clojure use and alias not working within a do block
In clojure when I do :
(do
(use 'oe.model.modelcore)
(alias 'model 'oe.model.modelcore)
(str ::model/record)
)
I get the error:
java.lang.Exception: Invalid token: ::modelcore/a
java.lang.Exception: Unmatched delimiter: )
java.lang.Exception: Unmatched delimiter: )
However, if I run the commands separately outside of the do block they work:
(use 'oe.model.modelcore)
(alias 'model 'oe.model.modelcore)
(str ::model/record开发者_JAVA百科 )
: returns :
:oe.model.modelcore/record
Does anyone know why?
This issue results from the interaction of read time and run time.
In the first example, the entire form is read before it is executed. ::model/record
gives the invalid token exception because there is not namespace aliased as model
yet.
In the second example, the first form is read, then executed. The the same with the second and then the third. By the time the third form is read in, there is a namespace aliased as model
so no exception is thrown.
This is due to a tricky edge case known as the Gilardi Scenario: http://technomancy.us/143
The whole do must be compiled before the require runs. The above link shows you how to work around it by resolving the var at runtime with ns-resolve.
Also: calling bare use and alias outside the ns form is usually not what you want.
精彩评论