gpt4 book ai didi

macros - 有没有一种干净的方法可以将函数添加到动态创建的命名空间?

转载 作者:太空宇宙 更新时间:2023-11-03 18:33:55 24 4
gpt4 key购买 nike

我正在创建一个黑色网络应用程序,我需要动态创建新的 View 和模型。我一直在关注 noir 示例,其中资源的 View 和 Controller 具有单独的命名空间,我发现这是一种非常简洁的方法。

与此保持一致,我需要能够动态创建与 View 和模型相对应的新命名空间,然后在其中实习适当的功能。我的想法是在一个单独的命名空间中指定宏,当在新命名空间中调用时,它将提供适当的路由/部分/任何内容。

例如(原谅我的第一个defmacro):

(ns project.views.proto
(:use noir.core
hiccup.core
hiccup.element
hiccup.form))

(defmacro def-all-page
[path]
`(defpage ~path []
(html
[:h1 "Ya'll here"])))

从...调用

(ns project.proto
(:use [clojure.contrib.with-ns :only [with-ns]])

(create-ns 'foo)
(intern 'foo 'path "path") ; In reality, the path is dynamic which is why I intern it
(with-ns 'foo
(clojure.core/refer-clojure)
(use 'noir.core
'hiccup.core
'hiccup.element
'[project.views.proto :only [def-all-page]])

(def-all-page path)

但是,从我的新命名空间中调用它会给我一个 NullPointerException。我将不胜感激任何帮助,以及是否有更好的方法。比如,只对包含所有必要定义的命名空间使用引用?

第一篇文章,我不认为这是 this 的重复.谢谢!

最佳答案

首先,这个问题有点过时了。 Noir 和 Clojure 在过去的一年里都有所发展。为清楚起见,我将把 Noir 排除在等式之外,并尝试回答您有关使用宏动态创建函数的问题。

跟随 REPL:

$ lein repl
user=> (in-ns 'foo)
#<Namespace foo>
foo=> (clojure.core/refer-clojure)
nil
foo=> (defmacro say-hello-to
#_=> [name]
#_=> `(defn ~(symbol (str "hello-" name))
#_=> []
#_=> ~(str "hello: " name)))
#'foo/say-hello-to

在这里,我们创建了一个命名空间“foo”,其中包含一个用于定义“hello-yourname”函数的宏。让我们创建另一个命名空间:

foo=> (in-ns 'bar)
#<Namespace bar>
bar=> (clojure.core/refer-clojure)
nil
bar=> (refer 'foo :only '[say-hello-to])
nil
bar=> (say-hello-to "tom")
#'bar/hello-tom
bar=> (say-hello-to "jerry")
#'bar/hello-jerry

让我们看看这些是否真的有效:

bar=> (hello-tom)
"hello: tom"
bar=> (hello-jerry)
"hello: jerry"

我认为这与您的原始示例非常接近。

希望对您有所帮助!

关于macros - 有没有一种干净的方法可以将函数添加到动态创建的命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10271653/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com