2013-09-19 1 views
3

Хотя это не стандартная практика, мне любопытно, можно ли вводить методы в контекст компиляции GroovyShell.Могу ли я добавлять методы в базовый скрипт Groovy динамически с Java?

Идея заключается в том, чтобы иметь что-то вроде (в Java):

GroovyShell shell = new GroovyShell(); 
Script script = shell.parse("test()"); 
script.run(); 

Где я хотел бы динамически добавлять методы, которые invokable, где test() было включено.

Я немного экспериментировал с беспорядком с ScriptmetaClass, но я не вижу способа фактически манипулировать metaClass с Java. В частности, вызов script.getMetaClass().getMethods().add(...) вызывает исключение UnsupportedOperationException.

По сути, я бы хотел определить точки вызова DSL, которые вызывают методы Java, а не Groovy-based. Я готов написать эту часть в Groovy (и знаю, как это сделать), но мне действительно интересно, является ли это жизнеспособным альтернативным подходом, или, если это не так, то, что такое подводные камни.

Вкратце: как я могу динамически определить метод, о котором знает GroovyShell?

ответ

4

Есть две очень простые решения для этого: а) типичный «сценариев» подход б) более заводной-иш подход

а) просто предваряя ваш скрипт-String с String, который определяет методы. b) помещает ссылку в связывание, например. под названием «тест». Значение этой ссылки является объектом Closure или любым другим объектом, который имеет метод «вызов (args)». Когда во время выполнения скрипта Groovy видит «test()», он сначала попытается найти такой метод, и если такого метода нет, он пытается разрешить «тест» как свойство и найдет его в привязке. Затем он вызовет так разрешенную ссылку (закрытие) с предоставленными аргументами (если таковые имеются).

Есть еще более сложные параметры, такие как предоставление CompilerConfiguration, которые перечислены в главе DSL в разделе «Groovy in Action, 2nd edition» (бесстыдный плагин).

+0

Привет, я тоже застрял в аналогичной проблеме. Вы отправили здесь: http://stackoverflow.com/questions/27315115/groovy-dsl-with-java, но я все еще размещаю этот комментарий здесь, выдвигая проблему, застрявшую с в надежде, что вы предложите некоторую помощь. Я хочу передать имя класса (Java) и его имя метода в DSL. И я хочу иметь экземпляр, созданный для этого класса, и данный метод, вызванный из Groovy. Но так как я получаю класс, прошедший как «класс xx.class-name», я не могу создать его экземпляр и выполнить требуемый вызов метода. Не могли бы вы дать здесь небольшое руководство? Благодарю. – 5122014009

+0

Из Java можно сделать 'binding.setProperty (« wishMethodName », новый MethodClosure (myObject,« myMethod »));'. Единственная проблема заключается в том, что существующие методы не могут быть перезаписаны. Спасибо, что указали этот вариант. – akostadinov