首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >def的闭包行为

def的闭包行为
EN

Stack Overflow用户
提问于 2012-06-19 23:11:20
回答 2查看 232关注 0票数 3

我有一个lein项目(使用cascalog--但这并不是特别重要)。我试图将属性外部化,比如文件的路径,所以我最终得到的代码如下所示:

代码语言:javascript
复制
(defn output-tap [path] (hfs-textline (str (get-prop :output-path-prefix) path) :sinkmode :replace))

(def some-cascalog-query 
    (<- [?f1 ?f2 ?f3] 
        ((output-tap (get-prop :output-path)) ?line)
        (tab-split ?line :> ?f1 ?f2 ?f3)))

在上面的示例中,假设函数get-prop存在;它只是使用标准java读取属性值(基于此示例:loading configuration file in clojure as data structure)。

现在我有了一个加载属性值的main方法,例如:

代码语言:javascript
复制
(defn -main [& args] (do (load-props (first args)) (do-cascalog-stuff)))

但是当我使用lein uberjar时,我得到了一个编译时错误,说:

代码语言:javascript
复制
Caused by: java.lang.IllegalArgumentException: Can not create a Path from an empty string
at org.apache.hadoop.fs.Path.checkPathArg(Path.java:82)
at org.apache.hadoop.fs.Path.<init>(Path.java:90)
at cascading.tap.hadoop.Hfs.getPath(Hfs.java:343)

defs是否总是在编译时求值(而不是运行时求值)?还是我误解了这个错误?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-20 00:35:56

那么,您希望属性查找在运行时发生吗?是的,您需要将some-cascalog-query定义为函数或宏。空def会导致在加载代码时计算表达式,而不是在取消引用var时计算表达式。

在REPL中可以非常简单地说明这一点:

代码语言:javascript
复制
user=> (def foo (do (println "Hello, world!") 1))
Hello, world!
#'user/foo
user=> foo
1

来自documentation (重点是我的):

(默认符号初始化?)

创建并实例化或定位具有symbol名称和当前命名空间(ns)值的命名空间的全局变量。如果提供了init,则对其求值,并将var的根绑定设置为结果值。

票数 3
EN

Stack Overflow用户

发布于 2012-06-20 00:11:33

该错误看起来像是(get-prop :output-path) (get-prop :output-path-prefix)没有返回任何内容,str将其包装成一个空字符串。也许没有找到该属性?

get-prop是否如预期的那样工作?

你对defs的理解是正确的,它们是编译时,而不是(通常)运行时。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11103980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档