Статьи

Groovy 1.7.2 — три особенности, которые стоит обновить

Groovy 1.7.2 был выпущен 22 часа назад, так что к настоящему времени вы наверняка потратили часы, играя с новыми битами и просматривая примечания к выпуску, ища новые самородки производительности.

А может и нет.

Для всех тех, кто более занят, чем я, вот три основных причины для обновления до

точного выпуска: Преобразование GPathResults в XMLJIRA 1178

XmlSlurperэто отличный способ разбирать, манипулировать и вообще дразнить XML. Проблема в том, что как только вы начинаете детализацию XML с использованием динамического синтаксиса, вы работаете с объектами GPathResults, а не с простым текстом или строками. Было довольно сложно вытащить фрагменты XML в виде текста. Больше не надо! Теперь вы можете использовать XmlSlurper для извлечения фрагментов XML, а затем легко манипулировать ими как текстом, преобразовав GPathResult в строку.

Вот классическая структура XML из документации XmlSlurper:

def CAR_RECORDS = '''
<records>
<car name='HSV Maloo' make='Holden' year='2006' >
<country>Australia</country>
<record type='speed'>Production Pickup Truck with speed of 271kph</record>
</car>
<car name='P50' make='Peel' year='1962'>
<country>Isle of Man</country>
<record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record>
</car>
<car name='Royale' make='Bugatti' year='1931'>
<country>France</country>
<record type='price'>Most Valuable Car at $15 million</record>
</car>
</records>
'''

Так или иначе, XmlSlurper упрощает извлечение второго элемента car из примера XML:

def records = new XmlSlurper().parseText(CAR_RECORDS)
def secondCar = records.car[1]
assert secondCar.getClass() == NodeChild
assert secondCar.toString() == 'Isle of ManSmallest Street-Legal Car at 99cm wide and 59 kg in weight'

В этом примере есть несколько проблем, и это не значит, что второй элемент car имеет индекс 1. Переменная secondCar имеет тип NodeChild. Это замечательно, если вы хотите выполнить более динамическое сопоставление с NodeChild, но не так здорово, если вы хотите получить полный XML дочернего и всех потомков. ToString () довольно бессмысленно, это просто объединение всех значений дочерних узлов. В 1.7.2 StreamingMarkupBuilder позволяет быстро получить дочерний XML в виде строки. Утверждение и пример кода являются грязными, но функция не:

def xmlString = new StreamingMarkupBuilder().bindNode(secondCar).toString()
assert xmlString == "<car name='P50' year='1962' make='Peel'><country>Isle of Man</country><record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg in weight</record></car>"

Ницца. Я понимаю, что вы могли каким-то образом получить XML в предыдущих версиях Groovy, но я так и не понял. Мне повезло, если я смогу просто что-нибудь напечатать.

Упрощенная сортировка карт и недвижимости
JIRA 2597

Сортировать объекты «Карты» и «Свойства» проще, чем когда-либо. Первым шагом является создание несортированной карты:

def map = [c: 1, b: 2, a: 3]

В предыдущих выпусках Groovy было два варианта сортировки карты. Один метод сортировки использует замыкание, которое вызывается как Comparator, а другой способ — просто обернуть карту в TreeMap. Вот некоторые утверждения, показывающие, как они работали:

assert map.sort { Entry it -> it.key }*.key == ['a', 'b', 'c']
assert new TreeMap(map)*.key == ['a', 'b', 'c']

Неплохо, но теперь объект Map имеет сортировку без аргументов, которая выполняет сортировку по умолчанию, и API, который позволяет передавать настоящий Comparator :

assert map.sort()*.key == ['a', 'b', 'c']
assert map.sort({ a, b -> a <=> b } as Comparator)*.key == ['a', 'b', 'c']

И помните, эти методы возвращают новую карту, они не изменяют оригинал. Карты не пострадали во время сортировки карт.

ncurry и rcurry — JIRA 4144

Карри метод был вокруг Groovy в течение длительного времени . Это позволяет связывать переменные в замыкания слева направо:

def multiply = { a, b -> a * b }
def doubler = multiply.curry(2)
assert doubler(4) == 8

В приведенном выше примере, multiply имеет сигнатуру типа «Object -> Object -> Object» (два параметра Object и возвращаемый тип Object). Когда вы умножаете карри на удвоитель, вы получаете сигнатуру типа «Object -> Object» (один параметр Object и возвращаемый тип Object). Параметры связаны слева направо. Карри всегда ограничивал самый левый параметр в списке параметров. До нынешнего момента.

rcurry свяжет параметры справа налево. Таким образом, половина может теперь быть сделана из делителя. Whee!

def divider = { a, b -> a / b }
def halver = divider.rcurry(2)
assert 5 == halver(10)

ncurry — это API-интерфейс для карри и rcurry. Это позволяет связывать параметры на основе целочисленного индекса параметра в сигнатуре. Таким образом, вы можете связать параметр 2, 3, 4 или что-то еще. Проверьте это:

def operation = { int x, Closure f, int y -> f(x, y) }
def divider = operation.ncurry(1) { a, b -> a / b }
assert 5 == divider(10, 2)

Прежде чем вы начнете сходить с ума от ncurry и rcurry, имейте в виду, что я думаю, что есть ошибка при попытке их смешать. Использование ncurry и rcurry в одиночку работает замечательно, но повторное выполнение ncurried закрытия в настоящее время не работает. У меня есть догадка, что это не влияет на многих людей. Я отправлю комментарий, когда узнаю, что не так или когда это исправлено.

Теперь перейдите на обновление до 1.7.2!

От http://hamletdarcy.blogspot.com/2010/04/groovy-172-three-features-worth-upgrade.html