ClojureScript

Reading a value from a module does not work if the module is def'ed

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Declined
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Environment:
    Clojure 1.5.0-RC16
    Clojurescript 0.0-1586
    java version "1.7.0_04"
    Java(TM) SE Runtime Environment (build 1.7.0_04-b21)
    Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
    OSX Mountain Lion 10.8.2

Description

Referring to a value in a module can have a scoping issue when using the "static accessor" operator of module/VALUE_NAME. The static accessor works if the module is loaded into a local value but not if def'ed. This example uses the mmap module for Node.js, and successfully reads the PROT_READ value:

(ns stat.core)
(defn -main []
  (let [m (js/require "mmap")]
    (println "value: " m/PROT_READ)))
(set! *main-cli-fn* -main)

This correctly prints "value: 1"

However, if the value for m is def'ed instead, then the compiler assumes that the reference to m is local to the function and therefore not defined:

(ns stat.core)
(def m (js/require "mmap"))
(defn -main []
  (println "value: " m/PROT_READ))
(set! *main-cli-fn* -main)

/Users/pag/src/test/clj/stat/target/stat.js:12836
  return cljs.core.println.call(null, "value: ", m.PROT_READ)
                                                 ^
ReferenceError: m is not defined
    at Function.stat.core._main (/Users/pag/src/test/clj/stat/target/stat.js:12836:50)
    at cljs.core.apply.b (/Users/pag/src/test/clj/stat/target/stat.js:5621:14)
    at cljs.core.apply.a (/Users/pag/src/test/clj/stat/target/stat.js:5656:18)
    at Object.<anonymous> (/Users/pag/src/test/clj/stat/target/stat.js:12844:17)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

In this case, the value of m.PROT_READ should have been stat.core.m.PROT_READ.

On the other hand, using . syntax fixes the scoping issue:

(ns stat.core)
(def m (js/require "mmap"))
(defn -main []
  (println "value: " (.-PROT_READ m)))
(set! *main-cli-fn* -main)

Activity

David Nolen made changes -
Field Original Value New Value
Description Referring to a value in a module can have a scoping issue when using the "static accessor" operator of module/VALUE_NAME. The static accessor works if the module is loaded into a local value but not if def'ed. This example uses the mmap module for Node.js, and successfully reads the PROT_READ value:

(ns stat.core)
(defn -main []
  (let [m (js/require "mmap")]
    (println "value: " m/PROT_READ)))
(set! *main-cli-fn* -main)

This correctly prints "value: 1"

However, if the value for m is def'ed instead, then the compiler assumes that the reference to m is local to the function and therefore not defined:

(ns stat.core)
(def m (js/require "mmap"))
(defn -main []
  (println "value: " m/PROT_READ))
(set! *main-cli-fn* -main)

/Users/pag/src/test/clj/stat/target/stat.js:12836
  return cljs.core.println.call(null, "value: ", m.PROT_READ)
                                                 ^
ReferenceError: m is not defined
    at Function.stat.core._main (/Users/pag/src/test/clj/stat/target/stat.js:12836:50)
    at cljs.core.apply.b (/Users/pag/src/test/clj/stat/target/stat.js:5621:14)
    at cljs.core.apply.a (/Users/pag/src/test/clj/stat/target/stat.js:5656:18)
    at Object.<anonymous> (/Users/pag/src/test/clj/stat/target/stat.js:12844:17)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

In this case, the value of m.PROT_READ should have been stat.core.m.PROT_READ.

On the other hand, using . syntax fixes the scoping issue:
(ns stat.core)
(def m (js/require "mmap"))
(defn -main []
  (println "value: " (.-PROT_READ m)))
(set! *main-cli-fn* -main)

Referring to a value in a module can have a scoping issue when using the "static accessor" operator of module/VALUE_NAME. The static accessor works if the module is loaded into a local value but not if def'ed. This example uses the mmap module for Node.js, and successfully reads the PROT_READ value:

{code}
(ns stat.core)
(defn -main []
  (let [m (js/require "mmap")]
    (println "value: " m/PROT_READ)))
(set! *main-cli-fn* -main)
{code}

This correctly prints "value: 1"

However, if the value for m is def'ed instead, then the compiler assumes that the reference to m is local to the function and therefore not defined:

{code}
(ns stat.core)
(def m (js/require "mmap"))
(defn -main []
  (println "value: " m/PROT_READ))
(set! *main-cli-fn* -main)

/Users/pag/src/test/clj/stat/target/stat.js:12836
  return cljs.core.println.call(null, "value: ", m.PROT_READ)
                                                 ^
ReferenceError: m is not defined
    at Function.stat.core._main (/Users/pag/src/test/clj/stat/target/stat.js:12836:50)
    at cljs.core.apply.b (/Users/pag/src/test/clj/stat/target/stat.js:5621:14)
    at cljs.core.apply.a (/Users/pag/src/test/clj/stat/target/stat.js:5656:18)
    at Object.<anonymous> (/Users/pag/src/test/clj/stat/target/stat.js:12844:17)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)
{code}

In this case, the value of m.PROT_READ should have been stat.core.m.PROT_READ.

On the other hand, using . syntax fixes the scoping issue:

{code}
(ns stat.core)
(def m (js/require "mmap"))
(defn -main []
  (println "value: " (.-PROT_READ m)))
(set! *main-cli-fn* -main)
{code}

Hide
David Nolen added a comment -

the slash syntax is reserved for real CLJS namespaces for everything else the dot syntax must be used.

Show
David Nolen added a comment - the slash syntax is reserved for real CLJS namespaces for everything else the dot syntax must be used.
David Nolen made changes -
Resolution Declined [ 2 ]
Status Open [ 1 ] Resolved [ 5 ]
David Nolen made changes -
Status Resolved [ 5 ] Closed [ 6 ]

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: