在Clojure宏中的动态方法调用? [英] Dynamic method calls in a Clojure macro?

查看:112
本文介绍了在Clojure宏中的动态方法调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我试图写一个宏,它将根据给定的参数调用java setter方法。例如:

 (my-macro login-as-fred {用户名fred密码wilma})

可能会扩展为以下内容:

 (doto(new MyClass)
(.setUsernamefred)
(.setPasswordwilma))

您建议如何解决这个问题?



具体来说,方法名称,并将其解释为一个符号的宏。

解决方案

宏的好处是你实际上必须挖掘类或类似的东西。



首先创建一个函数来生成一个s表达式,例如(。setName 42)

 (defn make-call [name val] 
(列表(符号(str.set名称)val)))

生成表达式并将它们(〜@)插入到 doto 表达式中。

 (defmacro map-set [class things] 
`(doto〜class〜@(map make-call things))

因为它是一个宏,所以它从来不必知道它被调用的东西是什么类,甚至是它将被使用的类存在。


I'm attempting to write a macro which will call java setter methods based on the arguments given to it.

So, for example:

(my-macro login-as-fred {"Username" "fred" "Password" "wilma"})

might expand to something like the following:

(doto (new MyClass)
  (.setUsername "fred")
  (.setPassword "wilma"))

How would you recommend tackling this?

Specifically, I'm having trouble working out the best way to construct the setter method name and have it interpreted it as a symbol by the macro.

解决方案

The nice thing about macros is you don't actually have to dig into the classes or anything like that. You just have to write code that generates the proper s-expressions.

First a function to generate an s-expression like (.setName 42)

(defn make-call [name val]
  (list (symbol (str ".set" name) val)))

then a macro to generate the expressions and plug (~@) them into a doto expression.

(defmacro map-set [class things]
  `(doto ~class ~@(map make-call things))

Because it's a macro it never has to know what class the thing it's being called on is or even that the class on which it will be used exists.

这篇关于在Clojure宏中的动态方法调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆