Как заставить змею и GString работать вместе

Когда я пытаюсь использовать змею для вывода Yaml из интерполированных строк Groovy, вместо этого он печатает имя класса.

Например:

@Grab(group='org.yaml', module='snakeyaml', version='1.16')

import org.yaml.snakeyaml.Yaml

Yaml yaml = new Yaml();
def a = "a"
def list = ["$a"]   
def s = yaml.dump(list)

Отпечатки:

- !!org.codehaus.groovy.runtime.GStringImpl
  metaClass: !!groovy.lang.MetaClassImpl {}

Я предполагаю, что это как-то связано с тем фактом, что GStrings преобразуются в Strings, когда они используются, и я подозреваю, что snakeyaml использует своего рода самоанализ для определения класса объекта.

Есть ли лучшее решение, чем вызов toString() для всех строк GString?


person mck    schedule 30.01.2016    source источник


Ответы (2)


Попробуйте создать нового представителя:

public class GroovyRepresenter extends Representer {
  public GroovyRepresenter() {
    this.representers.put(GString.class, new StringRepresenter());
  }
}

Yaml yaml = new Yaml(new GroovyRepresenter())
...
person Jérémie B    schedule 30.01.2016
comment
Поскольку GString является абстрактным классом, мне пришлось использовать multiRepresenters: def representer = new Representer() {{ this.multiRepresenters.put(GString, this.representers.get(String)) }} - person thorin; 23.07.2018

Вы можете добавить информацию о типе к своим переменным

Yaml yaml = new Yaml();
def a = "a"
String aStr = "$a"
def list = [aStr]   
def s = yaml.dump(list)
person tim_yates    schedule 30.01.2016
comment
Это резко увеличит размер моего кода, toString() кажется проще. Например, если бы у меня было def list = ["john $a", "frank $a", "simon $a"], мне пришлось бы определить 3 переменные. - person mck; 30.01.2016
comment
Вы могли бы написать метод, который принимает аргументы String и строит из них список? def list(String... args) { args as List } - person tim_yates; 30.01.2016