简体   繁体   中英

How can I pass in the list of methods to gen-class?

When using gen-class this compiles fine:

(ns clj.sandbox)

(defn -hello
  [this]
  "Hello World")

(gen-class
  :name com.sandbox.GeneratedClass
  :methods [[hello [] String]])

But if you do this:

(ns clj.sandbox)

(def my-methods (atom [[hello [] String]]))

(defn -hello
  [this]
  "Hello World")

(gen-class
  :name com.sandbox.GeneratedClass
  :methods @my-methods)

You get this error:

CompilerException java.lang.RuntimeException: Unable to resolve symbol: hello in this context, compiling:(clj\\sandbox.clj:3:17)

Is there any way to get around this error? I'd like to be able to pass in the :methods value instead of defining it inline.


In case it matters, this is the pom.xml I'm using to generate this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    
    <artifactId>sandbox</artifactId>
    <groupId>com.sandbox</groupId>
    <version>1.0-SNAPSHOT</version>    
    <packaging>clojure</packaging>
    <modelVersion>4.0.0</modelVersion>    
    <build>        
        <plugins>
            <plugin>
                <groupId>com.theoryinpractise</groupId>
                <artifactId>clojure-maven-plugin</artifactId>
                <version>1.3.13</version>
                <extensions>true</extensions>
                <configuration>
                  <sourceDirectories>
                    <sourceDirectory>src</sourceDirectory>
                  </sourceDirectories>
                </configuration>
            </plugin>
        </plugins>        
    </build>
    <dependencies>        
        <dependency>
            <groupId>org.clojure</groupId>
            <artifactId>clojure</artifactId>
            <version>1.5.1</version>
        </dependency>
    </dependencies>
</project>

Because gen-class is a macro and passing @my-methods to it will cause the macro to get (deref my-method) as value of method argument which is not what is expected. You need to create a wrapper macro and then call it as shown below:

(defn -hello []
  "Hello world")

(def my-methods (atom '[[hello [] String]]))

(defmacro my-class []
  `(gen-class
    :name com.sandbox.GeneratedClass
    :methods ~(deref my-methods)))

(my-class)

Also note that the atom value is quoted otherwise you will get hello not found exception because it tries to resolve hello var which is not there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM