2013-03-21 2 views
2

Clojure에서 간단한 응용 프로그램을 작성하고 있습니다. 내 임무는 Runnable 인터페이스를 구현하고 start 메서드를 호출하는 정규화 된 클래스 이름 (Java 클래스)을 사용자로부터 가져 오는 것입니다. 내 문제는 클래스 이름을 선험적으로 모를 때이 메서드를 실행하는 방법입니다. 나는 또한 그것으로 실패했기 때문에,이름이 동적으로 생성되는 클래스의 메서드 호출

(defn schedule [parameter] 
    (def class-name (subs parameter 6))  ; get just class name for e.g. java.lang.String 
    (println (.getName class-name))) 

또한 this을 발견하지만 난 그것을 사용하는 방법을 아주 확실하지 않다 : this을 바탕으로 내가 (단순 String 클래스에) 이런 식으로 뭔가를 시도했다하지만 난 실패했습니다. 어떤 아이디어?

+0

일부 샘플 입력 및 원하는 출력을 일정에 추가 할 수 있습니까? –

+0

그것은 단지 내가 필요한 것의 예입니다. 마지막으로 나는 Java.lang.Runnable을 구현하는 클래스를 호출 할 것이므로 myClass.start()를 호출하고 그대로 두어야합니다. 그래서 출력은 NULL이고 입력은 정규화 된 클래스 이름 (패키지 이름을 가진 클래스 이름)을 작성한 것입니다. – Blood

답변

2

당신이 매크로를 사용하지 않도록하려면, 당신은 뭔가를 할 수 있습니다.

+0

이 서브를 신경 쓰지 마라. 솔루션에 대한 한 가지 질문입니다. 스레드가 시작되었는지 어떻게 확인할 수 있습니까? – Blood

+0

죄송합니다. 중요한 (스레드) 단계를 생략했습니다! 위의 스 니펫을 리팩터링하여 스레드 자체를 반환하므로 원하는 경우 상호 작용할 수 있습니다. – dfreeman

+0

감사합니다. 내일, 내가 오늘 좀비 같아요 확인하십시오 : D – Blood

2

매크로 또는 eval으로이 작업을 수행 할 수 있습니다. 일반적으로 평가할 매크로를 선호합니다. 그런 다음 일반적인 자바 방법으로 반환 된 Thread 객체와 상호 작용할 수

(defn schedule [name] 
    (let [thread (-> name Class/forName .newInstance Thread.)] 
    (.start thread) 
    thread)) 

:

user> (defmacro runnerizer [class-name] 
      `(~(symbol (str class-name "/" "start"))))              
#'user/runnerizer                              
user> (macroexpand-1 '(runnerizer "myClass"))                       
(myClass/start) 
+0

오 대단합니다. 그리고 스레드가 이미 시작되었는지 확인할 수 있습니까? 그리고 더 이상, 내 Clojure 응용 프로그램에서 볼 수 있도록 수업을 배치해야합니까? – Blood

+0

나는 당신이 런타임에 전달 된 클래스 이름으로 작동하도록 eval을 사용해야 할 수도 있다고 생각 하는가? 아니면 컴파일 후 매크로 확장을 연기 할 수있는 다른 방법이 있는가? – Alex

+0

클래스/forName 접근 방식은 eval뿐만 아니라 런타임에서도 작동해야합니다. 내가 dfreeman의 답을 투표 할 것을 감안할 때, 나는 eval을 사용하는 것에 편향되어 있기 때문에 –

관련 문제