Статьи

Как вы можете извлечь выгоду из Groovy Shell

Это пост о Groovy Shell и о том, как он может помочь вам в вашей повседневной работе (если вы работаете разработчиком программного обеспечения). Вы можете воспользоваться Groovy Shell независимо от того, какой язык (языки) программирования или технологии вы используете. Единственным реальным требованием является то, что вы можете писать (и читать) небольшие фрагменты кода на Groovy .

Начиная

Я думаю, что назначение оболочки Groovy лучше всего описано в официальной документации:

Groovy Shell, он же. groovysh — это приложение командной строки, которое обеспечивает легкий доступ для оценки выражений Groovy, определения классов и проведения простых экспериментов.

Оболочка Groovy включена в дистрибутив языка программирования Groovy и находится в <groovy home> / bin. Для запуска Groovy Shell просто запустите groovysh из командной строки:

1
2
3
4
5
GROOVY_HOME\bin>groovysh
Groovy Shell (2.2.2, JVM: 1.7.0)
Type 'help' or '\h' for help.
--------------------------------------------------------------------
groovy:000>

Теперь внутри оболочки вы можете запускать команды Groovy:

1
2
3
4
groovy:000> println("hu?")
hu?
===> null
groovy:000>

Он поддерживает переменные и многострочные операторы:

1
2
3
4
5
6
7
8
9
groovy:000> foo = 42
===> 42
groovy:000> baz = {
groovy:001> return 42 * 2
groovy:002> }
===> groovysh_evaluate$_run_closure1@3c661f99
groovy:000> baz(foo)
===> 84
groovy:000>

(Обратите внимание, что вам нужно пропустить ключевое слово def, чтобы позже использовать переменные и замыкания)

Несколько слов для пользователей Windows

Я могу четко порекомендовать Console (2), которая представляет собой небольшую оболочку вокруг неудобного окна cmd. Он обеспечивает поддержку вкладок, лучший выбор текста и другие полезные вещи.

К сожалению, оболочка Groovy 2.2.0 имеет проблемы с клавишами со стрелками в Windows 7/8 в некоторых регионах (включая немецкий). Однако вы можете использовать CTRL-P и CTRL-N вместо UP и DOWN. В качестве альтернативы вы можете использовать оболочку более старой версии Groovy (groovysh из Groovy 2.1.9 работает отлично).

Итак, для чего мы можем это использовать?

Самая очевидная вещь, которую мы можем сделать, это оценить код Groovy. Это особенно полезно, если вы работаете с приложениями, использующими Groovy.

Может быть, вы знаете, что можете использовать оператор << для добавления элементов в списки, но вы не уверены, работает ли этот же оператор для карт? В этом случае вы можете начать поиск в Google или посмотреть его в документации. Или вы можете просто ввести его в Groovy Shell и посмотреть, работает ли он:

1
2
groovy:000> [a:1] << [b:2]
===> {a=1, b=2}

Оно работает!

Вы не уверены, что можете перебирать значения перечислений?

1
2
3
4
5
6
7
groovy:000enum Day { Mo, Tu, We }
===> true
groovy:000> Day.each { println it }
Mo
Tu
We
===> class Day

Это тоже работает!

Это калькулятор!

Оболочка Groovy может использоваться для простых математических расчетов:

1
2
3
4
5
6
7
8
9
groovy:000> 40 + 2
===> 42
groovy:000>
groovy:000> 123456789123456789 * 123456789123456789123456789
===> 15241578780673678530864199515622620750190521
groovy:000>
groovy:000> 2 ** 1024
===> 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216
groovy:000>

Как видите, Groovy может хорошо работать с числами, которые могут вызвать переполнение в других языках программирования. Groovy использует BigInteger и BigDecimal для этих вычислений. Кстати, вы сами можете очень быстро это проверить:

1
2
groovy:000> (2 ** 1024).getClass()
===> class java.math.BigInteger

Обратите внимание, что Groovy math старается быть максимально естественным:

1
2
3
4
groovy:000> 3/2
===> 1.5
groovy:000> 1.1+0.1
===> 1.2

В Java эти вычисления приведут к 1 ( целочисленное деление ) и 1.2000000000000002 ( арифметика с плавающей запятой ).

Сделать больше

Может быть, вам нужен контент определенной веб-страницы? Это может быть легко достигнуто с Groovy:

1
2
3
4
5
6
7
8
groovy:000"http://groovy.codehaus.org".toURL().text
===> <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <meta name="description" content="Groovy Wiki"/>
    ...

Может быть, вам нужны только теги <meta> по какой-то причине?

1
2
3
4
5
6
7
groovy:000"http://groovy.codehaus.org".toURL().eachLine { if (it.contains('<meta')) println it }
    <meta charset="utf-8"/>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <meta name="description" content="Groovy Wiki"/>
    <meta name="keywords"
    <meta name="author" content="Codehaus Groovy Community"/>
===> null

Я уверен, что вы оказались в ситуации, когда вам понадобилась зашифрованная по URL-адресу версия некоторого текста:

1
2
groovy:000> URLEncoder.encode("foo=bar")
===> foo%3Dbar

Конечно, вам не нужно запоминать точные имена классов и методов. Просто введите первые символы и нажмите клавишу Tab, чтобы получить возможные варианты:

1
2
3
groovy:000> URL
URL                       URLClassLoader            URLConnection             URLDecoder                URLEncoder
URLStreamHandler          URLStreamHandlerFactory

Это работает с методами тоже:

1
2
groovy:000> URLEncoder.e
each(            eachWithIndex(   encode(          every(           every()

Настроить его

Чтобы по-настоящему воспользоваться Groovy Shell, вы должны настроить его под свои нужды и предоставить функции, которые помогут вам в вашей повседневной работе. Для этого вы можете добавить свой собственный код Groovy в $ HOME / .groovy / groovysh.profile (просто создайте файл, если он не существует). Этот файл загружается и исполняется при запуске groovysh.

Предположим, вы хотите декодировать фрагмент текста в кодировке Base64 . Жизнеспособный подход состоит в том, чтобы начать поиск в Интернете для декодера Base64 онлайн. Альтернативой является добавление нескольких строк в ваш файл groovysh.profile для выполнения этой работы:

1
2
3
4
5
6
7
encodeBase64 = { str ->
  return str.bytes.encodeBase64().toString()
}
 
decodeBase64 = { str ->
  return new String(str.decodeBase64())
}

Теперь вы можете использовать функции encodeBase64 () и decodeBase64 () в Groovy Shell для выполнения этой работы:

1
2
3
4
groovy:000> encoded = encodeBase64('test')
===> dGVzdA==
groovy:000> decodeBase64(encoded)
===> test

Этот подход может быть немного медленнее в первый раз, когда вы используете его, но вы получите выгоду от него в следующий раз, когда вам понадобится кодировать / декодировать сообщение Base64. Обратите внимание, что автозаполнение также работает с вашими собственными методами, поэтому вам не нужно запоминать точное имя.

Другая примерная функция, которая может быть полезна время от времени, — это та, которая вычисляет хеш MD5 из переданной строки. Мы можем использовать Java-класс MessageDigest для выполнения этой задачи в Groovy:

1
2
3
4
5
6
7
8
import java.security.MessageDigest
 
md5 = { str ->
  MessageDigest digest = MessageDigest.getInstance("MD5")
  digest.update(str.bytes)
  return new BigInteger(1, digest.digest()).toString(16).padLeft(32'0')
}

Чтобы вычислить хеш MD5, нам просто нужно вызвать функцию md5 ():

1
2
groovy:000> md5('test')
===> 098f6bcd4621d373cade4e832627b4f6

Но что, если мы хотим вычислить значение MD5 файла?

Если файл не такой большой, получить его содержимое так просто:

1
new File('test.txt').text

Нам просто нужно передать это в функцию md5 () для вычисления хеша md5 файла:

1
2
groovy:000> md5(new File('test.txt').text)
===> a4ba431c56925ce98ff04fa7d51a89bf

Может быть, вы много работаете с датой и временем. В этом случае может быть полезно добавить поддержку Joda-Time в вашу оболочку Groovy. Просто добавьте следующие строки в groovysh.profile:

1
2
@Grab('joda-time:joda-time:2.3'import org.joda.time.DateTime
import org.joda.time.DateTime

Если вы запустите groovysh в следующий раз, Joda-Time будет загружен с использованием Grape . Кроме того, класс Joda DateTime импортируется, поэтому его можно использовать в Groovy Console без добавления префикса имени пакета:

1
2
groovy:000new DateTime().plusDays(42)
===> 2014-04-22T22:27:20.860+02:00

Вам обычно нужно конвертировать значения времени в / из временных меток Unix?

Просто добавьте две простые функции для него, и вам больше не нужна закладка для онлайн-конвертера:

01
02
03
04
05
06
07
08
09
10
import java.text.SimpleDateFormat
dateFormat = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss')
 
toUnixTimestamp = { str ->
  return dateFormat.parse(str).getTime() / 1000
}
 
fromUnixTimestamp = { timestamp ->
  return dateFormat.format(new Date(timestamp.toLong() * 1000))
}

Использование в Groovy Shell:

1
2
3
4
groovy:000> toUnixTimestamp('2014-04-15 12:30:00')
===> 1397557800
groovy:000> fromUnixTimestamp('1397557800')
===> 2014-04-15 12:30:00

Может быть, вы хотите выполнить команду на удаленной машине?

Вам нужна только другая простая функция для выполнения этой задачи с Groovy Shell:

1
2
3
4
5
6
7
ssh = { cmd ->
  def proc = "ssh -i keyfile user@host $cmd".execute()
  proc.waitFor()
  println "return code: ${proc.exitValue()}"
  println "stderr: ${proc.err.text}"
  println "stdout: ${proc.in.text}" 
}

Использование:

1
2
3
4
5
6
7
8
groovy:000> ssh 'ls -l'
return code: 0
stderr:
stdout: total 1234
-rw-r--r-- 1 foo foo 7678563 Oct 28  2009 file
drwxr-xr-x 4 foo foo    4096 Mar  1 17:07 folder
-rw-r--r-- 1 foo foo      19 Feb 27 22:19 bar
...

Если вы не знали: в Groovy вы можете пропустить скобки при вызове функции с одним или несколькими параметрами. Таким образом, ssh ‘ls -l’ совпадает с ssh (‘ls -l’).

Вывод

Прежде чем перейти на Groovy Shell, я использовал оболочку Python практически по тем же причинам (даже если я вообще не работал с Python). В течение прошлого года я много использовал Groovy и быстро обнаружил, что Groovy Web Console является очень ценным инструментом для тестирования и создания прототипов. Для меня Groovy Shell заменил оба инструмента. Ясно, что это инструмент разработки, который я не хочу пропустить.

Я думаю, что это действительно зависит от вас, насколько вы позволили Groovy Shell помочь вам.