From dee392f22511b9e91dfa3dc089be30a940e027c9 Mon Sep 17 00:00:00 2001 From: murphy Date: Tue, 13 Jan 2009 16:00:19 +0000 Subject: New: *Groovy Scanner* (feature #60) * It inherits from Java Scanner, re-using some constants. * Thanks to Stefan Weinmann for helping me with Groovy. * PLEAC code used for testing. * Some issues with remain with strings and regexps. * Rating: 2 / 5 stars, "Basic support" * Added .groovy and .gvy to FileType. * CodeRay now supports a language that pygments doesn't support ;-) --- lib/coderay/helpers/file_type.rb | 2 + lib/coderay/scanners/groovy.rb | 247 + test/scanners/groovy/pleac.expected.raydebug | 10953 +++++++++++++++++++++++++ test/scanners/groovy/pleac.in.groovy | 10953 +++++++++++++++++++++++++ test/scanners/groovy/suite.rb | 4 + 5 files changed, 22159 insertions(+) create mode 100644 lib/coderay/scanners/groovy.rb create mode 100644 test/scanners/groovy/pleac.expected.raydebug create mode 100644 test/scanners/groovy/pleac.in.groovy create mode 100644 test/scanners/groovy/suite.rb diff --git a/lib/coderay/helpers/file_type.rb b/lib/coderay/helpers/file_type.rb index fbc95ec..3c5979a 100644 --- a/lib/coderay/helpers/file_type.rb +++ b/lib/coderay/helpers/file_type.rb @@ -87,6 +87,8 @@ module FileType 'mab' => :ruby, 'cpp' => :c, 'c' => :c, + 'gvy' => :groovy, + 'groovy' => :groovy, 'h' => :c, 'java' => :java, 'js' => :java_script, diff --git a/lib/coderay/scanners/groovy.rb b/lib/coderay/scanners/groovy.rb new file mode 100644 index 0000000..5e76357 --- /dev/null +++ b/lib/coderay/scanners/groovy.rb @@ -0,0 +1,247 @@ +module CodeRay +module Scanners + + load :java + + class Groovy < Java + + include Streamable + register_for :groovy + + # TODO: Check this! + KEYWORDS = Java::KEYWORDS + %w[ + def assert as in + ] + KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[ + case instanceof new return throw typeof while as assert in + ] + + MAGIC_VARIABLES = Java::MAGIC_VARIABLES + %w[ it ] + # DIRECTIVES = %w[ + # abstract extends final implements native private protected public + # static strictfp synchronized threadsafe throws transient volatile + # ] + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(MAGIC_VARIABLES, :local_variable). + add(TYPES, :type). + add(BuiltinTypes::List, :pre_type). + add(DIRECTIVES, :directive) + + ESCAPE = / [bfnrtv$\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # no 4-byte unicode chars? U[a-fA-F0-9]{8} + REGEXP_ESCAPE = / [bBdDsSwW] /x + STRING_CONTENT_PATTERN = { + "'" => /[^\\$'\n]+/, + '"' => /[^\\$"\n]+/, + "'''" => /(?>[^\\$']+|'(?!''))+/, + '"""' => /(?>[^\\$"]+|"(?!""))+/, + '/' => /[^\\$\/\n]+/, + } + + def scan_tokens tokens, options + + state = :initial + string_delimiter = nil + import_clause = class_name_follows = last_token_dot = after_def = false + value_expected = true + + until eos? + + kind = nil + match = nil + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + tokens << [match, :space] + if match.index ?\n + import_clause = after_def = false + value_expected = true + end + next + + elsif scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + value_expected = true + after_def = false + kind = :comment + + elsif bol? && scan(/ \#!.* /x) + kind = :doctype + + elsif import_clause && scan(/ (?!as) #{IDENT} (?: \. #{IDENT} )* (?: \.\* )? /ox) + after_def = value_expected = false + kind = :include + + elsif match = scan(/ #{IDENT} | \[\] /ox) + kind = IDENT_KIND[match] + value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match] + if last_token_dot + kind = :ident + elsif class_name_follows + kind = :class + class_name_follows = false + elsif after_def && check(/\s*[({]/) + kind = :method + after_def = false + elsif kind == :ident && check(/:/) + kind = :key + else + class_name_follows = true if match == 'class' || (import_clause && match == 'as') + import_clause = match == 'import' + after_def = true if match == 'def' + end + + # TODO: ~'...', ~"..." and ~/.../ style regexps + elsif scan(/ \.\.] | \+\+ | + && | \|\| | \*\*=? | ==?~ | [-+*%^~&|<>=!]=? | <<>>?=? /x) + value_expected = true + after_def = false + kind = :operator + + elsif scan(/ [)\]}]+ /x) + value_expected = after_def = false + + elsif scan(/;/) + import_clause = after_def = false + value_expected = true + kind = :operator + + elsif scan(/\{/) + class_name_follows = after_def = false + value_expected = true + kind = :operator + + elsif check(/[\d.]/) + after_def = value_expected = false + if scan(/0[xX][0-9A-Fa-f]+/) + kind = :hex + elsif scan(/(?>0[0-7]+)(?![89.eEfF])/) + kind = :oct + elsif scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/) + kind = :float + elsif scan(/\d+[lLgG]?/) + kind = :integer + end + + elsif match = scan(/'''|"""/) + after_def = value_expected = false + state = :multiline_string + tokens << [:open, :string] + string_delimiter = match + kind = :delimiter + + elsif match = scan(/["']/) + after_def = value_expected = false + state = match == '/' ? :regexp : :string + tokens << [:open, state] + string_delimiter = match + kind = :delimiter + + elsif value_expected && (match = scan(/\/(?=\S)/)) + after_def = value_expected = false + tokens << [:open, :regexp] + state = :regexp + string_delimiter = '/' + kind = :delimiter + + elsif scan(/ @ #{IDENT} /ox) + after_def = value_expected = false + kind = :annotation + + elsif scan(/\//) + after_def = false + value_expected = true + kind = :operator + + else + getch + kind = :error + + end + + when :string, :regexp, :multiline_string + if scan(STRING_CONTENT_PATTERN[string_delimiter]) + kind = :content + elsif match = scan(state == :multiline_string ? /'''|"""/ : /["'\/]/) + tokens << [match, :delimiter] + if state == :regexp + modifiers = scan(/[ix]+/) + tokens << [modifiers, :modifier] if modifiers && !modifiers.empty? + end + state = :string if state == :multiline_string + tokens << [:close, state] + string_delimiter = nil + after_def = value_expected = false + state = :initial + next + + elsif state == :string && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) + if string_delimiter == "'" && !(match == "\\\\" || match == "\\'") + kind = :content + else + kind = :char + end + elsif state == :regexp && scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + kind = :char + + elsif match = scan(/ \$ #{IDENT} /mox) + tokens << [:open, :inline] + tokens << ['$', :inline_delimiter] + match = match[1..-1] + tokens << [match, IDENT_KIND[match]] + tokens << [:close, :inline] + next + elsif match = scan(/ \$ \{ [^}]* \} /mox) + # TODO: recursive inline strings + tokens << [:open, :inline] + tokens << ['${', :inline_delimiter] + tokens << [match[2..-2], :ident] + tokens << ['}', :inline_delimiter] + tokens << [:close, :inline] + next + + elsif scan(/ \\. | \$ /mx) + kind = :content + + elsif scan(/ \\ | $ /x) + tokens << [:close, :delimiter] + kind = :error + after_def = value_expected = false + state = :initial + else + raise_inspect "else case \" reached; %p not handled." % peek(1), tokens + end + + else + raise_inspect 'Unknown state', tokens + + end + + match ||= matched + if $DEBUG and not kind + raise_inspect 'Error token %p in line %d' % + [[match, kind], line], tokens + end + raise_inspect 'Empty token', tokens unless match + + last_token_dot = match == '.' + + tokens << [match, kind] + + end + + if [:string, :regexp].include? state + tokens << [:close, state] + end + + tokens + end + + end + +end +end diff --git a/test/scanners/groovy/pleac.expected.raydebug b/test/scanners/groovy/pleac.expected.raydebug new file mode 100644 index 0000000..d66e50d --- /dev/null +++ b/test/scanners/groovy/pleac.expected.raydebug @@ -0,0 +1,10953 @@ +comment(// -*- groovy -*-) +comment(// The examples make use of Groovy's built-in assert) +comment(// command so that the script is self-checking) + +comment(// @@PLEAC@@_NAME) +comment(// @@SKIP@@ Groovy) + +comment(// @@PLEAC@@_WEB) +comment(// @@SKIP@@ http://groovy.codehaus.org) + +comment(// @@PLEAC@@_1.0) +comment(//----------------------------------------------------------------------------------) +ident(string) operator(=) string comment(// two characters, \\ and an n) +keyword(assert) ident(string)operator(.)ident(size)operator(()(\)) operator(==) integer(2) +ident(string) operator(=) string comment(// a "newline" character) +ident(string) operator(=) string comment(// a "newline" character) + +ident(string) operator(=) string comment(// literal single quote inside double quotes) +ident(string) operator(=) string comment(// escaped single quotes) + +ident(string) operator(=) string comment(// literal double quotes inside single quotes) +ident(string) operator(=) string comment(// escaped double quotes) + +ident(string) operator(=) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.1) +comment(//----------------------------------------------------------------------------------) +comment(// accessing substrings) +ident(string) operator(=) string +ident(start) operator(=) integer(5)operator(;) ident(end) operator(=) integer(7)operator(;) ident(endplus1) operator(=) integer(8) +keyword(assert) ident(string)operator(.)ident(substring)operator(()ident(start)operator(,) ident(endplus1)(\)) operator(==) string +keyword(assert) ident(string)operator([)ident(start)operator(..)ident(end)(]) operator(==) string + +keyword(assert) ident(string)operator(.)ident(substring)operator(()ident(start)(\)) operator(==) string +keyword(assert) ident(string)operator([)ident(start)operator(..)operator(-)integer(1)(]) operator(==) string + +comment(// String is immutable but new strings can be created in various ways) +keyword(assert) ident(string) operator(-) string operator(-) string operator(+) string operator(==) string +keyword(assert) ident(string)operator(.)ident(replace)operator(()stringoperator(,)string(\)) operator(==) string +keyword(assert) ident(string)operator(.)ident(substring)operator(()integer(0)operator(,) integer(2)(\)) operator(+) string operator(+) ident(string)operator([)operator(-)integer(2)operator(..)operator(-)integer(1)(]) operator(==) string +comment(// StringBuffer is mutable) +ident(sb) operator(=) keyword(new) pre_type(StringBuffer)operator(()ident(string)(\)) +ident(sb)operator([)integer(2)operator(..)operator(-)integer(3)(]) operator(=) string +keyword(assert) ident(sb)operator(.)ident(toString)operator(()(\)) operator(==) string + +comment(// No exact pack/unpack equivalents exist in Groovy. Examples here use a custom) +comment(// implementation to split an original string into chunks of specified length) +comment(// the method is a modified version of the Java PLEAC version) + +comment(// get a 5-character string, skip 8, then grab 2 5-character strings) +comment(// skipping the trailing spaces, then grab the rest) +ident(data) operator(=) string +keyword(def) ident(fields) operator(=) ident(unpack)operator(()stringoperator(,) ident(data)(\)) +keyword(assert) ident(fields) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +comment(// On a Java 5 or 6 JVM, Groovy can also make use of Scanners:) +ident(s) operator(=) keyword(new) pre_type(Scanner)operator(()ident(data)(\)) +ident(s)operator(.)ident(findInLine)operator(()regexp(\)) +ident(m) operator(=) ident(s)operator(.)ident(match)operator(()(\)) +ident(fields) operator(=) type([]) +operator(()integer(1)operator(..)ident(m)operator(.)ident(groupCount)operator(()(\)\))operator(.)ident(each)operator({) ident(fields) operator(<)operator(<) ident(m)operator(.)ident(group)operator(()local_variable(it)(\)) (}) +keyword(assert) ident(fields) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +comment(// another scanner example similar to the javadoc example) +ident(input) operator(=) string +ident(s) operator(=) keyword(new) pre_type(Scanner)operator(()ident(input)(\))operator(.)ident(useDelimiter)operator(()regexp(\)) +ident(fields) operator(=) type([]) +integer(2)operator(.)ident(times)operator({) ident(fields) operator(<)operator(<) ident(s)operator(.)ident(nextInt)operator(()(\)) (}) +integer(2)operator(.)ident(times)operator({) ident(fields) operator(<)operator(<) ident(s)operator(.)ident(next)operator(()(\)) (}) +keyword(assert) ident(fields) operator(==) operator([)integer(1)operator(,) integer(2)operator(,) stringoperator(,) string(]) + +comment(// split at five characters boundaries) +pre_type(String)type([]) ident(fivers) operator(=) ident(unpack)operator(()string operator(*) operator(()ident(data)operator(.)ident(length)operator(()(\)) operator(/) integer(5)(\))operator(,) ident(data)(\)) +keyword(assert) ident(fivers) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +comment(// chop string into individual characters) +keyword(assert) string keyword(as) pre_type(String)type([]) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +ident(string) operator(=) string +comment(// Indexing forwards (left to right\)) +comment(// tens 000000000011111111112) +comment(// units +012345678901234567890) +comment(// Indexing backwards (right to left\)) +comment(// tens 221111111111000000000) +comment(// units 109876543210987654321-) + +keyword(assert) ident(string)operator([)integer(0)(]) operator(==) string +keyword(assert) ident(string)operator([)integer(5)operator(..)integer(6)(]) operator(==) string +keyword(assert) ident(string)operator([)integer(13)operator(..)operator(-)integer(1)(]) operator(==) string +keyword(assert) ident(string)operator([)operator(-)integer(1)(]) operator(==) string +keyword(assert) ident(string)operator([)operator(-)integer(4)operator(..)operator(-)integer(1)(]) operator(==) string +keyword(assert) ident(string)operator([)operator(-)integer(8)operator(,) operator(-)integer(7)operator(,) operator(-)integer(6)(]) operator(==) string + +ident(data) operator(=) keyword(new) pre_type(StringBuffer)operator(()ident(string)(\)) +ident(data)operator([)integer(5)operator(..)integer(6)(]) operator(=) string operator(;) keyword(assert) ident(data)operator(.)ident(toString)operator(()(\)) operator(==) string +ident(data)operator([)operator(-)integer(12)operator(..)operator(-)integer(1)(]) operator(=) string operator(;) keyword(assert) ident(data)operator(.)ident(toString)operator(()(\)) operator(==) string +ident(data)operator([)integer(0)operator(..)integer(0)(]) operator(=) string operator(;) keyword(assert) ident(data)operator(.)ident(toString)operator(()(\)) operator(==) string +ident(data)operator([)operator(-)integer(10)operator(..)operator(-)integer(1)(]) operator(=) string operator(;) keyword(assert) ident(data)operator(.)ident(toString)operator(()(\)) operator(==) string + +ident(string) operator(=) string +comment(// check last ten characters match some pattern) +keyword(assert) ident(string)operator([)operator(-)integer(10)operator(..)operator(-)integer(1)(]) operator(=~) regexp + +ident(string) operator(=) string +keyword(assert) ident(string)operator([)integer(0)operator(..)integer(4)(])operator(.)ident(replaceAll)operator(()stringoperator(,) string(\)) operator(+) ident(string)operator([)integer(5)operator(..)operator(-)integer(1)(]) operator(==) string + +comment(// exchange the first and last letters in a string) +ident(string) operator(=) string +ident(string) operator(=) ident(string)operator([)operator(-)integer(1)(]) operator(+) ident(string)operator([)integer(1)operator(..)operator(-)integer(2)(]) operator(+) ident(string)operator([)integer(0)(]) +keyword(assert) ident(string) operator(==) string + +comment(// extract column with unpack) +ident(string) operator(=) string + +comment(// skip 6, grab 6) +keyword(assert) ident(unpack)operator(()stringoperator(,) ident(string)(\)) operator(==) operator([)string(]) + +comment(// forward 6, grab 2, backward 5, grab 2) +keyword(assert) ident(unpack)operator(()stringoperator(,) ident(string)(\)) operator(==) operator([)stringoperator(,) string(]) + +keyword(assert) ident(cut2fmt)operator(()operator([)integer(8)operator(,) integer(14)operator(,) integer(20)operator(,) integer(26)operator(,) integer(30)(]\)) operator(==) string + +comment(// utility method (derived from Java PLEAC version\)) +keyword(def) method(unpack)operator(()pre_type(String) ident(format)operator(,) pre_type(String) ident(data)(\)) operator({) + keyword(def) ident(result) operator(=) type([]) + type(int) ident(formatOffset) operator(=) integer(0)operator(,) ident(dataOffset) operator(=) integer(0) + type(int) ident(minDataOffset) operator(=) integer(0)operator(,) ident(maxDataOffset) operator(=) ident(data)operator(.)ident(size)operator(()(\)) + + keyword(new) pre_type(StringTokenizer)operator(()ident(format)(\))operator(.)ident(each)operator({) ident(token) operator(->) + type(int) ident(tokenLen) operator(=) ident(token)operator(.)ident(length)operator(()(\)) + + comment(// count determination) + type(int) ident(count) operator(=) integer(0) + keyword(if) operator(()ident(tokenLen) operator(==) integer(1)(\)) ident(count) operator(=) integer(1) + keyword(else) keyword(if) operator(()ident(token)operator(.)ident(charAt)operator(()integer(1)(\)) operator(==) string(\)) ident(count) operator(=) operator(-)integer(1) + keyword(else) ident(count) operator(=) ident(token)operator([)integer(1)operator(..)operator(-)integer(1)(])operator(.)ident(toInteger)operator(()(\)) + + comment(// action determination) + type(char) ident(action) operator(=) ident(token)operator(.)ident(charAt)operator(()integer(0)(\)) + keyword(switch) operator(()ident(action)(\)) operator({) + keyword(case) stringoperator(:) + keyword(if) operator(()ident(count) operator(==) operator(-)integer(1)(\)) operator({) + ident(start) operator(=) operator([)ident(dataOffset)operator(,) ident(maxDataOffset)(])operator(.)ident(min)operator(()(\)) + ident(result)operator(.)ident(add)operator(()ident(data)operator([)ident(start)operator(..)operator(-)integer(1)(]\)) + ident(dataOffset) operator(=) ident(maxDataOffset) + (}) keyword(else) operator({) + ident(start) operator(=) operator([)ident(dataOffset)operator(,) ident(maxDataOffset)(])operator(.)ident(min)operator(()(\)) + ident(end) operator(=) operator([)ident(dataOffset) operator(+) ident(count)operator(,) ident(maxDataOffset)(])operator(.)ident(min)operator(()(\)) + ident(result)operator(.)ident(add)operator(()ident(data)operator([)ident(start)operator(..<)ident(end)(]\)) + ident(dataOffset) operator(+=) ident(count) + (}) + keyword(break) + keyword(case) stringoperator(:) + keyword(if) operator(()ident(count) operator(==) operator(-)integer(1)(\)) ident(dataOffset) operator(=) ident(maxDataOffset) + keyword(else) ident(dataOffset) operator(+=) ident(count) + keyword(break) + keyword(case) stringoperator(:) + keyword(if) operator(()ident(count) operator(==) operator(-)integer(1)(\)) ident(dataOffset) operator(=) ident(minDataOffset) + keyword(else) ident(dataOffset) operator(-=) ident(count) + keyword(break) + keyword(default)operator(:) + keyword(throw) keyword(new) pre_type(RuntimeException)operator(()stringoperator(,) ident(formatOffset)(\)) + (}) + ident(formatOffset) operator(+=) ident(tokenLen) operator(+) integer(1) + (}) + keyword(return) ident(result) keyword(as) pre_type(String)type([]) +(}) + +comment(// utility method) +keyword(def) method(cut2fmt)operator(()ident(positions)(\)) operator({) + ident(template) operator(=) string + ident(lastpos) operator(=) integer(1) + keyword(for) operator(()ident(pos) keyword(in) ident(positions)(\)) operator({) + ident(template) operator(+=) string operator(+) operator(()ident(pos) operator(-) ident(lastpos)(\)) operator(+) string + ident(lastpos) operator(=) ident(pos) + (}) + keyword(return) ident(template) operator(+) string +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.2) +comment(//----------------------------------------------------------------------------------) +comment(// use b if b is true, else c) +ident(b) operator(=) keyword(false)operator(;) ident(c) operator(=) string +keyword(assert) operator(()ident(b) operator(?) ident(b) operator(:) ident(c)(\)) operator(==) string +ident(b) operator(=) keyword(true) +keyword(assert) operator(()ident(b) operator(?) ident(b) operator(:) ident(c)(\)) +comment(// can be simplified to 'b || c' if c is a boolean) +comment(// strictly speaking, b doesn't have to be a boolean,) +comment(// e.g. an empty list is coerced to boolean false) +ident(b) operator(=) type([]) +keyword(assert) operator(()ident(b) operator(?) ident(b) operator(:) ident(c)(\)) operator(==) string + +comment(// set x to y unless x is already true) +ident(x) operator(=) keyword(false)operator(;) ident(y) operator(=) string +keyword(if) operator(()operator(!)ident(x)(\)) ident(x) operator(=) ident(y) +keyword(assert) ident(x) operator(==) string +comment(// can be simplified to 'x ||= y' if y is a boolean) +comment(// x doesn't need to be a boolean, e.g. a non-empty) +comment(// string is coerced to boolean true) +ident(x) operator(=) string +keyword(if) operator(()operator(!)ident(x)(\)) ident(x) operator(=) ident(y) +keyword(assert) ident(x) operator(==) string + +comment(// JVM supplies user name) +comment(// otherwise could use exec or built-in Ant features for reading environment vars) +keyword(assert) pre_type(System)operator(.)ident(getProperty)operator(()string(\)) + +comment(// test for nullity then for emptyness) +keyword(def) method(setDefaultIfNullOrEmpty)operator(()ident(startingPoint)(\)) operator({) + operator(()operator(!)ident(startingPoint) operator(||) ident(startingPoint)operator(.)ident(length)operator(()(\)) operator(==) integer(0)(\)) operator(?) string operator(:) ident(startingPoint) +(}) +keyword(assert) ident(setDefaultIfNullOrEmpty)operator(()keyword(null)(\)) operator(==) string +keyword(assert) ident(setDefaultIfNullOrEmpty)operator(()string(\)) operator(==) string +keyword(assert) ident(setDefaultIfNullOrEmpty)operator(()string(\)) operator(==) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.3) +comment(//----------------------------------------------------------------------------------) +ident(v1) operator(=) stringoperator(;) ident(v2) operator(=) string +comment(// this can done with explicit swapping via a temp variable) +comment(// or in a slightly more interesting way with a closure) +ident(swap) operator(=) operator({) ident(temp) operator(=) ident(v1)operator(;) ident(v1) operator(=) ident(v2)operator(;) ident(v2) operator(=) ident(temp) (}) +ident(swap)operator(()(\)) +keyword(assert) ident(v1) operator(==) string operator(&&) ident(v2) operator(==) string +comment(// a more generic swap(\) is also possible using Groovy's metaclass mechanisms) +comment(// but is not idiomatic of Groovy usage) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.4) +comment(//----------------------------------------------------------------------------------) +comment(// char and int are interchangable, apart from precision difference) +comment(// char use 16 bits while int use 32, requiring a cast from int to char) +type(char) ident(ch) operator(=) string +type(int) ident(num) operator(=) ident(ch) comment(// no problem) +ident(ch) operator(=) operator(()type(char)(\)) ident(num) comment(// needs an explicit cast) + +ident(s1) operator(=) string operator(+) ident(num) operator(+) string operator(+) operator(()type(char)(\)) ident(num) +keyword(assert) ident(s1) operator(==) string +ident(s2) operator(=) string operator(+) ident(ch) operator(+) string operator(+) operator(()type(int)(\)) ident(ch) +keyword(assert) ident(s2) operator(==) string + +comment(// easy conversion between char arrays, char lists and Strings) +type(char)type([]) ident(ascii) operator(=) stringoperator(.)ident(toCharArray)operator(()(\)) comment(// {115, 97, 109, 112, 108, 101}) +keyword(assert) keyword(new) pre_type(String)operator(()ident(ascii)(\)) operator(==) string +keyword(assert) keyword(new) pre_type(String)operator(()operator([)integer(115)operator(,) integer(97)operator(,) integer(109)operator(,) integer(112)operator(,) integer(108)operator(,) integer(101)(]) keyword(as) type(char)type([])(\)) operator(==) string + +comment(// convert 'HAL' to 'IBM' (in increasing order of Grooviness\)) +keyword(assert) stringoperator(.)ident(toCharArray)operator(()(\))operator(.)ident(collect)operator({)keyword(new) pre_type(String)operator(()local_variable(it)operator(+)integer(1) keyword(as) type(char)type([])(\)})operator(.)ident(join)operator(()(\)) operator(==) string +keyword(assert) operator(()string keyword(as) pre_type(String)type([])(\))operator(.)ident(collect)operator({)local_variable(it)operator(.)ident(next)operator(()(\)})operator(.)ident(join)operator(()(\)) operator(==) string +keyword(assert) stringoperator(.)ident(replaceAll)operator(()stringoperator(,) operator({)local_variable(it)operator(.)ident(next)operator(()(\)}\)) operator(==) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.5) +comment(//----------------------------------------------------------------------------------) +ident(string) operator(=) string +keyword(assert) ident(string)operator([)integer(3)operator(..)integer(7)(])operator(.)ident(split)operator(()string(\))operator([)integer(1)operator(..)integer(5)(]) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(]) +keyword(assert) ident(string)operator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\))operator(.)ident(unique)operator(()(\))operator(.)ident(sort)operator(()(\))operator(.)ident(join)operator(()(\)) operator(==) string + +comment(//----------------------------------------------------------------------------------) +comment(// CheckSum.groovy: Compute 16-bit checksum of input file) +comment(// Usage: groovy CheckSum ) +comment(// script:) +ident(checksum) operator(=) integer(0) +keyword(new) pre_type(File)operator(()ident(args)operator([)integer(0)(]\))operator(.)ident(eachByte)operator({) ident(checksum) operator(+=) local_variable(it) (}) +ident(checksum) operator(%=) operator(()type(int)(\)) pre_type(Math)operator(.)ident(pow)operator(()integer(2)operator(,) integer(16)(\)) operator(-) integer(1) +ident(println) ident(checksum) +comment(//----------------------------------------------------------------------------------) +comment(// to run on its own source code:) +comment(//=> % groovy CheckSum CheckSum.groovy) +comment(//=> 9349) +comment(//----------------------------------------------------------------------------------) +comment(// Slowcat.groovy: Emulate a s l o w line printer) +comment(// Usage: groovy Slowcat ) +comment(// script:) +ident(delay) operator(=) ident(args)operator([)integer(1)(])operator(.)ident(toInteger)operator(()(\)) +keyword(new) pre_type(File)operator(()ident(args)operator([)integer(0)(]\))operator(.)ident(eachByte)operator({) ident(print) operator(()operator(()type(char)(\)) local_variable(it)(\))operator(;) pre_type(Thread)operator(.)ident(sleep)operator(()ident(delay)(\)) (}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.6) +comment(//----------------------------------------------------------------------------------) +keyword(assert) stringoperator(.)ident(reverse)operator(()(\)) operator(==) string + +ident(string) operator(=) string +ident(revwords) operator(=) ident(string)operator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\))operator(.)ident(reverse)operator(()(\))operator(.)ident(join)operator(()string(\)) +keyword(assert) ident(revwords) operator(==) string + +ident(words) operator(=) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(]) +ident(long_palindromes) operator(=) ident(words)operator(.)ident(findAll)operator({) ident(w) operator(->) ident(w) operator(==) ident(w)operator(.)ident(reverse)operator(()(\)) operator(&&) ident(w)operator(.)ident(size)operator(()(\)) operator(>) integer(5) (}) +keyword(assert) ident(long_palindromes) operator(==) operator([)stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.7) +comment(//----------------------------------------------------------------------------------) +ident(s1) operator(=) string +ident(s2) operator(=) string +keyword(def) method(expand)operator(()ident(s)(\)) operator({) + ident(s)operator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\))operator(.)ident(collect)operator({) + ident(line) operator(=) local_variable(it) + keyword(while) operator(()ident(line)operator(.)ident(contains)operator(()string(\)\)) operator({) + ident(line) operator(=) ident(line)operator(.)ident(replaceAll)operator(()regexp(\))operator({) + ident(all)operator(,)ident(pre)operator(,)ident(tab)operator(,)ident(suf) operator(->) ident(pre) operator(+) string operator(*) operator(()integer(8) operator(-) ident(pre)operator(.)ident(size)operator(()(\)) operator(%) integer(8)(\)) operator(+) ident(suf) + (}) + (}) + keyword(return) ident(line) + (})operator(.)ident(join)operator(()string(\)) +(}) +keyword(def) method(unexpand)operator(()ident(s)(\)) operator({) + ident(s)operator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\))operator(.)ident(collect)operator({) + ident(line) operator(=) local_variable(it) + keyword(for) operator(()ident(i) keyword(in) ident(line)operator(.)ident(size)operator(()(\))operator(-)integer(1)operator(..)integer(1)(\)) operator({) + keyword(if) operator(()ident(i) operator(%) integer(8) operator(==) integer(0)(\)) operator({) + ident(prefix) operator(=) ident(line)operator([)integer(0)operator(..<)ident(i)(]) + keyword(if) operator(()ident(prefix)operator(.)ident(trim)operator(()(\))operator(.)ident(size)operator(()(\)) operator(!=) ident(prefix)operator(.)ident(size)operator(()(\)\)) operator({) + ident(line) operator(=) ident(prefix)operator(.)ident(trim)operator(()(\)) operator(+) string operator(+) ident(line)operator([)ident(i)operator(..)operator(-)integer(1)(]) + (}) + (}) + (}) + keyword(return) ident(line) + (})operator(.)ident(join)operator(()string(\)) +(}) +keyword(assert) ident(expand)operator(()ident(s1)(\)) operator(==) ident(s2) +keyword(assert) ident(unexpand)operator(()ident(s2)(\)) operator(==) ident(s1) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.8) +comment(//----------------------------------------------------------------------------------) +ident(debt) operator(=) integer(150) +keyword(assert) stringcontent( to me)delimiter(")> operator(==) string + +ident(rows) operator(=) integer(24)operator(;) ident(cols) operator(=) integer(80) +keyword(assert) stringcontent( high and )inlinecontent( wide)delimiter(")> operator(==) string + +keyword(assert) stringoperator(.)ident(replaceAll)operator(()regexpoperator(,) operator({)integer(2)operator(*)local_variable(it)operator(.)ident(toInteger)operator(()(\)}\)) operator(==) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.9) +comment(//----------------------------------------------------------------------------------) +keyword(assert) stringoperator(.)ident(toUpperCase)operator(()(\)) operator(==) string +keyword(assert) stringoperator(.)ident(toLowerCase)operator(()(\)) operator(==) string +keyword(def) method(capitalize)operator(()ident(s)(\)) operator({)ident(s)operator([)integer(0)(])operator(.)ident(toUpperCase)operator(()(\)) operator(+) operator(()ident(s)operator(.)ident(size)operator(()(\))operator(<)integer(2) operator(?) string operator(:) ident(s)operator([)integer(1)operator(..)operator(-)integer(1)(])operator(?)operator(.)ident(toLowerCase)operator(()(\)\)}) +keyword(assert) ident(capitalize)operator(()string(\)) operator(==) string + +ident(s) operator(=) stringoperator(.)ident(replaceAll)operator(()regexp(\))operator({)ident(capitalize)operator(()local_variable(it)(\)}) +keyword(assert) ident(s) operator(==) string + +ident(s1) operator(=) stringoperator(;) ident(s2) operator(=) string +keyword(assert) ident(s1)operator(.)ident(equalsIgnoreCase)operator(()ident(s2)(\)) + +directive(private) pre_type(Random) ident(rand) +keyword(def) method(randomCase)operator(()type(char) ident(ch)(\)) operator({) + operator(()ident(rand)operator(.)ident(nextInt)operator(()integer(100)(\)) operator(<) integer(20)(\)) operator(?) pre_type(Character)operator(.)ident(toLowerCase)operator(()ident(ch)(\)) operator(:) ident(ch) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.10) +comment(//----------------------------------------------------------------------------------) +ident(n) operator(=) integer(10) +keyword(assert) stringcontent( guanacos.)delimiter(")> operator(==) string +keyword(assert) string operator(+) operator(()ident(n)operator(+)integer(1)(\)) operator(+) string operator(==) string + +comment(// sending templated email is solved in two parts: templating and sending) +comment(// Part 1: creating an email template) +ident(naughty) operator(=) string +keyword(def) method(get_manager_list)operator(()ident(s)(\)) operator({) string (}) +ident(msg) operator(=) stringcontent( +From: Your Bank +Cc: )inlinecontent( +Date: )inlinecontent( + +Dear )inlinecontent(, + +Today, you bounced check number )inlinecontent( to us. +Your account is now closed. + +Sincerely, +the management +)delimiter(""")> +ident(expected) operator(=) string +ident(sanitized) operator(=) ident(msg)operator(.)ident(replaceAll)operator(()stringoperator(,)string(\)) +ident(sanitized) operator(=) ident(sanitized)operator(.)ident(replaceAll)operator(()regexpoperator(,)string(\)) +keyword(assert) ident(sanitized) operator(==) ident(expected) +comment(// note: Groovy also has several additional built-in templating facilities) +comment(// Part 2: sending email) +comment(// SendMail.groovy: Send email) +comment(// Usage: groovy SendEmail ) +comment(// script:) +ident(ant) operator(=) keyword(new) ident(AntBuilder)operator(()(\)) +ident(ant)operator(.)ident(mail)operator(()key(from)operator(:)stringoperator(,) key(tolist)operator(:)stringoperator(,) + key(encoding)operator(:)stringoperator(,) key(mailhost)operator(:)stringoperator(,) + key(subject)operator(:)stringoperator(,) key(message)operator(:)string(\)) +comment(// Ant has many options for setting encoding, security, attachments, etc., see:) +comment(// http://ant.apache.org/manual/CoreTasks/mail.html) +comment(// Groovy could also use the Java Mail Api directly if required) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.11) +comment(//----------------------------------------------------------------------------------) +keyword(def) ident(raw) operator(=) string + +keyword(def) ident(expected) operator(=) string + +keyword(assert) ident(raw)operator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\))operator(.)ident(collect)operator({) + local_variable(it)operator(.)ident(replaceAll)operator(()regexpoperator(,)string(\)) +(})operator(.)ident(join)operator(()string(\)) operator(+) string operator(==) ident(expected) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.12) +comment(//----------------------------------------------------------------------------------) +ident(input) operator(=) string + +ident(expected) operator(=) string + +keyword(def) method(wrap)operator(()ident(text)operator(,) ident(maxSize)(\)) operator({) + ident(all) operator(=) type([]) + ident(line) operator(=) string + ident(text)operator(.)ident(eachMatch)operator(()regexp(\)) operator({) + ident(word) operator(=) local_variable(it)operator([)integer(0)(]) + keyword(if) operator(()ident(line)operator(.)ident(size)operator(()(\)) operator(+) integer(1) operator(+) ident(word)operator(.)ident(size)operator(()(\)) operator(>) ident(maxSize)(\)) operator({) + ident(all) operator(+=) ident(line) + ident(line) operator(=) ident(word) + (}) keyword(else) operator({) + ident(line) operator(+=) operator(()ident(line) operator(==) string operator(?) ident(word) operator(:) string operator(+) ident(word)(\)) + (}) + (}) + ident(all) operator(+=) ident(line) + keyword(return) ident(all)operator(.)ident(join)operator(()string(\)) +(}) +keyword(assert) ident(wrap)operator(()ident(input)operator(,) integer(20)(\)) operator(==) ident(expected) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.13) +comment(//----------------------------------------------------------------------------------) +ident(string) operator(=) regexp +comment(// backslash special chars) +keyword(assert) ident(string)operator(.)ident(replaceAll)operator(()regexp(\))operator({)regexpoperator(+)local_variable(it)operator([)integer(0)(]}) operator(==) regexp comment(//') +comment(// double special chars) +keyword(assert) ident(string)operator(.)ident(replaceAll)operator(()regexp(\))operator({)local_variable(it)operator([)integer(0)(])operator(+)local_variable(it)operator([)integer(0)(]}) operator(==) regexp comment(//') +comment(//backslash quote all non-capital letters) +keyword(assert) stringoperator(.)ident(replaceAll)operator(()regexp(\))operator({)regexpoperator(+)local_variable(it)operator([)integer(0)(]}) operator(==) regexp +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.14) +comment(//----------------------------------------------------------------------------------) +keyword(assert) stringoperator(.)ident(trim)operator(()(\)) operator(==) string +comment(// print what's typed, but surrounded by >< symbols) +comment(// script:) +keyword(new) pre_type(BufferedReader)operator(()keyword(new) pre_type(InputStreamReader)operator(()pre_type(System)operator(.)ident(in)(\)\))operator(.)ident(eachLine)operator({) + ident(println)operator(()string)delimiter(")> operator(+) local_variable(it)operator(.)ident(trim)operator(()(\)) operator(+) string(\))operator(;) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.15) +comment(//----------------------------------------------------------------------------------) +ident(pattern) operator(=) regexp +ident(line) operator(=) regexp +ident(m) operator(=) ident(line) operator(=~) ident(pattern) +ident(expected) operator(=) operator([)regexpoperator(,) stringoperator(,) regexpoperator(,) regexpoperator(,) comment(//') + regexpoperator(,) regexpoperator(,) regexp(]) +keyword(for) operator(()ident(i) keyword(in) integer(0)operator(..<)ident(m)operator(.)ident(size)operator(()(\))operator(.)ident(toInteger)operator(()(\)\)) + keyword(assert) ident(expected)operator([)ident(i)(]) operator(==) operator(()ident(m)operator([)ident(i)(])operator([)integer(2)(]) operator(?) ident(m)operator([)ident(i)(])operator([)integer(2)(]) operator(:) ident(m)operator([)ident(i)(])operator([)integer(1)(]\)) + +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.16) +comment(//----------------------------------------------------------------------------------) +comment(// A quick google search found several Java implementations.) +comment(// As an example, how to use commons codec is shown below.) +comment(// Just place the respective jar in your classpath.) +comment(// Further details: http://jakarta.apache.org/commons/codec) +comment(// require(groupId:'commons-codec', artifactId:'commons-codec', version:'1.3'\)) +ident(soundex) operator(=) keyword(new) ident(org)operator(.)ident(apache)operator(.)ident(commons)operator(.)ident(codec)operator(.)ident(language)operator(.)ident(Soundex)operator(()(\)) +keyword(assert) ident(soundex)operator(.)ident(soundex)operator(()string(\)) operator(==) ident(soundex)operator(.)ident(soundex)operator(()string(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.17) +comment(//----------------------------------------------------------------------------------) +ident(input) operator(=) string comment(//') + +ident(expected) operator(=) string comment(//') + +ident(translations) operator(=) operator([)key(colour)operator(:)stringoperator(,) key(analysed)operator(:)stringoperator(,) key(dropin)operator(:)string(]) + +keyword(def) method(fixstyle)operator(()ident(s)(\)) operator({) + ident(s)operator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\))operator(.)ident(collect)operator({) + ident(line) operator(=) local_variable(it) + ident(translations)operator(.)ident(each)operator({) ident(key)operator(,) ident(value) operator(->) + ident(line) operator(=) ident(line)operator(.)ident(replaceAll)operator(()regexp operator(+) ident(key) operator(+) regexpoperator(,) ident(value)(\)) + (}) + keyword(return) ident(line) + (})operator(.)ident(join)operator(()string(\)) +(}) +keyword(assert) ident(fixstyle)operator(()ident(input)(\)) operator(==) ident(expected) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_1.18) +comment(//----------------------------------------------------------------------------------) +comment(// Solved in two parts: 'screenscrape' text stream and return stream from process) +comment(// Part 1: text scraping) +ident(input) operator(=) string +ident(select1) operator(=) string +ident(select2) operator(=) string + +comment(// line below must be configured for your unix - this one's cygwin) +ident(format) operator(=) ident(cut2fmt)operator(()operator([)integer(10)operator(,) integer(18)operator(,) integer(26)operator(,) integer(37)operator(,) integer(42)operator(,) integer(47)operator(,) integer(56)(]\)) +keyword(def) method(psgrep)operator(()ident(s)(\)) operator({) + ident(out) operator(=) type([]) + ident(lines) operator(=) ident(input)operator(.)ident(split)operator(()string(\))operator(.)ident(findAll)operator({) local_variable(it)operator(.)ident(size)operator(()(\)) (}) + ident(vars) operator(=) ident(unpack)operator(()ident(format)operator(,) ident(lines)operator([)integer(0)(]\))operator(.)ident(toList)operator(()(\))operator(.)ident(collect)operator({) local_variable(it)operator(.)ident(toLowerCase)operator(()(\))operator(.)ident(trim)operator(()(\)) (}) + ident(out) operator(+=) ident(lines)operator([)integer(0)(]) + ident(lines)operator([)integer(1)operator(..)operator(-)integer(1)(])operator(.)ident(each)operator({) + ident(values) operator(=) ident(unpack)operator(()ident(format)operator(,) local_variable(it)(\))operator(.)ident(toList)operator(()(\))operator(.)ident(collect)operator({) + keyword(try) operator({) + keyword(return) local_variable(it)operator(.)ident(toInteger)operator(()(\)) + (}) keyword(catch)operator(()pre_type(NumberFormatException) ident(e)(\)) operator({) + keyword(return) local_variable(it)operator(.)ident(trim)operator(()(\)) + (}) + (}) + ident(vars)operator(.)ident(eachWithIndex)operator({) ident(var)operator(,) ident(i) operator(->) + ident(binding)operator(.)ident(setVariable)operator(()ident(var)operator(,) ident(values)operator([)ident(i)(]\)) + (}) + keyword(if) operator(()keyword(new) ident(GroovyShell)operator(()ident(binding)(\))operator(.)ident(evaluate)operator(()ident(s)(\)\)) ident(out) operator(+=) local_variable(it) + (}) + keyword(return) string operator(+) ident(out)operator(.)ident(join)operator(()string(\)) operator(+) string +(}) +keyword(assert) ident(psgrep)operator(()string(\)) operator(==) ident(select1) +keyword(assert) ident(psgrep)operator(()string(\)) operator(==) ident(select2) +comment(// Part 2: obtaining text stream from process) +comment(// unixScript:) +ident(input) operator(=) stringoperator(.)ident(execute)operator(()(\))operator(.)ident(text) +comment(// cygwinScript:) +ident(input) operator(=) stringoperator(.)ident(execute)operator(()(\))operator(.)ident(text) +comment(// windowsScript:) +comment(// can use something like sysinternal.com s pslist (with minor script tweaks\)) +ident(input) operator(=) stringoperator(.)ident(execute)operator(()(\))operator(.)ident(text) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.1) +comment(//----------------------------------------------------------------------------------) +comment(// four approaches possible (shown for Integers, similar for floats, double etc.\):) +comment(// (1\) NumberFormat.getInstance(\).parse(s\) // getInstance(\) can take locale) +comment(// (2\) Integer.parseInt(s\)) +comment(// (3\) new Integer(s\)) +comment(// (4\) regex) +keyword(import) include(java.text.*) +type(int) ident(nb) operator(=) integer(0) +keyword(try) operator({) + ident(nb) operator(=) pre_type(NumberFormat)operator(.)ident(getInstance)operator(()(\))operator(.)ident(parse)operator(()string(\)) comment(// '.5' will be ignored) + ident(nb) operator(=) pre_type(NumberFormat)operator(.)ident(getInstance)operator(()(\))operator(.)ident(parse)operator(()string(\)) +(}) keyword(catch) operator(()pre_type(ParseException) ident(ex)(\)) operator({) + keyword(assert) ident(ex)operator(.)ident(getMessage)operator(()(\))operator(.)ident(contains)operator(()string(\)) +(}) +keyword(assert) ident(nb) operator(==) integer(33) + +keyword(try) operator({) + ident(nb) operator(=) pre_type(Integer)operator(.)ident(parseInt)operator(()string(\)) + keyword(assert) ident(nb) operator(==) integer(34) + ident(nb) operator(=) keyword(new) pre_type(Integer)operator(()string(\)) + ident(nb) operator(=) pre_type(Integer)operator(.)ident(parseInt)operator(()string(\)) +(}) keyword(catch) operator(()pre_type(NumberFormatException) ident(ex)(\)) operator({) + keyword(assert) ident(ex)operator(.)ident(getMessage)operator(()(\))operator(.)ident(contains)operator(()string(\)) +(}) +keyword(assert) ident(nb) operator(==) integer(35) + +ident(integerPattern) operator(=) regexp +keyword(assert) string operator(=~) ident(integerPattern) +keyword(assert) operator(!)operator(()string operator(=~) ident(integerPattern)(\)) +ident(decimalPattern) operator(=) regexp +keyword(assert) string operator(=~) ident(decimalPattern) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.2) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy defaults to BigDecimal if you don't use an explicit float or double) +ident(wage) operator(=) float(5.36) +ident(week) operator(=) integer(40) operator(*) ident(wage) +keyword(assert) stringdelimiter(")> operator(==) regexp +comment(// if you want to use explicit doubles and floats you can still use) +comment(// printf in version 5, 6 or 7 JVMs) +comment(// printf('%5.2f', week as double\)) +comment(// => 214.40) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.3) +comment(//----------------------------------------------------------------------------------) +ident(a) operator(=) float(0.255) +ident(b) operator(=) ident(a)operator(.)ident(setScale)operator(()integer(2)operator(,) pre_type(BigDecimal)operator(.)ident(ROUND_HALF_UP)(\))operator(;) +keyword(assert) ident(a)operator(.)ident(toString)operator(()(\)) operator(==) string +keyword(assert) ident(b)operator(.)ident(toString)operator(()(\)) operator(==) string + +ident(a) operator(=) operator([)float(3.3) operator(,) float(3.5) operator(,) float(3.7)operator(,) operator(-)float(3.3)(]) keyword(as) type(double)type([]) +comment(// warning rint(\) rounds to nearest integer - slightly different to Perl's int(\)) +ident(rintExpected) operator(=) operator([)float(3.0)operator(,) float(4.0)operator(,) float(4.0)operator(,) operator(-)float(3.0)(]) keyword(as) type(double)type([]) +ident(floorExpected) operator(=) operator([)float(3.0)operator(,) float(3.0)operator(,) float(3.0)operator(,) operator(-)float(4.0)(]) keyword(as) type(double)type([]) +ident(ceilExpected) operator(=) operator([)float(4.0)operator(,) float(4.0)operator(,) float(4.0)operator(,) operator(-)float(3.0)(]) keyword(as) type(double)type([]) +ident(a)operator(.)ident(eachWithIndex)operator({) ident(val)operator(,) ident(i) operator(->) + keyword(assert) pre_type(Math)operator(.)ident(rint)operator(()ident(val)(\)) operator(==) ident(rintExpected)operator([)ident(i)(]) + keyword(assert) pre_type(Math)operator(.)ident(floor)operator(()ident(val)(\)) operator(==) ident(floorExpected)operator([)ident(i)(]) + keyword(assert) pre_type(Math)operator(.)ident(ceil)operator(()ident(val)(\)) operator(==) ident(ceilExpected)operator([)ident(i)(]) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.4) +comment(//----------------------------------------------------------------------------------) +keyword(assert) pre_type(Integer)operator(.)ident(parseInt)operator(()stringoperator(,) integer(2)(\)) operator(==) integer(54) +keyword(assert) pre_type(Integer)operator(.)ident(toString)operator(()integer(54)operator(,) integer(2)(\)) operator(==) string +comment(// also works for other radix values, e.g. hex) +keyword(assert) pre_type(Integer)operator(.)ident(toString)operator(()integer(60)operator(,) integer(16)(\)) operator(==) string + +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.5) +comment(//----------------------------------------------------------------------------------) +ident(x) operator(=) integer(3)operator(;) ident(y) operator(=) integer(20) +keyword(for) operator(()ident(i) keyword(in) ident(x)operator(..)ident(y)(\)) operator({) + comment(//i is set to every integer from x to y, inclusive) +(}) + +operator(()ident(x)operator(..<)ident(y)(\))operator(.)ident(each) operator({) + comment(//implicit closure variable it is set to every integer from x up to but excluding y) +(}) + +keyword(assert) operator(()ident(x)operator(..)ident(y)(\))operator(.)ident(step)operator(()integer(7)(\)) operator(==) operator([)integer(3)operator(,) integer(10)operator(,) integer(17)(]) + +ident(years) operator(=) type([]) +operator(()integer(5)operator(..<)integer(13)(\))operator(.)ident(each)operator({) ident(age) operator(->) ident(years) operator(+=) ident(age) (}) +keyword(assert) ident(years) operator(==) operator([)integer(5)operator(,) integer(6)operator(,) integer(7)operator(,) integer(8)operator(,) integer(9)operator(,) integer(10)operator(,) integer(11)operator(,) integer(12)(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.6) +comment(//----------------------------------------------------------------------------------) +comment(// We can add additional methods to the Integer class) +type(class) class(IntegerCategory) operator({) + directive(static) keyword(def) ident(romanMap) operator(=) operator([)integer(1000)operator(:)stringoperator(,) integer(900)operator(:)stringoperator(,) integer(500)operator(:)stringoperator(,) integer(400)operator(:)stringoperator(,) integer(100)operator(:)stringoperator(,) integer(90)operator(:)stringoperator(,) + integer(50)operator(:)stringoperator(,) integer(40)operator(:)stringoperator(,) integer(10)operator(:)stringoperator(,) integer(9)operator(:)stringoperator(,) integer(5)operator(:)stringoperator(,) integer(4)operator(:)stringoperator(,) integer(1)operator(:)string(]) + + directive(static) ident(getRoman)operator(()pre_type(Integer) ident(self)(\)) operator({) + keyword(def) ident(remains) operator(=) ident(self) + keyword(def) ident(text) operator(=) string + ident(romanMap)operator(.)ident(keySet)operator(()(\))operator(.)ident(sort)operator(()(\))operator(.)ident(reverse)operator(()(\))operator(.)ident(each)operator({) ident(key) operator(->) + keyword(while) operator(()ident(remains) operator(>=) ident(key)(\)) operator({) + ident(remains) operator(-=) ident(key) + ident(text) operator(+=) ident(romanMap)operator([)ident(key)(]) + (}) + (}) + keyword(return) ident(text) + (}) + + directive(static) type(int) ident(parseRoman)operator(()pre_type(Object) ident(self)operator(,) pre_type(String) ident(input)(\)) operator({) + keyword(def) ident(ustr) operator(=) ident(input)operator(.)ident(toUpperCase)operator(()(\)) + type(int) ident(sum) operator(=) integer(0) + ident(romanMap)operator(.)ident(keySet)operator(()(\))operator(.)ident(sort)operator(()(\))operator(.)ident(reverse)operator(()(\))operator(.)ident(each)operator({) ident(key) operator(->) + keyword(while) operator(()ident(ustr)operator(.)ident(startsWith)operator(()ident(romanMap)operator([)ident(key)(]\)\)) operator({) + ident(sum) operator(+=) ident(key) + ident(ustr) operator(-=) ident(romanMap)operator([)ident(key)(]) + (}) + (}) + keyword(return) ident(sum) + (}) +(}) + +ident(use)operator(()ident(IntegerCategory)(\)) operator({) + type(int) ident(fifteen) operator(=) integer(15) + keyword(assert) ident(fifteen)operator(.)ident(roman) operator(==) string + keyword(assert) ident(parseRoman)operator(()string(\)) operator(==) integer(26) + keyword(for) operator(()ident(i) keyword(in) integer(1)operator(..)integer(3900)(\)) operator({) + keyword(assert) ident(i) operator(==) ident(parseRoman)operator(()ident(i)operator(.)ident(roman)(\)) + (}) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.7) +comment(//----------------------------------------------------------------------------------) +ident(random) operator(=) keyword(new) pre_type(Random)operator(()(\)) +integer(100)operator(.)ident(times)operator({) + ident(next) operator(=) ident(random)operator(.)ident(nextInt)operator(()integer(50)(\)) operator(+) integer(25) + keyword(assert) ident(next) operator(>) integer(24) + keyword(assert) ident(next) operator(<) integer(76) +(}) +ident(chars) operator(=) type([]) +operator([)stringoperator(..)stringoperator(,)stringoperator(..)stringoperator(,)stringoperator(..)stringoperator(,)operator(()string keyword(as) pre_type(String)type([])(\))operator(.)ident(toList)operator(()(\)])operator(.)ident(each)operator({)ident(chars) operator(+=) local_variable(it)(}) +ident(password) operator(=) operator(()integer(1)operator(..)integer(8)(\))operator(.)ident(collect)operator({) ident(chars)operator([)ident(random)operator(.)ident(nextInt)operator(()ident(chars)operator(.)ident(size)operator(()(\)\)]) (})operator(.)ident(join)operator(()(\)) +keyword(assert) ident(password)operator(.)ident(size)operator(()(\)) operator(==) integer(8) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.8) +comment(//----------------------------------------------------------------------------------) +comment(// By default Groovy uses Java's Random facilities which use the current time) +comment(// as the initial seed. This always changes but does so slowly over time.) +comment(// You are free to select a better seed if you want greater randomness or) +comment(// use the same one each time if you need repeatability.) +type(long) ident(seed) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) +ident(random1) operator(=) keyword(new) pre_type(Random)operator(()ident(seed)(\)) +ident(random2) operator(=) keyword(new) pre_type(Random)operator(()ident(seed)(\)) +keyword(assert) ident(random1)operator(.)ident(nextInt)operator(()(\)) operator(==) ident(random2)operator(.)ident(nextInt)operator(()(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.9) +comment(//----------------------------------------------------------------------------------) +comment(// java.util.Random which Groovy uses already uses a 48-bit seed) +comment(// You can make use 64 not 48 bits (and make better use of the 48 bits\) see here:) +comment(// http://alife.co.uk/nonrandom/) +comment(// You can choose a better seed, e.g. Ant uses:) +ident(seed) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) operator(+) pre_type(Runtime)operator(.)ident(runtime)operator(.)ident(freeMemory)operator(()(\)) +comment(// You can accept input from the user, e.g.) +comment(// http://examples.oreilly.com/javacrypt/files/oreilly/jonathan/util/Seeder.java) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.10) +comment(//----------------------------------------------------------------------------------) +comment(// use Java's Random.nextGaussian(\) method) +ident(random) operator(=) keyword(new) pre_type(Random)operator(()(\)) +ident(mean) operator(=) integer(25) +ident(sdev) operator(=) integer(2) +ident(salary) operator(=) ident(random)operator(.)ident(nextGaussian)operator(()(\)) operator(*) ident(sdev) operator(+) ident(mean) +comment(// script:) +ident(printf) stringoperator(,) ident(salary) +comment(// => You have been hired at $25.05) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.11) +comment(//----------------------------------------------------------------------------------) +comment(// radians = Math.toRadians(degrees\)) +keyword(assert) pre_type(Math)operator(.)ident(toRadians)operator(()integer(90)(\)) operator(==) pre_type(Math)operator(.)ident(PI) operator(/) integer(2) +comment(// degrees = Math.toDegrees(radians\)) +keyword(assert) pre_type(Math)operator(.)ident(toDegrees)operator(()pre_type(Math)operator(.)ident(PI)(\)) operator(==) integer(180) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.12) +comment(//----------------------------------------------------------------------------------) +comment(// use Java's trigonometry methods in java.lang.Math) +comment(//----------------------------------------------------------------------------------) +ident(t) operator(=) pre_type(Math)operator(.)ident(tan)operator(()float(1.5)(\)) +keyword(assert) ident(t) operator(>) float(14.1) operator(&&) ident(t) operator(<) float(14.11) +ident(ac) operator(=) pre_type(Math)operator(.)ident(acos)operator(()float(0.1)(\)) +keyword(assert) ident(ac) operator(>) float(1.47) operator(&&) ident(ac) operator(<) float(1.48) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.13) +comment(//----------------------------------------------------------------------------------) +keyword(assert) pre_type(Math)operator(.)ident(log)operator(()pre_type(Math)operator(.)ident(E)(\)) operator(==) integer(1) +keyword(assert) pre_type(Math)operator(.)ident(log10)operator(()integer(10000)(\)) operator(==) integer(4) +keyword(def) method(logn)operator(()ident(base)operator(,) ident(val)(\)) operator({) pre_type(Math)operator(.)ident(log)operator(()ident(val)(\))operator(/)pre_type(Math)operator(.)ident(log)operator(()ident(base)(\)) (}) +keyword(assert) ident(logn)operator(()integer(2)operator(,) integer(1024)(\)) operator(==) integer(10) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.14) +comment(//----------------------------------------------------------------------------------) +comment(// there are several Java Matrix packages available, e.g.) +comment(// http://math.nist.gov/javanumerics/jama) +keyword(import) include(Jama.Matrix) +ident(matrix1) operator(=) keyword(new) ident(Matrix)operator(()operator([) + operator([)integer(3)operator(,) integer(2)operator(,) integer(3)(])operator(,) + operator([)integer(5)operator(,) integer(9)operator(,) integer(8)(]) +(]) keyword(as) type(double)type([])type([])(\)) + +ident(matrix2) operator(=) keyword(new) ident(Matrix)operator(()operator([) + operator([)integer(4)operator(,) integer(7)(])operator(,) + operator([)integer(9)operator(,) integer(3)(])operator(,) + operator([)integer(8)operator(,) integer(1)(]) +(]) keyword(as) type(double)type([])type([])(\)) + +ident(expectedArray) operator(=) operator([)operator([)float(54.0)operator(,) float(30.0)(])operator(,) operator([)float(165.0)operator(,) float(70.0)(]]) keyword(as) type(double)type([])type([]) +ident(productArray) operator(=) ident(matrix1)operator(.)ident(times)operator(()ident(matrix2)(\))operator(.)ident(array) + +keyword(for) operator(()ident(i) keyword(in) integer(0)operator(..<)ident(productArray)operator(.)ident(size)operator(()(\)\)) operator({) + keyword(assert) ident(productArray)operator([)ident(i)(]) operator(==) ident(expectedArray)operator([)ident(i)(]) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.15) +comment(//----------------------------------------------------------------------------------) +comment(// there are several Java Complex number packages, e.g.:) +comment(// http://jakarta.apache.org/commons/math/userguide/complex.html) +keyword(import) include(org.apache.commons.math.complex.Complex) +ident(a) operator(=) keyword(new) ident(Complex)operator(()integer(3)operator(,) integer(5)(\)) comment(// 3 + 5i) +ident(b) operator(=) keyword(new) ident(Complex)operator(()integer(2)operator(,) operator(-)integer(2)(\)) comment(// 2 - 2i) +ident(expected) operator(=) keyword(new) ident(Complex) operator(()integer(16)operator(,) integer(4)(\)) comment(// 16 + 4i) +keyword(assert) ident(expected) operator(==) ident(a) operator(*) ident(b) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.16) +comment(//----------------------------------------------------------------------------------) +keyword(assert) pre_type(Integer)operator(.)ident(parseInt)operator(()stringoperator(,) integer(16)(\)) operator(==) integer(257) +keyword(assert) pre_type(Integer)operator(.)ident(parseInt)operator(()stringoperator(,) integer(8)(\)) operator(==) integer(63) +comment(//----------------------------------------------------------------------------------) +comment(// conversionScript:) +ident(print) string +ident(reader) operator(=) keyword(new) pre_type(BufferedReader)operator(()keyword(new) pre_type(InputStreamReader)operator(()pre_type(System)operator(.)ident(in)(\)\)) +ident(input) operator(=) ident(reader)operator(.)ident(readLine)operator(()(\))operator(.)ident(trim)operator(()(\)) +keyword(switch)operator(()ident(input)(\)) operator({) + keyword(case) operator(~)stringoperator(:) + ident(number) operator(=) pre_type(Integer)operator(.)ident(parseInt)operator(()ident(input)operator(.)ident(substring)operator(()integer(2)(\))operator(,) integer(16)(\))operator(;) keyword(break) + keyword(case) operator(~)stringoperator(:) + ident(number) operator(=) pre_type(Integer)operator(.)ident(parseInt)operator(()ident(input)operator(.)ident(substring)operator(()integer(1)(\))operator(,) integer(8)(\))operator(;) keyword(break) + keyword(default)operator(:) + ident(number) operator(=) pre_type(Integer)operator(.)ident(parseInt)operator(()ident(input)(\)) +(}) +ident(println) string operator(+) ident(number) + +comment(// permissionScript:) +ident(print) string +ident(input) operator(=) keyword(new) pre_type(BufferedReader)operator(()keyword(new) pre_type(InputStreamReader)operator(()pre_type(System)operator(.)ident(in)(\)\)) +ident(num) operator(=) ident(input)operator(.)ident(readLine)operator(()(\))operator(.)ident(trim)operator(()(\)) +ident(permission) operator(=) pre_type(Integer)operator(.)ident(parseInt)operator(()ident(num)operator(,) integer(8)(\)) +ident(println) string operator(+) ident(permission) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.17) +comment(//----------------------------------------------------------------------------------) +ident(nf) operator(=) pre_type(NumberFormat)operator(.)ident(getInstance)operator(()(\)) +keyword(assert) ident(nf)operator(.)ident(format)operator(()operator(-)integer(1740525205)(\)) operator(==) string +comment(//----------------------------------------------------------------------------------) +comment(// @@PLEAC@@_2.18) +comment(//----------------------------------------------------------------------------------) +keyword(def) method(timeMessage)operator(()ident(hour)(\)) operator({) string operator(+) ident(hour) operator(+) string operator(+) operator(()ident(hour) operator(==) integer(1) operator(?) string operator(:) string(\)) (}) +keyword(assert) string operator(==) ident(timeMessage)operator(()integer(1)(\)) +keyword(assert) string operator(==) ident(timeMessage)operator(()integer(2)(\)) + +comment(// you can also use Java's ChoiceFormat) +comment(// overkill for this example but extensible and compatible with MessageFormat) +ident(limits) operator(=) operator([)integer(1)operator(,) pre_type(ChoiceFormat)operator(.)ident(nextDouble)operator(()integer(1)(\)]) keyword(as) type(double)type([]) +ident(names) operator(=) operator([)stringoperator(,) string(]) keyword(as) pre_type(String)type([]) +ident(choice) operator(=) keyword(new) pre_type(ChoiceFormat)operator(()ident(limits)operator(,) ident(names)(\)) +ident(numCenturies) operator(=) integer(1) +ident(expected) operator(=) string +keyword(assert) ident(expected) operator(==) stringcontent( )delimiter(")> operator(+) ident(choice)operator(.)ident(format)operator(()ident(numCenturies)(\)) +comment(// an alternate constructor syntax) +ident(choice) operator(=) keyword(new) pre_type(ChoiceFormat)operator(()string(\)) +keyword(assert) ident(choice)operator(.)ident(format)operator(()integer(3)(\)) operator(==) string + +comment(// more complex pluralization can be done with Java libraries, e.g.:) +comment(// http://www.elvis.ac.nz/brain?PluralizationMapping) +comment(// org.springframework.util.Pluralizer within the Spring Framework (springframework.org\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_2.19) +comment(//----------------------------------------------------------------------------------) +comment(// calculating prime factors) +keyword(def) method(factorize)operator(()pre_type(BigInteger) ident(orig)(\)) operator({) + ident(factors) operator(=) operator([)operator(:)(]) + keyword(def) ident(addFactor) operator(=) operator({) ident(x) operator(->) keyword(if) operator(()ident(factors)operator([)ident(x)(]\)) ident(factors)operator([)ident(x)(]) operator(+=) integer(1) keyword(else) ident(factors)operator([)ident(x)(]) operator(=) integer(1) (}) + ident(n) operator(=) ident(orig) + ident(i) operator(=) integer(2) + ident(sqi) operator(=) integer(4) comment(// square of i) + keyword(while) operator(()ident(sqi) operator(<=) ident(n)(\)) operator({) + keyword(while) operator(()ident(n)operator(.)ident(remainder)operator(()ident(i)(\)) operator(==) integer(0)(\)) operator({) + ident(n) operator(/)operator(=) ident(i) + ident(addFactor) ident(i) + (}) + comment(// we take advantage of the fact that (i+1\)**2 = i**2 + 2*i + 1) + ident(sqi) operator(+=) integer(2) operator(*) ident(i) operator(+) integer(1) + ident(i) operator(+=) integer(1) + (}) + keyword(if) operator(()operator(()ident(n) operator(!=) integer(1)(\)) operator(&&) operator(()ident(n) operator(!=) ident(orig)(\)\)) ident(addFactor) ident(n) + keyword(return) ident(factors) +(}) + +keyword(def) method(pretty)operator(()ident(factors)(\)) operator({) + keyword(if) operator(()operator(!)ident(factors)(\)) keyword(return) string + ident(sb) operator(=) keyword(new) pre_type(StringBuffer)operator(()(\)) + ident(factors)operator(.)ident(keySet)operator(()(\))operator(.)ident(sort)operator(()(\))operator(.)ident(each) operator({) ident(key) operator(->) + ident(sb) operator(<)operator(<) ident(key) + keyword(if) operator(()ident(factors)operator([)ident(key)(]) operator(>) integer(1)(\)) ident(sb) operator(<)operator(<) string operator(+) ident(factors)operator([)ident(key)(]) + ident(sb) operator(<)operator(<) string + (}) + keyword(return) ident(sb)operator(.)ident(toString)operator(()(\))operator(.)ident(trim)operator(()(\)) +(}) + +keyword(assert) ident(pretty)operator(()ident(factorize)operator(()integer(2178)(\)\)) operator(==) string +keyword(assert) ident(pretty)operator(()ident(factorize)operator(()integer(39887)(\)\)) operator(==) string +keyword(assert) ident(pretty)operator(()ident(factorize)operator(()integer(239322000000000000000000)(\)\)) operator(==) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.0) +comment(//----------------------------------------------------------------------------------) +comment(// use Date to get the current time) +ident(println) keyword(new) pre_type(Date)operator(()(\)) +comment(// => Mon Jan 01 07:12:32 EST 2007) +comment(// use Calendar to compute year, month, day, hour, minute, and second values) +ident(cal) operator(=) pre_type(Calendar)operator(.)ident(instance) +ident(println) string operator(+) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(DAY_OF_YEAR)(\)) operator(+) string +comment(// => Today is day 1 of the current year.) +comment(// there are other Java Date/Time packages with extended capabilities, e.g.:) +comment(// http://joda-time.sourceforge.net/) +comment(// there is a special Grails (grails.codehaus.org\) time DSL (see below\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.1) +comment(//----------------------------------------------------------------------------------) +ident(cal) operator(=) pre_type(Calendar)operator(.)ident(instance) +ident(Y) operator(=) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(YEAR)(\)) +ident(M) operator(=) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(MONTH)(\)) operator(+) integer(1) +ident(D) operator(=) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(DATE)(\)) +ident(println) stringcontent( )inlinecontent( )inlinedelimiter(")> +comment(// => The current date is 2006 04 28) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.2) +comment(//----------------------------------------------------------------------------------) +comment(// create a calendar with current time and time zone) +ident(cal) operator(=) pre_type(Calendar)operator(.)ident(instance) +comment(// set time zone using long or short timezone values) +ident(cal)operator(.)ident(timeZone) operator(=) pre_type(TimeZone)operator(.)ident(getTimeZone)operator(()string(\)) +ident(cal)operator(.)ident(timeZone) operator(=) pre_type(TimeZone)operator(.)ident(getTimeZone)operator(()string(\)) +comment(// set date fields one at a time) +ident(cal)operator(.)ident(set)operator(()pre_type(Calendar)operator(.)ident(MONTH)operator(,) pre_type(Calendar)operator(.)ident(DECEMBER)(\)) +comment(// or several together) +comment(//calendar.set(year, month - 1, day, hour, minute, second\)) +comment(// get time in seconds since EPOCH) +type(long) ident(time) operator(=) ident(cal)operator(.)ident(time)operator(.)ident(time) operator(/) integer(1000) +ident(println) ident(time) +comment(// => 1196522682) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.3) +comment(//----------------------------------------------------------------------------------) +comment(// create a calendar with current time and time zone) +ident(cal) operator(=) pre_type(Calendar)operator(.)ident(instance) +comment(// set time) +ident(cal)operator(.)ident(time) operator(=) keyword(new) pre_type(Date)operator(()ident(time) operator(*) integer(1000)(\)) +comment(// get date fields) +ident(println)operator(()string + operator(+) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(HOUR_OF_DAY)(\)) operator(+) string + operator(+) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(MINUTE)(\)) operator(+) string + operator(+) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(SECOND)(\)) operator(+) string + operator(+) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(YEAR)(\)) operator(+) string + operator(+) operator(()ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(MONTH)(\)) operator(+) integer(1)(\)) operator(+) string + operator(+) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(DATE)(\)\)) +comment(// => Dateline: 7:33:16-2007/1/1) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.4) +comment(//----------------------------------------------------------------------------------) +keyword(import) include(java.text.SimpleDateFormat) +type(long) ident(difference) operator(=) integer(100) +type(long) ident(after) operator(=) ident(time) operator(+) ident(difference) +type(long) ident(before) operator(=) ident(time) operator(-) ident(difference) + +comment(// any field of a calendar is incrementable via add(\) and roll(\) methods) +ident(cal) operator(=) pre_type(Calendar)operator(.)ident(instance) +ident(df) operator(=) keyword(new) pre_type(SimpleDateFormat)operator(()(\)) +ident(printCal) operator(=) operator({)ident(cal) operator(->) ident(df)operator(.)ident(format)operator(()ident(cal)operator(.)ident(time)(\)}) +ident(cal)operator(.)ident(set)operator(()integer(2000)operator(,) integer(0)operator(,) integer(1)operator(,) oct(00)operator(,) oct(01)operator(,) integer(0)(\)) +keyword(assert) ident(printCal)operator(()ident(cal)(\)) operator(==) string +comment(// roll minute back by 2 but don't adjust other fields) +ident(cal)operator(.)ident(roll)operator(()pre_type(Calendar)operator(.)ident(MINUTE)operator(,) operator(-)integer(2)(\)) +keyword(assert) ident(printCal)operator(()ident(cal)(\)) operator(==) string +comment(// adjust hour back 1 and adjust other fields if needed) +ident(cal)operator(.)ident(add)operator(()pre_type(Calendar)operator(.)ident(HOUR)operator(,) operator(-)integer(1)(\)) +keyword(assert) ident(printCal)operator(()ident(cal)(\)) operator(==) string + +comment(// larger example) +ident(cal)operator(.)ident(timeZone) operator(=) pre_type(TimeZone)operator(.)ident(getTimeZone)operator(()string(\)) +ident(cal)operator(.)ident(set)operator(()integer(1973)operator(,) integer(0)operator(,) integer(18)operator(,) integer(3)operator(,) integer(45)operator(,) integer(50)(\)) +ident(cal)operator(.)ident(add)operator(()pre_type(Calendar)operator(.)ident(DATE)operator(,) integer(55)(\)) +ident(cal)operator(.)ident(add)operator(()pre_type(Calendar)operator(.)ident(HOUR_OF_DAY)operator(,) integer(2)(\)) +ident(cal)operator(.)ident(add)operator(()pre_type(Calendar)operator(.)ident(MINUTE)operator(,) integer(17)(\)) +ident(cal)operator(.)ident(add)operator(()pre_type(Calendar)operator(.)ident(SECOND)operator(,) integer(5)(\)) +keyword(assert) ident(printCal)operator(()ident(cal)(\)) operator(==) string + +comment(// alternatively, work with epoch times) +type(long) ident(birthTime) operator(=) integer(96176750359) comment(// 18/Jan/1973, 3:45:50 am) +type(long) ident(interval) operator(=) integer(5) operator(+) comment(// 5 second) + integer(17) operator(*) integer(60) operator(+) comment(// 17 minute) + integer(2) operator(*) integer(60) operator(*) integer(60) operator(+) comment(// 2 hour) + integer(55) operator(*) integer(60) operator(*) integer(60) operator(*) integer(24) comment(// and 55 day) +ident(then) operator(=) keyword(new) pre_type(Date)operator(()ident(birthTime) operator(+) ident(interval) operator(*) integer(1000)(\)) +keyword(assert) ident(df)operator(.)ident(format)operator(()ident(then)(\)) operator(==) string + +comment(// Alternatively, the Google Data module has a category with DSL-like time support:) +comment(// http://docs.codehaus.org/display/GROOVY/Google+Data+Support) +comment(// which supports the following syntax) +comment(// def interval = 5.seconds + 17.minutes + 2.hours + 55.days) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.5) +comment(//----------------------------------------------------------------------------------) +ident(bree) operator(=) integer(361535725) comment(// 16 Jun 1981, 4:35:25) +ident(nat) operator(=) integer(96201950) comment(// 18 Jan 1973, 3:45:50) +ident(difference) operator(=) ident(bree) operator(-) ident(nat) +ident(println) stringcontent( seconds between Nat and Bree)delimiter(")> +comment(// => There were 265333775 seconds between Nat and Bree) +ident(seconds) operator(=) ident(difference) operator(%) integer(60) +ident(difference) operator(=) operator(()ident(difference) operator(-) ident(seconds)(\)) operator(/) integer(60) +ident(minutes) operator(=) ident(difference) operator(%) integer(60) +ident(difference) operator(=) operator(()ident(difference) operator(-) ident(minutes)(\)) operator(/) integer(60) +ident(hours) operator(=) ident(difference) operator(%) integer(24) +ident(difference) operator(=) operator(()ident(difference) operator(-) ident(hours)(\)) operator(/) integer(24) +ident(days) operator(=) ident(difference) operator(%) integer(7) +ident(weeks) operator(=) operator(()ident(difference) operator(-) ident(days)(\)) operator(/) integer(7) +ident(println) stringcontent( weeks, )inlinecontent( days, )inlinecontent(:)inlinecontent(:)inlinecontent(\))delimiter(")> +comment(// => (438 weeks, 4 days, 23:49:35\)) +comment(//----------------------------------------------------------------------------------) +ident(cal) operator(=) pre_type(Calendar)operator(.)ident(getInstance)operator(()pre_type(TimeZone)operator(.)ident(getTimeZone)operator(()string(\)\)) +ident(cal)operator(.)ident(set)operator(()integer(1981)operator(,) integer(5)operator(,) integer(16)(\)) comment(// 16 Jun 1981) +ident(date1) operator(=) ident(cal)operator(.)ident(time) +ident(cal)operator(.)ident(set)operator(()integer(1973)operator(,) integer(0)operator(,) integer(18)(\)) comment(// 18 Jan 1973) +ident(date2) operator(=) ident(cal)operator(.)ident(time) +ident(difference) operator(=) pre_type(Math)operator(.)ident(abs)operator(()ident(date2)operator(.)ident(time) operator(-) ident(date1)operator(.)ident(time)(\)) +ident(days) operator(=) ident(difference) operator(/) operator(()integer(1000) operator(*) integer(60) operator(*) integer(60) operator(*) integer(24)(\)) +keyword(assert) ident(days) operator(==) integer(3071) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.6) +comment(//----------------------------------------------------------------------------------) +comment(// create a calendar with current time and time zone) +ident(cal) operator(=) pre_type(Calendar)operator(.)ident(instance) +ident(cal)operator(.)ident(set)operator(()integer(1981)operator(,) integer(5)operator(,) integer(16)(\)) +ident(yearDay) operator(=) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(DAY_OF_YEAR)(\))operator(;) +ident(year) operator(=) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(YEAR)(\))operator(;) +ident(yearWeek) operator(=) ident(cal)operator(.)ident(get)operator(()pre_type(Calendar)operator(.)ident(WEEK_OF_YEAR)(\))operator(;) +ident(df1) operator(=) keyword(new) pre_type(SimpleDateFormat)operator(()string(\)) +ident(df2) operator(=) keyword(new) pre_type(SimpleDateFormat)operator(()string(\)) +ident(print)operator(()ident(df1)operator(.)ident(format)operator(()ident(cal)operator(.)ident(time)(\)) operator(+) string operator(+) ident(df2)operator(.)ident(format)operator(()ident(cal)operator(.)ident(time)(\)\)) +ident(println) stringcontent( and week number )inlinecontent( of )inlinedelimiter(")> +comment(// => 16/Jun/81 was a Tuesday and was day number 167 and week number 25 of 1981) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.7) +comment(//----------------------------------------------------------------------------------) +ident(input) operator(=) string +ident(df1) operator(=) keyword(new) pre_type(SimpleDateFormat)operator(()string(\)) +ident(date) operator(=) ident(df1)operator(.)ident(parse)operator(()ident(input)(\)) +ident(df2) operator(=) keyword(new) pre_type(SimpleDateFormat)operator(()string(\)) +ident(println) string operator(+) ident(df2)operator(.)ident(format)operator(()ident(date)(\)) +comment(// => Date was Jun/03/1998) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.8) +comment(//----------------------------------------------------------------------------------) +keyword(import) include(java.text.DateFormat) +ident(df) operator(=) keyword(new) pre_type(SimpleDateFormat)operator(()string(\)) +ident(cal)operator(.)ident(set)operator(()integer(2007)operator(,) integer(0)operator(,) integer(1)(\)) +ident(println) string operator(+) ident(df)operator(.)ident(format)operator(()ident(cal)operator(.)ident(time)(\)) +comment(// => Mon 1 1 09:02:29 EST 2007 (differs depending on your timezone\)) +ident(df) operator(=) pre_type(DateFormat)operator(.)ident(getDateInstance)operator(()pre_type(DateFormat)operator(.)ident(FULL)operator(,) pre_type(Locale)operator(.)ident(FRANCE)(\)) +ident(println) string operator(+) ident(df)operator(.)ident(format)operator(()ident(cal)operator(.)ident(time)(\)) +comment(// => lundi 1 janvier 2007) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.9) +comment(//----------------------------------------------------------------------------------) +comment(// script:) +ident(println) string +ident(before) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) +ident(input) operator(=) keyword(new) pre_type(BufferedReader)operator(()keyword(new) pre_type(InputStreamReader)operator(()pre_type(System)operator(.)ident(in)(\)\))operator(.)ident(readLine)operator(()(\)) +ident(after) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) +ident(elapsed) operator(=) operator(()ident(after) operator(-) ident(before)(\)) operator(/) integer(1000) +ident(println) stringcontent( seconds.)delimiter(")> +comment(// => You took2.313 seconds.) + +comment(// take mean sorting time) +ident(size) operator(=) integer(500)operator(;) ident(number) operator(=) integer(100)operator(;) ident(total) operator(=) integer(0) +keyword(for) operator(()ident(i) keyword(in) integer(0)operator(..<)ident(number)(\)) operator({) + ident(array) operator(=) type([]) + ident(size)operator(.)ident(times)operator({) ident(array) operator(<)operator(<) pre_type(Math)operator(.)ident(random)operator(()(\)) (}) + ident(doubles) operator(=) ident(array) keyword(as) type(double)type([]) + comment(// sort it) + type(long) ident(t0) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) + pre_type(Arrays)operator(.)ident(sort)operator(()ident(doubles)(\)) + type(long) ident(t1) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) + ident(total) operator(+=) operator(()ident(t1) operator(-) ident(t0)(\)) +(}) +ident(println) stringcontent( random numbers takes )inlinecontent( milliseconds)delimiter(")> +comment(// => On average, sorting 500 random numbers takes 0.32 milliseconds) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.10) +comment(//----------------------------------------------------------------------------------) +ident(delayMillis) operator(=) integer(50) +pre_type(Thread)operator(.)ident(sleep)operator(()ident(delayMillis)(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_3.11) +comment(//----------------------------------------------------------------------------------) +comment(// this could be done more simply using JavaMail's getAllHeaderLines(\) but is shown) +comment(// in long hand for illustrative purposes) +ident(sampleMessage) operator(=) string; + Sat, 30 Dec 2006 15:16:11 +0000 +From: someone@somewhere.com +To: +Date: Sun, 31 Dec 2006 02:14:57 +1100 +Subject: Re: [Pleac-discuss] C/Posix/GNU - @@pleac@@_10x +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: 7bit +Sender: pleac-discuss-bounces@lists.sourceforge.net +Errors-To: pleac-discuss-bounces@lists.sourceforge.net + +----- Original Message ----- +From: someone@somewhere.com +To: otherperson@somewhereelse.com +Cc: +Sent: Wednesday, December 27, 2006 9:18 AM +Subject: Re: [Pleac-discuss] C/Posix/GNU - @@pleac@@_10x + +I really like that description of PLEAC. +)delimiter(''')> +ident(expected) operator(=) string somewhere.com 01:14:57 06/12/31 +win2K001 omta05ps.mx.bigpond.com 01:14:57 06/12/31 1m 14s +omta05ps.mx.bigpond.com mail.sourceforge.net 01:16:11 06/12/31 8s +sc8-sf-mx1-b.sourceforge. sc8-sf-list2-new.sourcefo 01:16:19 06/12/31 1s +sc8-sf-list2-new.sourcefo sc8-sf-spam2.sourceforge. 01:16:20 06/12/31 4s +unknown bne012m.server-web.com 01:16:24 06/12/31 1s +)delimiter(''')> + +type(class) class(MailHopDelta) operator({) + keyword(def) ident(headers)operator(,) ident(firstSender)operator(,) ident(firstDate)operator(,) ident(out) + + ident(MailHopDelta)operator(()ident(mail)(\)) operator({) + ident(extractHeaders)operator(()ident(mail)(\)) + ident(out) operator(=) keyword(new) pre_type(StringBuffer)operator(()(\)) + keyword(def) ident(m) operator(=) operator(()ident(mail) operator(=~) regexp(\)) + ident(firstDate) operator(=) ident(parseDate)operator(()ident(m)operator([)integer(0)(])operator([)integer(1)(]\)) + ident(firstSender) operator(=) operator(()ident(mail) operator(=~) regexp]*\))delimiter(/)>(\))operator([)integer(0)(])operator([)integer(1)(]) + ident(out)operator(()stringoperator(.)ident(split)operator(()string(\)\)) + (}) + + keyword(def) method(parseDate)operator(()ident(date)(\)) operator({) + keyword(try) operator({) + keyword(return) keyword(new) pre_type(SimpleDateFormat)operator(()string(\))operator(.)ident(parse)operator(()ident(date)(\)) + (}) keyword(catch)operator(()ident(java)operator(.)ident(text)operator(.)ident(ParseException) ident(ex)(\)) operator({)(}) + keyword(try) operator({) + keyword(return) keyword(new) pre_type(SimpleDateFormat)operator(()string(\))operator(.)ident(parse)operator(()ident(date)(\)) + (}) keyword(catch)operator(()ident(java)operator(.)ident(text)operator(.)ident(ParseException) ident(ex)(\)) operator({)(}) + keyword(try) operator({) + keyword(return) pre_type(DateFormat)operator(.)ident(getDateInstance)operator(()pre_type(DateFormat)operator(.)ident(FULL)(\))operator(.)ident(parse)operator(()ident(date)(\)) + (}) keyword(catch)operator(()ident(java)operator(.)ident(text)operator(.)ident(ParseException) ident(ex)(\)) operator({)(}) + pre_type(DateFormat)operator(.)ident(getDateInstance)operator(()pre_type(DateFormat)operator(.)ident(LONG)(\))operator(.)ident(parse)operator(()ident(date)(\)) + (}) + + keyword(def) method(extractHeaders)operator(()ident(mail)(\)) operator({) + ident(headers) operator(=) type([]) + keyword(def) ident(isHeader) operator(=) keyword(true) + keyword(def) ident(currentHeader) operator(=) string + ident(mail)operator(.)ident(split)operator(()string(\))operator(.)ident(each)operator({) ident(line) operator(->) + keyword(if) operator(()operator(!)ident(isHeader)(\)) keyword(return) + keyword(switch)operator(()ident(line)(\)) operator({) + keyword(case) operator(~)regexpoperator(:) + ident(isHeader) operator(=) keyword(false) + keyword(if) operator(()ident(currentHeader)(\)) ident(headers) operator(<)operator(<) ident(currentHeader) + keyword(break) + keyword(case) operator(~)regexpoperator(:) + ident(currentHeader) operator(+=) ident(line)operator(;) keyword(break) + keyword(default)operator(:) + keyword(if) operator(()ident(currentHeader)(\)) ident(headers) operator(<)operator(<) ident(currentHeader) + ident(currentHeader) operator(=) ident(line) + (}) + (}) + (}) + + keyword(def) method(out)operator(()ident(line)(\)) operator({) + ident(out) operator(<)operator(<) ident(line)operator([)integer(0)(])operator([)integer(0)operator(..<)operator([)integer(25)operator(,)ident(line)operator([)integer(0)(])operator(.)ident(size)operator(()(\)])operator(.)ident(min)operator(()(\)])operator(.)ident(padRight)operator(()integer(26)(\)) + ident(out) operator(<)operator(<) ident(line)operator([)integer(1)(])operator([)integer(0)operator(..<)operator([)integer(25)operator(,)ident(line)operator([)integer(1)(])operator(.)ident(size)operator(()(\)])operator(.)ident(min)operator(()(\)])operator(.)ident(padRight)operator(()integer(26)(\)) + ident(out) operator(<)operator(<) ident(line)operator([)integer(2)(])operator(.)ident(padRight)operator(()integer(17)(\)) operator(+) string + ident(out) operator(<)operator(<) ident(line)operator([)integer(3)(]) operator(+) string + (}) + + keyword(def) method(prettyDate)operator(()ident(date)(\)) operator({) + keyword(new) pre_type(SimpleDateFormat)operator(()string(\))operator(.)ident(format)operator(()ident(date)(\)) + (}) + + keyword(def) method(process)operator(()(\)) operator({) + ident(out)operator(()operator([)string)delimiter(')>operator(,) ident(firstSender)operator(,) ident(prettyDate)operator(()ident(firstDate)(\))operator(,) string(]\)) + keyword(def) ident(prevDate) operator(=) ident(firstDate) + ident(headers)operator(.)ident(grep)operator(()operator(~)regexp(\))operator(.)ident(reverseEach)operator({) ident(hop) operator(->) + keyword(def) ident(from) operator(=) operator(()ident(hop) operator(=~) regexp(\))operator([)integer(0)(])operator([)integer(1)(]) + keyword(def) ident(by) operator(=) operator(()ident(hop) operator(=~) regexp(\))operator([)integer(0)(])operator([)integer(1)(]) + keyword(def) ident(hopDate) operator(=) ident(parseDate)operator(()ident(hop)operator([)ident(hop)operator(.)ident(lastIndexOf)operator(()string(\))operator(+)integer(2)operator(..)operator(-)integer(1)(]\)) + ident(out)operator(()operator([)ident(from)operator(,) ident(by)operator(,) ident(prettyDate)operator(()ident(prevDate)(\))operator(,) ident(prettyDelta)operator(()ident(hopDate)operator(.)ident(time) operator(-) ident(prevDate)operator(.)ident(time)(\)]\)) + ident(prevDate) operator(=) ident(hopDate) + (}) + keyword(return) ident(out)operator(.)ident(toString)operator(()(\)) + (}) + + keyword(def) method(prettyField)operator(()ident(secs)operator(,) ident(sign)operator(,) ident(ch)operator(,) ident(multiplier)operator(,) ident(sb)(\)) operator({) + keyword(def) ident(whole) operator(=) operator(()type(int)(\))operator(()ident(secs) operator(/) ident(multiplier)(\)) + keyword(if) operator(()operator(!)ident(whole)(\)) keyword(return) integer(0) + ident(sb) operator(<)operator(<) string operator(+) operator(()ident(sign) operator(*) ident(whole)(\)) operator(+) ident(ch) operator(+) string + keyword(return) ident(whole) operator(*) ident(multiplier) + (}) + + keyword(def) method(prettyDelta)operator(()ident(millis)(\)) operator({) + keyword(def) ident(sign) operator(=) ident(millis) operator(<) integer(0) operator(?) operator(-)integer(1) operator(:) integer(1) + keyword(def) ident(secs) operator(=) operator(()type(int)(\))pre_type(Math)operator(.)ident(abs)operator(()ident(millis)operator(/)integer(1000)(\)) + keyword(def) ident(sb) operator(=) keyword(new) pre_type(StringBuffer)operator(()(\)) + ident(secs) operator(-=) ident(prettyField)operator(()ident(secs)operator(,) ident(sign)operator(,) stringoperator(,) integer(60) operator(*) integer(60) operator(*) integer(24)operator(,) ident(sb)(\)) + ident(secs) operator(-=) ident(prettyField)operator(()ident(secs)operator(,) ident(sign)operator(,) stringoperator(,) integer(60) operator(*) integer(60)operator(,) ident(sb)(\)) + ident(secs) operator(-=) ident(prettyField)operator(()ident(secs)operator(,) ident(sign)operator(,) stringoperator(,) integer(60)operator(,) ident(sb)(\)) + ident(prettyField)operator(()ident(secs)operator(,) ident(sign)operator(,) stringoperator(,) integer(1)operator(,) ident(sb)(\)) + keyword(return) ident(sb)operator(.)ident(toString)operator(()(\))operator(.)ident(trim)operator(()(\)) + (}) +(}) + +keyword(assert) string operator(+) keyword(new) ident(MailHopDelta)operator(()ident(sampleMessage)(\))operator(.)ident(process)operator(()(\)) operator(==) ident(expected) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_4.0) +comment(//----------------------------------------------------------------------------------) +ident(simple) operator(=) operator([) stringoperator(,) stringoperator(,) stringoperator(,) string (]) +ident(nested) operator(=) operator([) stringoperator(,) stringoperator(,) operator([) stringoperator(,) string (]) (]) +keyword(assert) ident(nested)operator(.)ident(size)operator(()(\)) operator(==) integer(3) +keyword(assert) ident(nested)operator([)integer(2)(])operator(.)ident(size)operator(()(\)) operator(==) integer(2) + +ident(flattenNestedToSimple) operator(=) operator([) stringoperator(,) stringoperator(,) operator([) stringoperator(,) string (]) (])operator(.)ident(flatten)operator(()(\)) +keyword(assert) ident(flattenNestedToSimple)operator(.)ident(size)operator(()(\)) operator(==) integer(4) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.1) +comment(//----------------------------------------------------------------------------------) +ident(a) operator(=) operator([) stringoperator(,) stringoperator(,) string (]) +keyword(assert) ident(a)operator(.)ident(size)operator(()(\)) operator(==) integer(3) +ident(a) operator(=) stringoperator(.)ident(split)operator(()string(\)) +keyword(assert) ident(a) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +ident(removeLeadingSpaces) operator(=) operator({) local_variable(it)operator(.)ident(trim)operator(()(\)) (}) +ident(nonBlankLines) operator(=) operator({) local_variable(it) (}) +ident(lines) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(collect)operator(()ident(removeLeadingSpaces)(\))operator(.)ident(findAll)operator(()ident(nonBlankLines)(\)) + +keyword(assert) ident(lines) operator(==) operator([)stringoperator(,) + string(]) + +comment(// initialiseListFromFileScript:) +ident(lines) operator(=) keyword(new) pre_type(File)operator(()string(\))operator(.)ident(readLines)operator(()(\)) + +comment(// processFileScript:) +keyword(new) pre_type(File)operator(()string(\))operator(.)ident(eachLine)operator({) + comment(// dosomething) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.2) +comment(//----------------------------------------------------------------------------------) +ident(marbleColors) operator(=) operator([)stringoperator(,) stringoperator(,) string(]) +keyword(assert) ident(marbleColors)operator(.)ident(join)operator(()string(\)) operator(==) string + +keyword(def) method(commify)operator(()ident(items)(\)) operator({) + keyword(if) operator(()operator(!)ident(items)(\)) keyword(return) ident(items) + keyword(def) ident(sepchar) operator(=) ident(items)operator(.)ident(find)operator({) local_variable(it) operator(=~) regexp (}) operator(?) string operator(:) string + keyword(switch) operator(()ident(items)operator(.)ident(size)operator(()(\)\)) operator({) + keyword(case) integer(1)operator(:) keyword(return) ident(items)operator([)integer(0)(]) + keyword(case) integer(2)operator(:) keyword(return) ident(items)operator(.)ident(join)operator(()string(\)) + (}) + ident(items)operator([)integer(0)operator(..)operator(-)integer(2)(])operator(.)ident(join)operator(()ident(sepchar)(\)) operator(+) ident(sepchar) operator(+) string operator(+) ident(items)operator([)operator(-)integer(1)(]) +(}) + +keyword(assert) ident(commify)operator(()ident(marbleColors)(\)) operator(==) string + +ident(lists) operator(=) operator([) + operator([) string (])operator(,) + operator([) stringoperator(,) string (])operator(,) + stringoperator(.)ident(split)operator(()string(\))operator(,) + operator([) stringoperator(,) stringoperator(,) string (])operator(,) + operator([) stringoperator(,) stringoperator(,) stringoperator(,) string (])operator(,) + operator([) stringoperator(,) string (])operator(,) + operator([) stringoperator(,) + stringoperator(,) + string (])operator(,) +(]) + +ident(expected) operator(=) string + +keyword(assert) ident(expected) operator(==) string operator(+) ident(lists)operator(.)ident(collect)operator({)ident(commify)operator(()local_variable(it)(\)})operator(.)ident(join)operator(()string(\)) operator(+) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.3) +comment(//----------------------------------------------------------------------------------) +comment(// In Groovy, lists and arrays are more or less interchangeable) +comment(// here is the example using lists) +ident(people) operator(=) operator([)stringoperator(,) stringoperator(,) string(]) +keyword(assert) ident(people)operator(.)ident(size)operator(()(\)) operator(==) integer(3) +ident(people)operator([)integer(3)(]) operator(=) string +keyword(assert) ident(people)operator(.)ident(size)operator(()(\)) operator(==) integer(4) +keyword(assert) ident(people) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(// to use arrays simply do 'people = peopleArray.toList(\)' at the start) +comment(// and 'peopleArray = people as String[]' at the end) +comment(// if you attempt to do extension on a Java array you will get an) +comment(// ArrayIndexOutOfBoundsException - which is why Java has ArrayList et al) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.4) +comment(//----------------------------------------------------------------------------------) +comment(// list to process) +ident(people) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(// helper) +ident(startsWithCapital) operator(=) operator({) ident(word) operator(->) ident(word)operator([)integer(0)(]) keyword(in) stringoperator(..)string (}) + +comment(// various styles are possible for processing lists) +comment(// closure style) +ident(people)operator(.)ident(each) operator({) ident(person) operator(->) keyword(assert) ident(startsWithCapital)operator(()ident(person)(\)) (}) +comment(// for loop style) +keyword(for) operator(()ident(person) keyword(in) ident(people)(\)) operator({) keyword(assert) ident(startsWithCapital)operator(()ident(person)(\)) (}) + +comment(// unixScriptToFindAllUsersStartingWithLetterA:) +ident(all) operator(=) stringoperator(.)ident(execute)operator(()(\))operator(.)ident(text)operator(.)ident(replaceAll)operator(()stringoperator(,) string(\))operator(.)ident(split)operator(()string(\)) +ident(all)operator(.)ident(grep)operator(()operator(~)regexp(\))operator(.)ident(each)operator({) ident(println) local_variable(it) (}) + +comment(// printFileWithWordsReversedScript:) +keyword(new) pre_type(File)operator(()string(\))operator(.)ident(eachLine)operator({) ident(line) operator(->) + ident(line)operator(.)ident(split)operator(()string(\))operator(.)ident(each)operator({) ident(print) local_variable(it)operator(.)ident(reverse)operator(()(\)) (}) +(}) + +ident(a) operator(=) operator([)float(0.5)operator(,) integer(3)(])operator(;) ident(b) operator(=) operator([)integer(0)operator(,) integer(1)(]) +keyword(assert) operator([)ident(a)operator(,) ident(b)(])operator(.)ident(flatten)operator(()(\))operator(.)ident(collect)operator({) local_variable(it) operator(*) integer(7) (}) operator(==) operator([)float(3.5)operator(,) integer(21)operator(,) integer(0)operator(,) integer(7)(]) +comment(// above doesn't modify original arrays) +comment(// instead use a = a.collect{ ... }) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.5) +comment(//----------------------------------------------------------------------------------) +comment(// not relevant in Groovy since we have always references) +ident(items) operator(=) type([]) +keyword(for) operator(()ident(item) keyword(in) ident(items)(\)) operator({) + comment(// do something with item) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.6) +comment(//----------------------------------------------------------------------------------) +keyword(assert) operator([) integer(1)operator(,) integer(1)operator(,) integer(2)operator(,) integer(2)operator(,) integer(3)operator(,) integer(3)operator(,) integer(3)operator(,) integer(5) (])operator(.)ident(unique)operator(()(\)) operator(==) operator([) integer(1)operator(,) integer(2)operator(,) integer(3)operator(,) integer(5) (]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.7) +comment(//----------------------------------------------------------------------------------) +keyword(assert) operator([) integer(1)operator(,) integer(1)operator(,) integer(2)operator(,) integer(2)operator(,) integer(3)operator(,) integer(3)operator(,) integer(3)operator(,) integer(4)operator(,) integer(5) (]) operator(-) operator([) integer(1)operator(,) integer(2)operator(,) integer(4) (]) operator(==) operator([)integer(3)operator(,) integer(3)operator(,) integer(3)operator(,) integer(5)(]) +keyword(assert) operator([) integer(1)operator(,) integer(1)operator(,) integer(2)operator(,) integer(2)operator(,) integer(3)operator(,) integer(3)operator(,) integer(3)operator(,) integer(4)operator(,) integer(5) (])operator(.)ident(unique)operator(()(\)) operator(-) operator([) integer(1)operator(,) integer(2)operator(,) integer(4) (]) operator(==) operator([)integer(3)operator(,) integer(5)(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.8) +comment(//----------------------------------------------------------------------------------) +ident(a) operator(=) operator([)integer(1)operator(,) integer(3)operator(,) integer(5)operator(,) integer(6)operator(,) integer(7)operator(,) integer(8)(]) +ident(b) operator(=) operator([)integer(2)operator(,) integer(3)operator(,) integer(5)operator(,) integer(7)operator(,) integer(9)(]) +comment(// intersection) +keyword(assert) ident(a)operator(.)ident(intersect)operator(()ident(b)(\)) operator(==) operator([)integer(3)operator(,) integer(5)operator(,) integer(7)(]) +comment(// union) +keyword(assert) operator(()ident(a) operator(+) ident(b)(\))operator(.)ident(unique)operator(()(\))operator(.)ident(sort)operator(()(\)) operator(==) operator([)integer(1)operator(,) integer(2)operator(,) integer(3)operator(,) integer(5)operator(,) integer(6)operator(,) integer(7)operator(,) integer(8)operator(,) integer(9)(]) +comment(// difference) +keyword(assert) operator(()ident(a) operator(-) ident(b)(\)) operator(==) operator([)integer(1)operator(,) integer(6)operator(,) integer(8)(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.9) +comment(//----------------------------------------------------------------------------------) +ident(members) operator(=) operator([) stringoperator(,) string (]) +ident(initiates) operator(=) operator([) stringoperator(,) string (]) +ident(members) operator(+=) ident(initiates) +keyword(assert) ident(members) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +ident(members)operator(.)ident(add)operator(()integer(2)operator(,) string(\)) +keyword(assert) ident(members) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +ident(members)operator([)integer(0)(]) operator(=) string +ident(members)operator([)integer(3)operator(..)integer(4)(]) operator(=) operator([)stringoperator(,) string(]) +keyword(assert) ident(members) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.10) +comment(//----------------------------------------------------------------------------------) +ident(items) operator(=) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +keyword(assert) ident(items)operator(.)ident(reverse)operator(()(\)) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +ident(firstLetters) operator(=) type([]) +ident(items)operator(.)ident(reverseEach)operator({) ident(firstLetters) operator(+=) local_variable(it)operator([)integer(0)(]) (}) +keyword(assert) ident(firstLetters)operator(.)ident(join)operator(()(\)) operator(==) string + +ident(descending) operator(=) ident(items)operator(.)ident(sort)operator(()(\))operator(.)ident(reverse)operator(()(\)) +keyword(assert) ident(descending) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +ident(descendingBySecondLastLetter) operator(=) ident(items)operator(.)ident(sort) operator({) ident(a)operator(,)ident(b) operator(->) ident(b)operator([)operator(-)integer(2)(]) operator(<=)operator(>) ident(a)operator([)operator(-)integer(2)(]) (}) +keyword(assert) ident(descendingBySecondLastLetter) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.11) +comment(//----------------------------------------------------------------------------------) +comment(// warning: not an exact equivalent, idiomatic use would return copies) +keyword(def) ident(shift2) operator(=) operator({)ident(one) operator(=) ident(friends)operator([)integer(0)(])operator(;) ident(two) operator(=) ident(friends)operator([)integer(1)(])operator(;) integer(2)operator(.)ident(times)operator({)ident(friends)operator(.)ident(remove)operator(()integer(0)(\)}}) +ident(friends) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\)) +ident(shift2)operator(()(\)) +keyword(assert) ident(one) operator(==) string +keyword(assert) ident(two) operator(==) string +keyword(assert) ident(friends) operator(==) operator([)stringoperator(,) stringoperator(,) string(]) + +keyword(def) method(pop2)operator(()ident(items)(\)) operator({) ident(items)operator([)integer(0)operator(..)integer(1)(]) (}) +ident(beverages) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\)) +ident(pair) operator(=) ident(pop2)operator(()ident(beverages)(\)) +keyword(assert) ident(pair) operator(==) operator([)stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_4.12) +comment(//----------------------------------------------------------------------------------) +type(class) class(Employee) operator({) + keyword(def) ident(name) + keyword(def) ident(position) + keyword(def) ident(salary) +(}) +ident(staff) operator(=) operator([)keyword(new) ident(Employee)operator(()key(name)operator(:)stringoperator(,)key(position)operator(:)stringoperator(,)key(salary)operator(:)integer(26000)(\))operator(,) + keyword(new) ident(Employee)operator(()key(name)operator(:)stringoperator(,)key(position)operator(:)stringoperator(,)key(salary)operator(:)integer(24000)(\))operator(,) + keyword(new) ident(Employee)operator(()key(name)operator(:)stringoperator(,)key(position)operator(:)stringoperator(,)key(salary)operator(:)integer(22000)(\)]) +ident(highestEngineer) operator(=) ident(staff)operator(.)ident(find) operator({) ident(emp) operator(->) ident(emp)operator(.)ident(position) operator(==) string (}) +keyword(assert) ident(highestEngineer)operator(.)ident(salary) operator(==) integer(24000) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.13) +comment(//----------------------------------------------------------------------------------) +ident(engineers) operator(=) ident(staff)operator(.)ident(findAll) operator({) ident(e) operator(->) ident(e)operator(.)ident(position) operator(==) string (}) +keyword(assert) ident(engineers)operator(.)ident(size)operator(()(\)) operator(==) integer(2) + +ident(highPaid) operator(=) ident(staff)operator(.)ident(findAll) operator({) ident(e) operator(->) ident(e)operator(.)ident(salary) operator(>) integer(23000) (}) +keyword(assert) ident(highPaid)operator(*.)ident(name) operator(==) operator([)stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.14) +comment(//----------------------------------------------------------------------------------) +comment(// sort works for numbers) +keyword(assert) operator([)integer(100)operator(,) integer(3)operator(,) integer(20)(])operator(.)ident(sort)operator(()(\)) operator(==) operator([)integer(3)operator(,) integer(20)operator(,) integer(100)(]) +comment(// strings representing numbers will be sorted alphabetically) +keyword(assert) operator([)stringoperator(,) stringoperator(,) string(])operator(.)ident(sort)operator(()(\)) operator(==) operator([)stringoperator(,) stringoperator(,) string(]) +comment(// closure style sorting allows arbitrary expressions for the comparison) +keyword(assert) operator([)stringoperator(,) stringoperator(,) string(])operator(.)ident(sort)operator({) ident(a)operator(,)ident(b) operator(->) ident(a)operator(.)ident(toLong)operator(()(\)) operator(<=)operator(>) ident(b)operator(.)ident(toLong)operator(()(\)}) operator(==) operator([)stringoperator(,) stringoperator(,) string(]) + +comment(// obtain the following on unix systems using: 'ps ux'.execute(\).text) +ident(processInput) operator(=) string +ident(nonEmptyLines) operator(=) operator({)local_variable(it)operator(.)ident(trim)operator(()(\)}) +ident(lines) operator(=) ident(processInput)operator(.)ident(split)operator(()string(\))operator(.)ident(findAll)operator(()ident(nonEmptyLines)(\))operator([)integer(1)operator(..)operator(-)integer(1)(]) +keyword(def) method(col)operator(()ident(n)operator(,) ident(s)(\)) operator({) ident(s)operator(.)ident(tokenize)operator(()(\))operator([)ident(n)(]) (}) +ident(commandIdx) operator(=) integer(7) +ident(pidIdx) operator(=) integer(0) +ident(ppidIdx) operator(=) integer(1) +ident(linesByPid) operator(=) ident(lines)operator(.)ident(sort)operator({) ident(col)operator(()ident(pidIdx)operator(,)local_variable(it)(\))operator(.)ident(toLong)operator(()(\)) (}) +keyword(assert) ident(col)operator(()ident(commandIdx)operator(,) ident(linesByPid)operator([)integer(0)(]\)) operator(==) string +ident(linesByPpid) operator(=) ident(lines)operator(.)ident(sort)operator({) ident(col)operator(()ident(ppidIdx)operator(,)local_variable(it)(\))operator(.)ident(toLong)operator(()(\)) (}) +keyword(assert) ident(col)operator(()ident(commandIdx)operator(,) ident(linesByPpid)operator([)integer(0)(]\)) operator(==) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.15) +comment(//----------------------------------------------------------------------------------) +comment(// sort staff from 4.12 by name) +keyword(assert) ident(staff)operator(.)ident(sort) operator({) ident(a)operator(,)ident(b) operator(->) ident(a)operator(.)ident(name) operator(<=)operator(>) ident(b)operator(.)ident(name) (})operator(*.)ident(name) operator(==) operator([)stringoperator(,) stringoperator(,) string(]) +comment(// sort by first two characters of name and if equal by descending salary) +keyword(assert) ident(staff)operator(.)ident(sort) operator({) ident(a)operator(,)ident(b) operator(->) + ident(astart) operator(=) ident(a)operator(.)ident(name)operator([)integer(0)operator(..)integer(1)(]) + ident(bstart) operator(=) ident(b)operator(.)ident(name)operator([)integer(0)operator(..)integer(1)(]) + keyword(if) operator(()ident(astart) operator(==) ident(bstart)(\)) keyword(return) ident(b)operator(.)ident(salary) operator(<=)operator(>) ident(a)operator(.)ident(salary) + keyword(return) ident(astart) operator(<=)operator(>) ident(bstart) +(})operator(*.)ident(name) operator(==) operator([)stringoperator(,) stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.16) +comment(//----------------------------------------------------------------------------------) +ident(items) operator(=) operator([)integer(1)operator(,) integer(2)operator(,) integer(3)operator(,) integer(4)operator(,) integer(5)(]) +ident(processed) operator(=) type([]) +integer(10)operator(.)ident(times)operator({) + ident(processed) operator(<)operator(<) ident(items)operator([)integer(0)(]) + ident(items) operator(=) ident(items)operator([)integer(1)operator(..)operator(-)integer(1)(]) operator(+) ident(items)operator([)integer(0)(]) +(}) +keyword(assert) ident(processed) operator(==) operator([)integer(1)operator(,) integer(2)operator(,) integer(3)operator(,) integer(4)operator(,) integer(5)operator(,) integer(1)operator(,) integer(2)operator(,) integer(3)operator(,) integer(4)operator(,) integer(5)(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.17) +comment(//----------------------------------------------------------------------------------) +keyword(import) include(java.text.DateFormatSymbols) keyword(as) class(Symbols) +ident(items) operator(=) keyword(new) ident(Symbols)operator(()(\))operator(.)ident(shortWeekdays)operator(.)ident(toList)operator(()(\))operator([)integer(1)operator(..)integer(7)(]) +keyword(assert) ident(items) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(// not as random as you might expect) +ident(println) ident(items)operator(.)ident(sort)operator({) pre_type(Math)operator(.)ident(random)operator(()(\)) (}) +comment(// => ["Sat", "Tue", "Sun", "Wed", "Mon", "Thu", "Fri"]) +comment(// better to use the built-in method for this purpose) +pre_type(Collections)operator(.)ident(shuffle)operator(()ident(items)(\)) +ident(println) ident(items) +comment(// => ["Wed", "Tue", "Fri", "Sun", "Sat", "Thu", "Mon"]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.18) +comment(//----------------------------------------------------------------------------------) +ident(symbols) operator(=) keyword(new) ident(Symbols)operator(()(\)) +ident(words) operator(=) ident(symbols)operator(.)ident(weekdays)operator(.)ident(toList)operator(()(\))operator([)integer(1)operator(..)integer(7)(]) operator(+) + ident(symbols)operator(.)ident(months)operator(.)ident(toList)operator(()(\))operator([)integer(0)operator(..)integer(11)(]) operator(+) + ident(symbols)operator(.)ident(eras)operator(.)ident(toList)operator(()(\)) operator(+) + ident(symbols)operator(.)ident(amPmStrings)operator(.)ident(toList)operator(()(\)) + +ident(expected) operator(=) comment(//) +string operator(+) +string operator(+) +string + +type(class) class(WordFormatter) operator({) + keyword(def) ident(cols) + + keyword(def) method(process)operator(()ident(list)(\)) operator({) + keyword(def) ident(sb) operator(=) keyword(new) pre_type(StringBuffer)operator(()(\)) + keyword(def) ident(colWidth) operator(=) ident(list)operator(.)ident(max)operator({)local_variable(it)operator(.)ident(size)operator(()(\)})operator(.)ident(size)operator(()(\)) operator(+) integer(1) + type(int) ident(columns) operator(=) operator([)ident(cols)operator(/)ident(colWidth)operator(,) integer(1)(])operator(.)ident(max)operator(()(\)) + keyword(def) ident(numWords) operator(=) ident(list)operator(.)ident(size)operator(()(\)) + type(int) ident(rows) operator(=) operator(()ident(numWords) operator(+) ident(columns) operator(-) integer(1)(\)) operator(/) ident(columns) + keyword(for) operator(()ident(row) keyword(in) integer(0)operator(..<)ident(rows)(\)) operator({) + keyword(for) operator(()ident(col) keyword(in) integer(0)operator(..<)ident(columns)(\)) operator({) + keyword(def) ident(target) operator(=) ident(row) operator(+) ident(col) operator(*) ident(rows) + keyword(if) operator(()ident(target) operator(<) ident(numWords)(\)) + ident(sb) operator(<)operator(<) ident(list)operator([)ident(target)(])operator(.)ident(padRight)operator(()ident(colWidth)(\)) + (}) + ident(sb) operator(<)operator(<) string + (}) + keyword(return) ident(sb)operator(.)ident(toString)operator(()(\)) + (}) +(}) + +comment(// get nr of chars that fit in window or console, see PLEAC 15.4) +comment(// hard-coded here but several packages are available, e.g. in JLine) +comment(// use a concrete implementation of Terminal.getTerminalWidth(\)) +keyword(def) method(getWinCharWidth)operator(()(\)) operator({) integer(80) (}) + +comment(// main script) +ident(actual) operator(=) keyword(new) ident(WordFormatter)operator(()key(cols)operator(:)ident(getWinCharWidth)operator(()(\)\))operator(.)ident(process)operator(()ident(words)operator(.)ident(sort)operator(()(\)\)) +keyword(assert) ident(actual) operator(==) ident(expected) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_4.19) +comment(//----------------------------------------------------------------------------------) +comment(// recursive version is simplest but can be inefficient) +keyword(def) method(fact)operator(()ident(n)(\)) operator({) operator(()ident(n) operator(==) integer(1)(\)) operator(?) integer(1) operator(:) ident(n) operator(*) ident(fact)operator(()ident(n)operator(-)integer(1)(\)}) +keyword(assert) ident(fact)operator(()integer(10)(\)) operator(==) integer(3628800) +comment(// unwrapped version: note use of BigInteger) +keyword(def) method(factorial)operator(()ident(n)(\)) operator({) + keyword(def) ident(result) operator(=) integer(1G) comment(// 1 as BigInteger) + keyword(while) operator(()ident(n) operator(>) integer(0)(\)) operator({) + ident(result) operator(*=) ident(n) + ident(n) operator(-=) integer(1) + (}) + keyword(return) ident(result) +(}) +ident(expected) operator(=) integer(93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000) +keyword(assert) ident(expected) operator(==) ident(factorial)operator(()integer(100)(\)) +comment(// println factorial(10000\)) +comment(// => 284625... (greater than 35,000 digits\)) + +comment(// simple version but less efficient) +keyword(def) method(simplePermute)operator(()ident(items)operator(,) ident(perms)(\)) operator({) + keyword(if) operator(()ident(items)operator(.)ident(size)operator(()(\)) operator(==) integer(0)(\)) + ident(println) ident(perms)operator(.)ident(join)operator(()string(\)) + keyword(else) + keyword(for) operator(()ident(i) keyword(in) ident(items)(\)) operator({) + ident(newitems) operator(=) ident(items)operator(.)ident(clone)operator(()(\)) + ident(newperms) operator(=) ident(perms)operator(.)ident(clone)operator(()(\)) + ident(newperms)operator(.)ident(add)operator(()ident(i)(\)) + ident(newitems)operator(.)ident(remove)operator(()ident(i)(\)) + ident(simplePermute)operator(()ident(newitems)operator(,) ident(newperms)(\)) + (}) +(}) +ident(simplePermute)operator(()operator([)stringoperator(,) stringoperator(,) string(])operator(,) type([])(\)) +comment(// =>) +comment(//dog bites man) +comment(//dog man bites) +comment(//bites dog man) +comment(//bites man dog) +comment(//man dog bites) +comment(//man bites dog) + +comment(// optimised version below) +ident(expected) operator(=) string + +comment(// n2pat(n, len\): produce the N-th pattern of length len) +keyword(def) method(n2pat)operator(()ident(n)operator(,) ident(length)(\)) operator({) + keyword(def) ident(pat) operator(=) type([]) + type(int) ident(i) operator(=) integer(1) + keyword(while) operator(()ident(i) operator(<=) ident(length)(\)) operator({) + ident(pat) operator(<)operator(<) operator(()ident(n) operator(%) ident(i)(\)) + ident(n) operator(=) ident(n)operator(.)ident(intdiv)operator(()ident(i)(\)) + ident(i) operator(+=) integer(1) + (}) + ident(pat) +(}) + +comment(// pat2perm(pat\): turn pattern returned by n2pat(\) into) +comment(// permutation of integers.) +keyword(def) method(pat2perm)operator(()ident(pat)(\)) operator({) + keyword(def) ident(source) operator(=) operator(()integer(0) operator(..<) ident(pat)operator(.)ident(size)operator(()(\)\))operator(.)ident(collect)operator({) local_variable(it)comment(/*.toString(\)*/) (}) + keyword(def) ident(perm) operator(=) type([]) + keyword(while) operator(()ident(pat)operator(.)ident(size)operator(()(\)) operator(>) integer(0)(\)) operator({) + keyword(def) ident(next) operator(=) ident(pat)operator(.)ident(remove)operator(()ident(pat)operator(.)ident(size)operator(()(\))operator(-)integer(1)(\)) + ident(perm) operator(<)operator(<) ident(source)operator([)ident(next)(]) + ident(source)operator(.)ident(remove)operator(()ident(next)(\)) + (}) + ident(perm) +(}) + +keyword(def) method(n2perm)operator(()ident(n)operator(,) ident(len)(\)) operator({) + ident(pat2perm)operator(()ident(n2pat)operator(()operator(()type(int)(\))ident(n)operator(,)ident(len)(\)\)) +(}) + +ident(data) operator(=) operator([)stringoperator(,) stringoperator(,) string(]) +ident(sb) operator(=) keyword(new) pre_type(StringBuffer)operator(()(\)) +ident(numPermutations) operator(=) ident(fact)operator(()ident(data)operator(.)ident(size)operator(()(\)\)) +keyword(for) operator(()ident(j) keyword(in) integer(0)operator(..<)ident(numPermutations)(\)) operator({) + keyword(def) ident(permutation) operator(=) ident(n2perm)operator(()ident(j)operator(,) ident(data)operator(.)ident(size)operator(()(\)\))operator(.)ident(collect) operator({) ident(k) operator(->) ident(data)operator([)ident(k)(]) (}) + ident(sb) operator(<)operator(<) ident(permutation)operator(.)ident(join)operator(()string(\)) operator(+) string +(}) +keyword(assert) string operator(+) ident(sb)operator(.)ident(toString)operator(()(\)) operator(==) ident(expected) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.0) +comment(//----------------------------------------------------------------------------------) +comment(// quotes are optional around the key) +ident(age) operator(=) operator([) key(Nat)operator(:)integer(24)operator(,) key(Jules)operator(:)integer(25)operator(,) key(Josh)operator(:)integer(17) (]) + +keyword(assert) ident(age)operator([)string(]) operator(==) integer(24) +comment(// alternate syntax) +keyword(assert) ident(age)operator(.)string operator(==) integer(25) + +ident(foodColor) operator(=) operator([) + key(Apple)operator(:) stringoperator(,) + key(Banana)operator(:) stringoperator(,) + key(Lemon)operator(:) stringoperator(,) + key(Carrot)operator(:) string +(]) +keyword(assert) ident(foodColor)operator(.)ident(size)operator(()(\)) operator(==) integer(4) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.1) +comment(//----------------------------------------------------------------------------------) +ident(foodColor)operator([)string(]) operator(=) string +keyword(assert) ident(foodColor)operator(.)ident(size)operator(()(\)) operator(==) integer(4) +keyword(assert) ident(foodColor)operator([)string(]) operator(==) string +ident(foodColor)operator([)string(]) operator(=) string +keyword(assert) ident(foodColor)operator(.)ident(size)operator(()(\)) operator(==) integer(5) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.2) +comment(//----------------------------------------------------------------------------------) +keyword(assert) operator([)stringoperator(,) string(])operator(.)ident(collect)operator({) ident(foodColor)operator(.)ident(containsKey)operator(()local_variable(it)(\))operator(?)stringoperator(:)string (}) operator(==) operator([) stringoperator(,) string (]) + +ident(age) operator(=) operator([)key(Toddler)operator(:)integer(3)operator(,) key(Unborn)operator(:)integer(0)operator(,) key(Phantasm)operator(:)keyword(null)(]) +operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(])operator(.)ident(each)operator({) ident(key) operator(->) + ident(print) stringcontent(: )delimiter(")> + keyword(if) operator(()ident(age)operator(.)ident(containsKey)operator(()ident(key)(\)\)) ident(print) string + keyword(if) operator(()ident(age)operator(.)ident(containsKey)operator(()ident(key)(\)) operator(&&) ident(age)operator([)ident(key)(])operator(!=)keyword(null)(\)) ident(print) string + keyword(if) operator(()ident(age)operator(.)ident(containsKey)operator(()ident(key)(\)) operator(&&) ident(age)operator([)ident(key)(]\)) ident(print) string + ident(println) string +(}) +comment(// =>) +comment(// Toddler: has key non-null true) +comment(// Unborn: has key non-null) +comment(// Phantasm: has key) +comment(// Relic:) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.3) +comment(//----------------------------------------------------------------------------------) +keyword(assert) ident(foodColor)operator(.)ident(size)operator(()(\)) operator(==) integer(5) +ident(foodColor)operator(.)ident(remove)operator(()string(\)) +keyword(assert) ident(foodColor)operator(.)ident(size)operator(()(\)) operator(==) integer(4) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.4) +comment(//----------------------------------------------------------------------------------) +ident(hash) operator(=) operator([)operator(:)(]) +ident(hash)operator(.)ident(each) operator({) ident(key)operator(,) ident(value) operator(->) + comment(// do something with key and value) +(}) + +ident(hash)operator(.)ident(each) operator({) ident(entry) operator(->) + comment(// do something with entry) +(}) + +ident(hash)operator(.)ident(keySet)operator(()(\))operator(.)ident(each) operator({) ident(key) operator(->) + comment(// do something with key) +(}) + +ident(sb) operator(=) keyword(new) pre_type(StringBuffer)operator(()(\)) +ident(foodColor)operator(.)ident(each) operator({) ident(food)operator(,) ident(color) operator(->) + ident(sb) operator(<)operator(<) stringcontent( is )inlinechar(\\n)delimiter(")> +(}) +keyword(assert) string operator(+) ident(sb)operator(.)ident(toString)operator(()(\)) operator(==) string + +ident(foodColor)operator(.)ident(each) operator({) ident(entry) operator(->) + keyword(assert) ident(entry)operator(.)ident(key)operator(.)ident(size)operator(()(\)) operator(>) integer(4) operator(&&) ident(entry)operator(.)ident(value)operator(.)ident(size)operator(()(\)) operator(>) integer(2) +(}) + +ident(foodColorsSortedByFood) operator(=) type([]) +ident(foodColor)operator(.)ident(keySet)operator(()(\))operator(.)ident(sort)operator(()(\))operator(.)ident(each) operator({) ident(k) operator(->) ident(foodColorsSortedByFood) operator(<)operator(<) ident(foodColor)operator([)ident(k)(]) (}) +keyword(assert) ident(foodColorsSortedByFood) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +ident(fakedInput) operator(=) string + +ident(from) operator(=) operator([)operator(:)(]) +ident(fakedInput)operator(.)ident(split)operator(()string(\))operator(.)ident(each)operator({) + ident(matcher) operator(=) operator(()local_variable(it) operator(=~) regexp]*\))delimiter(/)>(\)) + keyword(if) operator(()ident(matcher)operator(.)ident(matches)operator(()(\)\)) operator({) + ident(sender) operator(=) ident(matcher)operator([)integer(0)(])operator([)integer(1)(]) + keyword(if) operator(()ident(from)operator(.)ident(containsKey)operator(()ident(sender)(\)\)) ident(from)operator([)ident(sender)(]) operator(+=) integer(1) + keyword(else) ident(from)operator([)ident(sender)(]) operator(=) integer(1) + (}) +(}) + +comment(// More useful to sort by number of received mail by person) +ident(from)operator(.)ident(entrySet)operator(()(\))operator(.)ident(sort) operator({) ident(a)operator(,)ident(b) operator(->) ident(b)operator(.)ident(value)operator(<=)operator(>)ident(a)operator(.)ident(value)(})operator(.)ident(each) operator({) ident(e)operator(->) + ident(println) stringcontent(: )inlinedelimiter(")> +(}) +comment(// =>) +comment(// someone@somewhere.com: 2) +comment(// someone@spam.com: 1) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.5) +comment(//----------------------------------------------------------------------------------) +ident(hash) operator(=) operator([)key(a)operator(:)integer(1)operator(,) key(b)operator(:)integer(2)operator(,) key(c)operator(:)integer(3)(]) +comment(// Map#toString already produce a pretty decent output:) +ident(println) ident(hash) +comment(// => ["b":2, "a":1, "c":3]) + +comment(// Or do it by longhand for customised formatting) +ident(hash)operator(.)ident(each) operator({) ident(k)operator(,)ident(v) operator(->) ident(println) stringcontent( => )inlinedelimiter(")> (}) +comment(// =>) +comment(// b => 2) +comment(// a => 1) +comment(// c => 3) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.6) +comment(//----------------------------------------------------------------------------------) +comment(// java.util.LinkedHashMap "maintains a doubly-linked list running through all of its entries.) +comment(// This linked list defines the iteration ordering, which is normally the order in which keys) +comment(// were inserted into the map (insertion-order\)".) +ident(foodColor) operator(=) keyword(new) pre_type(LinkedHashMap)operator(()(\)) +ident(foodColor)operator([)string(]) operator(=) string +ident(foodColor)operator([)string(]) operator(=) string +ident(foodColor)operator([)string(]) operator(=) string + +ident(foodColor)operator(.)ident(keySet)operator(()(\))operator(.)ident(each)operator({) ident(key) operator(->) ident(println) ident(key) (}) +comment(// =>) +comment(// Banana) +comment(// Apple) +comment(// Lemon) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.7) +comment(//----------------------------------------------------------------------------------) +ident(foodsOfColor) operator(=) operator([) key(Yellow)operator(:)operator([)stringoperator(,) string(])operator(,) key(Green)operator(:)operator([)string(]) (]) +ident(foodsOfColor)operator([)string(]) operator(+=) string +keyword(assert) ident(foodsOfColor) operator(==) operator([)stringoperator(:)operator([)stringoperator(,) string(])operator(,) stringoperator(:)operator([)stringoperator(,) string(]]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.8) +comment(//----------------------------------------------------------------------------------) +ident(surname) operator(=) operator([)key(Mickey)operator(:) stringoperator(,) key(Babe)operator(:) string(]) +keyword(assert) ident(surname)operator(.)ident(findAll)operator({) local_variable(it)operator(.)ident(value) operator(==) string (})operator(.)ident(collect)operator({) local_variable(it)operator(.)ident(key) (}) operator(==) operator([)string(]) + +ident(firstname) operator(=) operator([)operator(:)(]) +ident(surname)operator(.)ident(each)operator({) ident(entry) operator(->) ident(firstname)operator([)ident(entry)operator(.)ident(value)(]) operator(=) ident(entry)operator(.)ident(key) (}) +keyword(assert) ident(firstname) operator(==) operator([)stringoperator(:)stringoperator(,) stringoperator(:)string(]) + +comment(// foodfindScript:) +doctype(#!/usr/bin/groovy) +comment(// usage: foodfind food_or_color") +ident(color) operator(=) operator([)key(Apple)operator(:)stringoperator(,) key(Banana)operator(:)stringoperator(,) key(Lemon)operator(:)stringoperator(,) key(Carrot)operator(:)string(]) +ident(given) operator(=) ident(args)operator([)integer(0)(]) +keyword(if) operator(()ident(color)operator(.)ident(containsKey)operator(()ident(given)(\)\)) + ident(println) stringcontent( is a food with color )inlinecontent(.)delimiter(")> +ident(if) operator(()ident(color)operator(.)ident(containsValue)operator(()ident(given)(\)\)) operator({) + comment(// could use commify(\) here - see 4.2) + ident(foods) operator(=) ident(color)operator(.)ident(findAll)operator({)local_variable(it)operator(.)ident(value) operator(==) ident(given)(})operator(.)ident(collect)operator({)local_variable(it)operator(.)ident(key)(}) + ident(join) operator(=) ident(foods)operator(.)ident(size)operator(()(\)) operator(==) integer(1) operator(?) string operator(:) string + ident(println) stringcontent( )inlinecontent( with color )inlinecontent(.)delimiter(")> +(}) +comment(// foodfind red) +comment(// => Apple is a food with color red.) +comment(// foodfind yellow) +comment(// => Lemon, Banana are foods with color yellow.) +comment(// foodfind Carrot) +comment(// => Carrot is a food with color orange.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.9) +comment(//----------------------------------------------------------------------------------) +ident(foodColor) operator(=) operator([)key(Apple)operator(:)stringoperator(,) key(Carrot)operator(:)stringoperator(,) key(Banana)operator(:)stringoperator(,) key(Cherry)operator(:)string(]) + +comment(// Sorted by keys) +keyword(assert) ident(foodColor)operator(.)ident(keySet)operator(()(\))operator(.)ident(sort)operator(()(\)) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(// you could now iterate through the hash with the sorted keys) +keyword(assert) ident(foodColor)operator(.)ident(values)operator(()(\))operator(.)ident(sort)operator(()(\)) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +keyword(assert) ident(foodColor)operator(.)ident(values)operator(()(\))operator(.)ident(sort)operator({)local_variable(it)operator(.)ident(size)operator(()(\)}) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.10) +comment(//----------------------------------------------------------------------------------) +comment(//merged = a.clone.update(b\) # because Hash#update changes object in place) + +ident(drinkColor) operator(=) operator([)key(Galliano)operator(:)stringoperator(,) stringoperator(:)string(]) +ident(ingestedColor) operator(=) operator([)operator(:)(]) +ident(ingestedColor)operator(.)ident(putAll)operator(()ident(drinkColor)(\)) +comment(// overrides any common keys) +ident(ingestedColor)operator(.)ident(putAll)operator(()ident(foodColor)(\)) + +ident(totalColors) operator(=) ident(ingestedColor)operator(.)ident(values)operator(()(\))operator(.)ident(sort)operator(()(\))operator(.)ident(unique)operator(()(\)) +keyword(assert) ident(totalColors) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.11) +comment(//----------------------------------------------------------------------------------) +ident(foodColor)operator([)string(])operator(=)string +ident(citrusColor) operator(=) operator([)key(Lemon)operator(:)stringoperator(,) key(Orange)operator(:)stringoperator(,) key(Lime)operator(:)string(]) +ident(println) ident(foodColor) +ident(println) ident(citrusColor) +ident(common) operator(=) ident(foodColor)operator(.)ident(keySet)operator(()(\))operator(.)ident(intersect)operator(()ident(citrusColor)operator(.)ident(keySet)operator(()(\)\)) +keyword(assert) ident(common) operator(==) operator([)string(]) + +ident(foodButNotCitrus) operator(=) ident(foodColor)operator(.)ident(keySet)operator(()(\))operator(.)ident(toList)operator(()(\)) operator(-) ident(citrusColor)operator(.)ident(keySet)operator(()(\))operator(.)ident(toList)operator(()(\)) +keyword(assert) ident(foodButNotCitrus) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.12) +comment(//----------------------------------------------------------------------------------) +comment(// no problem here, Groovy handles any kind of object for key-ing) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.13) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy uses Java implementations for storing hashes and these) +comment(// support setting an initial capacity and load factor (which determines) +comment(// at what point the hash will be resized if needed\)) +ident(hash) operator(=) operator([)operator(:)(]) comment(// Groovy shorthand gets defaults) +ident(hash) operator(=) keyword(new) pre_type(HashMap)operator(()(\)) comment(// default capacity and load factor) +ident(println) ident(hash)operator(.)ident(capacity)operator(()(\)) +comment(// => 16) +operator(()stringoperator(..)string(\))operator(.)ident(each)operator({) ident(hash)operator([)local_variable(it)(]) operator(=) local_variable(it) (}) +ident(println) ident(hash)operator(.)ident(capacity)operator(()(\)) +comment(// => 64) +ident(hash) operator(=) keyword(new) pre_type(HashMap)operator(()integer(100)(\)) comment(// initial capacity of 100 and default load factor) +ident(hash) operator(=) keyword(new) pre_type(HashMap)operator(()integer(100)operator(,) float(0.8f)(\)) comment(// initial capacity of 100 and 0.8 load factor) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.14) +comment(//----------------------------------------------------------------------------------) +ident(count) operator(=) operator([)operator(:)(]) +ident(letters) operator(=) type([]) +ident(foodColor)operator(.)ident(values)operator(()(\))operator(.)ident(each)operator({) ident(letters)operator(.)ident(addAll)operator(()operator(()local_variable(it) keyword(as) pre_type(String)type([])(\))operator(.)ident(toList)operator(()(\)\)) (}) +ident(letters)operator(.)ident(each)operator({) keyword(if) operator(()ident(count)operator(.)ident(containsKey)operator(()local_variable(it)(\)\)) ident(count)operator([)local_variable(it)(]) operator(+=) integer(1) keyword(else) ident(count)operator([)local_variable(it)(]) operator(=) integer(1) (}) +keyword(assert) ident(count) operator(==) operator([)stringoperator(:)integer(3)operator(,) stringoperator(:)integer(1)operator(,) stringoperator(:)integer(1)operator(,) stringoperator(:)integer(2)operator(,) stringoperator(:)integer(2)operator(,) stringoperator(:)integer(1)operator(,) stringoperator(:)integer(5)operator(,) stringoperator(:)integer(1)operator(,) stringoperator(:)integer(1)operator(,) stringoperator(:)integer(2)operator(,) stringoperator(:)integer(2)operator(,) stringoperator(:)integer(1)operator(,) stringoperator(:)integer(4)(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.15) +comment(//----------------------------------------------------------------------------------) +ident(father) operator(=) operator([) + key(Cain)operator(:)stringoperator(,) + key(Abel)operator(:)stringoperator(,) + key(Seth)operator(:)stringoperator(,) + key(Enoch)operator(:)stringoperator(,) + key(Irad)operator(:)stringoperator(,) + key(Mehujael)operator(:)stringoperator(,) + key(Methusael)operator(:)stringoperator(,) + key(Lamech)operator(:)stringoperator(,) + key(Jabal)operator(:)stringoperator(,) + key(Jubal)operator(:)stringoperator(,) + key(Tubalcain)operator(:)stringoperator(,) + key(Enos)operator(:)string +(]) + +keyword(def) method(upline)operator(()ident(person)(\)) operator({) + keyword(while) operator(()ident(father)operator(.)ident(containsKey)operator(()ident(person)(\)\)) operator({) + ident(print) ident(person) operator(+) string + ident(person) operator(=) ident(father)operator([)ident(person)(]) + (}) + ident(println) ident(person) +(}) + +ident(upline)operator(()string(\)) +comment(// => Irad Enoch Cain Adam) + +ident(children) operator(=) operator([)operator(:)(]) +ident(father)operator(.)ident(each) operator({) ident(k)operator(,)ident(v) operator(->) + keyword(if) operator(()operator(!)ident(children)operator(.)ident(containsKey)operator(()ident(v)(\)\)) ident(children)operator([)ident(v)(]) operator(=) type([]) + ident(children)operator([)ident(v)(]) operator(+=) ident(k) +(}) +keyword(def) method(downline)operator(()ident(person)(\)) operator({) + ident(println) stringcontent( begat )inlinecontent(.)char(\\n)delimiter(")> +(}) +ident(downline)operator(()string(\)) +comment(// => Tubalcain begat Nobody.) +ident(downline)operator(()string(\)) +comment(// => Adam begat Abel, Seth, Cain.) + +comment(// This one doesn't recurse through subdirectories (as a simplification\)) +comment(// scriptToFindIncludeFilesWhichContainNoIncludesScript:) +ident(dir) operator(=) string)delimiter(')> +ident(includes) operator(=) operator([)operator(:)(]) +keyword(new) pre_type(File)operator(()ident(dir)(\))operator(.)ident(eachFile)operator({) ident(file) operator(->) + keyword(if) operator(()ident(file)operator(.)ident(directory)(\)) keyword(return) + ident(file)operator(.)ident(eachLine)operator({) ident(line) operator(->) + ident(matcher) operator(=) operator(()ident(line) operator(=~) string]+\)>)delimiter(')>(\)) + keyword(if) operator(()ident(matcher)operator(.)ident(matches)operator(()(\)\)) operator({) + keyword(if) operator(()operator(!)ident(includes)operator(.)ident(containsKey)operator(()ident(file)operator(.)ident(name)(\)\)) ident(includes)operator([)ident(file)operator(.)ident(name)(]) operator(=) type([]) + ident(includes)operator([)ident(file)operator(.)ident(name)(]) operator(+=) ident(matcher)operator([)integer(0)(])operator([)integer(1)(]) + (}) + (}) +(}) +comment(// find referenced files which have no includes; assumes all files) +comment(// were processed and none are missing) +ident(println) ident(includes)operator(.)ident(values)operator(()(\))operator(.)ident(sort)operator(()(\))operator(.)ident(flatten)operator(()(\))operator(.)ident(unique)operator(()(\)) operator(-) ident(includes)operator(.)ident(keySet)operator(()(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_5.16) +comment(//----------------------------------------------------------------------------------) +comment(// dutree - print sorted indented rendition of du output) +comment(// obtaining this input is not shown, it is similar to other examples) +comment(// on some unix systems it will be: duProcessFakedInput = "du options".process(\).text) +ident(duProcessFakedInput) operator(=) string + +comment(// The DuNode class collects all information about a directory,) +type(class) class(DuNode) operator({) + keyword(def) ident(name) + keyword(def) ident(size) + keyword(def) ident(kids) operator(=) type([]) + + comment(// support for sorting nodes with side) + keyword(def) method(compareTo)operator(()ident(node2)(\)) operator({) ident(size) operator(<=)operator(>) ident(node2)operator(.)ident(size) (}) + + keyword(def) method(getBasename)operator(()(\)) operator({) + ident(name)operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) + (}) + + comment(// returns substring before last "/", otherwise null) + keyword(def) method(getParent)operator(()(\)) operator({) + keyword(def) ident(p) operator(=) ident(name)operator(.)ident(replaceAll)operator(()regexpoperator(,)string(\)) + keyword(return) operator(()ident(p) operator(==) ident(name)(\)) operator(?) keyword(null) operator(:) ident(p) + (}) +(}) + +comment(// The DuTree does the actual work of) +comment(// getting the input, parsing it, building up a tree) +comment(// and formatting it for output) +type(class) class(DuTree) operator({) + keyword(def) ident(input) + keyword(def) ident(topdir) + keyword(def) ident(nodes) operator(=) operator([)operator(:)(]) + keyword(def) ident(dirsizes) operator(=) operator([)operator(:)(]) + keyword(def) ident(kids) operator(=) operator([)operator(:)(]) + + comment(// get a node by name, create it if it does not exist yet) + keyword(def) method(getOrCreateNode)operator(()ident(name)(\)) operator({) + keyword(if) operator(()operator(!)ident(nodes)operator(.)ident(containsKey)operator(()ident(name)(\)\)) + ident(nodes)operator([)ident(name)(]) operator(=) keyword(new) ident(DuNode)operator(()key(name)operator(:)ident(name)(\)) + keyword(return) ident(nodes)operator([)ident(name)(]) + (}) + + comment(// figure out how much is taken in each directory) + comment(// that isn't stored in the subdirectories. Add a new) + comment(// fake kid called "." containing that much.) + keyword(def) method(getDots)operator(()ident(node)(\)) operator({) + keyword(def) ident(cursize) operator(=) ident(node)operator(.)ident(size) + keyword(for) operator(()ident(kid) keyword(in) ident(node)operator(.)ident(kids)(\)) operator({) + ident(cursize) operator(-=) ident(kid)operator(.)ident(size) + ident(getDots)operator(()ident(kid)(\)) + (}) + keyword(if) operator(()ident(node)operator(.)ident(size) operator(!=) ident(cursize)(\)) operator({) + keyword(def) ident(newnode) operator(=) ident(getOrCreateNode)operator(()ident(node)operator(.)ident(name) operator(+) string(\)) + ident(newnode)operator(.)ident(size) operator(=) ident(cursize) + ident(node)operator(.)ident(kids) operator(+=) ident(newnode) + (}) + (}) + + keyword(def) method(processInput)operator(()(\)) operator({) + keyword(def) ident(name) operator(=) string + ident(input)operator(.)ident(split)operator(()string(\))operator(.)ident(findAll)operator({)local_variable(it)operator(.)ident(trim)operator(()(\)})operator(.)ident(each)operator({) ident(line) operator(->) + keyword(def) ident(tokens) operator(=) ident(line)operator(.)ident(tokenize)operator(()(\)) + keyword(def) ident(size) operator(=) ident(tokens)operator([)integer(0)(]) + ident(name) operator(=) ident(tokens)operator([)integer(1)(]) + keyword(def) ident(node) operator(=) ident(getOrCreateNode)operator(()ident(name)(\)) + ident(node)operator(.)ident(size) operator(=) ident(size)operator(.)ident(toInteger)operator(()(\)) + ident(nodes)operator([)ident(name)(]) operator(=) ident(node) + keyword(def) ident(parent) operator(=) ident(node)operator(.)ident(parent) + keyword(if) operator(()ident(parent)(\)) + ident(getOrCreateNode)operator(()ident(parent)(\))operator(.)ident(kids) operator(<)operator(<) ident(node) + (}) + ident(topdir) operator(=) ident(nodes)operator([)ident(name)(]) + (}) + + comment(// recursively output everything) + comment(// passing padding and number width as well) + comment(// on recursive calls) + keyword(def) method(output)operator(()ident(node)operator(,) ident(prefix)operator(=)stringoperator(,) ident(width)operator(=)integer(0)(\)) operator({) + keyword(def) ident(line) operator(=) ident(node)operator(.)ident(size)operator(.)ident(toString)operator(()(\))operator(.)ident(padRight)operator(()ident(width)(\)) operator(+) string operator(+) ident(node)operator(.)ident(basename) + ident(println) operator(()ident(prefix) operator(+) ident(line)(\)) + ident(prefix) operator(+=) ident(line)operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) + ident(prefix) operator(=) ident(prefix)operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) + keyword(if) operator(()ident(node)operator(.)ident(kids)operator(.)ident(size)operator(()(\)) operator(>) integer(0)(\)) operator({) comment(// not a bachelor node) + ident(kids) operator(=) ident(node)operator(.)ident(kids) + ident(kids)operator(.)ident(sort)operator({) ident(a)operator(,)ident(b) operator(->) ident(b)operator(.)ident(compareTo)operator(()ident(a)(\)) (}) + ident(width) operator(=) ident(kids)operator([)integer(0)(])operator(.)ident(size)operator(.)ident(toString)operator(()(\))operator(.)ident(size)operator(()(\)) + keyword(for) operator(()ident(kid) keyword(in) ident(kids)(\)) ident(output)operator(()ident(kid)operator(,) ident(prefix)operator(,) ident(width)(\)) + (}) + (}) +(}) + +ident(tree) operator(=) keyword(new) ident(DuTree)operator(()key(input)operator(:)ident(duProcessFakedInput)(\)) +ident(tree)operator(.)ident(processInput)operator(()(\)) +ident(tree)operator(.)ident(getDots)operator(()ident(tree)operator(.)ident(topdir)(\)) +ident(tree)operator(.)ident(output)operator(()ident(tree)operator(.)ident(topdir)(\)) +comment(// =>) +comment(// 11966 groovysoap) +comment(// | 11732 lib) +comment(// | 202 src) +comment(// | | 102 test) +comment(// | | 77 main) +comment(// | | | 74 groovy) +comment(// | | | | 71 net) +comment(// | | | | | 68 soap) +comment(// | | | | | 3 .) +comment(// | | | | 3 .) +comment(// | | | 3 .) +comment(// | | 14 .) +comment(// | | 9 examples) +comment(// | | | 8 groovy) +comment(// | | | 1 .) +comment(// | 32 .) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_6.0) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy has built-in language support for Regular Expressions:) +comment(// * Strings quoted with '/' characters have special escaping) +comment(// rules for backslashes and the like.) +comment(// * ~string (regex pattern operator\)) +comment(// * m =~ /pattern/ (regex find operator\)) +comment(// * m ==~/pattern/ (regex match operator\)) +comment(// * patterns can be used in case expressions in a switch statement) +comment(// * string.replaceAll can take a closure expression as the second argument) +comment(// In addition, Groovy can make use of Java's Pattern, Matcher and Scanner classes) +comment(// directly. (The sugar coating metnioed above sits on top of these anyway\).) +comment(// There are also additional open source Java regex libraries which can be used.) + +ident(meadow1) operator(=) string +ident(meadow2) operator(=) string +comment(// pattern strings can benefit from 'slashy' quotes) +ident(partial) operator(=) regexp +ident(full) operator(=) regexp + +comment(// find operator) +keyword(assert) operator(!)operator(()ident(meadow1) operator(=~) ident(partial)(\)) +keyword(assert) ident(meadow2) operator(=~) ident(partial) +ident(finder) operator(=) operator(()ident(meadow2) operator(=~) ident(partial)(\)) +comment(// underneath Groovy sugar coating is Java implementation) +keyword(assert) ident(finder) keyword(instanceof) ident(java)operator(.)ident(util)operator(.)ident(regex)operator(.)ident(Matcher) + +comment(// match operator) +keyword(assert) operator(!)operator(()ident(meadow1) operator(==~) ident(full)(\)) +keyword(assert) ident(meadow2) operator(==~) ident(full) +ident(matcher) operator(=) operator(()ident(meadow2) operator(==~) ident(full)(\)) +comment(// under the covers is just a boolean) +keyword(assert) ident(matcher) keyword(instanceof) pre_type(Boolean) + +keyword(assert) ident(meadow1) operator(=~) regexp comment(// (?i\) == case flag) + +ident(string) operator(=) string +ident(println) ident(string)operator(.)ident(replaceFirst)operator(()regexpoperator(,) string(\)) +comment(// => egood food) +ident(println) ident(string)operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) +comment(// => egeede efeede (global\)) +comment(// beware this one is just textual replacement) +ident(println) ident(string)operator(.)ident(replace)operator(()regexpoperator(,) string(\)) +comment(// => good food) +ident(println) stringoperator(.)ident(replace)operator(()regexpoperator(,) string(\)) +comment(// => ee) + +comment(// groovy -e "m = args[0] =~ /(a|ba|b\)+(a|ac\)+/; if (m.matches(\)\) println m[0][0]" ababacaca) +comment(// => ababa) + +ident(digits) operator(=) string +ident(nonlap) operator(=) ident(digits) operator(=~) regexp +keyword(assert) ident(nonlap)operator(.)ident(count) operator(==) integer(3) +ident(print) string +operator(()integer(0)operator(..<)ident(nonlap)operator(.)ident(count)(\))operator(.)ident(each)operator({) ident(print) ident(nonlap)operator([)local_variable(it)(]) operator(+) string (})operator(;) ident(print) string +ident(print) string +ident(yeslap) operator(=) operator(()ident(digits) operator(=~) regexp(\)) +keyword(assert) ident(yeslap)operator(.)ident(count) operator(==) integer(7) +operator(()integer(0)operator(..<)ident(yeslap)operator(.)ident(count)(\))operator(.)ident(each)operator({) ident(print) ident(yeslap)operator([)local_variable(it)(])operator([)integer(1)(]) operator(+) string (})operator(;) ident(print) string +comment(// Non-overlapping: 123 456 789) +comment(// Overlapping: 123 234 345 456 567 678 789) + +ident(string) operator(=) string +comment(// Greedy version) +ident(parts) operator(=) ident(string) operator(=~) regexp +operator(()integer(1)operator(..)ident(parts)operator(.)ident(groupCount)operator(()(\)\))operator(.)ident(each)operator({) ident(print) stringcontent(\) )delimiter(")> (})operator(;) ident(print) string +comment(// (And little \) (lambs\) ( eat ivy\)) + +comment(// Reluctant version) +ident(parts) operator(=) ident(string) operator(=~) regexp +operator(()integer(1)operator(..)ident(parts)operator(.)ident(groupCount)operator(()(\)\))operator(.)ident(each)operator({) ident(print) stringcontent(\) )delimiter(")> (})operator(;) ident(print) string +comment(// (And \) (little lambs\) ( eat ivy\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.1) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy splits src and dest to avoid this problem) +ident(src) operator(=) string +ident(dst) operator(=) ident(src)operator(.)ident(replaceFirst)operator(()stringoperator(,) string(\)) +keyword(assert) ident(dst) operator(==) string + +comment(// extract basename) +ident(src) operator(=) string +ident(dst) operator(=) ident(src)operator(.)ident(replaceFirst)operator(()stringoperator(,) string(\)) +keyword(assert) ident(dst) operator(==) string + +comment(// Make All Words Title-Cased (not that you would do it this way\)) +comment(// The preprocessing operations \\X where X is one of l, u, L, and U are not supported) +comment(// in the sun regex library but other Java regex libraries may support this. Instead:) +ident(src) operator(=) string +ident(dst) operator(=) ident(src) +operator(()stringoperator(..)string(\))operator(.)ident(each)operator({) ident(dst) operator(=) ident(dst)operator(.)ident(replaceAll)operator(()regexpoperator(+)local_variable(it)operator(+)regexpoperator(+)local_variable(it)operator(,) regexpoperator(+)local_variable(it)operator(.)ident(toUpperCase)operator(()(\)\)) (}) +keyword(assert) ident(dst) operator(==) string + +comment(// rename list of dirs) +ident(bindirs) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\)) +ident(expected) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\)) +ident(libdirs) operator(=) ident(bindirs)operator(.)ident(collect) operator({) ident(dir) operator(->) ident(dir)operator(.)ident(replaceFirst)operator(()stringoperator(,) string(\)) (}) +keyword(assert) ident(libdirs) operator(==) ident(expected) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.2) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy uses Java regex (other Java regex packages would also be possible\)) +comment(// It doesn't support Locale-based settings but you can roll your own to some) +comment(// extent, you can use any Unicode characters as per below and you can use) +comment(// \\p{Punct} Punctuation: One of !"#$%&'(\)*+,-./:;<=>?@[\\]^_`{|}~) +comment(// or the other special character classes) +ident(words) operator(=) string +ident(results) operator(=) string +ident(greekAlpha) operator(=) string +ident(special) operator(=) string operator(+) ident(greekAlpha) +comment(// flag as either Y (alphabetic\) or N (not\)) +ident(words)operator(.)ident(split)operator(()string(\))operator(.)ident(findAll)operator({)local_variable(it)operator(.)ident(trim)operator(()(\)})operator(.)ident(each)operator({) ident(results) operator(+=) local_variable(it) operator(==~) regexpoperator(+)ident(special)operator(+)regexp operator(?)stringoperator(:)string (}) +keyword(assert) ident(results) operator(==) string +ident(results) operator(=) string +ident(words)operator(.)ident(split)operator(()string(\))operator(.)ident(findAll)operator({)local_variable(it)operator(.)ident(trim)operator(()(\)})operator(.)ident(each)operator({) ident(results) operator(+=) local_variable(it) operator(==~) regexp operator(?)stringoperator(:)string (}) +keyword(assert) ident(results) operator(==) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.3) +comment(//----------------------------------------------------------------------------------) +comment(// as many non-whitespace bytes as possible) +ident(finder) operator(=) string operator(=~) regexp +keyword(assert) ident(finder)operator([)integer(0)(]) operator(==) string + +comment(// as many letters, apostrophes, and hyphens) +ident(finder) operator(=) string operator(=~) regexp comment(//') +keyword(assert) ident(finder)operator([)integer(0)(]) operator(==) string + +comment(// selecting words) +ident(finder) operator(=) string operator(=~) regexp comment(// usually best) +ident(println) ident(finder)operator([)integer(0)(])operator([)integer(0)(]) +comment(// => Psalm (23rd is not matched\)) +ident(finder) operator(=) string operator(=~) regexp comment(// fails at ends or w/ punctuation) +ident(println) ident(finder)operator(.)ident(matches)operator(()(\)) +comment(// => false (no whitespaces at ends\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.4) +comment(//----------------------------------------------------------------------------------) +ident(str) operator(=) string +ident(re) operator(=) string + +ident(finder) operator(=) ident(str) operator(=~) ident(re) +ident(out) operator(=) ident(str) +operator(()integer(0)operator(..<)ident(finder)operator(.)ident(count)(\))operator(.)ident(each)operator({) + ident(adr) operator(=) ident(finder)operator([)local_variable(it)(])operator([)integer(0)(]) + ident(out) operator(=) ident(out)operator(.)ident(replaceAll)operator(()ident(adr)operator(,) stringcontent( [)inlinecontent(])delimiter(")>(\)) +(}) +ident(println) ident(out) +comment(// => groovy.codehaus.org [63.246.7.187] and www.aboutgroovy.com [63.246.7.76]) + +comment(// to match whitespace or #-characters in an extended re you need to escape them.) +ident(foo) operator(=) integer(42) +ident(str) operator(=) string +ident(re) operator(=) string +ident(finder) operator(=) ident(str) operator(=~) ident(re) +ident(found) operator(=) ident(finder)operator([)integer(0)(]) +ident(out) operator(=) ident(str)operator(.)ident(replaceAll)operator(()ident(found)operator([)integer(0)(])operator(,) ident(evaluate)operator(()ident(found)operator([)integer(1)(]\))operator(.)ident(toString)operator(()(\)\)) +keyword(assert) ident(out) operator(==) string +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.5) +comment(//----------------------------------------------------------------------------------) +ident(fish) operator(=) string +ident(expected) operator(=) string +ident(thirdFish) operator(=) regexp +keyword(assert) ident(expected) operator(==) operator(()ident(fish)operator(.)ident(replaceAll)operator(()ident(thirdFish)operator(,) string(\)\)) + +ident(anyFish) operator(=) regexp +ident(finder) operator(=) ident(fish) operator(=~) ident(anyFish) +comment(// finder contains an array of matched groups) +comment(// 2 = third one (index start at 0\), 1 = matched word in group) +ident(out) operator(=) stringcontent( one.)delimiter(")> +keyword(assert) ident(out) operator(==) ident(expected) + +ident(evens) operator(=) type([]) +operator(()integer(0)operator(..<)ident(finder)operator(.)ident(count)(\))operator(.)ident(findAll)operator({)local_variable(it)operator(%)integer(2)operator(!=)integer(0)(})operator(.)ident(each)operator({) ident(evens) operator(+=) ident(finder)operator([)local_variable(it)(])operator([)integer(1)(]) (}) +ident(println) stringcontent(.)delimiter(")> +comment(// => Even numbered fish are two blue.) + +comment(// one of several ways to do this) +ident(pond) operator(=) ident(fish) operator(+) string +ident(fishInPond) operator(=) operator(()regexp(\)) operator(*) integer(4) operator(+) regexp +ident(found) operator(=) operator(()ident(pond) operator(=~) ident(fishInPond)(\))operator([)integer(0)(]) +ident(println) operator(()operator(()ident(found)operator([)integer(1)operator(..)integer(6)(]) operator(+) string operator(+) ident(found)operator([)integer(8)operator(..)integer(9)(]\))operator(.)ident(join)operator(()(\)\)) +comment(// => One fish two fish red fish sushi fish in the pond) + +comment(// find last fish) +ident(expected) operator(=) string +ident(pond) operator(=) string +ident(finder) operator(=) operator(()ident(pond) operator(=~) ident(anyFish)(\)) +keyword(assert) ident(expected) operator(==) stringdelimiter(")> +comment(// => Last fish is blue) + +comment(// greedy match version of above) +ident(finder) operator(=) operator(()ident(pond) operator(=~) regexp operator(+) ident(anyFish)(\)) +keyword(assert) ident(expected) operator(==) stringdelimiter(")> + +comment(// last fish match version of above) +ident(finder) operator(=) operator(()ident(pond) operator(=~) regexp(\)) +keyword(assert) ident(expected) operator(==) stringdelimiter(")> +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.6) +comment(//----------------------------------------------------------------------------------) +comment(// Html Stripper) +comment(// get this using: fakedfile = new File('path_to_file.htm'\).text) +ident(fakedFile) operator(=) string +Chapter 1 Title + +

Chapter 1: Some Heading

+A paragraph. + + +)delimiter(''')> + +ident(stripExpectations) operator(=) stringoperator(.)ident(trim)operator(()(\)) + +ident(stripped) operator(=) ident(fakedFile)operator(.)ident(replaceAll)operator(()regexp)delimiter(/)>operator(,)string(\))operator(.)ident(trim)operator(()(\)) +keyword(assert) ident(stripExpectations) operator(==) ident(stripped) + +ident(pattern) operator(=) string + +ident(headerfyExpectations) operator(=) stringChapter 1: Some Heading +A paragraph. +)delimiter(''')>operator(.)ident(trim)operator(()(\)) + +ident(headerfied) operator(=) ident(stripped)operator(.)ident(replaceAll)operator(()ident(pattern)operator(,) string)content($)content(1)delimiter(')>(\)) +keyword(assert) ident(headerfyExpectations) operator(==) ident(headerfied) + +comment(// one liner equivalent which prints to stdout) +comment(//% groovy -p -e "line.replaceAll(/^(Chapter\\s+\\d+\\s*:.*\)/,'

$1

'\)") + +comment(// one liner equivalent which modifies file in place and creates *.bak original file) +comment(//% groovy -pi .bak -e "line.replaceAll(/^(Chapter\\s+\\d+\\s*:.*\)/,'

$1

'\)") + +comment(// use: realFileInput = new File(path_to_file\).text) +ident(fakeFileInput) operator(=) string + +ident(chunkyPattern) operator(=) regexp +ident(finder) operator(=) ident(fakeFileInput) operator(=~) ident(chunkyPattern) +operator(()integer(0)operator(..<)ident(finder)operator(.)ident(count)(\))operator(.)ident(each) operator({) + ident(println) stringcontent( contains )inlinecontent( lines.)delimiter(")> +(}) +comment(// =>) +comment(// Chunk #0 contains 2 lines.) +comment(// Chunk #1 contains 1 lines.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.7) +comment(//----------------------------------------------------------------------------------) +comment(// general pattern is:) +comment(//file = new File("datafile"\).text.split(/pattern/\)) +comment(// .Ch, .Se and .Ss divide chunks of input text) +ident(fakedFiletext) operator(=) string +ident(chunks) operator(=) ident(fakedFiletext)operator(.)ident(split)operator(()regexp(\)) +ident(println) stringcontent( chunks.)delimiter(")> +comment(// => I read 10 chunks.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.8) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy doesn't support the ~/BEGIN/ .. ~/END/ notation) +comment(// you have to emulate it as shown in the example below) +comment(// The from line number to line number processing is supported) +comment(// from the command line but not within a script, e.g.) +comment(// command-line to print lines 15 through 17 inclusive (see below\)) +comment(// > groovy -p -e "if (count in 15..17\) return line" datafile) +comment(// Within a script itself, you emulate the count by keeping state) + +ident(htmlContent) operator(=) stringA Heading +Here is inline AAA. +And the bigger Example 2: + +line BBB +line CCC + +Done. +)delimiter(''')>operator(.)ident(trim)operator(()(\)) + +ident(examplePattern) operator(=) regexp(.*?\)<)content(\\/)content(XMP>)delimiter(/)> +ident(finder) operator(=) ident(htmlContent) operator(=~) ident(examplePattern) +operator(()integer(0)operator(..<)ident(finder)operator(.)ident(count)(\))operator(.)ident(each) operator({) + ident(println) stringcontent(:)delimiter(")> + ident(println) ident(finder)operator([)local_variable(it)(])operator([)integer(1)(]) +(}) +comment(// =>) +comment(// Example 1:) +comment(// inline AAA) +comment(// Example 2:) +comment(//) +comment(// line BBB) +comment(// line CCC) +comment(//) + +ident(htmlContent)operator(.)ident(split)operator(()string(\))operator(.)ident(eachWithIndex)operator({) ident(line)operator(,) ident(count) operator(->) + keyword(if) operator(()ident(count) keyword(in) integer(4)operator(..)integer(5)(\)) ident(println) ident(line) +(}) +comment(// =>) +comment(// line BBB) +comment(// line CCC) + +comment(// You would probably use a mail Api for this in Groovy) +ident(fakedMailInput) operator(=) string +To: +Date: Sun, 31 Dec 2006 02:14:57 +1100 + +From: noone@nowhere.com +To: +Date: Sun, 31 Dec 2006 02:14:58 +1100 + +From: someone@somewhere.com +To: +Date: Sun, 31 Dec 2006 02:14:59 +1100 +)delimiter(''')>operator(.)ident(trim)operator(()(\))operator(+)string + +ident(seen) operator(=) operator([)operator(:)(]) +ident(fakedMailInput)operator(.)ident(split)operator(()string(\))operator(.)ident(each)operator({) ident(line) operator(->) + ident(m) operator(=) operator(()ident(line) operator(=~) regexp(\)) + keyword(if) operator(()ident(m)(\)) operator({) + ident(addr) operator(=) ident(m)operator([)integer(0)(])operator([)integer(1)(]) operator(=~) regexp(\),;)char(\\s)content(]+)content(\\@)content([^<>(\),;)char(\\s)content(]+\))delimiter(/)> + ident(x) operator(=) ident(addr)operator([)integer(0)(])operator([)integer(1)(]) + keyword(if) operator(()ident(seen)operator(.)ident(containsKey)operator(()ident(x)(\)\)) ident(seen)operator([)ident(x)(]) operator(+=) integer(1) keyword(else) ident(seen)operator([)ident(x)(]) operator(=) integer(1) + (}) +(}) +ident(seen)operator(.)ident(each)operator({) ident(k)operator(,)ident(v) operator(->) ident(println) stringcontent( seen )inlinecontent( time)inlinecontent(.)delimiter(")> (}) +comment(// =>) +comment(// Address noone@nowhere.com seen 1 time.) +comment(// Address someone@somewhere.com seen 2 times.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.9) +comment(//----------------------------------------------------------------------------------) +keyword(import) include(java.util.regex.Pattern) + +ident(names) operator(=) string + +keyword(def) method(glob2pat)operator(()ident(globstr)(\)) operator({) + keyword(def) ident(patmap) operator(=) operator([) stringoperator(:)stringoperator(,) stringoperator(:)stringoperator(,) stringoperator(:)stringoperator(,) stringoperator(:)string (]) + keyword(def) ident(result) operator(=) string + string operator(+) ident(globstr)operator(.)ident(replaceAll)operator(()regexp(\)) operator({) ident(all)operator(,) ident(c) operator(->) + ident(result) operator(+=) operator(()ident(patmap)operator(.)ident(containsKey)operator(()ident(c)(\)) operator(?) ident(patmap)operator([)ident(c)(]) operator(:) pre_type(Pattern)operator(.)ident(quote)operator(()ident(c)(\)\)) + (}) + ident(result) operator(+) string +(}) + +keyword(def) method(checkNumMatches)operator(()ident(pat)operator(,) ident(count)(\)) operator({) + keyword(assert) operator(()ident(names) operator(=~) ident(glob2pat)operator(()ident(pat)(\)\))operator(.)ident(count) operator(==) ident(count) +(}) + +ident(checkNumMatches)operator(()stringoperator(,) integer(3)(\)) +ident(checkNumMatches)operator(()stringoperator(,) integer(2)(\)) +ident(checkNumMatches)operator(()stringoperator(,) integer(2)(\)) +ident(checkNumMatches)operator(()stringoperator(,) integer(2)(\)) +ident(checkNumMatches)operator(()stringoperator(,) integer(0)(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.10) +comment(//----------------------------------------------------------------------------------) +comment(// version 1: simple obvious way) +ident(states) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\)) + +keyword(def) method(popgrep1)operator(()ident(file)(\)) operator({) + ident(file)operator(.)ident(eachLine)operator({) ident(line) operator(->) + keyword(if) operator(()ident(states)operator(.)ident(any)operator({) ident(line) operator(=~) regexpchar(\\b)delimiter(/)> (}\)) ident(println) ident(line) + (}) +(}) +comment(// popgrep1(new File('path_to_file'\)\)) + +comment(// version 2: eval strings; fast but hard to quote (SLOW\)) +keyword(def) method(popgrep2)operator(()ident(file)(\)) operator({) + keyword(def) ident(code) operator(=) string + ident(states)operator(.)ident(each)operator({) + ident(code) operator(+=) stringchar(\\\\)content(b/\) found = true)char(\\n)delimiter(")> + (}) + ident(code) operator(+=) string + ident(file)operator(.)ident(eachLine)operator({) ident(line) operator(=) local_variable(it)operator(;) ident(evaluate)operator(()ident(code)(\)) (}) +(}) +comment(// popgrep2(new File('path_to_file'\)\)) + +comment(// version 2b: eval using switch/case (not in Perl cookbook\) (SLOW\)) +keyword(def) method(popgrep2b)operator(()ident(file)(\)) operator({) + keyword(def) ident(code) operator(=) string + ident(states)operator(.)ident(each)operator({) + ident(code) operator(+=) stringchar(\\\\)content(b.*/:)char(\\n)content(println line;break)char(\\n)delimiter(")> + (}) + ident(code) operator(+=) string + ident(file)operator(.)ident(eachLine)operator({) ident(line) operator(=) local_variable(it)operator(;) ident(evaluate)operator(()ident(code)(\)) (}) +(}) +comment(// popgrep2b(new File('path_to_file'\)\)) + +comment(// version3: build a match_any function as a GString) +keyword(def) method(popgrep3)operator(()ident(file)(\)) operator({) + keyword(def) ident(code) operator(=) ident(states)operator(.)ident(collect)operator({) stringchar(\\\\)content(b/)delimiter(")> (})operator(.)ident(join)operator(()string(\)) + ident(file)operator(.)ident(eachLine)operator({) ident(line) operator(=) local_variable(it)operator(;) keyword(if) operator(()ident(evaluate)operator(()ident(code)(\)\)) ident(println) ident(line) (}) +(}) +comment(// popgrep3(new File('path_to_file'\)\)) + +comment(// version4: pretty fast, but simple: compile all re's first:) +ident(patterns) operator(=) ident(states)operator(.)ident(collect)operator({) operator(~)regexpchar(\\b)delimiter(/)> (}) +keyword(def) method(popgrep4)operator(()ident(file)(\)) operator({) + ident(file)operator(.)ident(eachLine)operator({) ident(line) operator(->) + keyword(if) operator(()ident(patterns)operator(.)ident(any)operator({) local_variable(it)operator(.)ident(matcher)operator(()ident(line)(\)}\)) ident(println) ident(line) + (}) +(}) +comment(// popgrep4(new File('path_to_file'\)\)) + +comment(// version5: faster) +ident(str) operator(=) ident(states)operator(.)ident(collect)operator({) regexpchar(\\b)delimiter(/)> (})operator(.)ident(join)operator(()string(\)) +keyword(def) method(popgrep5)operator(()ident(file)(\)) operator({) + ident(file)operator(.)ident(eachLine)operator({) ident(line) operator(->) + keyword(if) operator(()ident(line) operator(=~) ident(str)(\)) ident(println) ident(line) + (}) +(}) +comment(// popgrep5(new File('path_to_file'\)\)) + +comment(// version5b: faster (like 5 but compiled outside loop\)) +ident(pattern) operator(=) operator(~)ident(states)operator(.)ident(collect)operator({) regexpchar(\\b)delimiter(/)> (})operator(.)ident(join)operator(()string(\)) +keyword(def) method(popgrep5b)operator(()ident(file)(\)) operator({) + ident(file)operator(.)ident(eachLine)operator({) ident(line) operator(->) + keyword(if) operator(()ident(pattern)operator(.)ident(matcher)operator(()ident(line)(\)\)) ident(println) ident(line) + (}) +(}) +comment(// popgrep5b(new File('path_to_file'\)\)) + +comment(// speeds trials ON the current source file (~1200 lines\)) +comment(// popgrep1 => 0.39s) +comment(// popgrep2 => 25.08s) +comment(// popgrep2b => 23.86s) +comment(// popgrep3 => 22.42s) +comment(// popgrep4 => 0.12s) +comment(// popgrep5 => 0.05s) +comment(// popgrep5b => 0.05s) +comment(// Groovy's built-in support is the way to go in terms of) +comment(// both speed and simplicity of understanding. Avoid using) +comment(// evaluate(\) unless you absolutely need it) + +comment(// generic matching functions) +ident(input) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(findAll)operator({)local_variable(it)operator(.)ident(trim)operator(()(\)}) + +keyword(def) method(matchAny)operator(()ident(line)operator(,) ident(patterns)(\)) operator({) ident(patterns)operator(.)ident(any)operator({) ident(line) operator(=~) local_variable(it) (}) (}) +keyword(def) method(matchAll)operator(()ident(line)operator(,) ident(patterns)(\)) operator({) ident(patterns)operator(.)ident(every)operator({) ident(line) operator(=~) local_variable(it) (}) (}) + +keyword(assert) ident(input)operator(.)ident(findAll)operator({) ident(matchAny)operator(()local_variable(it)operator(,) operator([)stringoperator(,)string(]\)) (})operator(.)ident(size)operator(()(\)) operator(==) integer(3) +keyword(assert) ident(input)operator(.)ident(findAll)operator({) ident(matchAny)operator(()local_variable(it)operator(,) operator([)stringoperator(,)string(]\)) (})operator(.)ident(size)operator(()(\)) operator(==) integer(2) +keyword(assert) ident(input)operator(.)ident(findAll)operator({) ident(matchAll)operator(()local_variable(it)operator(,) operator([)stringoperator(,)string(]\)) (})operator(.)ident(size)operator(()(\)) operator(==) integer(1) +keyword(assert) ident(input)operator(.)ident(findAll)operator({) ident(matchAll)operator(()local_variable(it)operator(,) operator([)stringoperator(,)string(]\)) (})operator(.)ident(size)operator(()(\)) operator(==) integer(0) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.11) +comment(//----------------------------------------------------------------------------------) +comment(// patternCheckingScript:) +ident(prompt) operator(=) string )delimiter(')> +ident(print) string operator(+) ident(prompt) +keyword(new) pre_type(BufferedReader)operator(()keyword(new) pre_type(InputStreamReader)operator(()pre_type(System)operator(.)ident(in)(\)\))operator(.)ident(eachLine)operator({) ident(line) operator(->) + keyword(try) operator({) + pre_type(Pattern)operator(.)ident(compile)operator(()ident(line)(\)) + ident(print) string operator(+) ident(prompt) + (}) keyword(catch) operator(()ident(java)operator(.)ident(util)operator(.)ident(regex)operator(.)ident(PatternSyntaxException) ident(ex)(\)) operator({) + ident(print) string operator(+) ident(ex)operator(.)ident(message) operator(+) ident(prompt) + (}) +(}) +comment(// =>) +comment(// Enter patterns to check:) +comment(// > ab*.c) +comment(// Valid) +comment(// > ^\\s+[^a-z]*$) +comment(// Valid) +comment(// > **) +comment(// Invalid pattern: Dangling meta character '*' near index 0) +comment(// **) +comment(// ^) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.12) +comment(//----------------------------------------------------------------------------------) +ident(src) operator(=) string +comment(// simplistic with locale issue) +ident(dst) operator(=) ident(src) +operator(()stringoperator(..)string(\))operator(.)ident(each)operator({) ident(dst) operator(=) ident(dst)operator(.)ident(replaceAll)operator(()regexpoperator(+)local_variable(it)operator(+)regexpoperator(+)local_variable(it)operator(,) local_variable(it)operator(.)ident(toUpperCase)operator(()(\)\)) (}) +ident(println) ident(dst) +comment(// => Dierk KöNig) +comment(// locale avoidance) +ident(dst) operator(=) ident(src) +operator(()stringoperator(..)string(\))operator(.)ident(each)operator({) ident(dst) operator(=) ident(dst)operator(.)ident(replaceAll)operator(()regexpoperator(+)local_variable(it)operator(,) local_variable(it)operator(.)ident(toUpperCase)operator(()(\)\)) (}) +ident(println) ident(dst) +comment(// => Dierk König) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.13) +comment(//----------------------------------------------------------------------------------) +comment(// Several libraries exist, e.g.) +comment(// http://secondstring.sourceforge.net/) +comment(// http://sourceforge.net/projects/simmetrics/) +comment(// both support numerous algorithms. Using the second as an example:) +keyword(import) include(uk.ac.shef.wit.simmetrics.similaritymetrics.*) +ident(target) operator(=) string +ident(candidates) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(findAll)operator({)local_variable(it)operator(.)ident(trim)operator(()(\)}) +ident(metrics) operator(=) operator([)keyword(new) ident(Levenshtein)operator(()(\))operator(,) keyword(new) ident(MongeElkan)operator(()(\))operator(,) keyword(new) ident(JaroWinkler)operator(()(\))operator(,) keyword(new) ident(Soundex)operator(()(\)]) +keyword(def) method(out)operator(()ident(name)operator(,) ident(results)(\)) operator({) + ident(print) ident(name)operator(.)ident(padLeft)operator(()integer(14)(\)) operator(+) stringoperator(;) ident(results)operator(.)ident(each)operator({)ident(print)operator(()local_variable(it)operator(.)ident(padRight)operator(()integer(16)(\)\)})operator(;) ident(println)operator(()(\)) +(}) +keyword(def) method(outr)operator(()ident(name)operator(,) ident(results)(\))operator({)ident(out)operator(()ident(name)operator(,) ident(results)operator(.)ident(collect)operator({)stringoperator(+)operator(()operator(()type(int)(\))operator(()local_variable(it)operator(*)integer(100)(\)\))operator(/)integer(100)(}\)}) +ident(out) operator(()stringoperator(,) ident(metrics)operator(.)ident(collect)operator({)local_variable(it)operator(.)ident(shortDescriptionString)(}) (\)) +ident(candidates)operator(.)ident(each)operator({) ident(w) operator(->) ident(outr)operator(()ident(w)operator(,) ident(metrics)operator(.)ident(collect)operator({) ident(m) operator(->) ident(m)operator(.)ident(getSimilarity)operator(()ident(target)operator(,) ident(w)(\)}) (\)}) +comment(// =>) +comment(// Word/Metric Levenshtein MongeElkan JaroWinkler Soundex) +comment(// quick 0 0.11 0 0.66) +comment(// brown 0.16 0.23 0.5 0.73) +comment(// fox 0 0.2 0 0.66) +comment(// jumped 0 0.2 0 0.66) +comment(// over 0 0.44 0 0.55) +comment(// the 0 0.33 0 0.55) +comment(// lazy 0.33 0.5 0.44 0.66) +comment(// dog 0 0.2 0 0.66) +comment(// ballast 0.85 0.83 0.96 1) +comment(// ballasts 0.75 0.83 0.94 0.94) +comment(// balustrade 0.5 0.93 0.3 0.94) +comment(// balustrades 0.45 0.93 0.3 0.94) +comment(// blast 0.83 0.8 0.88 1) +comment(// blasted 0.57 0.66 0.8 0.94) +comment(// blaster 0.57 0.66 0.8 0.94) +comment(// blasters 0.5 0.66 0.77 0.94) +comment(// blasting 0.5 0.66 0.77 0.94) +comment(// blasts 0.66 0.66 0.84 0.94) +comment(// to implement the example, iterate through /usr/dict/words selecting words) +comment(// where one or a combination of metrics are greater than some threshold) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.14) +comment(//----------------------------------------------------------------------------------) +ident(n) operator(=) string +ident(println) ident(n)operator(.)ident(replaceAll)operator(()regexpoperator(,)string(\)) +comment(// => 00049 here) + +ident(str) operator(=) string +ident(print) string +ident(str)operator(.)ident(eachMatch)operator(()regexp(\))operator({) ident(print) string operator(+) local_variable(it)operator([)integer(1)(]) (}) +ident(println)operator(()(\)) +comment(// => Found numbers: 3 4 5 9 120) + +comment(// Groovy doesn't have the String.pos or a /c re modifier like Perl) +comment(// But it does have similar functionality. Matcher has start(\) and) +comment(// end(\) for find the position and Matcher's usePattern(\) allows) +comment(// you to swap patterns without changing the buffer position) +ident(text) operator(=) string +ident(p) operator(=) operator(~)regexp +ident(m) operator(=) ident(p)operator(.)ident(matcher)operator(()ident(text)(\)) +keyword(while) operator(()ident(m)operator(.)ident(find)operator(()(\)\)) operator({) + ident(println) string operator(+) ident(m)operator(.)ident(group)operator(()(\)) operator(+) string operator(+) ident(m)operator(.)ident(start)operator(()(\)) operator(+) + string operator(+) ident(m)operator(.)ident(end)operator(()(\)) +(}) +comment(// now reset pos back to between 1st and 2nd numbers) +keyword(if) operator(()ident(m)operator(.)ident(find)operator(()integer(16)(\)\)) operator({) ident(println) string operator(+) ident(m)operator(.)ident(group)operator(()(\)) (}) +comment(// =>) +comment(// Found 1752 starting at pos 9 and ending at pos 13) +comment(// Found 10 starting at pos 19 and ending at pos 21) +comment(// Found 3 starting at pos 34 and ending at pos 35) +comment(// Found 10) + +comment(// Alternatively you can use Scanner in Java 5-7+:) +ident(p1) operator(=) operator(~)regexp +ident(p2) operator(=) operator(~)regexp +ident(s) operator(=) keyword(new) pre_type(Scanner)operator(()ident(text)(\)) +keyword(while) operator(()operator(()ident(f) operator(=) ident(s)operator(.)ident(findInLine)operator(()ident(p1)(\)\)\)) operator({) ident(println) string operator(+) ident(f) (}) +keyword(if) operator(()operator(()ident(f) operator(=) ident(s)operator(.)ident(findInLine)operator(()ident(p2)(\)\)\)) operator({) ident(println) stringcontent( after the last number.)delimiter(")> (}) +comment(// =>) +comment(// Found: 1752) +comment(// Found: 10) +comment(// Found: 3) +comment(// Found rd after the last number.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.15) +comment(//----------------------------------------------------------------------------------) +ident(html) operator(=) stringthis and that are important Oh, me too!)delimiter(')> + +ident(greedyHtmlStripPattern) operator(=) operator(~)regexp)delimiter(/)> comment(// not good) +ident(nonGreedyHtmlStripPattern) operator(=) operator(~)regexp)delimiter(/)> comment(// not great) +ident(simpleNested) operator(=) operator(~)regexp(.*?\)<)content(\\/)content(i><)content(\\/)content(b>)delimiter(/)> +comment(// match BEGIN, then not BEGIN, then END) +ident(generalPattern) operator(=) operator(~)regexp +ident(betterButInefficient1) operator(=) operator(~)regexp( (?: (?!<)content(\\/)content(b>|<)content(\\/)content(i>\). \)* \) <)content(\\/)content(i><)content(\\/)content(b>)delimiter(/)> +ident(betterButInefficient2) operator(=) operator(~)regexp( (?: (?!<)content(\\/)content([ib]>\). \)* \) <)content(\\/)content(i><)content(\\/)content(b>)delimiter(/)> + +ident(efficientPattern) operator(=) string + [^<]* # stuff not possibly bad, and not possibly the end. + (?: + # at this point, we can have '<' if not part of something bad + (?! \) # what we can't have + < # okay, so match the '<' + [^<]* # and continue with more safe stuff + \) * + +)delimiter(''')> comment(//') +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.16) +comment(//----------------------------------------------------------------------------------) +ident(input) operator(=) string +ident(dupWordPattern) operator(=) string +ident(finder) operator(=) ident(input) operator(=~) ident(dupWordPattern) +ident(println) string operator(+) ident(finder)operator([)integer(0)(])operator([)integer(1)(]) +comment(// => Found duplicate word: test) + +ident(astr) operator(=) string +ident(bstr) operator(=) string +ident(m) operator(=) stringcontent( )inlinedelimiter(")> operator(=~) regexp +ident(actual) operator(=) stringcontent( overlaps in )inlinecontent(-)inlinecontent(-)inlinedelimiter(")> +keyword(assert) ident(actual) operator(==) string + +ident(cap) operator(=) string operator(*) integer(180) +keyword(while) operator(()ident(m) operator(=) operator(()ident(cap) operator(=~) regexp(\)\)) operator({) + ident(p1) operator(=) ident(m)operator([)integer(0)(])operator([)integer(1)(]) + ident(print) ident(p1)operator(.)ident(size)operator(()(\)) operator(+) string + ident(cap) operator(=) ident(cap)operator(.)ident(replaceAll)operator(()ident(p1)operator(,)string(\)) +(}) +ident(println) ident(cap)operator(.)ident(size)operator(()(\)) +comment(// => 2 2 3 3 5) + +comment(// diophantine) +comment(// solve for 12x + 15y + 16z = 281, maximizing x) +keyword(if) operator(()operator(()ident(m) operator(=) operator(()string operator(*) integer(281)(\)) operator(=~) regexp(\)\)) operator({) + ident(x)operator(=)ident(m)operator([)integer(0)(])operator([)integer(1)(])operator(.)ident(size)operator(()(\))operator(;) ident(y)operator(=)ident(m)operator([)integer(0)(])operator([)integer(2)(])operator(.)ident(size)operator(()(\))operator(;) ident(z)operator(=)ident(m)operator([)integer(0)(])operator([)integer(3)(])operator(.)ident(size)operator(()(\)) + ident(println) stringcontent(; y=)inlinecontent(; z=)inlinedelimiter(")> +(}) keyword(else) ident(println) string +comment(// => One solution is: x=17; y=3; z=2) + +comment(// using different quantifiers:) +comment(// /^(o+\)\\1{11}(o+\)\\2{14}(o+\)\\3{15}$/) +comment(// => One solution is: x=17; y=3; z=2) + +comment(// /^(o*?\)\\1{11}(o*\)\\2{14}(o*\)\\3{15}$/) +comment(// => One solution is: x=0; y=7; z=11) + +comment(// /^(o+?\)\\1{11}(o*\)\\2{14}(o*\)\\3{15}$/) +comment(// => One solution is: x=1; y=3; z=14) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.17) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy doesn't currently support x!~y so you must use the !(x=~y\) style) + +comment(// alpha OR beta) +keyword(assert) string operator(==~) regexp +keyword(assert) string operator(==~) regexp +keyword(assert) string operator(=~) regexp operator(||) string operator(=~) regexp + +comment(// alpha AND beta) +keyword(assert) operator(!)operator(()string operator(=~) regexp(\)) +keyword(assert) string operator(=~) regexp +keyword(assert) string operator(=~) regexp +keyword(assert) string operator(=~) regexp operator(&&) string operator(=~) regexp + +comment(// alpha AND beta, no overlap) +keyword(assert) string operator(=~) regexp +keyword(assert) operator(!)operator(()string operator(=~) regexp(\)) + +comment(// NOT beta) +keyword(assert) string operator(=~) regexp +keyword(assert) operator(!)operator(()string operator(=~) regexp(\)) + +comment(// NOT bad BUT good) +keyword(assert) operator(!)operator(()string operator(=~) regexp(\)) +keyword(assert) operator(!)operator(()string operator(=~) regexp(\)) +keyword(assert) operator(!)operator(()string operator(=~) regexp(\)) +keyword(assert) string operator(=~) regexp + +comment(// minigrep could be done as a one-liner as follows) +comment(// groovy -p -e "if (line =~ /pat/\) return line" datafile) + +ident(string) operator(=) string +keyword(assert) ident(string) operator(=~) regexp +keyword(assert) ident(string) operator(=~) regexp operator(&&) ident(string) operator(=~) string +ident(fakeAddress) operator(=) string +ident(murrayHillRegex) operator(=) string +keyword(assert) ident(string) operator(=~) ident(murrayHillRegex) +keyword(assert) operator(!)operator(()ident(fakeAddress) operator(=~) ident(murrayHillRegex)(\)) + +comment(// eliminate overlapping) +keyword(assert) operator(!)operator(()ident(string) operator(=~) regexp(\)) + +ident(brandRegex) operator(=) string +keyword(assert) operator(!)operator(()ident(string) operator(=~) ident(brandRegex)(\)) + +ident(map) operator(=) string + +keyword(assert) ident(map) operator(=~) regexp +ident(noWaldoRegex) operator(=) string +keyword(assert) ident(map) operator(=~) ident(noWaldoRegex) + +comment(// on unix systems use: realFakedInput = 'w'.process(\).text) +ident(fakedInput) operator(=) stringoperator(.)ident(trim)operator(()(\)) operator(+) string + +keyword(def) method(miniGrepMethod)operator(()ident(input)(\)) operator({) + ident(input)operator(.)ident(split)operator(()string(\))operator(.)ident(findAll)operator({)local_variable(it) operator(=~) string(}) +(}) +keyword(assert) ident(miniGrepMethod)operator(()ident(fakedInput)(\))operator(.)ident(size)operator(()(\)) operator(==) integer(2) + +ident(findUserRegex) operator(=) string +keyword(assert) operator(()ident(fakedInput) operator(=~) ident(findUserRegex)(\))operator(.)ident(count) operator(==) integer(2) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.18) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy uses Unicode character encoding) +comment(// special care needs to be taken when using unicode because of the different) +comment(// byte lengths, e.g. à can be encoded as two bytes \\u0061\\u0300 and is also) +comment(// supported in legacy character sets by a single character \\u00E0. To Match) +comment(// this character, you can't use any of /./, /../, /a/, /\\u00E0/, /\\u0061/\\u0300) +comment(// or /\\pL/. The correct way is to use /X (not currently supported\) or one) +comment(// of /\\pL/\\pM*/ to ensure that it is a letter or /\\PM\\pM*/ when you just want) +comment(// to combine multicharacter sequences and don't care whether it is a letter) +keyword(def) method(checkUnicode)operator(()ident(s)(\)) operator({) + ident(println) ident(s) operator(+) string operator(+) ident(s)operator(.)ident(size)operator(()(\)) + ident(println) string operator(+) operator(()ident(s) operator(==~) regexp(\)) + ident(println) string operator(+) operator(()ident(s) operator(==~) regexp(\)) + ident(println) string operator(+) operator(()ident(s) operator(==~) regexp(\)) + ident(println) string operator(+) operator(()ident(s) operator(==~) regexp(\)) + ident(println) string operator(+) operator(()ident(s) operator(==~) regexp(\)) + ident(println) string operator(+) operator(()ident(s) operator(==~) regexp(\)) + ident(println) string operator(+) operator(()ident(s) operator(==~) regexp(\)) + ident(println) string operator(+) operator(()ident(s) operator(==~) regexp(\)) +(}) +ident(checkUnicode)operator(()string(\)) +ident(checkUnicode)operator(()string(\)) +ident(checkUnicode)operator(()string(\)) +comment(// =>) +comment(// à is of size 1) +comment(// Exactly matches /./ true) +comment(// Exactly matches /../ false) +comment(// Exactly matches /a/ false) +comment(// Exactly matches /\\u00E0/ true) +comment(// Exactly matches /\\u0061\\u0300/ false) +comment(// Exactly matches /\\pL/ true) +comment(// Exactly matches /\\pL\\pM*/ true) +comment(// Exactly matches /\\PM\\pM*/ true) +comment(// a? is of size 2) +comment(// Exactly matches /./ false) +comment(// Exactly matches /../ true) +comment(// Exactly matches /a/ false) +comment(// Exactly matches /\\u00E0/ false) +comment(// Exactly matches /\\u0061\\u0300/ true) +comment(// Exactly matches /\\pL/ false) +comment(// Exactly matches /\\pL\\pM*/ true) +comment(// Exactly matches /\\PM\\pM*/ true) +comment(// à is of size 1) +comment(// Exactly matches /./ true) +comment(// Exactly matches /../ false) +comment(// Exactly matches /a/ false) +comment(// Exactly matches /\\u00E0/ true) +comment(// Exactly matches /\\u0061\\u0300/ false) +comment(// Exactly matches /\\pL/ true) +comment(// Exactly matches /\\pL\\pM*/ true) +comment(// Exactly matches /\\PM\\pM*/ true) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.19) +comment(//----------------------------------------------------------------------------------) +comment(// The Perl Cookbook categorizes this as a hard problem ... mostly for) +comment(// reasons not related to the actual regex - but with a 60-line regex) +comment(// perhaps there are some issues with that too. Further details:) +comment(// http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/ckaddr.gz) + +ident(simpleCommentStripper) operator(=) regexp +ident(println) string (We will spam you\))delimiter(')>operator(.)ident(replaceAll)operator(()ident(simpleCommentStripper)operator(,) string(\)) +comment(// => Book Publishing ) + +comment(// inspired by the fact that domain names can contain any foreign character these days) +ident(modern) operator(=) regexp?)content($)delimiter(/)> + +comment(// .Net ) +ident(lenient) operator(=) regexp + +comment(// a little more checking) +ident(strict) operator(=) regexp operator(+) + regexp?)content($)delimiter(/)> + +ident(addresses) operator(=) operator([)stringoperator(,) + string)delimiter(')>(]) +ident(addresses)operator(.)ident(each)operator({) + keyword(assert) local_variable(it) operator(=~) ident(lenient) + keyword(assert) local_variable(it) operator(=~) ident(strict) + keyword(assert) local_variable(it) operator(=~) ident(modern) +(}) + +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.20) +comment(//----------------------------------------------------------------------------------) +keyword(def) method(findAction)operator(()ident(ans)(\)) operator({) + keyword(def) ident(re) operator(=) string operator(+) pre_type(Pattern)operator(.)ident(quote)operator(()ident(ans)(\)) + keyword(if) operator(()string operator(=~) ident(re)(\)) ident(println) string + keyword(else) keyword(if) operator(()string operator(=~) ident(re)(\)) ident(println) string + keyword(else) keyword(if) operator(()string operator(=~) ident(re)(\)) ident(println) string + keyword(else) keyword(if) operator(()string operator(=~) ident(re)(\)) ident(println) string + keyword(else) ident(println) string +(}) +ident(findAction)operator(()string(\)) +comment(// => No Match) +ident(findAction)operator(()string(\)) +comment(// => Action is edit) +ident(findAction)operator(()string(\)) +comment(// => Action is send) +ident(findAction)operator(()string(\)) +comment(// => Action is edit) + +keyword(def) method(buildAbbrev)operator(()ident(words)(\)) operator({) + keyword(def) ident(table) operator(=) keyword(new) pre_type(TreeMap)operator(()(\)) + ident(words)operator(.)ident(each)operator({) ident(w) operator(->) + operator(()integer(0)operator(..<)ident(w)operator(.)ident(size)operator(()(\)\))operator(.)ident(each) operator({) ident(n) operator(->) + keyword(if) operator(()operator(!)operator(()ident(words) operator(-) ident(w)(\))operator(.)ident(any)operator({) + local_variable(it)operator(.)ident(size)operator(()(\)) operator(>=) ident(n)operator(+)integer(1) operator(&&) local_variable(it)operator([)integer(0)operator(..)ident(n)(]) operator(==) ident(w)operator([)integer(0)operator(..)ident(n)(]) + (}\)) ident(table)operator([)ident(w)operator([)integer(0)operator(..)ident(n)(]]) operator(=) ident(w) + (}) + (}) + ident(table) +(}) +ident(println) ident(buildAbbrev)operator(()stringoperator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\)\)) +comment(// => ["a":"abort", "ab":"abort", "abo":"abort", "abor":"abort", "abort":"abort",) +comment(// "e":"edit", "ed":"edit", "edi":"edit", "edit":"edit", "se":"send", "sen":"send",) +comment(// "send":"send", "st":"stop", "sto":"stop", "stop":"stop"]) + +comment(// miniShellScript:) +comment(// dummy methods) +keyword(def) method(invokeEditor)operator(()(\)) operator({) ident(println) string (}) +keyword(def) method(deliverMessage)operator(()(\)) operator({) ident(println) string operator(+) keyword(new) pre_type(Date)operator(()(\)) (}) +ident(actions) operator(=) operator([) + key(edit)operator(:) local_variable(this)operator(.)operator(&)ident(invokeEditor)operator(,) + key(send)operator(:) local_variable(this)operator(.)operator(&)ident(deliverMessage)operator(,) + key(list)operator(:) operator({) ident(println) pre_type(Runtime)operator(.)ident(runtime)operator(.)ident(freeMemory)operator(()(\)) (})operator(,) + key(abort)operator(:) operator({) pre_type(System)operator(.)ident(exit)operator(()integer(0)(\)) (})operator(,) + key(unknown)operator(:) operator({) ident(println) string(}) +(]) + +ident(table) operator(=) ident(buildAbbrev)operator(()ident(actions)operator(.)ident(keySet)operator(()(\))operator(.)ident(toList)operator(()(\)\)) +ident(prompt) operator(=) string )delimiter(')> +ident(print) string operator(+) ident(prompt) +keyword(new) pre_type(BufferedReader)operator(()keyword(new) pre_type(InputStreamReader)operator(()pre_type(System)operator(.)ident(in)(\)\))operator(.)ident(eachLine)operator({) ident(line) operator(->) + keyword(def) ident(idx) operator(=) operator(()ident(table)operator(.)ident(containsKey)operator(()ident(line)(\)\)) operator(?) ident(table)operator([)ident(line)(]) operator(:) string + ident(actions)operator([)ident(idx)(])operator(()(\)) + ident(print) ident(prompt) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.21) +comment(//----------------------------------------------------------------------------------) +comment(//% gunzip -c ~/mail/archive.gz | urlify > archive.urlified) +comment(//% urlify ~/mail/*.inbox > ~/allmail.urlified) + +ident(urls) operator(=) string +ident(ltrs) operator(=) regexp +ident(gunk) operator(=) regexp +ident(punc) operator(=) regexp +ident(doll) operator(=) regexp +ident(all) operator(=) regexpinlineinlinedelimiter(/)> + +ident(findUrls) operator(=) stringcontent( : # need resource and a colon + [)inlinecontent(] +? # followed by on or more of any valid + # character, but be conservative and + # take only what you need to... + \) # end group 1 } + (?= # look-ahead non-consumptive assertion + [)inlinecontent(]* # either 0 or more punctuation + [^)inlinecontent(] # followed by a non-url character + | # or else + )inlinecontent( # then end of the string + \) +)delimiter(""")> + +ident(input) operator(=) string + +ident(println) ident(input)operator(.)ident(replaceAll)operator(()ident(findUrls)operator(,)string)content($)content(1)delimiter(')>(\)) +comment(// =>) +comment(// If you find a typo on http://groovy.codehaus.org please) +comment(// send an email to mail:spelling.pedant@codehaus.org) + +comment(// urlifyScript:) +doctype(#!/usr/bin/groovy) +comment(// urlify - wrap HTML links around URL-like constructs) +comment(// definitions from above) +ident(args)operator(.)ident(each)operator({) ident(file) operator(->) + keyword(new) pre_type(File)operator(()ident(file)(\))operator(.)ident(eachLine)operator({) ident(line) operator(->) + ident(println) ident(line)operator(.)ident(replaceAll)operator(()ident(findUrls)operator(,)string)content($)content(1)delimiter(')>(\)) + (}) +(}) + +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.22) +comment(//----------------------------------------------------------------------------------) +comment(// @@INCOMPLETE@@) +comment(// @@INCOMPLETE@@) + +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_6.23) +comment(//----------------------------------------------------------------------------------) +ident(romans) operator(=) regexp +keyword(assert) string operator(=~) ident(romans) +comment(// can't have tens before 1000s (M\) or 100s (C\) after 5s (V\)) +keyword(assert) operator(!)operator(()string operator(=~) ident(romans)(\)) + +comment(// swap first two words) +keyword(assert) stringoperator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) operator(==) string + +comment(// extract keyword and value) +ident(m) operator(=) string operator(=~) regexp +keyword(assert) ident(m)operator(.)ident(matches)operator(()(\)) +keyword(assert) ident(m)operator([)integer(0)(])operator([)integer(1)(]) operator(==) string +keyword(assert) ident(m)operator([)integer(0)(])operator([)integer(2)(]) operator(==) string + +ident(hasAtLeastSize) operator(=) operator({) ident(n) operator(->) regexpcontent(,})delimiter(/)> (}) +keyword(assert) string operator(=~) ident(hasAtLeastSize)operator(()integer(20)(\)) + +comment(// MM/DD/YY HH:MM:SS (lenient - doesn't check HH > 23 etc\)) +ident(d) operator(=) regexp +ident(datetime) operator(=) stringcontent(\)/()inlinecontent(\)/()inlinecontent(\) ()inlinecontent(\):()inlinecontent(\):()inlinecontent(\))delimiter(")> +keyword(assert) string operator(=~) ident(datetime) + +ident(orig) operator(=) string +ident(expected) operator(=) string +ident(orig)operator(.)ident(replaceAll)operator(()stringoperator(,)string(\)) operator(==) ident(expected) + +ident(escapeSequenceRegex) operator(=) regexp +ident(convertEscapeToChar) operator(=) operator({) pre_type(Object)type([]) ident(ch) operator(->) keyword(new) pre_type(Character)operator(()operator(()type(char)(\))pre_type(Integer)operator(.)ident(parseInt)operator(()ident(ch)operator([)integer(1)(])operator(,)integer(16)(\)\)) (}) +keyword(assert) stringoperator(.)ident(replaceAll)operator(()ident(escapeSequenceRegex)operator(,) ident(convertEscapeToChar)(\)) operator(==) string + +ident(commentStripper) operator(=) string + +ident(input) operator(=) string +ident(expected) operator(=) string + +keyword(assert) ident(input)operator(.)ident(replaceAll)operator(()ident(commentStripper)operator(,)string(\)) operator(==) ident(expected) + +comment(// emulate s.trim(\)) +keyword(assert) stringoperator(.)ident(replaceAll)operator(()regexpoperator(,) string(\))operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) operator(==) string + +comment(// convert \\\\n into \\n) +keyword(assert) operator(()regexpoperator(.)ident(replaceAll)operator(()regexpoperator(,)string(\)) operator(==) string(\)) + +comment(// remove package symbol (Groovy/Java doesn't use this as package symbol\)) +keyword(assert) stringoperator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) operator(==) string + +comment(// match IP Address (requires leading 0's\)) +ident(ipregex) operator(=) regexp operator(+) + regexp +keyword(assert) operator(!)operator(()string operator(=~) ident(ipregex)(\)) +keyword(assert) string operator(=~) ident(ipregex) + +comment(// extract basename) +keyword(assert) stringoperator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) operator(==) string + +ident(termcap) operator(=) string +ident(m) operator(=) operator(()ident(termcap) operator(=~) regexp(\)) +keyword(assert) ident(m)operator(.)ident(count) operator(==) integer(1) +keyword(assert) ident(m)operator([)integer(0)(])operator([)integer(1)(]) operator(==) string + +keyword(assert) stringoperator(.)ident(replaceAll)operator(()operator(/) error(\\)ident(S)operator(+)error(\\)regexpoperator(,) string(\)) operator(==) string + +ident(os) operator(=) pre_type(System)operator(.)ident(getProperty)operator(()string(\)) +ident(println) string operator(+) operator(()ident(os) operator(==~) regexp(\)) +ident(println) string operator(+) operator(()ident(os) operator(==~) regexp(\)) +ident(println) string operator(+) operator(()ident(os) operator(==~) regexp(\)) + +comment(// join multiline sting) +ident(multi) operator(=) stringoperator(.)ident(trim)operator(()(\)) +keyword(assert) ident(multi)operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) operator(==) string + +comment(// nums in string) +ident(string) operator(=) string +ident(nums) operator(=) ident(string) operator(=~) regexp +keyword(assert) operator(()integer(0)operator(..<)ident(nums)operator(.)ident(count)(\))operator(.)ident(collect)operator({) ident(nums)operator([)local_variable(it)(])operator([)integer(1)(]) (})operator(.)ident(join)operator(()string(\)) operator(==) string + +comment(// capitalize words) +ident(words) operator(=) string +ident(capwords) operator(=) ident(words) operator(=~) regexp +keyword(assert) operator(()integer(0)operator(..<)ident(capwords)operator(.)ident(count)(\))operator(.)ident(collect)operator({) ident(capwords)operator([)local_variable(it)(])operator([)integer(1)(]) (})operator(.)ident(join)operator(()string(\)) operator(==) string + +ident(lowords) operator(=) ident(words) operator(=~) regexp +keyword(assert) operator(()integer(0)operator(..<)ident(lowords)operator(.)ident(count)(\))operator(.)ident(collect)operator({) ident(lowords)operator([)local_variable(it)(])operator([)integer(1)(]) (})operator(.)ident(join)operator(()string(\)) operator(==) string + +ident(capWords) operator(=) ident(words) operator(=~) regexp +keyword(assert) operator(()integer(0)operator(..<)ident(capWords)operator(.)ident(count)(\))operator(.)ident(collect)operator({) ident(capWords)operator([)local_variable(it)(])operator([)integer(1)(]) (})operator(.)ident(join)operator(()string(\)) operator(==) string + +ident(input) operator(=) stringhttp://groovy.codehaus.org please +send an email to mail:spelling.pedant@codehaus.org +)delimiter(''')> + +ident(linkRegex) operator(=) regexp]+?HREF)char(\\s)content(*=)char(\\s)content(*["']?([^'" >]+?\)[ '"]?>)delimiter(/)> comment(//') +ident(links) operator(=) ident(input) operator(=~) ident(linkRegex) +operator(()integer(0)operator(..<)ident(links)operator(.)ident(count)(\))operator(.)ident(each)operator({) ident(println) ident(links)operator([)local_variable(it)(])operator([)integer(1)(]) (}) +comment(// =>) +comment(// http://groovy.codehaus.org) +comment(// mail:spelling.pedant@codehaus.org) + +comment(// find middle initial if any) +ident(m) operator(=) string operator(=~) regexp +ident(initial) operator(=) ident(m)operator(.)ident(count) operator(?) ident(m)operator([)integer(0)(])operator([)integer(1)(]) operator(:) string +keyword(assert) ident(initial) operator(==) string + +comment(// inch marks to quotes) +ident(println) stringoperator(.)ident(replaceAll)operator(()regexpoperator(,) regexp(\)) comment(//") +comment(// => I said ``Hello'' to you.) + +comment(// extract sentences (2 spaces or newline after punctuation\)) +ident(input) operator(=) string +ident(sentences) operator(=) type([]) +ident(strip) operator(=) ident(input)operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\))operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\))operator(.)ident(replaceAll)operator(()operator(/) operator({)integer(3)operator(,)(})operator(/)operator(,)string(\)) +ident(m) operator(=) ident(strip) operator(=~) regexp +operator(()integer(0)operator(..<)ident(m)operator(.)ident(count)(\))operator(.)ident(each)operator({) ident(sentences) operator(+=) ident(m)operator([)local_variable(it)(])operator([)integer(1)(]) (}) +keyword(assert) ident(sentences) operator(==) operator([)stringoperator(,) stringoperator(,) stringoperator(,) string(]) + +comment(// YYYY-MM-DD) +ident(m) operator(=) string operator(=~) regexp +keyword(assert) ident(m)operator(.)ident(matches)operator(()(\)) +keyword(assert) operator([)stringoperator(,) stringoperator(,) string(]) operator(==) operator([)ident(m)operator([)integer(0)(])operator([)integer(1)(])operator(,) ident(m)operator([)integer(0)(])operator([)integer(2)(])operator(,) ident(m)operator([)integer(0)(])operator([)integer(3)(]]) + +ident(usPhoneRegex) operator(=) regexp +ident(numbers) operator(=) stringoperator(.)ident(trim)operator(()(\))operator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\)) +keyword(assert) ident(numbers)operator(.)ident(every)operator({) local_variable(it) operator(==~) ident(usPhoneRegex) (}) + +ident(exclaimRegex) operator(=) regexp +keyword(assert) string operator(=~) ident(exclaimRegex) +keyword(assert) operator(!)operator(()string operator(=~) ident(exclaimRegex)(\)) + +ident(input) operator(=) string +ident(m) operator(=) ident(input) operator(=~) regexp +keyword(assert) ident(m)operator(.)ident(count) operator(==) integer(4) + + +comment(// @@PLEAC@@_6.22) +comment(// not an exact equivalent to original cookbook but has) +comment(// a reasonable subset of mostly similar functionality) +comment(// instead of -r recursion option, use Ant fileset wildcards) +comment(// e.g. **/*.c. You can also specify an excludes pattern) +comment(// e.g. **/*.* -X **/*.h will process all but header files) +comment(// (currently not optimised and with minimal error checking\)) +comment(// uses jopt-simple (jopt-simple.sf.net\)) + +ident(op) operator(=) keyword(new) ident(joptsimple)operator(.)ident(OptionParser)operator(()(\)) +ident(NOCASE) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(NOCASE)operator(,) string (\)) +ident(WITHN) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(WITHN)operator(,) string (\)) +ident(WITHF) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(WITHF)operator(,) string (\)) +ident(NONAME) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(NONAME)operator(,) string (\)) +ident(COUNT) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(COUNT)operator(,) string (\)) +ident(TCOUNT) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(TCOUNT)operator(,) string (\)) +ident(WORD) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(WORD)operator(,) string (\)) +ident(EXACT) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(EXACT)operator(,) string (\)) +ident(INVERT) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(INVERT)operator(,) string (\)) +ident(EXCLUDE) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(EXCLUDE)operator(,) string (\))operator(.) + ident(withRequiredArg)operator(()(\))operator(.)ident(describedAs)operator(()string(\)) +ident(MATCH) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(MATCH)operator(,) string (\)) +ident(NOMATCH) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(NOMATCH)operator(,) string (\)) +ident(PARA) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(PARA)operator(,) string (\))operator(.) + ident(withOptionalArg)operator(()(\))operator(.)ident(describedAs)operator(()string(\)) +ident(EXPR) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(EXPR)operator(,) string (\))operator(.) + ident(withRequiredArg)operator(()(\))operator(.)ident(describedAs)operator(()string(\)) +ident(FILE) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(FILE)operator(,) string (\))operator(.) + ident(withRequiredArg)operator(()(\))operator(.)ident(describedAs)operator(()string(\)) +ident(HELP) operator(=) stringoperator(;) ident(op)operator(.)ident(accepts)operator(() ident(HELP)operator(,) string (\)) + +ident(options) operator(=) ident(op)operator(.)ident(parse)operator(()ident(args)(\)) +ident(params) operator(=) ident(options)operator(.)ident(nonOptionArguments)operator(()(\)) +keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(HELP) (\)\)) operator({) + ident(op)operator(.)ident(printHelpOn)operator(() pre_type(System)operator(.)ident(out) (\)) +(}) keyword(else) keyword(if) operator(()ident(params)operator(.)ident(size)operator(()(\)) operator(==) integer(0)(\)) operator({) + ident(println) stringcontent(' for more information.)delimiter(")> +(}) keyword(else) operator({) + ident(modifiers) operator(=) type([]) + ident(paraPattern) operator(=) string + ident(o_withn) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(WITHN) (\)) + ident(o_withf) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(WITHF) (\)) + ident(o_noname) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(NONAME) (\)) + ident(o_count) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(COUNT) (\)) + ident(o_tcount) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(TCOUNT) (\)) + ident(o_invert) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(INVERT) (\)) + ident(o_match) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(MATCH) (\)) + ident(o_nomatch) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(NOMATCH) (\)) + keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(EXPR) (\)\)) operator({) + ident(pattern) operator(=) ident(options)operator(.)ident(valueOf)operator(() ident(EXPR) (\)) + (}) keyword(else) keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(FILE) (\)\)) operator({) + ident(pattern) operator(=) keyword(new) pre_type(File)operator(()ident(options)operator(.)ident(valueOf)operator(() ident(FILE) (\)\))operator(.)ident(text)operator(.)ident(trim)operator(()(\)) + (}) keyword(else) operator({) + ident(pattern) operator(=) ident(params)operator([)integer(0)(]) + ident(params) operator(=) ident(params)operator([)integer(1)operator(..)operator(-)integer(1)(]) + (}) + keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(EXCLUDE) (\)\)) ident(excludes) operator(=) ident(options)operator(.)ident(valueOf)operator(() ident(EXCLUDE) (\)) + keyword(else) ident(excludes) operator(=) operator([)string(]) + keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(EXACT) (\)\)) ident(pattern) operator(=) string operator(+) ident(pattern) operator(+) string + keyword(else) keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(WORD) (\)\)) ident(pattern) operator(=) regexpchar(\\b)delimiter(/)> + keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(NOCASE) (\)\)) ident(modifiers) operator(+=) string + keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(PARA) (\)\)) operator({) + keyword(if) operator(()ident(options)operator(.)ident(hasArgument)operator(() ident(PARA) (\)\)) ident(paraPattern) operator(=) ident(options)operator(.)ident(valueOf)operator(() ident(PARA) (\)) + keyword(else) ident(paraPattern) operator(=) string + ident(paraPattern) operator(=) string operator(+) ident(paraPattern) + ident(modifiers) operator(+=) string + (}) + keyword(if) operator(()ident(modifiers)(\)) ident(pattern) operator(=) stringcontent(\))delimiter(")> operator(+) ident(pattern) + + keyword(if) operator(()ident(params)operator(.)ident(size)operator(()(\)) operator(==) integer(0)(\)) ident(grepStream)operator(()pre_type(System)operator(.)ident(in)operator(,) string)delimiter(')>(\)) + keyword(else) operator({) + ident(scanner) operator(=) keyword(new) ident(AntBuilder)operator(()(\))operator(.)ident(fileScanner) operator({) + ident(fileset)operator(()key(dir)operator(:)stringoperator(,) key(includes)operator(:)ident(params)operator(.)ident(join)operator(()string(\))operator(,) key(excludes)operator(:)ident(excludes)(\)) + (}) + keyword(for) operator(()ident(f) keyword(in) ident(scanner)(\)) operator({) + ident(grepStream)operator(()keyword(new) pre_type(FileInputStream)operator(()ident(f)(\))operator(,) ident(f)(\)) + (}) + (}) +(}) + +keyword(def) method(grepStream)operator(()ident(s)operator(,) ident(name)(\)) operator({) + keyword(def) ident(count) operator(=) integer(0) + keyword(def) ident(tcount) operator(=) integer(0) + keyword(def) ident(pieces) + keyword(if) operator(()ident(paraPattern)(\)) ident(pieces) operator(=) ident(s)operator(.)ident(text)operator(.)ident(split)operator(()ident(paraPattern)(\)) + keyword(else) ident(pieces) operator(=) ident(s)operator(.)ident(readLines)operator(()(\)) + keyword(def) ident(fileMode) operator(=) ident(o_match) operator(||) ident(o_nomatch) operator(||) ident(o_count) operator(||) ident(o_tcount) + ident(pieces)operator(.)ident(eachWithIndex)operator({)ident(line)operator(,) ident(index) operator(->) + keyword(def) ident(m) operator(=) ident(line) operator(=~) ident(pattern) + type(boolean) ident(found) operator(=) ident(m)operator(.)ident(count) + keyword(if) operator(()ident(found) operator(!=) ident(o_invert)(\)) operator({) + ident(count)operator(++) + ident(tcount) operator(+=) ident(m)operator(.)ident(count) + keyword(if) operator(()operator(!)ident(fileMode)(\)) operator({) + ident(linefields) operator(=) type([]) + keyword(if) operator(()ident(o_withf)(\)) ident(linefields) operator(+=) ident(name) + keyword(if) operator(()ident(o_withn)(\)) ident(linefields) operator(+=) ident(index) operator(+) integer(1) + ident(linefields) operator(+=) ident(line) + ident(println) ident(linefields)operator(.)ident(join)operator(()string(\)) + (}) + (}) + (}) + keyword(def) ident(display) operator(=) keyword(true) + keyword(if) operator(()operator(()ident(o_match) operator(&&) ident(count) operator(==) integer(0)(\)) operator(||) operator(()ident(o_nomatch) operator(&&) ident(count) operator(!=) integer(0)(\)\)) ident(display) operator(=) keyword(false) + keyword(if) operator(()ident(fileMode) operator(&&) ident(display)(\)) operator({) + ident(filefields) operator(=) type([]) + keyword(if) operator(()operator(!)ident(o_noname)(\)) ident(filefields) operator(+=) ident(name) + keyword(if) operator(()ident(o_tcount)(\)) ident(filefields) operator(+=) ident(tcount) + keyword(else) keyword(if) operator(()ident(o_count)(\)) ident(filefields) operator(+=) ident(count) + ident(println) ident(filefields)operator(.)ident(join)operator(()string(\)) + (}) +(}) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.0) +comment(//----------------------------------------------------------------------------------) +comment(//testfile = new File('/usr/local/widgets/data'\) // unix) +ident(testfile) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// windows) +ident(testfile)operator(.)ident(eachLine)operator({) keyword(if) operator(()local_variable(it) operator(=~) regexp(\)) ident(println) local_variable(it) (}) + +comment(// Groovy (like Java\) uses the File class as an abstraction for) +comment(// the path representing a potential file system resource.) +comment(// Channels and Streams (along with Reader adn Writer helper) +comment(// classes\) are used to read and write to files (and other) +comment(// things\). Files, channels, streams etc are all "normal") +comment(// objects; they can be passed around in your programs just) +comment(// like other objects (though there are some restrictions) +comment(// covered elsewhere - e.g. you can't expect to pass a File) +comment(// object between JVMs on different machines running different) +comment(// operating systems and expect them to maintain a meaningful) +comment(// value across the different JVMs\). In addition to Streams,) +comment(// there is also support for random access to files.) + +comment(// Many operations are available on streams and channels. Some) +comment(// return values to indicate success or failure, some can throw) +comment(// exceptions, other times both styles of error reporting may be) +comment(// available.) + +comment(// Streams at the lowest level are just a sequence of bytes though) +comment(// there are various abstractions at higher levels to allow) +comment(// interacting with streams at encoded character, data type or) +comment(// object levels if desired. Standard streams include System.in,) +comment(// System.out and System.err. Java and Groovy on top of that) +comment(// provide facilities for buffering, filtering and processing) +comment(// streams in various ways.) + +comment(// File channels provide more powerful operations than streams) +comment(// for reading and writing files such as locks, buffering,) +comment(// positioning, concurrent reading and writing, mapping to memory) +comment(// etc. In the examples which follow, streams will be used for) +comment(// simple cases, channels when more advanced features are) +comment(// required. Groovy currently focusses on providing extra support) +comment(// at the file and stream level rather than channel level.) +comment(// This makes the simple things easy but lets you do more complex) +comment(// things by just using the appropriate Java classes. All Java) +comment(// classes are available within Groovy by default.) + +comment(// Groovy provides syntactic sugar over the top of Java's file) +comment(// processing capabilities by providing meaning to shorthand) +comment(// operators and by automatically handling scaffolding type) +comment(// code such as opening, closing and handling exceptions behind) +comment(// the scenes. It also provides many powerful closure operators,) +comment(// e.g. file.eachLineMatch(pattern\){ some_operation } will open) +comment(// the file, process it line-by-line, finding all lines which) +comment(// match the specified pattern and then invoke some operation) +comment(// for the matching line(s\) if any, before closing the file.) + + +comment(// this example shows how to access the standard input stream) +comment(// numericCheckingScript:) +ident(prompt) operator(=) string )delimiter(')> +ident(print) string operator(+) ident(prompt) +keyword(new) pre_type(BufferedReader)operator(()keyword(new) pre_type(InputStreamReader)operator(()pre_type(System)operator(.)ident(in)(\)\))operator(.)ident(eachLine)operator({) ident(line) operator(->) + comment(// line is read from System.in) + keyword(if) operator(()ident(line) operator(=~) string(\)) ident(println) stringdelimiter(")> comment(// normal output to System.out) + keyword(else) pre_type(System)operator(.)ident(err)operator(.)ident(println) string comment(// this message to System.err) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.1) +comment(//----------------------------------------------------------------------------------) +comment(// test values (change for your os and directories\)) +ident(inputPath)operator(=)stringoperator(;) ident(outPath)operator(=)string + +comment(// For input Java uses InputStreams (for byte-oriented processing\) or Readers) +comment(// (for character-oriented processing\). These can throw FileNotFoundException.) +comment(// There are also other stream variants: buffered, data, filters, objects, ...) +ident(inputFile) operator(=) keyword(new) pre_type(File)operator(()ident(inputPath)(\)) +ident(inputStream) operator(=) keyword(new) pre_type(FileInputStream)operator(()ident(inputFile)(\)) +ident(reader) operator(=) keyword(new) pre_type(FileReader)operator(()ident(inputFile)(\)) +ident(inputChannel) operator(=) ident(inputStream)operator(.)ident(channel) + +comment(// Examples for random access to a file) +ident(file) operator(=) keyword(new) pre_type(RandomAccessFile)operator(()ident(inputFile)operator(,) string(\)) comment(// for read and write) +ident(channel) operator(=) ident(file)operator(.)ident(channel) + +comment(// Groovy provides some sugar coating on top of Java) +ident(println) ident(inputFile)operator(.)ident(text)operator(.)ident(size)operator(()(\)) +comment(// => 13496) + +comment(// For output Java use OutputStreams or Writers. Can throw FileNotFound) +comment(// or IO exceptions. There are also other flavours of stream: buffered,) +comment(// data, filters, objects, ...) +ident(outFile) operator(=) keyword(new) pre_type(File)operator(()ident(outPath)(\)) +ident(appendFlag) operator(=) keyword(false) +ident(outStream) operator(=) keyword(new) pre_type(FileOutputStream)operator(()ident(outFile)operator(,) ident(appendFlag)(\)) +ident(writer) operator(=) keyword(new) pre_type(FileWriter)operator(()ident(outFile)operator(,) ident(appendFlag)(\)) +ident(outChannel) operator(=) ident(outStream)operator(.)ident(channel) + +comment(// Also some Groovy sugar coating) +ident(outFile) operator(<)operator(<) string +ident(println) ident(outFile)operator(.)ident(text)operator(.)ident(size)operator(()(\)) comment(// => 24) + +comment(// @@PLEAC@@_7.2) +comment(//----------------------------------------------------------------------------------) +comment(// No problem with Groovy since the filename doesn't contain characters with) +comment(// special meaning; like Perl's sysopen. Options are either additional parameters) +comment(// or captured in different classes, e.g. Input vs Output, Buffered vs non etc.) +keyword(new) pre_type(FileReader)operator(()ident(inputPath)(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.3) +comment(//----------------------------------------------------------------------------------) +comment(// '~' is a shell expansion feature rather than file system feature per se.) +comment(// Because '~' is a valid filename character in some operating systems, and Java) +comment(// attempts to be cross-platform, it doesn't automatically expand Tilde's.) +comment(// Given that '~' expansion is commonly used however, Java puts the $HOME) +comment(// environment variable (used by shells to do typical expansion\) into the) +comment(// "user.home" system property. This works across operating systems - though) +comment(// the value inside differs from system to system so you shouldn't rely on its) +comment(// content to be of a particular format. In most cases though you should be) +comment(// able to write a regex that will work as expected. Also, Apple's) +comment(// NSPathUtilities can expand and introduce Tildes on platforms it supports.) +ident(path) operator(=) string +ident(name) operator(=) pre_type(System)operator(.)ident(getProperty)operator(()string(\)) +ident(home) operator(=) pre_type(System)operator(.)ident(getProperty)operator(()string(\)) +ident(println) ident(home) operator(+) ident(path)operator(.)ident(replaceAll)operator(()stringcontent((.*\))delimiter(")>operator(,) string(\)) +comment(// => C:\\Documents and Settings\\Paul/.cvspass) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.4) +comment(//----------------------------------------------------------------------------------) +comment(// The exception raised in Groovy reports the filename) +keyword(try) operator({) + keyword(new) pre_type(File)operator(()string(\))operator(.)ident(text) +(}) keyword(catch) operator(()pre_type(Exception) ident(ex)(\)) operator({) + pre_type(System)operator(.)ident(err)operator(.)ident(println)operator(()ident(ex)operator(.)ident(message)(\)) +(}) +comment(// =>) +comment(// unknown_path\\bad_file.ext (The system cannot find the path specified\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.5) +comment(//----------------------------------------------------------------------------------) +keyword(try) operator({) + ident(temp) operator(=) pre_type(File)operator(.)ident(createTempFile)operator(()stringoperator(,) string(\)) + ident(temp)operator(.)ident(deleteOnExit)operator(()(\)) +(}) keyword(catch) operator(()pre_type(IOException) ident(ex)(\)) operator({) + pre_type(System)operator(.)ident(err)operator(.)ident(println)operator(()string(\)) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.6) +comment(//----------------------------------------------------------------------------------) +comment(// no special features are provided, here is a way to do it manually) +comment(// DO NOT REMOVE THE FOLLOWING STRING DEFINITION.) +ident(pleac_7_6_embeddedFileInfo) operator(=) string +ident(ls) operator(=) pre_type(System)operator(.)ident(getProperty)operator(()string(\)) +ident(file) operator(=) keyword(new) pre_type(File)operator(()string(\)) +ident(regex) operator(=) regexp +keyword(def) method(readEmbeddedInfo)operator(()(\)) operator({) + ident(m) operator(=) ident(file)operator(.)ident(text) operator(=~) ident(regex) + ident(println) string operator(+) ident(m)operator([)integer(0)(])operator([)integer(1)(]) +(}) +keyword(def) method(writeEmbeddedInfo)operator(()(\)) operator({) + ident(lastMod) operator(=) keyword(new) pre_type(Date)operator(()ident(file)operator(.)ident(lastModified)operator(()(\)\)) + ident(newInfo) operator(=) stringcontent(Script size is )inlineinlinecontent(Last script update: )inlineinlinedelimiter(")> + ident(file)operator(.)ident(write)operator(()ident(file)operator(.)ident(text)operator(.)ident(replaceAll)operator(()ident(regex)operator(,) ident(newInfo)(\)\)) +(}) +ident(readEmbeddedInfo)operator(()(\)) +comment(// writeEmbeddedInfo(\) // uncomment to make script update itself) +comment(// readEmbeddedInfo(\) // uncomment to redisplay the embedded info after the update) + +comment(// => (output when above two method call lines are uncommented\)) +comment(// Found:) +comment(//) +comment(// Script size is 13550) +comment(// Last script update: Wed Jan 10 18:56:03 EST 2007) +comment(//) +comment(// Found:) +comment(//) +comment(// Script size is 13731) +comment(// Last script update: Wed Jan 10 19:05:58 EST 2007) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.7) +comment(//----------------------------------------------------------------------------------) +comment(// general pattern for reading from System.in is:) +comment(// System.in.readLines(\).each{ processLine(it\) }) + +comment(// general pattern for a filter which can either process file args or read from System.in is:) +comment(// if (args.size(\) != 0\) args.each{) +comment(// file -> new File(file\).eachLine{ processLine(it\) }) +comment(// } else System.in.readLines(\).each{ processLine(it\) }) + +comment(// note: the following examples are file-related per se. They show) +comment(// how to do option processing in scenarios which typically also) +comment(// involve file arguments. The reader should also consider using a) +comment(// pre-packaged options parser package (there are several popular) +comment(// ones\) rather than the hard-coded processing examples shown here.) + +ident(chopFirst) operator(=) keyword(false) +ident(columns) operator(=) integer(0) +ident(args) operator(=) operator([)stringoperator(,) stringoperator(,) string(]) + +comment(// demo1: optional c) +keyword(if) operator(()ident(args)operator([)integer(0)(]) operator(==) string(\)) operator({) + ident(chopFirst) operator(=) keyword(true) + ident(args) operator(=) ident(args)operator([)integer(1)operator(..)operator(-)integer(1)(]) +(}) + +keyword(assert) ident(args) operator(==) operator([)stringoperator(,) string(]) +keyword(assert) ident(chopFirst) + +comment(// demo2: processing numerical options) +keyword(if) operator(()ident(args)operator([)integer(0)(]) operator(=~) regexp(\)) operator({) + ident(columns) operator(=) ident(args)operator([)integer(0)(])operator([)integer(1)operator(..)operator(-)integer(1)(])operator(.)ident(toInteger)operator(()(\)) + ident(args) operator(=) ident(args)operator([)integer(1)operator(..)operator(-)integer(1)(]) +(}) + +keyword(assert) ident(args) operator(==) operator([)string(]) +keyword(assert) ident(columns) operator(==) integer(30) + +comment(// demo3: multiple args (again consider option parsing package\)) +ident(args) operator(=) operator([)stringoperator(,)stringoperator(,)stringoperator(,)string(]) +ident(nostdout) operator(=) keyword(false) +ident(append) operator(=) keyword(false) +ident(unbuffer) operator(=) keyword(false) +ident(ignore_ints) operator(=) keyword(false) +ident(files) operator(=) type([]) +ident(args)operator(.)ident(each)operator({) ident(arg) operator(->) + keyword(switch)operator(()ident(arg)(\)) operator({) + keyword(case) stringoperator(:) ident(nostdout) operator(=) keyword(true)operator(;) keyword(break) + keyword(case) stringoperator(:) ident(append) operator(=) keyword(true)operator(;) keyword(break) + keyword(case) stringoperator(:) ident(unbuffer) operator(=) keyword(true)operator(;) keyword(break) + keyword(case) stringoperator(:) ident(ignore_ints) operator(=) keyword(true)operator(;) keyword(break) + keyword(default)operator(:) ident(files) operator(+=) ident(arg) + (}) +(}) +keyword(if) operator(()ident(files)operator(.)ident(any)operator({) local_variable(it)operator(.)ident(startsWith)operator(()string(\)}\)) operator({) + pre_type(System)operator(.)ident(err)operator(.)ident(println)operator(()string(\)) +(}) +comment(// process files ...) +keyword(assert) ident(nostdout) operator(&&) ident(append) operator(&&) operator(!)ident(unbuffer) operator(&&) operator(!)ident(ignore_ints) +keyword(assert) ident(files) operator(==) operator([)stringoperator(,)string(]) + +comment(// find login: print all lines containing the string "login" (command-line version\)) +comment(//% groovy -ne "if (line =~ 'login'\) println line" filename) + +comment(// find login variation: lines containing "login" with line number (command-line version\)) +comment(//% groovy -ne "if (line =~ 'login'\) println count + ':' + line" filename) + +comment(// lowercase file (command-line version\)) +comment(//% groovy -pe "line.toLowerCase(\)") + + +comment(// count chunks but skip comments and stop when reaching "__DATA__" or "__END__") +ident(chunks) operator(=) integer(0)operator(;) ident(done) operator(=) keyword(false) +ident(testfile) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// change on your system) +ident(lines) operator(=) ident(testfile)operator(.)ident(readLines)operator(()(\)) +keyword(for) operator(()ident(line) keyword(in) ident(lines)(\)) operator({) + keyword(if) operator(()operator(!)ident(line)operator(.)ident(trim)operator(()(\)\)) keyword(continue) + ident(words) operator(=) ident(line)operator(.)ident(split)operator(()regexp(\))operator(.)ident(toList)operator(()(\)) + keyword(for) operator(()ident(word) keyword(in) ident(words)(\)) operator({) + keyword(if) operator(()ident(word) operator(=~) regexp(\)) keyword(break) + keyword(if) operator(()ident(word) keyword(in) operator([)stringoperator(,) string(]\)) operator({) ident(done) operator(=) keyword(true)operator(;) keyword(break) (}) + ident(chunks) operator(+=) integer(1) + (}) + keyword(if) operator(()ident(done)(\)) keyword(break) +(}) +ident(println) stringcontent( chunks)delimiter(")> + + +comment(// groovy "one-liner" (cough cough\) for turning .history file into pretty version:) +comment(//% groovy -e "m=new File(args[0]\).text=~/(?ms\)^#\\+(\\d+\)\\r?\\n(.*?\)$/;(0..) +comment(// Sun Jan 11 18:26:22 EST 1970 less /etc/motd) +comment(// Sun Jan 11 18:26:22 EST 1970 vi ~/.exrc) +comment(// Sun Jan 11 18:26:22 EST 1970 date) +comment(// Sun Jan 11 18:26:22 EST 1970 who) +comment(// Sun Jan 11 18:26:22 EST 1970 telnet home) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.8) +comment(//----------------------------------------------------------------------------------) +comment(// test data for below) +ident(testPath) operator(=) string + +comment(// general pattern) +keyword(def) method(processWithBackup)operator(()ident(inputPath)operator(,) ident(Closure) ident(processLine)(\)) operator({) + keyword(def) ident(input) operator(=) keyword(new) pre_type(File)operator(()ident(inputPath)(\)) + keyword(def) ident(out) operator(=) pre_type(File)operator(.)ident(createTempFile)operator(()stringoperator(,) string(\)) + ident(out)operator(.)ident(write)operator(()string(\)) comment(// create empty file) + ident(count) operator(=) integer(0) + ident(input)operator(.)ident(eachLine)operator({) ident(line) operator(->) + ident(count)operator(++) + ident(processLine)operator(()ident(out)operator(,) ident(line)operator(,) ident(count)(\)) + (}) + keyword(def) ident(dest) operator(=) keyword(new) pre_type(File)operator(()ident(inputPath) operator(+) string(\)) + ident(dest)operator(.)ident(delete)operator(()(\)) comment(// clobber previous backup) + ident(input)operator(.)ident(renameTo)operator(()ident(dest)(\)) + ident(out)operator(.)ident(renameTo)operator(()ident(input)(\)) +(}) + +comment(// use withPrintWriter if you don't want the '\\n''s appearing) +ident(processWithBackup)operator(()ident(testPath)(\)) operator({) ident(out)operator(,) ident(line)operator(,) ident(count) operator(->) + keyword(if) operator(()ident(count) operator(==) integer(20)(\)) operator({) comment(// we are at the 20th line) + ident(out) operator(<)operator(<) string + ident(out) operator(<)operator(<) string + (}) + ident(out) operator(<)operator(<) ident(line) operator(+) string +(}) + +ident(processWithBackup)operator(()ident(testPath)(\)) operator({) ident(out)operator(,) ident(line)operator(,) ident(count) operator(->) + keyword(if) operator(()operator(!)operator(()ident(count) keyword(in) integer(20)operator(..)integer(30)(\)\)) comment(// skip the 20th line to the 30th) + ident(out) operator(<)operator(<) ident(line) operator(+) string +(}) +comment(// equivalent to "one-liner":) +comment(//% groovy -i.orig -pe "if (!(count in 20..30\)\) out << line" testPath) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.9) +comment(//----------------------------------------------------------------------------------) +comment(//% groovy -i.orig -pe 'FILTER COMMAND' file1 file2 file3 ...) + +comment(// the following may also be possible on unix systems (unchecked\)) +comment(//#!/usr/bin/groovy -i.orig -p) +comment(// filter commands go here) + +comment(// "one-liner" templating scenario: change DATE -> current time) +comment(//% groovy -pi.orig -e 'line.replaceAll(/DATE/\){new Date(\)}') + +comment(//% groovy -i.old -pe 'line.replaceAll(/\\bhisvar\\b/, 'hervar'\)' *.[Cchy] (globbing platform specific\)) + +comment(// one-liner for correcting spelling typos) +comment(//% groovy -i.orig -pe 'line.replaceAll(/\\b(p\)earl\\b/i, '\\1erl'\)' *.[Cchy] (globbing platform specific\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.10) +comment(//----------------------------------------------------------------------------------) +comment(// general pattern) +keyword(def) method(processFileInplace)operator(()ident(file)operator(,) ident(Closure) ident(processText)(\)) operator({) + keyword(def) ident(text) operator(=) ident(file)operator(.)ident(text) + ident(file)operator(.)ident(write)operator(()ident(processText)operator(()ident(text)(\)\)) +(}) + +comment(// templating scenario: change DATE -> current time) +ident(testfile) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// replace on your system) +ident(processFileInplace)operator(()ident(testfile)(\)) operator({) ident(text) operator(->) + ident(text)operator(.)ident(replaceAll)operator(()regexpoperator(,) keyword(new) pre_type(Date)operator(()(\))operator(.)ident(toString)operator(()(\)\)) +(}) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.11) +comment(//----------------------------------------------------------------------------------) +comment(// You need to use Java's Channel class to acquire locks. The exact) +comment(// nature of the lock is somewhat dependent on the operating system.) +keyword(def) method(processFileWithLock)operator(()ident(file)operator(,) ident(processStream)(\)) operator({) + keyword(def) ident(random) operator(=) keyword(new) pre_type(RandomAccessFile)operator(()ident(file)operator(,) string(\)) + keyword(def) ident(lock) operator(=) ident(random)operator(.)ident(channel)operator(.)ident(lock)operator(()(\)) comment(// acquire exclusive lock) + ident(processStream)operator(()ident(random)(\)) + ident(lock)operator(.)ident(release)operator(()(\)) + ident(random)operator(.)ident(close)operator(()(\)) +(}) + +comment(// Instead of an exclusive lock you can acquire a shared lock.) + +comment(// Also, you can acquire a lock for a region of a file by specifying) +comment(// start and end positions of the region when acquiring the lock.) + +comment(// For non-blocking functionality, use tryLock(\) instead of lock(\).) +keyword(def) method(processFileWithTryLock)operator(()ident(file)operator(,) ident(processStream)(\)) operator({) + ident(random) operator(=) keyword(new) pre_type(RandomAccessFile)operator(()ident(file)operator(,) string(\)) + ident(channel) operator(=) ident(random)operator(.)ident(channel) + keyword(def) ident(MAX_ATTEMPTS) operator(=) integer(30) + keyword(for) operator(()ident(i) keyword(in) integer(0)operator(..<)ident(MAX_ATTEMPTS)(\)) operator({) + ident(lock) operator(=) ident(channel)operator(.)ident(tryLock)operator(()(\)) + keyword(if) operator(()ident(lock) operator(!=) keyword(null)(\)) keyword(break) + ident(println) string + pre_type(Thread)operator(.)ident(sleep)operator(()integer(500)(\)) comment(// 500 millis = 0.5 secs) + (}) + keyword(if) operator(()ident(lock) operator(==) keyword(null)(\)) operator({) + ident(println) string + (}) keyword(else) operator({) + ident(processStream)operator(()ident(random)(\)) + ident(lock)operator(.)ident(release)operator(()(\)) + (}) + ident(random)operator(.)ident(close)operator(()(\)) +(}) + + +comment(// non-blocking multithreaded example: print first line while holding lock) +pre_type(Thread)operator(.)ident(start)operator({) + ident(processFileWithLock)operator(()ident(testfile)(\)) operator({) ident(source) operator(->) + ident(println) string operator(+) ident(source)operator(.)ident(readLine)operator(()(\))operator(.)ident(toUpperCase)operator(()(\)) + pre_type(Thread)operator(.)ident(sleep)operator(()integer(2000)(\)) comment(// 2000 millis = 2 secs) + (}) +(}) +ident(processFileWithTryLock)operator(()ident(testfile)(\)) operator({) ident(source) operator(->) + ident(println) string operator(+) ident(source)operator(.)ident(readLine)operator(()(\))operator(.)ident(toUpperCase)operator(()(\)) +(}) +comment(// =>) +comment(// Could not get lock, pausing ...) +comment(// First reader: WAS LOWERCASE) +comment(// Could not get lock, pausing ...) +comment(// Could not get lock, pausing ...) +comment(// Could not get lock, pausing ...) +comment(// Could not get lock, pausing ...) +comment(// Second reader: WAS LOWERCASE) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.12) +comment(//----------------------------------------------------------------------------------) +comment(// In Java, input and output streams have a flush(\) method and file channels) +comment(// have a force(\) method (applicable also to memory-mapped files\). When creating) +comment(// PrintWriters and // PrintStreams, an autoFlush option can be provided.) +comment(// From a FileInput or Output Stream you can ask for the FileDescriptor) +comment(// which has a sync(\) method - but you wouldn't you'd just use flush(\).) + +ident(inputStream) operator(=) ident(testfile)operator(.)ident(newInputStream)operator(()(\)) comment(// returns a buffered input stream) +ident(autoFlush) operator(=) keyword(true) +ident(printStream) operator(=) keyword(new) pre_type(PrintStream)operator(()ident(outStream)operator(,) ident(autoFlush)(\)) +ident(printWriter) operator(=) keyword(new) pre_type(PrintWriter)operator(()ident(outStream)operator(,) ident(autoFlush)(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.13) +comment(//----------------------------------------------------------------------------------) +comment(// See the comments in 7.14 about scenarios where non-blocking can be) +comment(// avoided. Also see 7.14 regarding basic information about channels.) +comment(// An advanced feature of the java.nio.channels package is supported) +comment(// by the Selector and SelectableChannel classes. These allow efficient) +comment(// server multiplexing amongst responses from a number of potential sources.) +comment(// Under the covers, it allows mapping to native operating system features) +comment(// supporting such multiplexing or using a pool of worker processing threads) +comment(// much smaller in size than the total available connections.) +comment(//) +comment(// The general pattern for using selectors is:) +comment(//) +comment(// while (true\) {) +comment(// selector.select(\)) +comment(// def it = selector.selectedKeys(\).iterator(\)) +comment(// while (it.hasNext(\)\) {) +comment(// handleKey(it++\)) +comment(// it.remove(\)) +comment(// }) +comment(// }) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.14) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy has no special support for this apart from making it easier to) +comment(// create threads (see note at end\); it relies on Java's features here.) + +comment(// InputStreams in Java/Groovy block if input is not yet available.) +comment(// This is not normally an issue, because if you have a potential blocking) +comment(// operation, e.g. save a large file, you normally just create a thread) + comment(// and save it in the background.) + +comment(// Channels are one way to do non-blocking stream-based IO.) +comment(// Classes which implement the AbstractSelectableChannel interface provide) +comment(// a configureBlocking(boolean\) method as well as an isBlocking(\) method.) +comment(// When processing a non-blocking stream, you need to process incoming) +comment(// information based on the number of bytes read returned by the various) +comment(// read methods. For non-blocking, this can be 0 bytes even if you pass) +comment(// a fixed size byte[] buffer to the read method. Non-blocking IO is typically) +comment(// not used with Files but more normally with network streams though they) +comment(// can when Pipes (couple sink and source channels\) are involved where) +comment(// one side of the pipe is a file.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.15) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy uses Java's features here.) +comment(// For both blocking and non-blocking reads, the read operation returns the number) +comment(// of bytes read. In blocking operations, this normally corresponds to the number) +comment(// of bytes requested (typically the size of some buffer\) but can have a smaller) +comment(// value at the end of a stream. Java also makes no guarantees about whether) +comment(// other streams in general will return bytes as they become available under) +comment(// certain circumstances (rather than blocking until the entire buffer is filled.) +comment(// In non-blocking operations, the number of bytes returned will typically be) +comment(// the number of bytes available (up to some maximum buffer or requested size\).) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_7.16) +comment(//----------------------------------------------------------------------------------) +comment(// This just works in Java and Groovy as per the previous examples.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.17) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy uses Java's features here.) +comment(// More work has been done in the Java on object caching than file caching) +comment(// with several open source and commercial offerings in that area. File caches) +comment(// are also available, for one, see:) +comment(// http://portals.apache.org/jetspeed-1/apidocs/org/apache/jetspeed/cache/FileCache.html) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.18) +comment(//----------------------------------------------------------------------------------) +comment(// The general pattern is: streams.each{ stream -> stream.println 'item to print' }) +comment(// See the MultiStream example in 13.5 for a coded example.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.19) +comment(//----------------------------------------------------------------------------------) +comment(// You wouldn't normally be dealing with FileDescriptors. In case were you have) +comment(// one you would normally walk through all known FileStreams asking each for) +comment(// it's FileDescriptor until you found one that matched. You would then close) +comment(// that stream.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.20) +comment(//----------------------------------------------------------------------------------) +comment(// There are several concepts here. At the object level, any two object references) +comment(// can point to the same object. Any changes made by one of these will be visible) +comment(// in the 'alias'. You can also have multiple stream, reader, writer or channel objects) +comment(// referencing the same resource. Depending on the kind of resource, any potential) +comment(// locks, the operations being requested and the behaviour of third-party programs,) +comment(// the result of trying to perform such concurrent operations may not always be) +comment(// deterministic. There are strategies for coping with such scenarious but the) +comment(// best bet is to avoid the issue.) + +comment(// For the scenario given, copying file handles, that corresponds most closely) +comment(// with cloning streams. The best bet is to just use individual stream objects) +comment(// both created from the same file. If you are attempting to do write operations,) +comment(// then you should consider using locks.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.21) +comment(//----------------------------------------------------------------------------------) +comment(// locking is built in to Java (since 1.4\), so should not be missing) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_7.22) +comment(//----------------------------------------------------------------------------------) +comment(// Java locking supports locking just regions of files.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.0) +comment(//----------------------------------------------------------------------------------) +ident(datafile) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// change on your system) + +ident(datafile)operator(.)ident(eachLine)operator({) ident(line) operator(->) ident(print) ident(line)operator(.)ident(size)operator(()(\)) (}) + +ident(lines) operator(=) ident(datafile)operator(.)ident(readLines)operator(()(\)) + +ident(wholeTextFile) operator(=) ident(datafile)operator(.)ident(text) + +comment(// on command line Groovy use -a auto split pattern instead of record separator) +comment(// default pattern is /\\s/) +comment(// groovy -a -e 'println "First word is ${split[0][1]}"') + +comment(// (additional examples to original cookbook to illustrate -a\)) +comment(// Print processes owned by root:) +comment(// ps aux|groovy -ane "if(split[0][1] =~ 'root'\)println split[0][10..-1]") + +comment(// Print all logins from /etc/passwd that are not commented:) +comment(// groovy -a':' -ne "if(!(split[0][1] =~ /^#/\)\)println split[0][1]" /etc/passwd) + +comment(// Add the first and the penultimate column of a file:) +comment(// groovy -ape "split[0][1].toInteger(\)+split[0][-2].toInteger(\)" accounts.txt) + +comment(// no BEGIN and END in Groovy (has been proposed, may be added soon\)) + +ident(datafile)operator(.)ident(withOutputStream)operator({) ident(stream) operator(->) + ident(stream)operator(.)ident(print) string operator(+) string operator(+) string comment(// "onetwothree" -> file) + ident(println) string comment(// sent to $stdout) +(}) + +comment(// use streams or channels for advanced file handling) +type(int) ident(size) operator(=) ident(datafile)operator(.)ident(size)operator(()(\)) +ident(buffer) operator(=) pre_type(ByteBuffer)operator(.)ident(allocate)operator(()ident(size)(\)) comment(// for large files, use some block size, e.g. 4096) +ident(channel) operator(=) keyword(new) pre_type(FileInputStream)operator(()ident(datafile)(\))operator(.)ident(channel) +ident(println) stringdelimiter(")> comment(// -1 = EOF) + +ident(channel) operator(=) keyword(new) pre_type(FileOutputStream)operator(()pre_type(File)operator(.)ident(createTempFile)operator(()stringoperator(,) string(\)\))operator(.)ident(channel) +ident(size) operator(=) ident(channel)operator(.)ident(size)operator(()(\)) +ident(channel)operator(.)ident(truncate)operator(()ident(size)(\)) comment(// shrinks file (in our case to same size\)) + +ident(pos) operator(=) ident(channel)operator(.)ident(position)operator(()(\)) +ident(println) stringcontent( bytes from the start of datafile)delimiter(")> +ident(channel)operator(.)ident(position)operator(()ident(pos)(\)) comment(// move to pos (in our case unchanged\)) +ident(channel)operator(.)ident(position)operator(()integer(0)(\)) comment(// move to start of file) +ident(channel)operator(.)ident(position)operator(()ident(size)(\)) comment(// move to end of file) + +comment(// no sysread and syswrite are available but dataInput/output streams) +comment(// can be used to achieve similar functionality, see 8.15.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.1) +comment(//----------------------------------------------------------------------------------) +ident(testfile) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// change on your system) +comment(// contents of testfile:) +comment(// DISTFILES = $(DIST_COMMON\) $(SOURCES\) $(HEADERS\) \\ +// $(TEXINFOS\) $(INFOS\) $(MANS\) $(DATA\)) +comment(// DEP_DISTFILES = $(DIST_COMMON\) $(SOURCES\) $(HEADERS\) \\ +// $(TEXINFOS\) $(INFO_DEPS\) $(MANS\) $(DATA\) \\ +// $(EXTRA_DIST\)) + +ident(lines) operator(=) type([]) +ident(continuing) operator(=) keyword(false) +ident(regex) operator(=) regexp +ident(testfile)operator(.)ident(eachLine)operator({) ident(line) operator(->) + ident(stripped) operator(=) ident(line)operator(.)ident(replaceAll)operator(()ident(regex)operator(,)string(\)) + keyword(if) operator(()ident(continuing)(\)) ident(lines)operator([)operator(-)integer(1)(]) operator(+=) ident(stripped) + keyword(else) ident(lines) operator(+=) ident(stripped) + ident(continuing) operator(=) operator(()ident(line) operator(=~) ident(regex)(\)) +(}) +ident(println) ident(lines)operator(.)ident(join)operator(()string(\)) +comment(// =>) +comment(// DISTFILES = $(DIST_COMMON\) $(SOURCES\) $(HEADERS\) $(TEXINFOS\) $(INFOS\) $(MANS\) $(DATA\)) +comment(// DEP_DISTFILES = $(DIST_COMMON\) $(SOURCES\) $(HEADERS\) $(TEXINFOS\) $(INFO_DEPS\) $(MANS\) $(DATA\) $(EXTRA_DIST\)) + +comment(// to remove hidden spaces after the slash (but keep the slash\):) +keyword(def) method(trimtail)operator(()ident(line)(\)) operator({) + ident(line) operator(=) ident(line)operator(.)ident(replaceAll)operator(()regexpoperator(,) string(\)) +(}) +ident(b) operator(=) regexp comment(// backslash) +keyword(assert) stringdelimiter(")> operator(==) ident(trimtail)operator(()stringdelimiter(")>(\)) +keyword(assert) string operator(==) ident(trimtail)operator(()string(\)) +keyword(assert) stringdelimiter(")> operator(==) ident(trimtail)operator(()stringcontent( )delimiter(")>(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.2) +comment(//----------------------------------------------------------------------------------) +comment(// unixScript:) +ident(println) operator(()stringdelimiter(")>operator(.)ident(execute)operator(()(\))operator(.)ident(text)(\)) + +comment(// for small files which fit in memory) +ident(println) ident(testfile)operator(.)ident(readLines)operator(()(\))operator(.)ident(size)operator(()(\)) + +comment(// streaming approach (lines and paras\)) +ident(lines) operator(=) integer(0)operator(;) ident(paras) operator(=) integer(1) +ident(testfile)operator(.)ident(eachLine)operator({) ident(lines)operator(++)operator(;) keyword(if) operator(()local_variable(it) operator(=~) regexp(\)) ident(paras)operator(++) (}) +ident(println) stringcontent( lines and )inlinecontent( paras.)delimiter(")> +comment(// note: counts blank line at end as start of next empty para) + +comment(// with a StreamTokenizer) +ident(st) operator(=) keyword(new) pre_type(StreamTokenizer)operator(()ident(testfile)operator(.)ident(newReader)operator(()(\)\)) +keyword(while) operator(()ident(st)operator(.)ident(nextToken)operator(()(\)) operator(!=) pre_type(StreamTokenizer)operator(.)ident(TT_EOF)(\)) operator({)(}) +ident(println) ident(st)operator(.)ident(lineno)operator(()(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.3) +comment(//----------------------------------------------------------------------------------) +comment(// general pattern) +keyword(def) method(processWordsInFile)operator(()ident(file)operator(,) ident(processWord)(\)) operator({) + ident(testfile)operator(.)ident(splitEachLine)operator(()regexp(\)) operator({) ident(matched) operator(->) + ident(matched)operator(.)ident(each)operator({) ident(w) operator(->) keyword(if) operator(()ident(w)(\)) ident(processWord)operator(()ident(w)(\)) (}) + (}) +(}) + +ident(testfile) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// change path on your system) + +comment(// count words) +ident(count) operator(=) integer(0) +ident(processWordsInFile)operator(()ident(testfile)(\))operator({) ident(count)operator(++) (}) +ident(println) ident(count) + +comment(// (variation to Perl example\)) +comment(// with a StreamTokenizer (counting words and numbers in Pleac chapter 8 source file\)) +ident(words) operator(=) integer(0)operator(;) ident(numbers) operator(=) integer(0) +ident(st) operator(=) keyword(new) pre_type(StreamTokenizer)operator(()ident(testfile)operator(.)ident(newReader)operator(()(\)\)) +ident(st)operator(.)ident(slashSlashComments)operator(()keyword(true)(\)) comment(// ignore words and numbers in comments) +keyword(while) operator(()ident(st)operator(.)ident(nextToken)operator(()(\)) operator(!=) pre_type(StreamTokenizer)operator(.)ident(TT_EOF)(\)) operator({) + keyword(if) operator(()ident(st)operator(.)ident(ttype) operator(==) pre_type(StreamTokenizer)operator(.)ident(TT_WORD)(\)) ident(words)operator(++) + keyword(else) keyword(if) operator(()ident(st)operator(.)ident(ttype) operator(==) pre_type(StreamTokenizer)operator(.)ident(TT_NUMBER)(\)) ident(numbers)operator(++) +(}) +ident(println) stringcontent( words and )inlinecontent( numbers.)delimiter(")> + + +comment(// word frequency count) +ident(seen) operator(=) operator([)operator(:)(]) +ident(processWordsInFile)operator(()ident(testfile)(\)) operator({) + ident(w) operator(=) local_variable(it)operator(.)ident(toLowerCase)operator(()(\)) + keyword(if) operator(()ident(seen)operator(.)ident(containsKey)operator(()ident(w)(\)\)) ident(seen)operator([)ident(w)(]) operator(+=) integer(1) + keyword(else) ident(seen)operator([)ident(w)(]) operator(=) integer(1) +(}) +comment(// output map in a descending numeric sort of its values) +ident(seen)operator(.)ident(entrySet)operator(()(\))operator(.)ident(sort) operator({) ident(a)operator(,)ident(b) operator(->) ident(b)operator(.)ident(value) operator(<=)operator(>) ident(a)operator(.)ident(value) (})operator(.)ident(each)operator({) ident(e) operator(->) + ident(printf)operator(()stringoperator(,) operator([)ident(e)operator(.)ident(value)operator(,) ident(e)operator(.)ident(key)(]) (\)) +(}) +comment(// =>) +comment(// 25 pleac) +comment(// 22 line) +comment(// 20 file) +comment(// 19 println) +comment(// 19 lines) +comment(// 13 testfile) +comment(// ...) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.4) +comment(//----------------------------------------------------------------------------------) +ident(testfile)operator(.)ident(readLines)operator(()(\))operator(.)ident(reverseEach)operator({) + ident(println) local_variable(it) +(}) + +ident(lines) operator(=) ident(testfile)operator(.)ident(readLines)operator(()(\)) +comment(// normally one would use the reverseEach, but you can use) +comment(// a numerical index if you want) +operator(()operator(()ident(lines)operator(.)ident(size)operator(()(\)) operator(-) integer(1)(\))operator(..)integer(0)(\))operator(.)ident(each)operator({) + ident(println) ident(lines)operator([)local_variable(it)(]) +(}) + +comment(// Paragraph-based processing could be done as in 8.2.) + +comment(// A streaming-based solution could use random file access) +comment(// and have a sliding buffer working from the back of the) +comment(// file to the front.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.5) +comment(//----------------------------------------------------------------------------------) +ident(logfile) operator(=) keyword(new) pre_type(File)operator(()string(\)) +comment(// logTailingScript:) +ident(sampleInterval) operator(=) integer(2000) comment(// 2000 millis = 2 secs) +ident(file) operator(=) keyword(new) pre_type(RandomAccessFile)operator(() ident(logfile)operator(,) string (\)) +ident(filePointer) operator(=) integer(0) comment(// set to logfile.size(\) to begin tailing from the end of the file) +keyword(while)operator(() keyword(true) (\)) operator({) + comment(// Compare the length of the file to the file pointer) + type(long) ident(fileLength) operator(=) ident(logfile)operator(.)ident(size)operator(()(\)) + keyword(if)operator(() ident(fileLength) operator(<) ident(filePointer) (\)) operator({) + comment(// Log file must have been rotated or deleted;) + pre_type(System)operator(.)ident(err)operator(.)ident(println) stringcontent(: Reopening )inlinedelimiter(")> + ident(file) operator(=) keyword(new) pre_type(RandomAccessFile)operator(() ident(logfile)operator(,) string (\)) + ident(filePointer) operator(=) integer(0) + (}) + keyword(if)operator(() ident(fileLength) operator(>) ident(filePointer) (\)) operator({) + comment(// There is data to read) + ident(file)operator(.)ident(seek)operator(() ident(filePointer) (\)) + keyword(while)operator(() operator(()ident(line) operator(=) ident(file)operator(.)ident(readLine)operator(()(\)\)) operator(!=) keyword(null) (\)) operator({) + ident(println) string operator(+) ident(line) + (}) + ident(filePointer) operator(=) ident(file)operator(.)ident(filePointer) + (}) + comment(// Sleep for the specified interval) + pre_type(Thread)operator(.)ident(sleep)operator(() ident(sampleInterval) (\)) +(}) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.6) +comment(//----------------------------------------------------------------------------------) +comment(//testfile = newFile('/usr/share/fortune/humorists'\)) + +comment(// small files:) +ident(random) operator(=) keyword(new) pre_type(Random)operator(()(\)) +ident(lines) operator(=) ident(testfile)operator(.)ident(readLines)operator(()(\)) +ident(println) ident(lines)operator([)ident(random)operator(.)ident(nextInt)operator(()ident(lines)operator(.)ident(size)operator(()(\)\)]) + +comment(// streamed alternative) +ident(count) operator(=) integer(0) +keyword(def) ident(adage) +ident(testfile)operator(.)ident(eachLine)operator({) ident(line) operator(->) + ident(count)operator(++) + keyword(if) operator(()ident(random)operator(.)ident(nextInt)operator(()ident(count)(\)) operator(<) integer(1)(\)) ident(adage) operator(=) ident(line) +(}) +ident(println) ident(adage) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.7) +comment(//----------------------------------------------------------------------------------) +comment(// non-streamed solution (like Perl and Ruby\)) +ident(lines) operator(=) ident(testfile)operator(.)ident(readLines)operator(()(\)) +pre_type(Collections)operator(.)ident(shuffle)operator(()ident(lines)(\)) +ident(println) ident(lines)operator(.)ident(join)operator(()string(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.8) +comment(//----------------------------------------------------------------------------------) +ident(desiredLine) operator(=) integer(235) +comment(// for small files) +ident(lines) operator(=) ident(testfile)operator(.)ident(readLines)operator(()(\)) +ident(println) stringcontent(: )inlinedelimiter(")> + +comment(// streaming solution) +ident(reader) operator(=) ident(testfile)operator(.)ident(newReader)operator(()(\)) +ident(count) operator(=) integer(0) +keyword(def) ident(line) +keyword(while) operator(()operator(()ident(line) operator(=) ident(reader)operator(.)ident(readLine)operator(()(\)\))operator(!=) keyword(null)(\)) operator({) + keyword(if) operator(()operator(++)ident(count) operator(==) ident(desiredLine)(\)) keyword(break) +(}) +ident(println) stringcontent(: )inlinedelimiter(")> +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.9) +comment(//----------------------------------------------------------------------------------) +ident(println) ident(testfile)operator(.)ident(text)operator(.)ident(split)operator(()regexp(\))operator(.)ident(size)operator(()(\)) +comment(// => 23 (21 sections .0 .. .20 plus before .0 plus line above\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.10) +comment(//----------------------------------------------------------------------------------) +ident(file) operator(=) keyword(new) pre_type(RandomAccessFile)operator(() ident(logfile)operator(,) string (\)) +type(long) ident(previous)operator(,) ident(lastpos) operator(=) integer(0) +keyword(while)operator(() operator(()ident(line) operator(=) ident(file)operator(.)ident(readLine)operator(()(\)\)) operator(!=) keyword(null) (\)) operator({) + ident(previous) operator(=) ident(lastpos) + ident(lastpos) operator(=) ident(file)operator(.)ident(filePointer) +(}) +keyword(if) operator(()ident(previous)(\)) ident(file)operator(.)ident(setLength)operator(()ident(previous)(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.11) +comment(//----------------------------------------------------------------------------------) +comment(// Java's streams are binary at the lowest level if not processed with) +comment(// higher level stream mechanisms or readers/writers. Some additions) +comment(// to the Perl cookbook which illustrate the basics.) + +comment(// Print first ten bytes of a binary file:) +keyword(def) method(dumpStart)operator(()ident(filename)(\)) operator({) + ident(bytes) operator(=) keyword(new) pre_type(File)operator(()ident(filename)(\))operator(.)ident(newInputStream)operator(()(\)) + integer(10)operator(.)ident(times)operator({) + ident(print) ident(bytes)operator(.)ident(read)operator(()(\)) operator(+) string + (}) + ident(println)operator(()(\)) +(}) +ident(dumpStart)operator(()pre_type(System)operator(.)ident(getProperty)operator(()string(\))operator(+)string(\)) +comment(// => 80 75 3 4 10 0 0 0 0 0 (note first two bytes = PK - you might recognize this) +comment(// as the starting sequence of a zip file\)) +ident(dumpStart)operator(()string(\)) comment(// after running groovyc compiler in src directory) +comment(// => 202 254 186 190 0 0 0 47 2 20 (starting bytes in HEX: CAFEBABE\)) + +ident(binfile) operator(=) keyword(new) pre_type(File)operator(()string(\)) +ident(binfile)operator(.)ident(withOutputStream)operator({) ident(stream) operator(->) operator(()integer(0)operator(..<)integer(20)(\))operator(.)ident(each)operator({) ident(stream)operator(.)ident(write)operator(()local_variable(it)(\)) (}}) +ident(binfile)operator(.)ident(eachByte)operator({) ident(print) local_variable(it) operator(+) string (})operator(;) ident(println)operator(()(\)) +comment(// => 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.12) +comment(//----------------------------------------------------------------------------------) +comment(// lets treat binfile as having 5 records of size 4, let's print out the 3rd record) +ident(recsize) operator(=) integer(4) +ident(recno) operator(=) integer(2) comment(// index starts at 0) +ident(address) operator(=) ident(recsize) operator(*) ident(recno) +ident(randomaccess) operator(=) keyword(new) pre_type(RandomAccessFile)operator(()ident(binfile)operator(,) string(\)) +ident(randomaccess)operator(.)ident(seek)operator(()ident(address)(\)) +ident(recsize)operator(.)ident(times)operator({) ident(print) ident(randomaccess)operator(.)ident(read)operator(()(\)) operator(+) string (})operator(;) ident(println)operator(()(\)) comment(// => 8 9 10 11) +ident(randomaccess)operator(.)ident(close)operator(()(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.13) +comment(//----------------------------------------------------------------------------------) +comment(// let's take the example from 8.12 but replace the 3rd record with) +comment(// 90 - the original value in the file) +comment(// this is an alternative example to the Perl cookbook which is cross platform) +comment(// see chapter 1 regarding un/pack which could be combined with below) +comment(// to achieve the full functionality of the original 8.13) +ident(recsize) operator(=) integer(4) +ident(recno) operator(=) integer(2) comment(// index starts at 0) +ident(address) operator(=) ident(recsize) operator(*) ident(recno) +ident(randomaccess) operator(=) keyword(new) pre_type(RandomAccessFile)operator(()ident(binfile)operator(,) string(\)) +ident(randomaccess)operator(.)ident(seek)operator(()ident(address)(\)) +ident(bytes) operator(=) type([]) +ident(recsize)operator(.)ident(times)operator({) ident(bytes) operator(+=) ident(randomaccess)operator(.)ident(read)operator(()(\)) (}) +ident(randomaccess)operator(.)ident(seek)operator(()ident(address)(\)) +ident(bytes)operator(.)ident(each)operator({) ident(b) operator(->) ident(randomaccess)operator(.)ident(write)operator(()integer(90) operator(-) ident(b)(\)) (}) +ident(randomaccess)operator(.)ident(close)operator(()(\)) +ident(binfile)operator(.)ident(eachByte)operator({) ident(print) local_variable(it) operator(+) string (})operator(;) ident(println)operator(()(\)) +comment(// => 0 1 2 3 4 5 6 7 82 81 80 79 12 13 14 15 16 17 18 19) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.14) +comment(//----------------------------------------------------------------------------------) +comment(// reading a String would involve looping and collecting the read bytes) + +comment(// simple bgets) +comment(// this is similar to the revised 8.13 but would look for the terminating 0) + +comment(// simplistic strings functionality) +ident(binfile)operator(.)ident(eachByte)operator({) ident(b) operator(->) keyword(if) operator(()operator(()type(int)(\))ident(b) keyword(in) integer(32)operator(..)integer(126)(\)) ident(print) operator(()operator(()type(char)(\))ident(b)(\)) (})operator(;) ident(println)operator(()(\)) comment(// => RQPO) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.15) +comment(//----------------------------------------------------------------------------------) +comment(// You could combine the byte-level reading/writing mechanisms shown) +comment(// in 8.11 - 8.12 and combine that with the un/pack functionality from) +comment(// Chapter 1 to achieve the desired functionality. A more Java and Groovy) +comment(// friendly way to do this would be to use the Scattering and Gathering) +comment(// stream operations of channels for byte-oriented record fields or) +comment(// data-oriented records. Alternatively, the dataInput/output stream) +comment(// capabilities for data-oriented records. Finally, the) +comment(// objectInput/output stream capabilities could be used for object types.) +comment(// Note, these examples mix reading and writing even though the original) +comment(// Perl example was just about reading.) + + +comment(// fixed-length byte-oriented records using channels) +comment(// typical approach used with low-level protocols or file formats) +keyword(import) include(java.nio.*) +ident(binfile)operator(.)ident(delete)operator(()(\))operator(;) ident(binfile)operator(.)ident(createNewFile)operator(()(\)) comment(// start from scratch) +ident(buf1) operator(=) pre_type(ByteBuffer)operator(.)ident(wrap)operator(()operator([)integer(10)operator(,)integer(11)operator(,)integer(12)operator(,)integer(13)(]) keyword(as) type(byte)type([])(\)) comment(// simulate 4 byte field) +ident(buf2) operator(=) pre_type(ByteBuffer)operator(.)ident(wrap)operator(()operator([)integer(44)operator(,)integer(45)(]) keyword(as) type(byte)type([])(\)) comment(// 2 byte field) +ident(buf3) operator(=) pre_type(ByteBuffer)operator(.)ident(wrap)operator(()stringoperator(.)ident(bytes)(\)) comment(// String) +ident(records) operator(=) operator([)ident(buf1)operator(,) ident(buf2)operator(,) ident(buf3)(]) keyword(as) pre_type(ByteBuffer)type([]) +ident(channel) operator(=) keyword(new) pre_type(FileOutputStream)operator(()ident(binfile)(\))operator(.)ident(channel) +ident(channel)operator(.)ident(write)operator(()ident(records)(\)) comment(// gathering byte records) +ident(channel)operator(.)ident(close)operator(()(\)) +ident(binfile)operator(.)ident(eachByte)operator({) ident(print) local_variable(it) operator(+) string (})operator(;) ident(println)operator(()(\)) +comment(// => 10 11 12 13 44 45 72 101 108 108 111) +comment(// ScatteringInputStream would convert this back into an array of byte[]) + + +comment(// data-oriented streams using channels) +ident(binfile)operator(.)ident(delete)operator(()(\))operator(;) ident(binfile)operator(.)ident(createNewFile)operator(()(\)) comment(// start from scratch) +ident(buf) operator(=) pre_type(ByteBuffer)operator(.)ident(allocate)operator(()integer(24)(\)) +ident(now) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) +ident(buf)operator(.)ident(put)operator(()stringoperator(.)ident(bytes)(\))operator(.)ident(putDouble)operator(()pre_type(Math)operator(.)ident(PI)(\))operator(.)ident(put)operator(()stringoperator(.)ident(bytes)(\))operator(.)ident(putLong)operator(()ident(now)(\)) +ident(buf)operator(.)ident(flip)operator(()(\)) comment(// readies for writing: set length and point back to start) +ident(channel) operator(=) keyword(new) pre_type(FileOutputStream)operator(()ident(binfile)(\))operator(.)ident(channel) +ident(channel)operator(.)ident(write)operator(()ident(buf)(\)) +ident(channel)operator(.)ident(close)operator(()(\)) +comment(// now read it back in) +ident(channel) operator(=) keyword(new) pre_type(FileInputStream)operator(()ident(binfile)(\))operator(.)ident(channel) +ident(buf) operator(=) pre_type(ByteBuffer)operator(.)ident(allocate)operator(()integer(24)(\)) +ident(channel)operator(.)ident(read)operator(()ident(buf)(\)) +ident(buf)operator(.)ident(flip)operator(()(\)) +integer(3)operator(.)ident(times)operator({) ident(print) operator(()operator(()type(char)(\))ident(buf)operator(.)ident(get)operator(()(\)\)) (}) +ident(println) operator(()ident(buf)operator(.)ident(getDouble)operator(()(\)\)) +integer(5)operator(.)ident(times)operator({) ident(print) operator(()operator(()type(char)(\))ident(buf)operator(.)ident(get)operator(()(\)\)) (}) +ident(println) operator(()keyword(new) pre_type(Date)operator(()ident(buf)operator(.)ident(getLong)operator(()(\)\)\)) +ident(channel)operator(.)ident(close)operator(()(\)) +comment(// =>) +comment(// PI=3.141592653589793) +comment(// Date=Sat Jan 13 00:14:50 EST 2007) + +comment(// object-oriented streams) +ident(binfile)operator(.)ident(delete)operator(()(\))operator(;) ident(binfile)operator(.)ident(createNewFile)operator(()(\)) comment(// start from scratch) +type(class) class(Person) directive(implements) pre_type(Serializable) operator({) keyword(def) ident(name)operator(,) ident(age) (}) +ident(binfile)operator(.)ident(withObjectOutputStream)operator({) ident(oos) operator(->) + ident(oos)operator(.)ident(writeObject)operator(()keyword(new) ident(Person)operator(()key(name)operator(:)stringoperator(,)key(age)operator(:)integer(16)(\)\)) + ident(oos)operator(.)ident(writeObject)operator(()operator([)integer(1)operator(:)stringoperator(,) integer(2)operator(:)string(]\)) + ident(oos)operator(.)ident(writeObject)operator(()keyword(new) pre_type(Date)operator(()(\)\)) +(}) +comment(// now read it back in) +ident(binfile)operator(.)ident(withObjectInputStream)operator({) ident(ois) operator(->) + ident(person) operator(=) ident(ois)operator(.)ident(readObject)operator(()(\)) + ident(println) stringcontent(.name is )inlinecontent(.age)delimiter(")> + ident(println) ident(ois)operator(.)ident(readObject)operator(()(\)) + ident(println) ident(ois)operator(.)ident(readObject)operator(()(\)) +(}) +comment(// =>) +comment(// Bernie is 16) +comment(// [1:"a", 2:"b"]) +comment(// Sat Jan 13 00:22:13 EST 2007) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.16) +comment(//----------------------------------------------------------------------------------) +comment(// use built-in Java property class) +comment(// suppose you have the following file:) +comment(// # set your database settings here) +comment(// server=localhost) +comment(// url=jdbc:derby:derbyDB;create=true) +comment(// user.name=me) +comment(// user.password=secret) +ident(props) operator(=) keyword(new) pre_type(Properties)operator(()(\)) +ident(propsfile)operator(=)keyword(new) pre_type(File)operator(()string(\)) +ident(props)operator(.)ident(load)operator(()ident(propsfile)operator(.)ident(newInputStream)operator(()(\)\)) +ident(props)operator(.)ident(list)operator(()pre_type(System)operator(.)ident(out)(\)) +comment(// =>) +comment(// -- listing properties --) +comment(// user.name=me) +comment(// user.password=secret) +comment(// url=jdbc:derby:derbyDB;create=true) +comment(// server=localhost) + +comment(// There are also provisions for writing properties file.) + +comment(// (additional example to Perl\)) +comment(// You can also read and write xml properties files.) +keyword(new) pre_type(File)operator(()string(\))operator(.)ident(withOutputStream)operator({) ident(os) operator(->) + ident(props)operator(.)ident(storeToXML)operator(()ident(os)operator(,) string(\)) +(}) +comment(// =>) +comment(// ) +comment(// ) +comment(// ) +comment(// Database Settings) +comment(// secret) +comment(// me) +comment(// jdbc:derby:derbyDB;create=true) +comment(// localhost) +comment(// ) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.17) +comment(//----------------------------------------------------------------------------------) +comment(// The File class provides canRead(\), canWrite(\) and canExecute(\) (JDK6\) methods) +comment(// for finding out about security information specific to the user. JSR 203) +comment(// (expected in Java 7\) provides access to additional security related attributes.) + +comment(// Another useful package to use when wondering about the trustworthiness of a) +comment(// file is the java.security package. It contains many classes. Just one is) +comment(// MessageDigest. This would allow you to create a strong checksum of a file.) +comment(// Your program could refuse to operate if a file it was accessing didn't have the) +comment(// checksum it was expecting - an indication that it may have been tampered with.) + +comment(// (additional info\)) +comment(// While getting file-based security permissions correct is important, it isn't the) +comment(// only mechanism to use for security when using Java based systems. Java provides) +comment(// policy files and an authorization and authentication API which lets you secure) +comment(// any reources (not just files\) at various levels of granularity with various) +comment(// security mechanisms.) +comment(// Security policies may be universal, apply to a particular codebase, or) +comment(// using JAAS apply to individuals. Some indicative policy statements:) +comment(// grant {) +comment(// permission java.net.SocketPermission "*", "connect";) +comment(// permission java.io.FilePermission "C:\\\\users\\\\cathy\\\\foo.bat", "read";) +comment(// };) +comment(// grant codebase "file:./*", Principal ExamplePrincipal "Secret" {) +comment(// permission java.io.FilePermission "dummy.txt", "read";) +comment(// };) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.18) +comment(//----------------------------------------------------------------------------------) +comment(// general purpose utility methods) +keyword(def) method(getString)operator(()ident(buf)operator(,)ident(size)(\))operator({) + comment(// consider get(buf[]\) instead of get(buf\) for efficiency) + ident(b)operator(=)type([])operator(;) ident(size)operator(.)ident(times)operator({)ident(b)operator(+=)ident(buf)operator(.)ident(get)operator(()(\)})operator(;) keyword(new) pre_type(String)operator(()ident(b) keyword(as) type(byte)type([])(\))operator(.)ident(trim)operator(()(\)) +(}) +keyword(def) method(getInt)operator(()ident(buf)operator(,)ident(size)(\)) operator({) + comment(// normally in Java we would just use methods like getLong(\)) + comment(// to read a long but wish to ignore platform issues here) + type(long) ident(val) operator(=) integer(0) + keyword(for) operator(()ident(n) keyword(in) integer(0)operator(..<)ident(size)(\)) operator({) ident(val) operator(+=) operator(()operator(()type(int)(\))ident(buf)operator(.)ident(get)operator(()(\)) operator(&) hex(0xFF)(\)) operator(<)operator(<) operator(()ident(n) operator(*) integer(8)(\)) (}) + keyword(return) ident(val) +(}) +keyword(def) method(getDate)operator(()ident(buf)(\)) operator({) + keyword(return) keyword(new) pre_type(Date)operator(()ident(getInt)operator(()ident(buf)operator(,)integer(4)(\)) operator(*) integer(1000)(\)) comment(// Java uses millis) +(}) + +comment(// specific utility method (wtmp file from ubuntu 6.10\)) +keyword(def) method(processWtmpRecords)operator(()ident(file)operator(,) ident(origpos)(\)) operator({) + ident(channel) operator(=) keyword(new) pre_type(RandomAccessFile)operator(()ident(file)operator(,) string(\))operator(.)ident(channel) + ident(recsize) operator(=) integer(4) operator(+) integer(4) operator(+) integer(32) operator(+) integer(4) operator(+) integer(32) operator(+) integer(256) operator(+) integer(8) operator(+) integer(4) operator(+) integer(40) + ident(channel)operator(.)ident(position)operator(()ident(origpos)(\)) + ident(newpos) operator(=) ident(origpos) + ident(buf) operator(=) pre_type(ByteBuffer)operator(.)ident(allocate)operator(()ident(recsize)(\)) + keyword(while) operator(()operator(()ident(count) operator(=) ident(channel)operator(.)ident(read)operator(()ident(buf)(\)\)) operator(!=) operator(-)integer(1)(\)) operator({) + keyword(if) operator(()ident(count) operator(!=) ident(recsize)(\)) keyword(break) + ident(buf)operator(.)ident(flip)operator(()(\)) + ident(print) ident(getInt)operator(()ident(buf)operator(,)integer(4)(\)) operator(+) string comment(// type) + ident(print) ident(getInt)operator(()ident(buf)operator(,)integer(4)(\)) operator(+) string comment(// pid) + ident(print) ident(getString)operator(()ident(buf)operator(,)integer(32)(\)) operator(+) string comment(// line) + ident(print) ident(getString)operator(()ident(buf)operator(,)integer(4)(\)) operator(+) string comment(// inittab) + ident(print) ident(getString)operator(()ident(buf)operator(,)integer(32)(\)) operator(+) string comment(// user) + ident(print) ident(getString)operator(()ident(buf)operator(,)integer(256)(\)) operator(+) string comment(// hostname) + ident(buf)operator(.)ident(position)operator(()ident(buf)operator(.)ident(position)operator(()(\)) operator(+) integer(8)(\)) comment(// skip) + ident(println) stringcontent( )delimiter(")> comment(// time) + ident(buf)operator(.)ident(clear)operator(()(\)) + ident(newpos) operator(=) ident(channel)operator(.)ident(position)operator(()(\)) + (}) + keyword(return) ident(newpos) +(}) + +ident(wtmp) operator(=) keyword(new) pre_type(File)operator(()string(\)) +comment(// wtmpTailingScript:) +ident(sampleInterval) operator(=) integer(2000) comment(// 2000 millis = 2 secs) +ident(filePointer) operator(=) ident(wtmp)operator(.)ident(size)operator(()(\)) comment(// begin tailing from the end of the file) +keyword(while)operator(()keyword(true)(\)) operator({) + comment(// Compare the length of the file to the file pointer) + type(long) ident(fileLength) operator(=) ident(wtmp)operator(.)ident(size)operator(()(\)) + keyword(if)operator(() ident(fileLength) operator(>) ident(filePointer) (\)) operator({) + comment(// There is data to read) + ident(filePointer) operator(=) ident(processWtmpRecords)operator(()ident(wtmp)operator(,) ident(filePointer)(\)) + (}) + comment(// Sleep for the specified interval) + pre_type(Thread)operator(.)ident(sleep)operator(() ident(sampleInterval) (\)) +(}) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.19) +comment(//----------------------------------------------------------------------------------) +comment(// contains most of the functionality of the original (not guaranteed to be perfect\)) +comment(// -i ignores errors, e.g. if one target is write protected, the others will work) +comment(// -u writes files in unbuffered mode (ignore for '|'\)) +comment(// -n not to stdout) +comment(// -a all files are in append mode) +comment(// '>>file1' turn on append for individual file) +comment(// '|wc' or '|grep x' etc sends output to forked process (only one at any time\)) +type(class) class(MultiStream) operator({) + directive(private) ident(targets) + directive(private) ident(ignoreErrors) + ident(MultiStream)operator(()pre_type(List) ident(targets)operator(,) ident(ignore)(\)) operator({) + local_variable(this)operator(.)ident(targets) operator(=) ident(targets) + ident(ignoreErrors) operator(=) ident(ignore) + (}) + keyword(def) method(println)operator(()pre_type(String) ident(content)(\)) operator({) + ident(targets)operator(.)ident(each)operator({) + keyword(try) operator({) + local_variable(it)operator(?)operator(.)ident(write)operator(()ident(content)operator(.)ident(bytes)(\)) + (}) keyword(catch) operator(()pre_type(Exception) ident(ex)(\)) operator({) + keyword(if) operator(()operator(!)ident(ignoreErrors)(\)) keyword(throw) ident(ex) + ident(targets) operator(-=) local_variable(it) + local_variable(it)operator(?)operator(.)ident(close)operator(()(\)) + (}) + (}) + (}) + keyword(def) method(close)operator(()(\)) operator({) ident(targets)operator(.)ident(each)operator({) local_variable(it)operator(?)operator(.)ident(close)operator(()(\)) (}) (}) +(}) + +type(class) class(TeeTarget) operator({) + directive(private) ident(filename) + directive(private) ident(stream) + directive(private) ident(p) + + ident(TeeTarget)operator(()pre_type(String) ident(name)operator(,) ident(append)operator(,) ident(buffered)operator(,) ident(ignore)(\)) operator({) + keyword(if) operator(()ident(name)operator(.)ident(startsWith)operator(()string>)delimiter(')>(\)\)) operator({) + ident(createFileStream)operator(()ident(name)operator([)integer(2)operator(..)operator(-)integer(1)(])operator(,)keyword(true)operator(,)ident(buffered)operator(,)ident(ignore)(\)) + (}) keyword(else) keyword(if) operator(()ident(name)operator(.)ident(startsWith)operator(()string(\)\)) operator({) + ident(createProcessReader)operator(()ident(name)operator([)integer(1)operator(..)operator(-)integer(1)(]\)) + (}) keyword(else) operator({) + ident(createFileStream)operator(()ident(name)operator(,)ident(append)operator(,)ident(buffered)operator(,)ident(ignore)(\)) + (}) + (}) + + ident(TeeTarget)operator(()pre_type(OutputStream) ident(stream)(\)) operator({) local_variable(this)operator(.)ident(stream) operator(=) ident(stream) (}) + + keyword(def) method(write)operator(()ident(bytes)(\)) operator({) ident(stream)operator(?)operator(.)ident(write)operator(()ident(bytes)(\)) (}) + keyword(def) method(close)operator(()(\)) operator({) ident(stream)operator(?)operator(.)ident(close)operator(()(\)) (}) + + directive(private) ident(createFileStream)operator(()ident(name)operator(,) ident(append)operator(,) ident(buffered)operator(,) ident(ignore)(\)) operator({) + ident(filename) operator(=) ident(name) + keyword(def) ident(fos) + keyword(try) operator({) + ident(fos) operator(=) keyword(new) pre_type(FileOutputStream)operator(()ident(name)operator(,) ident(append)(\)) + (}) keyword(catch) operator(()pre_type(Exception) ident(ex)(\)) operator({) + keyword(if) operator(()ident(ignore)(\)) keyword(return) + (}) + keyword(if) operator(()operator(!)ident(buffered)(\)) ident(stream) operator(=) ident(fos) + keyword(else) ident(stream) operator(=) keyword(new) pre_type(BufferedOutputStream)operator(()ident(fos)(\)) + (}) + directive(private) ident(createWriter)operator(()ident(os)(\)) operator({)keyword(new) pre_type(PrintWriter)operator(()keyword(new) pre_type(BufferedOutputStream)operator(()ident(os)(\)\)}) + directive(private) ident(createReader)operator(()ident(is)(\)) operator({)keyword(new) pre_type(BufferedReader)operator(()keyword(new) pre_type(InputStreamReader)operator(()ident(is)(\)\)}) + directive(private) ident(createPiperThread)operator(()ident(br)operator(,) ident(pw)(\)) operator({) + pre_type(Thread)operator(.)ident(start)operator({) + keyword(def) ident(next) + keyword(while)operator(()operator(()ident(next) operator(=) ident(br)operator(.)ident(readLine)operator(()(\)\))operator(!=)keyword(null)(\)) operator({) + ident(pw)operator(.)ident(println)operator(()ident(next)(\)) + (}) + ident(pw)operator(.)ident(flush)operator(()(\))operator(;) ident(pw)operator(.)ident(close)operator(()(\)) + (}) + (}) + directive(private) ident(createProcessReader)operator(()ident(name)(\)) operator({) + keyword(def) ident(readFromStream) operator(=) keyword(new) pre_type(PipedInputStream)operator(()(\)) + keyword(def) ident(r1) operator(=) ident(createReader)operator(()ident(readFromStream)(\)) + ident(stream) operator(=) keyword(new) pre_type(BufferedOutputStream)operator(()keyword(new) pre_type(PipedOutputStream)operator(()ident(readFromStream)(\)\)) + ident(p) operator(=) pre_type(Runtime)operator(.)ident(runtime)operator(.)ident(exec)operator(()ident(name)(\)) + keyword(def) ident(w1) operator(=) ident(createWriter)operator(()ident(p)operator(.)ident(outputStream)(\)) + ident(createPiperThread)operator(()ident(r1)operator(,) ident(w1)(\)) + keyword(def) ident(w2) operator(=) ident(createWriter)operator(()pre_type(System)operator(.)ident(out)(\)) + keyword(def) ident(r2) operator(=) ident(createReader)operator(()ident(p)operator(.)ident(inputStream)(\)) + ident(createPiperThread)operator(()ident(r2)operator(,) ident(w2)(\)) + (}) +(}) + +ident(targets) operator(=) type([]) +ident(append) operator(=) keyword(false)operator(;) ident(ignore) operator(=) keyword(false)operator(;) ident(includeStdout) operator(=) keyword(true)operator(;) ident(buffer) operator(=) keyword(true) +operator(()integer(0)operator(..<)ident(args)operator(.)ident(size)operator(()(\)\))operator(.)ident(each)operator({) + ident(arg) operator(=) ident(args)operator([)local_variable(it)(]) + keyword(if) operator(()ident(arg)operator(.)ident(startsWith)operator(()string(\)\)) operator({) + keyword(switch) operator(()ident(arg)(\)) operator({) + keyword(case) stringoperator(:) ident(append) operator(=) keyword(true)operator(;) keyword(break) + keyword(case) stringoperator(:) ident(ignore) operator(=) keyword(true)operator(;) keyword(break) + keyword(case) stringoperator(:) ident(includeStdout) operator(=) keyword(false)operator(;) keyword(break) + keyword(case) stringoperator(:) ident(buffer) operator(=) keyword(false)operator(;) keyword(break) + keyword(default)operator(:) + ident(println) string + pre_type(System)operator(.)ident(exit)operator(()integer(1)(\)) + (}) + (}) keyword(else) ident(targets) operator(+=) ident(arg) +(}) +ident(targets) operator(=) ident(targets)operator(.)ident(collect)operator({) keyword(new) ident(TeeTarget)operator(()local_variable(it)operator(,) ident(append)operator(,) ident(buffer)operator(,) ident(ignore)(\)) (}) +keyword(if) operator(()ident(includeStdout)(\)) ident(targets) operator(+=) keyword(new) ident(TeeTarget)operator(()pre_type(System)operator(.)ident(out)(\)) +keyword(def) ident(tee) operator(=) keyword(new) ident(MultiStream)operator(()ident(targets)operator(,) ident(ignore)(\)) +keyword(while) operator(()ident(line) operator(=) pre_type(System)operator(.)ident(in)operator(.)ident(readLine)operator(()(\)\)) operator({) + ident(tee)operator(.)ident(println)operator(()ident(line)(\)) +(}) +ident(tee)operator(.)ident(close)operator(()(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_8.20) +comment(//----------------------------------------------------------------------------------) +comment(// most of the functionality - uses an explicit uid - ran on ubuntu 6.10 on intel) +ident(lastlog) operator(=) keyword(new) pre_type(File)operator(()string(\)) +ident(channel) operator(=) keyword(new) pre_type(RandomAccessFile)operator(()ident(lastlog)operator(,) string(\))operator(.)ident(channel) +ident(uid) operator(=) integer(1000) +ident(recsize) operator(=) integer(4) operator(+) integer(32) operator(+) integer(256) +ident(channel)operator(.)ident(position)operator(()ident(uid) operator(*) ident(recsize)(\)) +ident(buf) operator(=) pre_type(ByteBuffer)operator(.)ident(allocate)operator(()ident(recsize)(\)) +ident(channel)operator(.)ident(read)operator(()ident(buf)(\)) +ident(buf)operator(.)ident(flip)operator(()(\)) +ident(date) operator(=) ident(getDate)operator(()ident(buf)(\)) +ident(line) operator(=) ident(getString)operator(()ident(buf)operator(,)integer(32)(\)) +ident(host) operator(=) ident(getString)operator(()ident(buf)operator(,)integer(256)(\)) +ident(println) stringcontent( last logged on )inlinecontent( from )inlinecontent( on )inlinedelimiter(")> +comment(// => User with uid 1000 last logged on Sat Jan 13 09:09:35 EST 2007 from unknown on :0) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_9.0) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy builds on Java's file and io classes which provide an operating) +comment(// system independent abstraction of a file system. The actual File class) +comment(// is the main class of interest. It represents a potential file or) +comment(// directory - which may or may not (yet\) exist. In versions of Java up to) +comment(// and including Java 6, the File class was missing some of the functionality) +comment(// required to implement some of the examples in the Chapter (workarounds) +comment(// and alternatives are noted below\). In Java 7, (also known as "Dolphin"\)) +comment(// new File abstraction facilities are being worked on but haven't yet been) +comment(// publically released. These new features are known as JSR 203 and are) +comment(// referred to when relevant to some of the examples. Thanks to Alan Bateman) +comment(// from Sun for clarification regarding various aspects of JSR 203. Apologies) +comment(// if I misunderstood any aspects relayed to me and also usual disclaimers) +comment(// apply regarding features which may change or be dropped before release.) + +comment(// path='/usr/bin'; file='vi' // linux/mac os?) +ident(path)operator(=)stringoperator(;) ident(file)operator(=)string comment(// windows) +ident(entry) operator(=) keyword(new) pre_type(File)operator(()stringdelimiter(")>(\)) +keyword(assert) ident(entry)operator(.)ident(isDirectory)operator(()(\)) +ident(entry) operator(=) keyword(new) pre_type(File)operator(()stringcontent(/)inlinedelimiter(")>(\)) +keyword(assert) ident(entry)operator(.)ident(isFile)operator(()(\)) + +ident(println) pre_type(File)operator(.)ident(separator) +comment(// => \\ (on Windows\)) +comment(// => / (on Unix\)) +comment(// however if you just stick to backslashes Java converts for you) +comment(// in most situations) + +comment(// File modification time (no exact equivalent of ctime - but you can) +comment(// call stat(\) using JNI or use exec(\) of dir or ls to get this kind of info\)) +comment(// JSR 203 also plans to provide such info in Java 7.) +ident(println) keyword(new) pre_type(Date)operator(()ident(entry)operator(.)ident(lastModified)operator(()(\)\)) +comment(// => Wed Aug 04 07:00:00 EST 2004) + +comment(// file size) +ident(println) ident(entry)operator(.)ident(size)operator(()(\)) +comment(// => 1032192) + +comment(// check if we have permission to read the file) +keyword(assert) ident(entry)operator(.)ident(canRead)operator(()(\)) + +comment(// check if file is binary or text?) +comment(// There is no functionality for this at the file level.) +comment(// Java has the Java Activation Framework (jaf\) which is used to) +comment(// associate files (and streams\) with MIME Types and subsequently) +comment(// binary data streams or character encodings for (potentially) +comment(// multilanguage\) text files. JSR-203 provides a method to determine) +comment(// the MIME type of a file. Depending on the platform the file type may) +comment(// be determined based on a file attribute, file name "extension", the) +comment(// bytes of the files (byte sniffing\) or other means. It is service) +comment(// provider based so developers can plug in their own file type detection) +comment(// mechanisms as required. "Out of the box" it will ship with file type) +comment(// detectors that are appropriate for the platform (integrates with GNOME,) +comment(// Windows registry, etc.\).) + +comment(// Groovy uses File for directories and files) +comment(// displayAllFilesInUsrBin:) +keyword(new) pre_type(File)operator(()string(\))operator(.)ident(eachFile)operator({) ident(file) operator(->) + ident(println) stringcontent(.name)delimiter(")> +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.1) +comment(//----------------------------------------------------------------------------------) +ident(file) operator(=) keyword(new) pre_type(File)operator(()string(\)) +ident(file) operator(<)operator(<) string +ident(timeModified) operator(=) ident(file)operator(.)ident(lastModified)operator(()(\)) +ident(println) keyword(new) pre_type(Date)operator(()ident(timeModified)(\)) +comment(// => Sun Jan 07 11:49:02 EST 2007) + +ident(MILLIS_PER_WEEK) operator(=) integer(60) operator(*) integer(60) operator(*) integer(24) operator(*) integer(1000) operator(*) integer(7) +ident(file)operator(.)ident(setLastModified)operator(()ident(timeModified) operator(-) ident(MILLIS_PER_WEEK)(\)) +ident(println) keyword(new) pre_type(Date)operator(()ident(file)operator(.)ident(lastModified)operator(()(\)\)) +comment(// => Sun Dec 31 11:49:02 EST 2006) + +comment(// Java currently doesn't provide access to other timestamps but) +comment(// there are things that can be done:) +comment(// (1\) You can use JNI to call to C, e.g. stat(\)) +comment(// (2\) Use exec(\) and call another program, e.g. dir, ls, ... to get the value you are after) +comment(// (3\) Here is a Windows specific patch to get lastAccessedTime and creationTime) +comment(// http://forum.java.sun.com/thread.jspa?forumID=31&start=0&threadID=409921&range=100#1800193) +comment(// (4\) There is an informal patch for Java 5/6 which gives lastAccessedTime on Windows and Linux) +comment(// and creationTime on windows:) +comment(// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6314708) +comment(// (5\) JSR 203 (currently targetted for Java 7\) aims to provide) +comment(// "bulk access to file attributes, change notification, escape to filesystem-specific APIs") +comment(// this is supposed to include creationTime and lastAccessedTime along with many) +comment(// security-related file attributes) + +comment(// viFileWithoutChangingModificationTimeScript:) +doctype(#!/usr/bin/groovy) +comment(// uvi - vi a file without changing it's last modified time) +keyword(if) operator(()ident(args)operator(.)ident(size)operator(()(\)) operator(!=) integer(1)(\)) + ident(println) string + pre_type(System)operator(.)ident(exit)operator(()integer(1)(\)) +(}) +ident(file) operator(=) ident(args)operator([)integer(0)(]) +ident(origTime) operator(=) keyword(new) pre_type(File)operator(()ident(file)(\))operator(.)ident(lastModified)operator(()(\)) +stringdelimiter(")>operator(.)ident(execute)operator(()(\)) +keyword(new) pre_type(File)operator(()ident(file)(\))operator(.)ident(setLastModified)operator(()ident(origTime)(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.2) +comment(//----------------------------------------------------------------------------------) +ident(println) keyword(new) pre_type(File)operator(()string(\))operator(.)ident(exists)operator(()(\)) comment(// => false) +ident(println) keyword(new) pre_type(File)operator(()string(\))operator(.)ident(delete)operator(()(\)) comment(// => false) + +keyword(new) pre_type(File)operator(()string(\)) operator(<)operator(<) string +ident(println) keyword(new) pre_type(File)operator(()string(\))operator(.)ident(exists)operator(()(\)) comment(// => true) +ident(println) keyword(new) pre_type(File)operator(()string(\))operator(.)ident(delete)operator(()(\)) comment(// => true) + +ident(names) operator(=) operator([)stringoperator(,)stringoperator(,)string(]) +ident(files) operator(=) ident(names)operator(.)ident(collect)operator({) keyword(new) pre_type(File)operator(()local_variable(it)(\)) (}) +comment(// create 2 of the files) +ident(files)operator([)integer(0)operator(..)integer(1)(])operator(.)ident(each)operator({) ident(f) operator(->) ident(f) operator(<)operator(<) ident(f)operator(.)ident(name) (}) + +keyword(def) method(deleteFiles)operator(()ident(files)(\)) operator({) + keyword(def) ident(problemFileNames) operator(=) type([]) + ident(files)operator(.)ident(each)operator({) ident(f) operator(->) + keyword(if) operator(()operator(!)ident(f)operator(.)ident(delete)operator(()(\)\)) + ident(problemFileNames) operator(+=) ident(f)operator(.)ident(name) + (}) + keyword(def) ident(delCnt) operator(=) ident(files)operator(.)ident(size)operator(()(\)) operator(-) ident(problemFileNames)operator(.)ident(size)operator(()(\)) + ident(println) stringcontent( of )inlinecontent( file(s\))delimiter(")> + keyword(if) operator(()ident(problemFileNames)(\)) + ident(println) string operator(+) ident(problemFileNames)operator(.)ident(join)operator(()string(\)) +(}) + +ident(deleteFiles)operator(()ident(files)(\)) +comment(// =>) +comment(// Successfully deleted 2 of 3 file(s\)) +comment(// Problems file(s\): file3) + +comment(// we can also set files for deletion on exit) +ident(tempFile) operator(=) keyword(new) pre_type(File)operator(()string(\)) +keyword(assert) operator(!)ident(tempFile)operator(.)ident(exists)operator(()(\)) +ident(tempFile) operator(<)operator(<) string +keyword(assert) ident(tempFile)operator(.)ident(exists)operator(()(\)) +ident(tempFile)operator(.)ident(deleteOnExit)operator(()(\)) +keyword(assert) ident(tempFile)operator(.)ident(exists)operator(()(\)) +comment(// To confirm this is working, run these steps multiple times in a row.) + +comment(// Discussion:) +comment(// Be careful with deleteOnExit(\) as there is no way to cancel it.) +comment(// There are also mechanisms specifically for creating unqiuely named temp files.) +comment(// On completion of JSR 203, there will be additional methods available for) +comment(// deleting which throw exceptions with detailed error messages rather than) +comment(// just return booleans.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.3) +comment(//----------------------------------------------------------------------------------) +comment(// (1\) Copy examples) + +comment(//shared setup) +ident(dummyContent) operator(=) string operator(+) pre_type(System)operator(.)ident(getProperty)operator(()string(\)) +ident(setUpFromFile)operator(()(\)) +ident(setUpToFile)operator(()(\)) + +comment(// built-in copy via memory (text files only\)) +ident(to) operator(<)operator(<) ident(from)operator(.)ident(text) +ident(checkSuccessfulCopyAndDelete)operator(()(\)) + +comment(// built-in as a stream (text or binary\) with optional encoding) +ident(to) operator(<)operator(<) ident(from)operator(.)ident(asWritable)operator(()string(\)) +ident(checkSuccessfulCopyAndDelete)operator(()(\)) + +comment(// built-in using AntBuilder) +comment(// for options, see: http://ant.apache.org/manual/CoreTasks/copy.html) +keyword(new) ident(AntBuilder)operator(()(\))operator(.)ident(copy)operator(() key(file)operator(:) ident(from)operator(.)ident(canonicalPath)operator(,) key(tofile)operator(:) ident(to)operator(.)ident(canonicalPath) (\)) +ident(checkSuccessfulCopyAndDelete)operator(()(\)) +comment(// =>) +comment(// [copy] Copying 1 file to D:\\ +) + +comment(// use Apache Jakarta Commons IO (jakarta.apache.org\)) +keyword(import) include(org.apache.commons.io.FileUtils) +comment(// Copies a file to a new location preserving the lastModified date.) +ident(FileUtils)operator(.)ident(copyFile)operator(()ident(from)operator(,) ident(to)(\)) +ident(checkSuccessfulCopyAndDelete)operator(()(\)) + +comment(// using execute(\)) +comment(// "cp $from.canonicalPath $to.canonicalPath".execute(\) // unix) +ident(println) stringcontent(.canonicalPath )inlinecontent(.canonicalPath)char(\\")delimiter(")>operator(.)ident(execute)operator(()(\))operator(.)ident(text) comment(// dos vms) +ident(checkSuccessfulCopyAndDelete)operator(()(\)) +comment(// =>) +comment(// 1 file(s\) copied.) + +comment(// (2\) Move examples) +comment(// You can just do copy followed by delete but many OS's can just 'rename' in place) +comment(// so you can additionally do using Java's functionality:) +keyword(assert) ident(from)operator(.)ident(renameTo)operator(()ident(to)(\)) +keyword(assert) operator(!)ident(from)operator(.)ident(exists)operator(()(\)) +ident(checkSuccessfulCopyAndDelete)operator(()(\)) +comment(// whether renameTo succeeds if from and to are on different platforms) +comment(// or if to pre-exists is OS dependent, so you should check the return boolean) + +comment(// alternatively, Ant has a move task:) +comment(// http://ant.apache.org/manual/CoreTasks/move.html) + +comment(//helper methods) +keyword(def) method(checkSuccessfulCopyAndDelete)operator(()(\)) operator({) + keyword(assert) ident(to)operator(.)ident(text) operator(==) ident(dummyContent) + keyword(assert) ident(to)operator(.)ident(delete)operator(()(\)) + keyword(assert) operator(!)ident(to)operator(.)ident(exists)operator(()(\)) +(}) +keyword(def) method(setUpFromFile)operator(()(\)) operator({) + ident(from) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// just a name) + ident(from) operator(<)operator(<) ident(dummyContent) comment(// now its a real file with content) + ident(from)operator(.)ident(deleteOnExit)operator(()(\)) comment(// that will be deleted on exit) +(}) +keyword(def) method(setUpToFile)operator(()(\)) operator({) + ident(to) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// target name) + ident(to)operator(.)ident(delete)operator(()(\)) comment(// ensure not left from previous aborted run) + keyword(assert) operator(!)ident(to)operator(.)ident(exists)operator(()(\)) comment(// double check) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.4) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy (because of its Java heritage\) doesn't have an exact) +comment(// equivalent of stat - as per 9.2 there are numerous mechanisms) +comment(// to achieve the equivalent, in particular, JSR203 (still in draft\)) +comment(// has specific SymLink support including a FileId class in the) +comment(// java.nio.filesystems package. This will allow (depending on the) +comment(// operating system capabilities\) files to be uniquely identified.) +comment(// If you work on Unix or Linux then you'll recognize this as it device/inode.) + +comment(// If you are not interested in the above workarounds/future features) +comment(// and you are on a unix system, you can compare the absolutePath and) +comment(// canonicalPath attributes for a file. If they are different it is) +comment(// a symbolic link. On other operating systems, this difference is not) +comment(// to be relied upon and even on *nix systems, this will only get you) +comment(// so far and will also be relatively expensive resource and timewise.) + +comment(// process only unique files) +ident(seen) operator(=) type([]) +keyword(def) method(myProcessing)operator(()ident(file)(\)) operator({) + keyword(def) ident(path) operator(=) ident(file)operator(.)ident(canonicalPath) + keyword(if) operator(()operator(!)ident(seen)operator(.)ident(contains)operator(()ident(path)(\)\)) operator({) + ident(seen) operator(<)operator(<) ident(path) + comment(// do something with file because we haven't seen it before) + (}) +(}) + +comment(// find linked files) +ident(seen) operator(=) operator([)operator(:)(]) +ident(filenames) operator(=) operator([)stringoperator(,)stringoperator(,)string(]) +ident(filenames)operator(.)ident(each)operator({) ident(filename) operator(->) + keyword(def) ident(file) operator(=) keyword(new) pre_type(File)operator(()ident(filename)(\)) + keyword(def) ident(cpath) operator(=) ident(file)operator(.)ident(canonicalPath) + keyword(if) operator(()operator(!)ident(seen)operator(.)ident(containsKey)operator(()ident(cpath)(\)\)) operator({) + ident(seen)operator([)ident(cpath)(]) operator(=) type([]) + (}) + ident(seen)operator([)ident(cpath)(]) operator(+=) ident(file)operator(.)ident(absolutePath) +(}) + +ident(println) string +ident(println) ident(seen)operator(.)ident(findAll)operator({) ident(k)operator(,)ident(v) operator(->) ident(v)operator(.)ident(size)operator(()(\)) operator(>) integer(1) (}) +comment(//---------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.5) +comment(//----------------------------------------------------------------------------------) +comment(// general pattern is:) +comment(// new File('dirname'\).eachFile{ /* do something ... */ }) + +comment(// setup (change this on your system\)) +ident(basedir) operator(=) string + +comment(// process all files printing out full name (. and .. auto excluded\)) +keyword(new) pre_type(File)operator(()ident(basedir)(\))operator(.)ident(eachFile)operator({) ident(f)operator(->) + keyword(if) operator(()ident(f)operator(.)ident(isFile)operator(()(\)\)) ident(println) ident(f)operator(.)ident(canonicalPath) +(}) +comment(// also remove dot files such as '.svn' and '.cvs' etc.) +keyword(new) pre_type(File)operator(()ident(basedir)(\))operator(.)ident(eachFileMatch)operator(()operator(~)string(\))operator({) ident(f)operator(->) + keyword(if) operator(()ident(f)operator(.)ident(isFile)operator(()(\)\)) ident(println) ident(f)operator(.)ident(canonicalPath) +(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.6) +comment(//----------------------------------------------------------------------------------) +comment(// Globbing via Apache Jakarta ORO) +keyword(import) include(org.apache.oro.io.GlobFilenameFilter) +ident(dir) operator(=) keyword(new) pre_type(File)operator(()ident(basedir)(\)) +ident(namelist) operator(=) ident(dir)operator(.)ident(list)operator(()keyword(new) ident(GlobFilenameFilter)operator(()string(\)\)) +ident(filelist) operator(=) ident(dir)operator(.)ident(listFiles)operator(()keyword(new) ident(GlobFilenameFilter)operator(()string(\)) keyword(as) pre_type(FilenameFilter)(\)) + +comment(// Built-in matching using regex's) +ident(files) operator(=) type([]) +keyword(new) pre_type(File)operator(()ident(basedir)(\))operator(.)ident(eachFileMatch)operator(()operator(~)regexp(\))operator({) ident(f)operator(->) + keyword(if) operator(()ident(f)operator(.)ident(isFile)operator(()(\)\)) ident(files) operator(+=) ident(f) +(}) + +comment(// Using Ant's FileScanner (supports arbitrary nested levels using **\)) +comment(// For more details about Ant FileSets, see here:) +comment(// http://ant.apache.org/manual/CoreTypes/fileset.html) +ident(scanner) operator(=) keyword(new) ident(AntBuilder)operator(()(\))operator(.)ident(fileScanner) operator({) + ident(fileset)operator(()key(dir)operator(:)ident(basedir)(\)) operator({) + ident(include)operator(()key(name)operator(:)string(\)) + ident(include)operator(()key(name)operator(:)string(\)) + ident(exclude)operator(()key(name)operator(:)string(\)) comment(// chaps 10 and above) + ident(exclude)operator(()key(name)operator(:)stringoperator(,) key(unless)operator(:)string(\)) + (}) +(}) +keyword(for) operator(()ident(f) keyword(in) ident(scanner)(\)) operator({) + ident(println) stringdelimiter(")> +(}) + +comment(// find and sort directories with numeric names) +ident(candidateFiles) operator(=) keyword(new) pre_type(File)operator(()ident(basedir)(\))operator(.)ident(listFiles)operator(()(\)) +ident(allDigits) operator(=) operator({) local_variable(it)operator(.)ident(name) operator(=~) regexp (}) +ident(isDir) operator(=) operator({) local_variable(it)operator(.)ident(isDirectory)operator(()(\)) (}) +ident(dirs) operator(=) ident(candidateFiles)operator(.)ident(findAll)operator(()ident(isDir)(\))operator(.)ident(findAll)operator(()ident(allDigits)(\))operator(*.)ident(canonicalPath)operator(.)ident(sort)operator(()(\)) +ident(println) ident(dirs) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.7) +comment(//----------------------------------------------------------------------------------) +comment(// find all files recursively) +ident(dir) operator(=) keyword(new) pre_type(File)operator(()ident(basedir)(\)) +ident(files) operator(=) type([]) +ident(dir)operator(.)ident(eachFileRecurse)operator({) ident(files) operator(+=) local_variable(it) (}) + +comment(// find total size) +ident(sum) operator(=) ident(files)operator(.)ident(sum)operator({) local_variable(it)operator(.)ident(size)operator(()(\)) (}) +ident(println) stringcontent( contains )inlinecontent( bytes)delimiter(")> +comment(// => Pleac/src contains 365676 bytes) + +comment(// find biggest) +ident(biggest) operator(=) ident(files)operator(.)ident(max)operator({) local_variable(it)operator(.)ident(size)operator(()(\)) (}) +ident(println) stringcontent(.name with )inlinecontent( bytes)delimiter(")> +comment(// => Biggest file is pleac6.groovy with 42415 bytes) + +comment(// find most recently modified) +ident(youngest) operator(=) ident(files)operator(.)ident(max)operator({) local_variable(it)operator(.)ident(lastModified)operator(()(\)) (}) +ident(println) stringcontent(.name, changed )inlinedelimiter(")> +comment(// => Most recently modified is pleac9.groovy, changed Tue Jan 09 07:35:39 EST 2007) + +comment(// find all directories) +ident(dir)operator(.)ident(eachDir)operator({) ident(println) string operator(+) local_variable(it)operator(.)ident(name)(}) + +comment(// find all directories recursively) +ident(dir)operator(.)ident(eachFileRecurse)operator({) ident(f) operator(->) keyword(if) operator(()ident(f)operator(.)ident(isDirectory)operator(()(\)\)) ident(println) string operator(+) ident(f)operator(.)ident(canonicalPath)(}) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.8) +comment(//----------------------------------------------------------------------------------) +ident(base) operator(=) keyword(new) pre_type(File)operator(()string(\)) + +comment(// delete using Jakarta Apache Commons IO) +ident(FileUtils)operator(.)ident(deleteDirectory)operator(()ident(base)(\)) + +comment(// delete using Ant, for various options see:) +comment(// http://ant.apache.org/manual/CoreTasks/delete.html) +ident(ant) operator(=) keyword(new) ident(AntBuilder)operator(()(\)) +ident(ant)operator(.)ident(delete)operator(()key(dir)operator(:) ident(base)(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.9) +comment(//----------------------------------------------------------------------------------) +ident(names) operator(=) operator([)stringoperator(,) string(]) +ident(names)operator(.)ident(each)operator({) ident(name) operator(->) keyword(new) pre_type(File)operator(()ident(name)(\))operator(.)ident(renameTo)operator(()keyword(new) pre_type(File)operator(()ident(name) operator(+) string(\)\)) (}) + +comment(// The Groovy way of doing rename using an expr would be to use a closure) +comment(// for the expr:) +comment(// groovySimpleRenameScript:) +doctype(#!/usr/bin/groovy) +comment(// usage rename closure_expr filenames) +ident(op) operator(=) ident(args)operator([)integer(0)(]) +ident(println) ident(op) +ident(files) operator(=) ident(args)operator([)integer(1)operator(..)operator(-)integer(1)(]) +ident(shell) operator(=) keyword(new) ident(GroovyShell)operator(()ident(binding)(\)) +ident(files)operator(.)ident(each)operator({) ident(f) operator(->) + ident(newname) operator(=) ident(shell)operator(.)ident(evaluate)operator(()stringcontent((')inlinecontent('\))delimiter(")>(\)) + keyword(new) pre_type(File)operator(()ident(f)(\))operator(.)ident(renameTo)operator(()keyword(new) pre_type(File)operator(()ident(newname)(\)\)) +(}) + +comment(// this would allow processing such as:) +comment(//% rename "{n -> 'FILE_' + n.toUpperCase(\)}" files) +comment(// with param pleac9.groovy => FILE_PLEAC9.GROOVY) +comment(//% rename "{n -> n.replaceAll(/9/,'nine'\) }" files) +comment(// with param pleac9.groovy => pleacnine.groovy) +comment(// The script could also be modified to take the list of) +comment(// files from stdin if no args were present (not shown\).) + +comment(// The above lets you type any Groovy code, but instead you might) +comment(// decide to provide the user with some DSL-like additions, e.g.) +comment(// adding the following lines into the script:) +ident(sep) operator(=) pre_type(File)operator(.)ident(separator) +ident(ext) operator(=) operator({) string operator(+) local_variable(it)operator(.)ident(tokenize)operator(()string(\))operator([)operator(-)integer(1)(]) (}) +ident(base) operator(=) operator({) keyword(new) pre_type(File)operator(()local_variable(it)(\))operator(.)ident(name) operator(-) ident(ext)operator(()local_variable(it)(\)) (}) +ident(parent) operator(=) operator({) keyword(new) pre_type(File)operator(()local_variable(it)(\))operator(.)ident(parent) (}) +ident(lastModified) operator(=) operator({) keyword(new) pre_type(Date)operator(()keyword(new) pre_type(File)operator(()local_variable(it)(\))operator(.)ident(lastModified)operator(()(\)\)) (}) +comment(// would then allow the following more succinct expressions:) +comment(//% rename "{ n -> parent(n\) + sep + base(n\).reverse(\) + ext(n\) }" files) +comment(// with param Pleac/src/pleac9.groovy => Pleac\\src\\9caelp.groovy) +comment(//% rename "{ n -> base(n\) + '_' + lastModified(n\).year + ext(n\) }" files) +comment(// with param pleac9.groovy => pleac9_07.groovy) + +comment(// As a different alternative, you could hook into Ant's mapper mechanism.) +comment(// You wouldn't normally type in this from the command-line but it could) +comment(// be part of a script, here is an example (excludes the actual rename part\)) +ident(ant) operator(=) keyword(new) ident(AntBuilder)operator(()(\)) +ident(ant)operator(.)ident(pathconvert)operator(()key(property)operator(:)stringoperator(,)key(targetos)operator(:)string(\))operator({) + ident(path)operator(()(\))operator({) ident(fileset)operator(()key(dir)operator(:)stringoperator(,) key(includes)operator(:)string(\)) (}) + ident(compositemapper)operator({) + ident(globmapper)operator(()key(from)operator(:)stringoperator(,) key(to)operator(:)string(\)) + ident(regexpmapper)operator(()key(from)operator(:)regexpoperator(,) key(to)operator(:)regexpoperator(,) key(casesensitive)operator(:)string(\)) + ident(chainedmapper)operator({) + ident(packagemapper)operator(()key(from)operator(:)stringoperator(,) key(to)operator(:)string(\)) + ident(filtermapper)operator(()(\))operator({) ident(replacestring)operator(()key(from)operator(:)stringoperator(,) key(to)operator(:)string(\)) (}) + (}) + ident(chainedmapper)operator({) + ident(regexpmapper)operator(()key(from)operator(:)regexpoperator(,) key(to)operator(:)regexp(\)) + ident(flattenmapper)operator(()(\)) + ident(filtermapper)operator(()(\))operator({) ident(replacestring)operator(()key(from)operator(:)stringoperator(,) key(to)operator(:)string(\)) (}) + (}) + (}) +(}) +ident(println) ident(ant)operator(.)ident(antProject)operator(.)ident(getProperty)operator(()string(\))operator(.)ident(replaceAll)operator(()stringoperator(,)string(\)) +comment(// =>) +comment(// C:\\Projects\\GroovyExamples\\Pleac\\src\\pleac1.groovy.bak) +comment(// C:\\Projects\\GroovyExamples\\Pleac\\src\\pleac2_beta.groovy) +comment(// Projects.GroovyExamples.Pleac.src.3.xml) +comment(// pleac_four.groovy) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.10) +comment(//----------------------------------------------------------------------------------) +comment(// Splitting a Filename into Its Component Parts) +ident(path) operator(=) keyword(new) pre_type(File)operator(()string(\)) +keyword(assert) ident(path)operator(.)ident(parent) operator(==) string operator(+) pre_type(File)operator(.)ident(separator) operator(+) string +keyword(assert) ident(path)operator(.)ident(name) operator(==) string +ident(ext) operator(=) ident(path)operator(.)ident(name)operator(.)ident(tokenize)operator(()string(\))operator([)operator(-)integer(1)(]) +keyword(assert) ident(ext) operator(==) string + +comment(// No fileparse_set_fstype(\) equivalent in Groovy/Java. Java's File constructor) +comment(// automatically performs such a parse and does so appropriately of the operating) +comment(// system it is running on. In addition, 3rd party libraries allow platform) +comment(// specific operations ot be performed. As an example, many Ant tasks are OS) +comment(// aware, e.g. the pathconvert task (callable from an AntBuilder instance\) has) +comment(// a 'targetos' parameter which can be one of 'unix', 'windows', 'netware',) +comment(// 'tandem' or 'os/2'.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.11) +comment(//----------------------------------------------------------------------------------) +comment(// Given the previous discussion regarding the lack of support for symlinks) +comment(// in Java's File class without exec'ing to the operating system or doing) +comment(// a JNI call (at least until JSR 203 arrives\), I have modified this example) +comment(// to perform an actual replica forest of actual file copies rather than) +comment(// a shadow forest full of symlinks pointing back at the real files.) +comment(// Use Apache Jakarta Commons IO) +ident(srcdir) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// path to src) +ident(destdir) operator(=) keyword(new) pre_type(File)operator(()string(\)) comment(// path to dest) +ident(preserveFileStamps) operator(=) keyword(true) +ident(FileUtils)operator(.)ident(copyDirectory)operator(()ident(srcdir)operator(,) ident(destdir)operator(,) ident(preserveFileStamps)(\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_9.12) +comment(//----------------------------------------------------------------------------------) +doctype(#!/usr/bin/groovy) +comment(// lst - list sorted directory contents (depth first\)) +comment(// Given the previous discussion around Java's more limited Date) +comment(// information available via the File class, this will be a reduced) +comment(// functionality version of ls) +ident(LONG_OPTION) operator(=) string +ident(REVERSE_OPTION) operator(=) string +ident(MODIFY_OPTION) operator(=) string +ident(SIZE_OPTION) operator(=) string +ident(HELP_OPTION) operator(=) string + +ident(op) operator(=) keyword(new) ident(joptsimple)operator(.)ident(OptionParser)operator(()(\)) +ident(op)operator(.)ident(accepts)operator(() ident(LONG_OPTION)operator(,) string (\)) +ident(op)operator(.)ident(accepts)operator(() ident(REVERSE_OPTION)operator(,) string (\)) +ident(op)operator(.)ident(accepts)operator(() ident(MODIFY_OPTION)operator(,) string (\)) +ident(op)operator(.)ident(accepts)operator(() ident(SIZE_OPTION)operator(,) string (\)) +ident(op)operator(.)ident(accepts)operator(() ident(HELP_OPTION)operator(,) string (\)) + +ident(options) operator(=) ident(op)operator(.)ident(parse)operator(()ident(args)(\)) +keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(HELP_OPTION) (\)\)) operator({) + ident(op)operator(.)ident(printHelpOn)operator(() pre_type(System)operator(.)ident(out) (\)) +(}) keyword(else) operator({) + ident(sort) operator(=) operator({)(}) + ident(params) operator(=) ident(options)operator(.)ident(nonOptionArguments)operator(()(\)) + ident(longFormat) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(LONG_OPTION) (\)) + ident(reversed) operator(=) ident(options)operator(.)ident(wasDetected)operator(() ident(REVERSE_OPTION) (\)) + keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(SIZE_OPTION) (\)\)) operator({) + ident(sort) operator(=) operator({)ident(a)operator(,)ident(b) operator(->) ident(a)operator(.)ident(size)operator(()(\))operator(<=)operator(>)ident(b)operator(.)ident(size)operator(()(\)}) + (}) keyword(else) keyword(if) operator(()ident(options)operator(.)ident(wasDetected)operator(() ident(MODIFY_OPTION) (\)\)) operator({) + ident(sort) operator(=) operator({)ident(a)operator(,)ident(b) operator(->) ident(a)operator(.)ident(lastModified)operator(()(\))operator(<=)operator(>)ident(b)operator(.)ident(lastModified)operator(()(\)}) + (}) + ident(displayFiles)operator(()ident(params)operator(,) ident(longFormat)operator(,) ident(reversed)operator(,) ident(sort)(\)) +(}) + +keyword(def) method(displayFiles)operator(()ident(params)operator(,) ident(longFormat)operator(,) ident(reversed)operator(,) ident(sort)(\)) operator({) + ident(files) operator(=) type([]) + ident(params)operator(.)ident(each)operator({) ident(name) operator(->) keyword(new) pre_type(File)operator(()ident(name)(\))operator(.)ident(eachFileRecurse)operator({) ident(files) operator(+=) local_variable(it) (}) (}) + ident(files)operator(.)ident(sort)operator(()ident(sort)(\)) + keyword(if) operator(()ident(reversed)(\)) ident(files) operator(=) ident(files)operator(.)ident(reverse)operator(()(\)) + ident(files)operator(.)ident(each) operator({) ident(file) operator(->) + keyword(if) operator(()ident(longFormat)(\)) operator({) + ident(print) operator(()ident(file)operator(.)ident(directory) operator(?) string operator(:) string (\)) + ident(print) operator(()ident(file)operator(.)ident(canRead)operator(()(\)) operator(?) string operator(:) string (\)) + ident(print) operator(()ident(file)operator(.)ident(canWrite)operator(()(\)) operator(?) string operator(:) string (\)) + comment(//print (file.canExecute(\) ? 'x' : '-' \) // Java 6) + ident(print) ident(file)operator(.)ident(size)operator(()(\))operator(.)ident(toString)operator(()(\))operator(.)ident(padLeft)operator(()integer(12)(\)) operator(+) string + ident(print) keyword(new) pre_type(Date)operator(()ident(file)operator(.)ident(lastModified)operator(()(\)\))operator(.)ident(toString)operator(()(\))operator(.)ident(padRight)operator(()integer(22)(\)) + ident(println) string operator(+) ident(file) + (}) keyword(else) operator({) + ident(println) ident(file) + (}) + (}) +(}) + +comment(// =>) +comment(// % lst -help) +comment(// Option Description) +comment(// ------ -------------------------------) +comment(// --help display this message) +comment(// -l long listing) +comment(// -m sort based on modification time) +comment(// -r reverse listing) +comment(// -s sort based on size) +comment(//) +comment(// % lst -l -m Pleac/src Pleac/lib) +comment(// ...) +comment(// drw 0 Mon Jan 08 22:33:00 EST 2007 Pleac\\lib\\.svn) +comment(// -rw 18988 Mon Jan 08 22:33:41 EST 2007 Pleac\\src\\pleac9.groovy) +comment(// -rw 2159 Mon Jan 08 23:15:41 EST 2007 Pleac\\src\\lst.groovy) +comment(//) +comment(// % -l -s -r Pleac/src Pleac/lib) +comment(// -rw 1034049 Sun Jan 07 19:24:41 EST 2007 Pleac\\lib\\ant.jar) +comment(// -r- 1034049 Sun Jan 07 19:40:27 EST 2007 Pleac\\lib\\.svn\\text-base\\ant.jar.svn-base) +comment(// -rw 421008 Thu Jun 02 15:15:34 EST 2005 Pleac\\lib\\ant-nodeps.jar) +comment(// -rw 294436 Sat Jan 06 21:19:58 EST 2007 Pleac\\lib\\geronimo-javamail_1.3.1_mail-1.0.jar) +comment(// ...) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_10.0) +comment(//----------------------------------------------------------------------------------) +keyword(def) method(hello)operator(()(\)) operator({) + ident(greeted) operator(+=) integer(1) + ident(println) string +(}) + +comment(// We need to initialize greeted before it can be used, because "+=" assumes predefinition) +ident(greeted) operator(=) integer(0) +ident(hello)operator(()(\)) +ident(println) ident(greeted) +comment(// =>) +comment(// hi there) +comment(// 1) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.1) +comment(//----------------------------------------------------------------------------------) +comment(// basic method calling examples) +comment(// In Groovy, parameters are named anyway) +keyword(def) method(hypotenuse)operator(()ident(side1)operator(,) ident(side2)(\)) operator({) + pre_type(Math)operator(.)ident(sqrt)operator(()ident(side1)operator(**)integer(2) operator(+) ident(side2)operator(**)integer(2)(\)) comment(// sqrt in Math package) +(}) +ident(diag) operator(=) ident(hypotenuse)operator(()integer(3)operator(,) integer(4)(\)) +keyword(assert) ident(diag) operator(==) integer(5) + +comment(// the star operator will magically convert an Array into a "tuple") +ident(a) operator(=) operator([)integer(5)operator(,) integer(12)(]) +keyword(assert) ident(hypotenuse)operator(()operator(*)ident(a)(\)) operator(==) integer(13) + +comment(// both = men + women) + +comment(// In Groovy, all objects are references, so the same problem arises.) +comment(// Typically we just return a new object. Especially for immutable objects) +comment(// this style of processing is very common.) +ident(nums) operator(=) operator([)float(1.4)operator(,) float(3.5)operator(,) float(6.7)(]) +keyword(def) method(toInteger)operator(()ident(n)(\)) operator({) + ident(n)operator(.)ident(collect) operator({) ident(v) operator(->) ident(v)operator(.)ident(toInteger)operator(()(\)) (}) +(}) +keyword(assert) ident(toInteger)operator(()ident(nums)(\)) operator(==) operator([)integer(1)operator(,) integer(3)operator(,) integer(6)(]) + +ident(orignums) operator(=) operator([)float(1.4)operator(,) float(3.5)operator(,) float(6.7)(]) +keyword(def) method(truncMe)operator(()ident(n)(\)) operator({) + operator(()integer(0)operator(..<)ident(n)operator(.)ident(size)operator(()(\)\))operator(.)ident(each)operator({) ident(idx) operator(->) ident(n)operator([)ident(idx)(]) operator(=) ident(n)operator([)ident(idx)(])operator(.)ident(toInteger)operator(()(\)) (}) +(}) +ident(truncMe)operator(()ident(orignums)(\)) +keyword(assert) ident(orignums) operator(==) operator([)integer(1)operator(,) integer(3)operator(,) integer(6)(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.2) +comment(//----------------------------------------------------------------------------------) +comment(// variable scope examples) +keyword(def) method(somefunc)operator(()(\)) operator({) + keyword(def) ident(variableInMethod) comment(// private is default in a method) +(}) + +keyword(def) ident(name) comment(// private is default for variable in a script) + +ident(bindingVar) operator(=) integer(10) comment(// this will be in the binding (sort of global\)) +ident(globalArray) operator(=) type([]) + +comment(// In Groovy, run_check can't access a, b, or c until they are) +comment(// explicitely defined global (using leading $\), even if they are) +comment(// both defined in the same scope) + +keyword(def) method(checkAccess)operator(()ident(x)(\)) operator({) + keyword(def) ident(y) operator(=) integer(200) + keyword(return) ident(x) operator(+) ident(y) operator(+) ident(bindingVar) comment(// access private, param, global) +(}) +keyword(assert) ident(checkAccess)operator(()integer(7)(\)) operator(==) integer(217) + +keyword(def) method(saveArray)operator(()ident(ary)(\)) operator({) + ident(globalArray) operator(<)operator(<) string + ident(globalArray) operator(+=) ident(ary) +(}) + +ident(saveArray)operator(()operator([)string(]\)) +keyword(assert) ident(globalArray) operator(==) operator([)stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.3) +comment(//----------------------------------------------------------------------------------) +comment(// you want a private persistent variable within a script method) + +comment(// you could use a helper class for this) +type(class) class(CounterHelper) operator({) + directive(private) directive(static) ident(counter) operator(=) integer(0) + keyword(def) directive(static) method(next)operator(()(\)) operator({) operator(++)ident(counter) (}) +(}) +keyword(def) method(greeting)operator(()ident(s)(\)) operator({) + keyword(def) ident(n) operator(=) ident(CounterHelper)operator(.)ident(next)operator(()(\)) + ident(println) stringcontent( (I have been called )inlinecontent( times\))delimiter(")> +(}) +ident(greeting)operator(()string(\)) +ident(greeting)operator(()string(\)) +ident(greeting)operator(()string(\)) +comment(// =>) +comment(// Hello tom (I have been called 1 times\)) +comment(// Hello dick (I have been called 2 times\)) +comment(// Hello harry (I have been called 3 times\)) + +comment(// you could make it more fancy by having separate keys,) +comment(// using synchronisation, singleton pattern, ThreadLocal, ...) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_10.4) +comment(//----------------------------------------------------------------------------------) +comment(// Determining Current Method Name) +comment(// Getting class, package and static info is easy. Method info is just a little work.) +comment(// From Java we can use:) +comment(// new Exception(\).stackTrace[0].methodName) +comment(// or for Java 5 and above (saves relatively expensive exception creation\)) +comment(// Thread.currentThread(\).stackTrace[3].methodName) +comment(// But these give the Java method name. Groovy wraps its own runtime) +comment(// system over the top. It's still a Java method, just a little bit further up the) +comment(// stack from where we might expect. Getting the Groovy method name can be done in) +comment(// an implementation specific way (subject to change as the language evolves\):) +keyword(def) method(myMethod)operator(()(\)) operator({) + ident(names) operator(=) keyword(new) pre_type(Exception)operator(()(\))operator(.)ident(stackTrace)operator(*.)ident(methodName) + ident(println) ident(groovyUnwrap)operator(()ident(names)(\)) +(}) +keyword(def) method(myMethod2)operator(()(\)) operator({) + ident(names) operator(=) pre_type(Thread)operator(.)ident(currentThread)operator(()(\))operator(.)ident(stackTrace)operator(*.)ident(methodName) + ident(names) operator(=) ident(names)operator([)integer(3)operator(..<)ident(names)operator(.)ident(size)operator(()(\)]) comment(// skip call to dumpThread) + ident(println) ident(groovyUnwrap)operator(()ident(names)(\)) +(}) +keyword(def) method(groovyUnwrap)operator(()ident(names)(\)) operator({) ident(names)operator([)ident(names)operator(.)ident(indexOf)operator(()string(\))operator(-)integer(1)(]) (}) +ident(myMethod)operator(()(\)) comment(// => myMethod) +ident(myMethod2)operator(()(\)) comment(// => myMethod2) + +comment(// Discussion: If what you really wanted was a tracing mechanism, you could overrie) +comment(// invokeMethod and print out method names before calling the original method. Or) +comment(// you could use one of the Aspect-Oriented Programming packages for Java.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.5) +comment(//----------------------------------------------------------------------------------) +comment(// Passing Arrays and Hashes by Reference) +comment(// In Groovy, every value is a reference to an object, thus there is) +comment(// no such problem, just call: arrayDiff(array1, array2\)) + +comment(// pairwise add (altered so it doesn't require equal sizes\)) +keyword(def) method(pairWiseAdd)operator(()ident(a1)operator(,) ident(a2)(\)) operator({) + ident(s1) operator(=) ident(a1)operator(.)ident(size)operator(()(\))operator(;) ident(s2) operator(=) ident(a2)operator(.)ident(size)operator(()(\)) + operator(()integer(0)operator(..<)operator([)ident(s1)operator(,)ident(s2)(])operator(.)ident(max)operator(()(\)\))operator(.)ident(collect)operator({) + local_variable(it) operator(>) ident(s1)operator(-)integer(1) operator(?) ident(a2)operator([)local_variable(it)(]) operator(:) operator(()local_variable(it) operator(>) ident(s2)operator(-)integer(1) operator(?) ident(a1)operator([)local_variable(it)(]) operator(:) ident(a1)operator([)local_variable(it)(]) operator(+) ident(a2)operator([)local_variable(it)(]\)) + (}) +(}) +ident(a) operator(=) operator([)integer(1)operator(,) integer(2)(]) +ident(b) operator(=) operator([)integer(5)operator(,) integer(8)(]) +keyword(assert) ident(pairWiseAdd)operator(()ident(a)operator(,) ident(b)(\)) operator(==) operator([)integer(6)operator(,) integer(10)(]) + +comment(// also works for unequal sizes) +ident(b) operator(=) operator([)integer(5)operator(,) integer(8)operator(,) operator(-)integer(1)(]) +keyword(assert) ident(pairWiseAdd)operator(()ident(a)operator(,) ident(b)(\)) operator(==) operator([)integer(6)operator(,) integer(10)operator(,) operator(-)integer(1)(]) +ident(b) operator(=) operator([)integer(5)(]) +keyword(assert) ident(pairWiseAdd)operator(()ident(a)operator(,) ident(b)(\)) operator(==) operator([)integer(6)operator(,) integer(2)(]) + +comment(// We could check if both arguments were of a particular type, e.g.) +comment(// (a1 instanceof List\) or (a2.class.isArray(\)\) but duck typing allows) +comment(// it to work on other things as well, so while wouldn't normally do this) +comment(// you do need to be a little careful when calling the method, e.g.) +comment(// here we call it with two maps of strings and get back strings) +comment(// the important thing here was that the arguments were indexed) +comment(// 0..size-1 and that the items supported the '+' operator (as String does\)) +ident(a) operator(=) operator([)integer(0)operator(:)stringoperator(,) integer(1)operator(:)string(]) +ident(b) operator(=) operator([)integer(0)operator(:)stringoperator(,) integer(1)operator(:)stringoperator(,) integer(2)operator(:)string(]) +keyword(assert) ident(pairWiseAdd)operator(()ident(a)operator(,) ident(b)(\)) operator(==) operator([)stringoperator(,) stringoperator(,) string(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.6) +comment(//----------------------------------------------------------------------------------) +comment(// Detecting Return Context) +comment(// There is no exact equivalent of return context in Groovy but) +comment(// you can behave differently when called under different circumstances) +keyword(def) method(addValueOrSize)operator(()ident(a1)operator(,) ident(a2)(\)) operator({) + ident(b1) operator(=) operator(()ident(a1) keyword(instanceof) pre_type(Number)(\)) operator(?) ident(a1) operator(:) ident(a1)operator(.)ident(size)operator(()(\)) + ident(b2) operator(=) operator(()ident(a2) keyword(instanceof) pre_type(Number)(\)) operator(?) ident(a2) operator(:) ident(a2)operator(.)ident(size)operator(()(\)) + ident(b1) operator(+) ident(b2) +(}) +keyword(assert) operator(()ident(addValueOrSize)operator(()integer(10)operator(,) string(\)\)) operator(==) integer(14) +keyword(assert) operator(()ident(addValueOrSize)operator(()integer(10)operator(,) operator([)integer(25)operator(,) integer(50)(]\)\)) operator(==) integer(12) +keyword(assert) operator(()ident(addValueOrSize)operator(()stringoperator(,) operator([)integer(25)operator(,) integer(50)(]\)\)) operator(==) integer(5) +keyword(assert) operator(()ident(addValueOrSize)operator(()integer(25)operator(,) integer(50)(\)\)) operator(==) integer(75) + +comment(// Of course, a key feature of many OO languages including Groovy is) +comment(// method overloading so that responding to dofferent parameters has) +comment(// a formal way of being captured in code with typed methods, e.g.) +type(class) class(MakeBiggerHelper) operator({) + keyword(def) method(triple)operator(()pre_type(List) ident(iList)(\)) operator({) ident(iList)operator(.)ident(collect)operator({) local_variable(it) operator(*) integer(3) (}) (}) + keyword(def) method(triple)operator(()type(int) ident(i)(\)) operator({) ident(i) operator(*) integer(3) (}) +(}) +ident(mbh) operator(=) keyword(new) ident(MakeBiggerHelper)operator(()(\)) +keyword(assert) ident(mbh)operator(.)ident(triple)operator(()operator([)integer(4)operator(,) integer(5)(]\)) operator(==) operator([)integer(12)operator(,) integer(15)(]) +keyword(assert) ident(mbh)operator(.)ident(triple)operator(()integer(4)(\)) operator(==) integer(12) + +comment(// Of course with duck typing, we can rely on dynamic typing if we want) +keyword(def) method(directTriple)operator(()ident(arg)(\)) operator({) + operator(()ident(arg) keyword(instanceof) pre_type(Number)(\)) operator(?) ident(arg) operator(*) integer(3) operator(:) ident(arg)operator(.)ident(collect)operator({) local_variable(it) operator(*) integer(3) (}) +(}) +keyword(assert) ident(directTriple)operator(()operator([)integer(4)operator(,) integer(5)(]\)) operator(==) operator([)integer(12)operator(,) integer(15)(]) +keyword(assert) ident(directTriple)operator(()integer(4)(\)) operator(==) integer(12) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.7) +comment(//----------------------------------------------------------------------------------) +comment(// Passing by Named Parameter) +comment(// Groovy supports named params or positional arguments with optional) +comment(// defaults to simplify method calling) + +comment(// named arguments work by using a map) +keyword(def) method(thefunc)operator(()pre_type(Map) ident(args)(\)) operator({) + comment(// in this example, we just call the positional version) + ident(thefunc)operator(()ident(args)operator(.)ident(start)operator(,) ident(args)operator(.)ident(end)operator(,) ident(args)operator(.)ident(step)(\)) +(}) + +comment(// positional arguments with defaults) +keyword(def) method(thefunc)operator(()ident(start)operator(=)integer(0)operator(,) ident(end)operator(=)integer(30)operator(,) ident(step)operator(=)integer(10)(\)) operator({) + operator(()operator(()ident(start)operator(..)ident(end)(\))operator(.)ident(step)operator(()ident(step)(\)\)) +(}) + +keyword(assert) ident(thefunc)operator(()(\)) operator(==) operator([)integer(0)operator(,) integer(10)operator(,) integer(20)operator(,) integer(30)(]) +keyword(assert) ident(thefunc)operator(()integer(15)(\)) operator(==) operator([)integer(15)operator(,) integer(25)(]) +keyword(assert) ident(thefunc)operator(()integer(0)operator(,)integer(40)(\)) operator(==) operator([)integer(0)operator(,) integer(10)operator(,) integer(20)operator(,) integer(30)operator(,) integer(40)(]) +keyword(assert) ident(thefunc)operator(()key(start)operator(:)integer(5)operator(,) key(end)operator(:)integer(20)operator(,) key(step)operator(:)integer(5)(\)) operator(==) operator([)integer(5)operator(,) integer(10)operator(,) integer(15)operator(,) integer(20)(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.8) +comment(//----------------------------------------------------------------------------------) +comment(// Skipping Selected Return Values) +comment(// Groovy 1.0 doesn't support multiple return types, so you always use) +comment(// a holder class, array or collection to return multiple values.) +keyword(def) method(getSystemInfo)operator(()(\)) operator({) + keyword(def) ident(millis) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) + keyword(def) ident(freemem) operator(=) pre_type(Runtime)operator(.)ident(runtime)operator(.)ident(freeMemory)operator(()(\)) + keyword(def) ident(version) operator(=) pre_type(System)operator(.)ident(getProperty)operator(()string(\)) + keyword(return) operator([)key(millis)operator(:)ident(millis)operator(,) key(freemem)operator(:)ident(freemem)operator(,) key(version)operator(:)ident(version)(]) + comment(// if you are likely to want all the information use a list) + comment(// return [millis, freemem, version]) + comment(// or dedicated holder class) + comment(// return new SystemInfo(millis, freemem, version\)) +(}) +ident(result) operator(=) ident(getSystemInfo)operator(()(\)) +ident(println) ident(result)operator(.)ident(version) +comment(// => 1.5.0_08-b03) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.9) +comment(//----------------------------------------------------------------------------------) +comment(// Returning More Than One Array or Hash) +comment(// As per 10.8, Groovy 1.0 doesn't support multiple return types but you) +comment(// just use a holder class, array or collection. There are no limitations) +comment(// on returning arbitrary nested values using this technique.) +keyword(def) method(getInfo)operator(()(\)) operator({) + keyword(def) ident(system) operator(=) operator([)key(millis)operator(:)pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\))operator(,) + key(version)operator(:)pre_type(System)operator(.)ident(getProperty)operator(()string(\)]) + keyword(def) ident(runtime) operator(=) operator([)key(freemem)operator(:)pre_type(Runtime)operator(.)ident(runtime)operator(.)ident(freeMemory)operator(()(\))operator(,) + key(maxmem)operator(:)pre_type(Runtime)operator(.)ident(runtime)operator(.)ident(maxMemory)operator(()(\)]) + keyword(return) operator([)key(system)operator(:)ident(system)operator(,) key(runtime)operator(:)ident(runtime)(]) +(}) +ident(println) ident(info)operator(.)ident(runtime)operator(.)ident(maxmem) comment(// => 66650112 (info automatically calls getInfo(\) here\)) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.10) +comment(//----------------------------------------------------------------------------------) +comment(// Returning Failure) +comment(// This is normally done in a heavy-weight way via Java Exceptions) +comment(// (see 10.12\) or in a lightweight way by returning null) +keyword(def) method(sizeMinusOne)operator(()ident(thing)(\)) operator({) + keyword(if) operator(()ident(thing) keyword(instanceof) pre_type(Number)(\)) keyword(return) + ident(thing)operator(.)ident(size)operator(()(\)) operator(-) integer(1) +(}) +keyword(def) method(check)operator(()ident(thing)(\)) operator({) + ident(result) operator(=) ident(sizeMinusOne)operator(()ident(thing)(\)) + ident(println) operator(()ident(result) operator(?) stringdelimiter(")> operator(:) string(\)) +(}) +ident(check)operator(()integer(4)(\)) +ident(check)operator(()operator([)integer(1)operator(,) integer(2)(]\)) +ident(check)operator(()string(\)) +comment(// =>) +comment(// Failed) +comment(// Worked with result: 1) +comment(// Worked with result: 2) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.11) +comment(//----------------------------------------------------------------------------------) +comment(// Prototyping Functions: Not supported by Groovy but arguably) +comment(// not important given other language features.) + +comment(// Omitting Parentheses Scenario: Groovy only lets you leave out) +comment(// parentheses in simple cases. If you had two methods sum(a1,a2,a3\)) +comment(// and sum(a1,a2\), there would be no way to indicate that whether) +comment(// 'sum sum 2, 3, 4, 5' meant sum(sum(2,3\),4,5\) or sum(sum(2,3,4\),5\).) +comment(// You would have to include the parentheses. Groovy does much less) +comment(// auto flattening than some other languages; it provides a *args) +comment(// operator, varargs style optional params and supports method) +comment(// overloading and ducktyping. Perhaps these other features mean) +comment(// that this scenario is always easy to avoid.) +keyword(def) method(sum)operator(()ident(a)operator(,)ident(b)operator(,)ident(c)(\))operator({) ident(a)operator(+)ident(b)operator(+)ident(c)operator(*)integer(2) (}) +keyword(def) method(sum)operator(()ident(a)operator(,)ident(b)(\))operator({) ident(a)operator(+)ident(b) (}) +comment(// sum sum 1,2,4,5) +comment(// => compilation error) +ident(sum) ident(sum)operator(()integer(1)operator(,)integer(2)(\))operator(,)integer(4)operator(,)integer(5) +ident(sum) ident(sum)operator(()integer(1)operator(,)integer(2)operator(,)integer(4)(\))operator(,)integer(5) +comment(// these work but if you try to do anything fancy you will run into trouble;) +comment(// your best bet is to actually include all the parentheses:) +ident(println) ident(sum)operator(()ident(sum)operator(()integer(1)operator(,)integer(2)(\))operator(,)integer(4)operator(,)integer(5)(\)) comment(// => 17) +ident(println) ident(sum)operator(()ident(sum)operator(()integer(1)operator(,)integer(2)operator(,)integer(4)(\))operator(,)integer(5)(\)) comment(// => 16) + +comment(// Mimicking built-ins scenario: this is a mechanism to turn-off) +comment(// auto flattening, Groovy only does flattening in restricted circumstances.) +comment(// func(array, 1, 2, 3\) is never coerced into a single list but varargs) +comment(// and optional args can be used instead) +keyword(def) method(push)operator(()ident(list)operator(,) pre_type(Object)type([]) ident(optionals)(\)) operator({) + ident(optionals)operator(.)ident(each)operator({) ident(list)operator(.)ident(add)operator(()local_variable(it)(\)) (}) +(}) +ident(items) operator(=) operator([)integer(1)operator(,)integer(2)(]) +ident(newItems) operator(=) operator([)integer(7)operator(,) integer(8)operator(,) integer(9)(]) +ident(push) ident(items)operator(,) integer(3)operator(,) integer(4) +ident(push) ident(items)operator(,) integer(6) +ident(push) operator(()ident(items)operator(,) operator(*)ident(newItems)(\)) comment(// brackets currently required, *=flattening) + comment(// without *: items = [1, 2, 3, 4, 6, [7, 8, 9]]) +keyword(assert) ident(items) operator(==) operator([)integer(1)operator(,) integer(2)operator(,) integer(3)operator(,) integer(4)operator(,) integer(6)operator(,) integer(7)operator(,) integer(8)operator(,) integer(9)(]) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.12) +comment(//----------------------------------------------------------------------------------) +comment(// Handling Exceptions) +comment(// Same story as in Java but Groovy has some nice Checked -> Unchecked) +comment(// magic behind the scenes (Java folk will know what this means\)) +comment(// When writing methods:) +comment(// throw exception to raise it) +comment(// When calling methods:) +comment(// try ... catch ... finally surrounds processing logic) +keyword(def) method(getSizeMostOfTheTime)operator(()ident(s)(\)) operator({) + keyword(if) operator(()ident(s) operator(=~) string(\)) keyword(throw) keyword(new) pre_type(RuntimeException)operator(()string(\)) + ident(s)operator(.)ident(size)operator(()(\)) +(}) +keyword(try) operator({) + ident(println) string operator(+) ident(getSizeMostOfTheTime)operator(()string(\)) + ident(println) string operator(+) ident(getSizeMostOfTheTime)operator(()string(\)) +(}) keyword(catch) operator(()pre_type(Exception) ident(ex)(\)) operator({) + ident(println) stringcontent(.message)delimiter(")> +(}) keyword(finally) operator({) + ident(println) string +(}) +comment(// =>) +comment(// Size is: 19) +comment(// Error was: The world is ending) +comment(// Doing common cleanup) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.13) +comment(//----------------------------------------------------------------------------------) +comment(// Saving Global Values) +comment(// We can just save the value and restore it later:) +keyword(def) method(printAge)operator(()(\)) operator({) ident(println) stringdelimiter(")> (}) + +ident(age) operator(=) integer(18) comment(// binding "global" variable) +ident(printAge)operator(()(\)) comment(// => 18) + +keyword(if) operator(()ident(age) operator(>) integer(0)(\)) operator({) + keyword(def) ident(origAge) operator(=) ident(age) + ident(age) operator(=) integer(23) + ident(printAge)operator(()(\)) comment(// => 23) + ident(age) operator(=) ident(origAge) +(}) +ident(printAge)operator(()(\)) comment(// => 18) + +comment(// Depending on the circmstances we could enhance this in various ways) +comment(// such as synchronizing, surrounding with try ... finally, using a) +comment(// memento pattern, saving the whole binding, using a ThreadLocal ...) + +comment(// There is no need to use local(\) for filehandles or directory) +comment(// handles in Groovy because filehandles are normal objects.) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.14) +comment(//----------------------------------------------------------------------------------) +comment(// Redefining a Function) +comment(// This can be done via a number of ways:) + +comment(// OO approach:) +comment(// The standard trick using OO is to override methods in subclasses) +type(class) class(Parent) operator({) keyword(def) method(foo)operator(()(\))operator({) ident(println) string (}) (}) +type(class) class(Child) directive(extends) ident(Parent) operator({) keyword(def) method(foo)operator(()(\))operator({) ident(println) string (}) (}) +keyword(new) ident(Parent)operator(()(\))operator(.)ident(foo)operator(()(\)) comment(// => foo) +keyword(new) ident(Child)operator(()(\))operator(.)ident(foo)operator(()(\)) comment(// => bar) + +comment(// Category approach:) +comment(// If you want to redefine a method from an existing library) +comment(// you can use categories. This can be done to avoid name conflicts) +comment(// or to patch functionality with local mods without changing) +comment(// original code) +ident(println) keyword(new) pre_type(Date)operator(()(\))operator(.)ident(toString)operator(()(\)) +comment(// => Sat Jan 06 16:44:55 EST 2007) +type(class) class(DateCategory) operator({) + directive(static) ident(toString)operator(()pre_type(Date) ident(self)(\)) operator({) string (}) +(}) +ident(use) operator(()ident(DateCategory)(\)) operator({) + ident(println) keyword(new) pre_type(Date)operator(()(\))operator(.)ident(toString)operator(()(\)) +(}) +comment(// => not telling) + +comment(// Closure approach:) +comment(// Groovy's closures let you have "anonymous methods" as objects.) +comment(// This allows you to be very flexible with "method" redefinition, e.g.:) +ident(colors) operator(=) stringoperator(.)ident(split)operator(()string(\))operator(.)ident(toList)operator(()(\)) +ident(color2html) operator(=) keyword(new) ident(Expando)operator(()(\)) +ident(colors)operator(.)ident(each) operator({) ident(c) operator(->) + ident(color2html)operator([)ident(c)(]) operator(=) operator({) ident(args) operator(->) string)inlinecontent()delimiter(")> (}) +(}) +ident(println) ident(color2html)operator(.)ident(yellow)operator(()string(\)) +comment(// => error) +ident(color2html)operator(.)ident(yellow) operator(=) operator({) ident(args) operator(->) string)inlinecontent()delimiter(")> (}) comment(// too hard to see yellow) +ident(println) ident(color2html)operator(.)ident(yellow)operator(()string(\)) +comment(// => error) + +comment(// Other approaches:) +comment(// you could use invokeMethod to intercept the original method and call) +comment(// your modified method on just particular input data) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.15) +comment(//----------------------------------------------------------------------------------) +comment(// Trapping Undefined Function Calls) +type(class) class(FontHelper) operator({) + comment(// we could define all the important colors explicitly like this) + keyword(def) method(pink)operator(()ident(info)(\)) operator({) + ident(buildFont)operator(()stringoperator(,) ident(info)(\)) + (}) + comment(// but this method will catch any undefined ones) + keyword(def) method(invokeMethod)operator(()pre_type(String) ident(name)operator(,) pre_type(Object) ident(args)(\)) operator({) + ident(buildFont)operator(()ident(name)operator(,) ident(args)operator(.)ident(join)operator(()string(\)\)) + (}) + keyword(def) method(buildFont)operator(()ident(name)operator(,) ident(info)(\)) operator({) + string)delimiter(")> operator(+) ident(info) operator(+) string)delimiter(")> + (}) +(}) +ident(fh) operator(=) keyword(new) ident(FontHelper)operator(()(\)) +ident(println) ident(fh)operator(.)ident(pink)operator(()string(\)) +ident(println) ident(fh)operator(.)ident(chartreuse)operator(()stringoperator(,) string(\)) +comment(// =>) +comment(// panther) +comment(// stuff and more stuff) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.16) +comment(//----------------------------------------------------------------------------------) +comment(// Simulating Nested Subroutimes: Using Closures within Methods) +keyword(def) method(outer)operator(()ident(arg)(\)) operator({) + keyword(def) ident(x) operator(=) ident(arg) operator(+) integer(35) + ident(inner) operator(=) operator({) ident(x) operator(*) integer(19) (}) + ident(x) operator(+) ident(inner)operator(()(\)) +(}) +keyword(assert) ident(outer)operator(()integer(10)(\)) operator(==) integer(900) +comment(//----------------------------------------------------------------------------------) + +comment(// @@PLEAC@@_10.17) +comment(//----------------------------------------------------------------------------------) +comment(// Program: Sorting Your Mail) +doctype(#!/usr/bin/groovy) +keyword(import) include(javax.mail.*) + +comment(// solution using mstor package (mstor.sf.net\)) +ident(session) operator(=) ident(Session)operator(.)ident(getDefaultInstance)operator(()keyword(new) pre_type(Properties)operator(()(\)\)) +ident(store) operator(=) ident(session)operator(.)ident(getStore)operator(()keyword(new) ident(URLName)operator(()string(\)\)) +ident(store)operator(.)ident(connect)operator(()(\)) + +comment(// read messages from Inbox) +ident(inbox) operator(=) ident(store)operator(.)ident(defaultFolder)operator(.)ident(getFolder)operator(()string(\)) +ident(inbox)operator(.)ident(open)operator(()ident(Folder)operator(.)ident(READ_ONLY)(\)) +ident(messages) operator(=) ident(inbox)operator(.)ident(messages)operator(.)ident(toList)operator(()(\)) + +comment(// extractor closures) +ident(subject) operator(=) operator({) ident(m) operator(->) ident(m)operator(.)ident(subject) (}) +ident(subjectExcludingReplyPrefix) operator(=) operator({) ident(m) operator(->) ident(subject)operator(()ident(m)(\))operator(.)ident(replaceAll)operator(()regexpoperator(,)string(\)) (}) comment(// double slash to single outside triple quotes) +ident(date) operator(=) operator({) ident(m) operator(->) ident(d) operator(=) ident(m)operator(.)ident(sentDate)operator(;) keyword(new) pre_type(Date)operator(()ident(d)operator(.)ident(year)operator(,) ident(d)operator(.)ident(month)operator(,) ident(d)operator(.)ident(date)(\)) (}) comment(// ignore time fields) + +comment(// sort by subject excluding 'Re:' prefixs then print subject for first 6) +ident(println) ident(messages)operator(.)ident(sort)operator({)ident(subjectExcludingReplyPrefix)operator(()local_variable(it)(\)})operator([)integer(0)operator(..)integer(5)(])operator(*.)ident(subject)operator(.)ident(join)operator(()string(\)) +comment(// =>) +comment(// Additional Resources for JDeveloper 10g (10.1.3\)) +comment(// Amazon Web Services Developer Connection Newsletter #18) +comment(// Re: Ant 1.7.0?) +comment(// ARN Daily | 2007: IT predictions for the year ahead) +comment(// Big Changes at Gentleware) +comment(// BigPond Account Notification) + +comment(// sort by date then subject (print first 6 entries\)) +ident(sorted) operator(=) ident(messages)operator(.)ident(sort)operator({) ident(a)operator(,)ident(b) operator(->) + ident(date)operator(()ident(a)(\)) operator(==) ident(date)operator(()ident(b)(\)) operator(?) + ident(subjectExcludingReplyPrefix)operator(()ident(a)(\)) operator(<=)operator(>) ident(subjectExcludingReplyPrefix)operator(()ident(b)(\)) operator(:) + ident(date)operator(()ident(a)(\)) operator(<=)operator(>) ident(date)operator(()ident(b)(\)) +(}) +ident(sorted)operator([)integer(0)operator(..)integer(5)(])operator(.)ident(each)operator({) ident(m) operator(->) ident(println) stringcontent(.sentDate: )inlinecontent(.subject)delimiter(")> (}) +comment(// =>) +comment(// Wed Jan 03 08:54:15 EST 2007: ARN Daily | 2007: IT predictions for the year ahead) +comment(// Wed Jan 03 15:33:31 EST 2007: EclipseSource: RCP Adoption, Where Art Thou?) +comment(// Wed Jan 03 00:10:11 EST 2007: What's New at Sams Publishing?) +comment(// Fri Jan 05 08:31:11 EST 2007: Building a Sustainable Open Source Business) +comment(// Fri Jan 05 09:53:45 EST 2007: Call for Participation: Agile 2007) +comment(// Fri Jan 05 05:51:36 EST 2007: IBM developerWorks Weekly Edition, 4 January 2007) + +comment(// group by date then print first 2 entries of first 2 dates) +ident(groups) operator(=) ident(messages)operator(.)ident(groupBy)operator({) ident(date)operator(()local_variable(it)(\)) (}) +ident(groups)operator(.)ident(keySet)operator(()(\))operator(.)ident(toList)operator(()(\))operator([)integer(0)operator(..)integer(1)(])operator(.)ident(each)operator({) + ident(println) local_variable(it) + ident(println) ident(groups)operator([)local_variable(it)(])operator([)integer(0)operator(..)integer(1)(])operator(.)ident(collect)operator({) string operator(+) local_variable(it)operator(.)ident(subject) (})operator(.)ident(join)operator(()string(\)) +(}) +comment(// =>) +comment(// Wed Jan 03 00:00:00 EST 2007) +comment(// ARN Daily | 2007: IT predictions for the year ahead) +comment(// EclipseSource: RCP Adoption, Where Art Thou?) +comment(// Fri Jan 05 00:00:00 EST 2007) +comment(// Building a Sustainable Open Source Business) +comment(// Call for Participation: Agile 2007) + + +comment(// @@PLEAC@@_11.0) +comment(//----------------------------------------------------------------------------------) +comment(// In Groovy, most usages of names are references (there are some special) +comment(// rules for the map shorthand notation and builders\).) +comment(// Objects are inherently anonymous, they don't know what names refer to them.) +ident(ref) operator(=) integer(3) comment(// points ref to an Integer object with value 3.) +ident(println) ident(ref) comment(// prints the value that the name ref refers to.) + +ident(myList) operator(=) operator([)integer(3)operator(,) integer(4)operator(,) integer(5)(]) comment(// myList is a name for this list) +ident(anotherRef) operator(=) ident(myList) +ident(myMap) operator(=) operator([)stringoperator(:) stringoperator(,) stringoperator(:) string(]) comment(// myMap is a name for this map) + +ident(anArray) operator(=) operator([)integer(1)operator(,) integer(2)operator(,) integer(3)(]) keyword(as) type(int)type([]) comment(// creates an array of three references to Integer objects) + +ident(list) operator(=) operator([)type([])(]) comment(// a list containing an empty list) +ident(list)operator([)integer(2)(]) operator(=) string +ident(println) ident(list) comment(// => [[], null, "Cat"]) +ident(list)operator([)integer(0)(])operator([)integer(2)(]) operator(=) string +ident(println) ident(list) comment(// => [[null, null, "Dog"], null, "Cat"]) + +ident(a) operator(=) operator([)integer(2)operator(,) integer(1)(]) +ident(b) operator(=) ident(a) comment(// b is a reference to the same thing as a) +ident(a)operator(.)ident(sort)operator(()(\)) +ident(println) ident(b) comment(// => [1, 2]) + +ident(nat) operator(=) operator([) pre_type(Name)operator(:) stringoperator(,) + key(Address)operator(:) stringoperator(,) + key(Birthday)operator(:) hex(0x5bb5580) +(]) +ident(println) ident(nat) +comment(// =>["Address":"1729 Ramanujan Lane\\nMathworld, PI 31416", "Name":"Leonhard Euler", "Birthday":96163200]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.1) +comment(//----------------------------------------------------------------------------------) +ident(aref) operator(=) ident(myList) +ident(anonList) operator(=) operator([)integer(1)operator(,) integer(3)operator(,) integer(5)operator(,) integer(7)operator(,) integer(9)(]) +ident(anonCopy) operator(=) ident(anonList) +ident(implicitCreation) operator(=) operator([)integer(2)operator(,) integer(4)operator(,) integer(6)operator(,) integer(8)operator(,) integer(10)(]) + +ident(anonList) operator(+=) integer(11) +ident(println) ident(anonList) comment(// => [1, 3, 5, 7, 9, 11]) + +ident(two) operator(=) ident(implicitCreation)operator([)integer(0)(]) +keyword(assert) ident(two) operator(==) integer(2) + +comment(// To get the last index of a list, you can use size(\)) +comment(// but you never would) +ident(lastIdx) operator(=) ident(aref)operator(.)ident(size)operator(()(\)) operator(-) integer(1) + +comment(// Normally, though, you'd use an index of -1 for the last) +comment(// element, -2 for the second last, etc.) +ident(println) ident(implicitCreation)operator([)operator(-)integer(1)(]) +comment(//=> 10) + +comment(// And if you were looping through (and not using a list closure operator\)) +operator(()integer(0)operator(..<)ident(aref)operator(.)ident(size)operator(()(\)\))operator(.)ident(each)operator({) comment(/* do something */) (}) + +ident(numItems) operator(=) ident(aref)operator(.)ident(size)operator(()(\)) + +keyword(assert) ident(anArray) keyword(instanceof) type(int)type([]) +keyword(assert) ident(anArray)operator(.)ident(class)operator(.)ident(isArray)operator(()(\)) +ident(println) ident(anArray) + +ident(myList)operator(.)ident(sort)operator(()(\)) comment(// sort is in place.) +ident(myList) operator(+=) string comment(// append item) + +keyword(def) method(createList)operator(()(\)) operator({) keyword(return) type([]) (}) +ident(aref1) operator(=) ident(createList)operator(()(\)) +ident(aref2) operator(=) ident(createList)operator(()(\)) +comment(// aref1 and aref2 point to different lists.) + +ident(println) ident(anonList)operator([)integer(4)(]) comment(// refers to the 4th item in the list_ref list.) + +comment(// The following two statements are equivalent and return up to 3 elements) +comment(// at indices 3, 4, and 5 (if they exist\).) +ident(x) operator(=) ident(anonList)operator([)integer(3)operator(..)integer(5)(]) +ident(x) operator(=) ident(anonList)operator([)operator(()integer(3)operator(..)integer(5)(\))operator(.)ident(step)operator(()integer(1)(\)]) + +comment(// This will insert 3 elements, overwriting elements at indices 3,4, or 5 - if they exist.) +ident(anonList)operator([)integer(3)operator(..)integer(5)(]) operator(=) operator([)stringoperator(,) stringoperator(,) string(]) + +comment(// non index-based looping) +keyword(for) operator(()ident(item) keyword(in) ident(anonList)(\)) ident(println) ident(item) +ident(anonList)operator(.)ident(each)operator({) ident(println) local_variable(it) (}) + +comment(// index-based looping) +operator(()integer(0)operator(..<)ident(anonList)operator(.)ident(size)operator(()(\)\))operator(.)ident(each)operator({) ident(idx) operator(->) ident(println) ident(anonList)operator([)ident(idx)(]) (}) +keyword(for) operator(()ident(idx) keyword(in) integer(0)operator(..<)ident(anonList)operator(.)ident(size)operator(()(\)\)) ident(println) ident(anonList)operator([)ident(idx)(]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.2) +comment(//----------------------------------------------------------------------------------) +comment(// Making Hashes of Arrays) +ident(hash) operator(=) operator([)operator(:)(]) comment(// empty map) +ident(hash)operator([)string(]) operator(=) string + +ident(hash)operator(.)ident(each)operator({) ident(key)operator(,) ident(value) operator(->) ident(println) ident(key) operator(+) string operator(+) ident(value) (}) + +ident(hash)operator([)string(]) operator(=) operator([)integer(3)operator(,) integer(4)operator(,) integer(5)(]) +ident(values) operator(=) ident(hash)operator([)string(]) + +ident(hash)operator([)string(]) operator(+=) integer(6) +ident(println) ident(hash) +comment(// => ["KEYNAME":"new value", "a key":[3, 4, 5, 6]]) + +comment(// attempting to access a value for a key not in the map yields null) +keyword(assert) ident(hash)operator([)string(]) operator(==) keyword(null) +keyword(assert) ident(hash)operator(.)ident(get)operator(()stringoperator(,) integer(45)(\)) operator(==) integer(45) +ident(println) ident(hash) +comment(// => ["unknown key":45, "KEYNAME":"new value", "a key":[3, 4, 5, 6]]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.3) +comment(//----------------------------------------------------------------------------------) +comment(// Hashes are no different to other objects) +ident(myHash) operator(=) operator([) key(key1)operator(:)integer(100)operator(,) key(key2)operator(:)integer(200) (]) +ident(myHashCopy) operator(=) ident(myHash)operator(.)ident(clone)operator(()(\)) + +ident(value) operator(=) ident(myHash)operator([)string(]) +ident(value) operator(=) ident(myHash)operator(.)string +ident(slice) operator(=) ident(myHash)operator([)integer(1)operator(..)integer(3)(]) +ident(keys) operator(=) ident(myHash)operator(.)ident(keySet)operator(()(\)) + +keyword(assert) ident(myHash) keyword(instanceof) pre_type(Map) + +operator([)ident(myHash)operator(,) ident(hash)(])operator(.)ident(each)operator({) ident(m) operator(->) + ident(m)operator(.)ident(each)operator({) ident(k)operator(,) ident(v) operator(->) ident(println) stringcontent( => )inlinedelimiter(")>(}) +(}) +comment(// =>) +comment(// key1 => 100) +comment(// key2 => 200) +comment(// unknown key => 45) +comment(// KEYNAME => new value) +comment(// a key => [3, 4, 5, 6]) + +ident(values) operator(=) operator([)stringoperator(,)string(])operator(.)ident(collect)operator({) ident(myHash)operator([)local_variable(it)(]) (}) +ident(println) ident(values) comment(// => [100, 200]) + +keyword(for) operator(()ident(key) keyword(in) operator([)stringoperator(,) string(]\)) operator({) + ident(myHash)operator([)ident(key)(]) operator(+=) integer(7) +(}) +ident(println) ident(myHash) comment(// => ["key1":107, "key2":207]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.4) +comment(//----------------------------------------------------------------------------------) +comment(// you can use closures or the &method notation) +keyword(def) method(joy)operator(()(\)) operator({) ident(println) string (}) +keyword(def) method(sullen)operator(()(\)) operator({) ident(println) string (}) +ident(angry) operator(=) operator({) ident(println) string (}) +ident(commands) operator(=) operator([)key(happy)operator(:) local_variable(this)operator(.)operator(&)ident(joy)operator(,) + key(sad)operator(:) local_variable(this)operator(.)operator(&)ident(sullen)operator(,) + key(done)operator(:) operator({) pre_type(System)operator(.)ident(exit)operator(()integer(0)(\)) (})operator(,) + key(mad)operator(:) ident(angry) +(]) + +ident(print) string +ident(cmd) operator(=) pre_type(System)operator(.)ident(in)operator(.)ident(readLine)operator(()(\)) +keyword(if) operator(()ident(cmd) keyword(in) ident(commands)operator(.)ident(keySet)operator(()(\)\)) ident(commands)operator([)ident(cmd)(])operator(()(\)) +keyword(else) ident(println) stringdelimiter(")> + + +comment(// a counter of the type referred to in the original cookbook) +comment(// would be implemented using a class) +keyword(def) method(counterMaker)operator(()(\))operator({) + keyword(def) ident(start) operator(=) integer(0) + keyword(return) operator({) operator(->) ident(start)operator(++)operator(;) ident(start)operator(-)integer(1) (}) +(}) + +ident(counter) operator(=) ident(counterMaker)operator(()(\)) +integer(5)operator(.)ident(times)operator({) ident(print) stringcontent( )delimiter(")> (})operator(;) ident(println)operator(()(\)) + +ident(counter1) operator(=) ident(counterMaker)operator(()(\)) +ident(counter2) operator(=) ident(counterMaker)operator(()(\)) + +integer(5)operator(.)ident(times)operator({) ident(println) stringcontent( )delimiter(")> (}) +ident(println) stringcontent( )inlinedelimiter(")> +comment(//=> 0) +comment(//=> 1) +comment(//=> 2) +comment(//=> 3) +comment(//=> 4) +comment(//=> 5 0) + + +keyword(def) method(timestamp)operator(()(\)) operator({) + keyword(def) ident(start) operator(=) pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) + keyword(return) operator({) operator(()pre_type(System)operator(.)ident(currentTimeMillis)operator(()(\)) operator(-) ident(start)(\))operator(.)ident(intdiv)operator(()integer(1000)(\)) (}) +(}) +ident(early) operator(=) ident(timestamp)operator(()(\)) +comment(//sleep(10000\)) +ident(later) operator(=) ident(timestamp)operator(()(\)) +ident(sleep)operator(()integer(2000)(\)) +ident(println) stringcontent( seconds since early.)delimiter(")> +ident(println) stringcontent( seconds since later.)delimiter(")> +comment(//=> It's been 12 seconds since early.) +comment(//=> It's been 2 seconds since later.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.5) +comment(//----------------------------------------------------------------------------------) +comment(// All variables in Groovy are objects including primitives. Some objects) +comment(// are immutable. Some operations on objects change mutable objects.) +comment(// Some operations produce new objects.) + +comment(// 15 is an Integer which is an immutable object.) +comment(// passing 15 to a method passes a reference to the Integer object.) +keyword(def) method(print)operator(()ident(n)(\)) operator({) ident(println) stringdelimiter(")> (}) +ident(print)operator(()integer(15)(\)) comment(// no need to create any kind of explicit reference) + +comment(// even though Integers are immutable, references to them are not) +ident(x) operator(=) integer(1) +ident(y) operator(=) ident(x) +ident(println) stringcontent( )inlinedelimiter(")> comment(// => 1 1) +ident(x) operator(+=) integer(1) comment(// "x" now refers to a different object than y) +ident(println) stringcontent( )inlinedelimiter(")> comment(// => 2 1) +ident(y) operator(=) integer(4) comment(// "y" now refers to a different object than it did before) +ident(println) stringcontent( )inlinedelimiter(")> comment(// => 2 4) + +comment(// Some objects (including ints and strings\) are immutable, however, which) +comment(// can give the illusion of a by-value/by-reference distinction:) +ident(list) operator(=) operator([)operator([)integer(1)(])operator(,) integer(1)operator(,) string(]) +ident(list)operator(.)ident(each)operator({) local_variable(it) operator(+=) integer(1) (}) comment(// plus operator doesn't operate inplace) +ident(print) ident(list) comment(//=> [[1] 1 s]) +ident(list) operator(=) ident(list)operator(.)ident(collect)operator({) local_variable(it) operator(+) integer(1) (}) +ident(print) ident(list) comment(//=> [[1, 1], 2, s1]) + +ident(list) operator(=) operator([)operator([)stringoperator(,) stringoperator(,) string(])operator(,) operator([)stringoperator(,) stringoperator(,) string(])operator(,) operator([)integer(5)operator(,) integer(3)operator(,) integer(1)(]]) +ident(list)operator(.)ident(each)operator({) local_variable(it)operator(.)ident(sort)operator(()(\)) (}) comment(// sort operation operates inline) +ident(println) ident(list) comment(// => [["X", "Y", "Z"], ["A", "B", "C"], [1, 3, 5]]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.6) +comment(//----------------------------------------------------------------------------------) +comment(// As indicated by the previous section, everything is referenced, so) +comment(// just create a list as normal, and beware that augmented assignment) +comment(// works differently with immutable objects to mutable ones and depends) +comment(// on the semantics of the particular operation invoked:) +ident(mylist) operator(=) operator([)integer(1)operator(,) stringoperator(,) operator([)integer(1)(]]) +ident(print) ident(mylist) +comment(//=> [1, s, [1]]) + +ident(mylist)operator(.)ident(each)operator({) local_variable(it) operator(*=) integer(2) (}) +ident(print) ident(mylist) +comment(//=> [1, s, [1,1]]) + +ident(mylist)operator([)integer(0)(]) operator(*=) integer(2) +ident(mylist)operator([)operator(-)integer(1)(]) operator(*=) integer(2) +ident(print) ident(mylist) +comment(//=> [2, s, [1, 1]]) + +comment(// If you need to modify every value in a list, you use collect) +comment(// which does NOT modify inplace but rather returns a new collection:) +ident(mylist) operator(=) integer(1)operator(..)integer(4) +ident(println) ident(mylist)operator(.)ident(collect)operator({) local_variable(it)operator(**)integer(3) operator(*) integer(4)operator(/)integer(3) operator(*) pre_type(Math)operator(.)ident(PI) (}) +comment(// => [4.188790204681671, 33.510321638395844, 113.09733552923255, 268.0825731062243]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.7) +comment(//----------------------------------------------------------------------------------) +keyword(def) method(mkcounter)operator(()ident(count)(\)) operator({) + keyword(def) ident(start) operator(=) ident(count) + keyword(def) ident(bundle) operator(=) operator([)operator(:)(]) + ident(bundle)operator(.)string operator(=) operator({) ident(count) operator(+=) integer(1) (}) + ident(bundle)operator(.)string operator(=) operator({) ident(count) operator(-=) integer(1) (}) + ident(bundle)operator(.)string operator(=) operator({) ident(count) operator(=) ident(start) (}) + ident(bundle)operator([)string(]) operator(=) ident(bundle)operator([)string(]) + keyword(return) ident(bundle) +(}) + +ident(c1) operator(=) ident(mkcounter)operator(()integer(20)(\)) +ident(c2) operator(=) ident(mkcounter)operator(()integer(77)(\)) + +ident(println) stringdelimiter(")> comment(// 21) +ident(println) stringdelimiter(")> comment(// 78) +ident(println) stringdelimiter(")> comment(// 22) +ident(println) stringdelimiter(")> comment(// 21) +ident(println) stringdelimiter(")> comment(// 20) +ident(println) stringdelimiter(")> comment(// 77) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.8) +comment(//----------------------------------------------------------------------------------) +keyword(def) method(addAndMultiply)operator(()ident(a)operator(,) ident(b)(\)) operator({) + ident(println) stringcontent( )inlinedelimiter(")> +(}) +ident(methRef) operator(=) local_variable(this)operator(.)operator(&)ident(addAndMultiply) +comment(// or use direct closure) +ident(multiplyAndAdd) operator(=) operator({) ident(a)operator(,)ident(b) operator(->) ident(println) stringcontent( )inlinedelimiter(")> (}) +comment(// later ...) +ident(methRef)operator(()integer(2)operator(,)integer(3)(\)) comment(// => 5 6) +ident(multiplyAndAdd)operator(()integer(2)operator(,)integer(3)(\)) comment(// => 6 5) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.9) +comment(//----------------------------------------------------------------------------------) +ident(record) operator(=) operator([) + stringoperator(:) stringoperator(,) + stringoperator(:) integer(132)operator(,) + stringoperator(:) stringoperator(,) + stringoperator(:) integer(23)operator(,) + stringoperator(:) integer(37000)operator(,) + stringoperator(:) operator([)stringoperator(,) stringoperator(,) string(])operator(,) +(]) +ident(println) stringcontent(, and my pals are )inlinecontent(.)delimiter(")> +comment(// => I am Jason, and my pals are Norbert, Rhys, Phineas.) + +ident(byname) operator(=) operator([)operator(:)(]) +ident(byname)operator([)ident(record)operator([)string(]]) operator(=) ident(record) + +ident(rp) operator(=) ident(byname)operator(.)ident(get)operator(()string(\)) +keyword(if) operator(()ident(rp)(\)) ident(println) stringcontent(.)delimiter(")> + +ident(byname)operator([)string(])operator([)string(]) operator(+=) string +ident(println) stringcontent( pals.)delimiter(")> + +ident(byname)operator(.)ident(each)operator({) ident(name)operator(,) ident(record) operator(->) + ident(println) stringcontent( is employee number )inlinecontent(.)delimiter(")> +(}) + +ident(employees) operator(=) operator([)operator(:)(]) +ident(employees)operator([)ident(record)operator([)string(]]) operator(=) ident(record) + +comment(// lookup by id) +ident(rp) operator(=) ident(employees)operator([)integer(132)(]) +keyword(if) operator(()ident(rp)(\)) ident(println) stringcontent(.)delimiter(")> + +ident(byname)operator([)string(])operator([)string(]) operator(*=) float(1.035) +ident(println) ident(record) +comment(// => ["pals":["Norbert", "Rhys", "Phineas", "Theodore"], "age":23,) +comment(// "title":"deputy peon", "name":"Jason", "salary":38295.000, "empno":132]) + +ident(peons) operator(=) ident(employees)operator(.)ident(findAll)operator({) ident(k)operator(,) ident(v) operator(->) ident(v)operator(.)string operator(=~) regexp (}) +keyword(assert) ident(peons)operator(.)ident(size)operator(()(\)) operator(==) integer(1) +ident(tsevens) operator(=) ident(employees)operator(.)ident(findAll)operator({) ident(k)operator(,) ident(v) operator(->) ident(v)operator(.)string operator(==) integer(27) (}) +keyword(assert) ident(tsevens)operator(.)ident(size)operator(()(\)) operator(==) integer(0) + +comment(// Go through all records) +ident(println) string operator(+) ident(employees)operator(.)ident(values)operator(()(\))operator(.)ident(collect)operator({)ident(r)operator(->)ident(r)operator(.)string(})operator(.)ident(join)operator(()string(\)) + +ident(byAge) operator(=) operator({)ident(a)operator(,)ident(b)operator(->) ident(a)operator(.)ident(value)operator(()(\))operator(.)string operator(<=)operator(>) ident(b)operator(.)ident(value)operator(()(\))operator(.)string(}) +ident(employees)operator(.)ident(values)operator(()(\))operator(.)ident(sort)operator({)ident(byAge)(})operator(.)ident(each)operator({) ident(r)operator(->) + ident(println) stringcontent( is )inlinedelimiter(")> +(}) + +comment(// byage, a hash: age => list of records) +ident(byage) operator(=) operator([)operator(:)(]) +ident(byage)operator([)ident(record)operator([)string(]]) operator(=) ident(byage)operator(.)ident(get)operator(()ident(record)operator([)string(])operator(,) type([])(\)) operator(+) operator([)ident(record)(]) + +ident(byage)operator(.)ident(each)operator({) ident(age)operator(,) ident(list) operator(->) + ident(println) stringcontent(: )inlinecontent(.join(', '\)})delimiter(")> +(}) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.10) +comment(//----------------------------------------------------------------------------------) +comment(// if you are using a Properties (see 8.16\) then just use load) +comment(// and store (or storeToXML\)) +comment(// variation to original cookbook as Groovy can use Java's object serialization) +ident(map) operator(=) operator([)integer(1)operator(:)stringoperator(,) integer(2)operator(:)stringoperator(,) integer(3)operator(:)string(]) +comment(// write) +keyword(new) pre_type(File)operator(()string(\))operator(.)ident(withObjectOutputStream)operator({) ident(oos) operator(->) + ident(oos)operator(.)ident(writeObject)operator(()ident(map)(\)) +(}) +comment(// reset) +ident(map) operator(=) keyword(null) +comment(// read) +keyword(new) pre_type(File)operator(()string(\))operator(.)ident(withObjectInputStream)operator({) ident(ois) operator(->) + ident(map) operator(=) ident(ois)operator(.)ident(readObject)operator(()(\)) +(}) +ident(println) ident(map) comment(// => [1:"Jan", 2:"Feb", 3:"Mar"]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.11) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy automatically does pretty printing for some of the key types, e.g.) +ident(mylist) operator(=) operator([)operator([)integer(1)operator(,)integer(2)operator(,)integer(3)(])operator(,) operator([)integer(4)operator(,) operator([)integer(5)operator(,)integer(6)operator(,)integer(7)(])operator(,) integer(8)operator(,)integer(9)operator(,) operator([)integer(0)operator(,)integer(3)operator(,)integer(5)(]])operator(,) integer(7)operator(,) integer(8)(]) +ident(println) ident(mylist) +comment(// => [[1, 2, 3], [4, [5, 6, 7], 8, 9, [0, 3, 5]], 7, 8]) + +ident(mydict) operator(=) operator([)stringoperator(:) stringoperator(,) stringoperator(:)operator([)integer(1)operator(,)integer(2)operator(,)integer(3)(]]) +ident(println) ident(mydict) +comment(// => ["abc":"def", "ghi":[1, 2, 3]]) + +comment(// if you have another type of object you can use the built-in dump(\) method) +type(class) class(PetLover) operator({) + keyword(def) ident(name) + keyword(def) ident(age) + keyword(def) ident(pets) +(}) +ident(p) operator(=) keyword(new) ident(PetLover)operator(()key(name)operator(:)stringoperator(,) key(age)operator(:)integer(23)operator(,) key(pets)operator(:)operator([)key(dog)operator(:)stringoperator(,)key(cat)operator(:)string(]\)) +ident(println) ident(p) +comment(// => PetLover@b957ea) +ident(println) ident(p)operator(.)ident(dump)operator(()(\)) +comment(// => ) + +comment(// If that isn't good enough, you can use Boost (http://tara-indigo.org/daisy/geekscape/g2/128\)) +comment(// or Jakarta Commons Lang *ToStringBuilders (jakarta.apache.org/commons\)) +comment(// Here's an example of Boost, just extend the supplied Primordial class) +keyword(import) include(au.net.netstorm.boost.primordial.Primordial) +type(class) class(PetLover2) directive(extends) ident(Primordial) operator({) keyword(def) ident(name)operator(,) ident(age)operator(,) ident(pets) (}) +ident(println) keyword(new) ident(PetLover2)operator(()key(name)operator(:)stringoperator(,) key(age)operator(:)integer(23)operator(,) key(pets)operator(:)operator([)key(dog)operator(:)stringoperator(,)key(cat)operator(:)string(]\)) +comment(// =>) +comment(// PetLover2[) +comment(// name=Jason) +comment(// age=23) +comment(// pets={cat=Garfield, dog=Rover}) +comment(// metaClass=groovy.lang.MetaClassImpl@1d8d39f[class PetLover2]) +comment(// ]) + +comment(// using Commons Lang ReflectionToStringBuilder (equivalent to dump(\)\)) +keyword(import) include(org.apache.commons.lang.builder.*) +type(class) class(PetLover3) operator({) + keyword(def) ident(name)operator(,) ident(age)operator(,) ident(pets) + pre_type(String) ident(toString)operator(()(\)) operator({) + ident(ReflectionToStringBuilder)operator(.)ident(toString)operator(()local_variable(this)(\)) + (}) +(}) +ident(println) keyword(new) ident(PetLover3)operator(()key(name)operator(:)stringoperator(,) key(age)operator(:)integer(23)operator(,) key(pets)operator(:)operator([)key(dog)operator(:)stringoperator(,)key(cat)operator(:)string(]\)) +comment(// => PetLover3@196e136[name=Jason,age=23,pets={cat=Garfield, dog=Rover}]) + +comment(// using Commons Lang ToStringBuilder if you want a custom format) +type(class) class(PetLover4) operator({) + keyword(def) ident(name)operator(,) ident(dob)operator(,) ident(pets) + pre_type(String) ident(toString)operator(()(\)) operator({) + keyword(def) ident(d1) operator(=) ident(dob)operator(.)ident(time)operator(;) keyword(def) ident(d2) operator(=) operator(()keyword(new) pre_type(Date)operator(()(\)\))operator(.)ident(time) + type(int) ident(age) operator(=) operator(()ident(d2) operator(-) ident(d1)(\))operator(/)integer(1000)operator(/)integer(60)operator(/)integer(60)operator(/)integer(24)operator(/)integer(365) comment(// close approx good enough here) + keyword(return) keyword(new) ident(ToStringBuilder)operator(()local_variable(this)(\))operator(.) + ident(append)operator(()stringoperator(,) ident(name)(\))operator(.) + ident(append)operator(()stringoperator(,) ident(pets)(\))operator(.) + ident(append)operator(()stringoperator(,) ident(age)(\)) + (}) +(}) +ident(println) keyword(new) ident(PetLover4)operator(()key(name)operator(:)stringoperator(,) key(dob)operator(:)keyword(new) pre_type(Date)operator(()integer(83)operator(,)oct(03)operator(,)oct(04)(\))operator(,) key(pets)operator(:)operator([)key(dog)operator(:)stringoperator(,)key(cat)operator(:)string(]\)) +comment(// => PetLover4@fdfc58[Pet Lover's name=Jason,Pets={cat=Garfield, dog=Rover},Age=23]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.12) +comment(//----------------------------------------------------------------------------------) +ident(oldlist) operator(=) operator([)integer(1)operator(,) integer(2)operator(,) integer(3)(]) +ident(newlist) operator(=) keyword(new) pre_type(ArrayList)operator(()ident(oldlist)(\)) comment(// shallow copy) +ident(newlist) operator(=) ident(oldlist)operator(.)ident(clone)operator(()(\)) comment(// shallow copy) + +ident(oldmap) operator(=) operator([)key(a)operator(:)integer(1)operator(,) key(b)operator(:)integer(2)operator(,) key(c)operator(:)integer(3)(]) +ident(newmap) operator(=) keyword(new) pre_type(HashMap)operator(()ident(oldmap)(\)) comment(// shallow copy) +ident(newmap) operator(=) ident(oldmap)operator(.)ident(clone)operator(()(\)) comment(// shallow copy) + +ident(oldarray) operator(=) operator([)integer(1)operator(,) integer(2)operator(,) integer(3)(]) keyword(as) type(int)type([]) +ident(newarray) operator(=) ident(oldarray)operator(.)ident(clone)operator(()(\)) + +comment(// shallow copies copy a data structure, but don't copy the items in those) +comment(// data structures so if there are nested data structures, both copy and) +comment(// original will refer to the same object) +ident(mylist) operator(=) operator([)stringoperator(,) stringoperator(,) string(]) +ident(newlist) operator(=) ident(mylist)operator(.)ident(clone)operator(()(\)) +ident(mylist)operator([)integer(0)(]) operator(=) string +ident(println) stringcontent( )inlinedelimiter(")> +comment(//=> ["0", "2", "3"] ["1", "2", "3"]) + +ident(mylist) operator(=) operator([)operator([)stringoperator(,) stringoperator(,) string(])operator(,) integer(4)(]) +ident(newlist) operator(=) ident(mylist)operator(.)ident(clone)operator(()(\)) +ident(mylist)operator([)integer(0)(])operator([)integer(0)(]) operator(=) string +ident(println) stringcontent( )inlinedelimiter(")> +comment(//=> [["0", "2", "3"], 4] [["0", "2", "3"], 4]) + +comment(// standard deep copy implementation) +keyword(def) method(deepcopy)operator(()ident(orig)(\)) operator({) + ident(bos) operator(=) keyword(new) pre_type(ByteArrayOutputStream)operator(()(\)) + ident(oos) operator(=) keyword(new) pre_type(ObjectOutputStream)operator(()ident(bos)(\)) + ident(oos)operator(.)ident(writeObject)operator(()ident(orig)(\))operator(;) ident(oos)operator(.)ident(flush)operator(()(\)) + ident(bin) operator(=) keyword(new) pre_type(ByteArrayInputStream)operator(()ident(bos)operator(.)ident(toByteArray)operator(()(\)\)) + ident(ois) operator(=) keyword(new) pre_type(ObjectInputStream)operator(()ident(bin)(\)) + keyword(return) ident(ois)operator(.)ident(readObject)operator(()(\)) +(}) + +ident(newlist) operator(=) ident(deepcopy)operator(()ident(oldlist)(\)) comment(// deep copy) +ident(newmap) operator(=) ident(deepcopy)operator(()ident(oldmap)(\)) comment(// deep copy) + +ident(mylist) operator(=) operator([)operator([)stringoperator(,) stringoperator(,) string(])operator(,) integer(4)(]) +ident(newlist) operator(=) ident(deepcopy)operator(()ident(mylist)(\)) +ident(mylist)operator([)integer(0)(])operator([)integer(0)(]) operator(=) string +ident(println) stringcontent( )inlinedelimiter(")> +comment(//=> [["0", "2", "3"], 4] [["1", "2", "3"], 4]) + +comment(// See also:) +comment(// http://javatechniques.com/public/java/docs/basics/low-memory-deep-copy.html) +comment(// http://javatechniques.com/public/java/docs/basics/faster-deep-copy.html) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.13) +comment(//----------------------------------------------------------------------------------) +comment(// use Java's serialization capabilities as per 11.10) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.14) +comment(//----------------------------------------------------------------------------------) +comment(// There are numerous mechanisms for persisting objects to disk) +comment(// using Groovy and Java mechanisms. Some are completely transparent,) +comment(// some require some initialization only, others make the persistence) +comment(// mechanisms visible. Here is a site that lists over 20 options:) +comment(// http://www.java-source.net/open-source/persistence) +comment(// (This list doesn't include EJB offerings which typically) +comment(// require an application server or XML-based options\)) + +comment(// We'll just consider one possibility from prevayler.sf.net.) +comment(// This package doesn't make changes to persistent data transparent;) +comment(// instead requiring an explicit call via a transaction object.) +comment(// It saves all such transaction objects in a journal file so) +comment(// that it can rollback the system any number of times (or if) +comment(// you make use of the timestamp feature\) to a particular point) +comment(// in time. It can also be set up to create snapshots which) +comment(// consolidate all changes made up to a certain point. The) +comment(// journalling will begin again from that point.) +keyword(import) include(org.prevayler.*) +type(class) class(ImportantHash) directive(implements) pre_type(Serializable) operator({) + directive(private) ident(map) operator(=) operator([)operator(:)(]) + keyword(def) method(putAt)operator(()ident(key)operator(,) ident(value)(\)) operator({) ident(map)operator([)ident(key)(]) operator(=) ident(value) (}) + keyword(def) method(getAt)operator(()ident(key)(\)) operator({) ident(map)operator([)ident(key)(]) (}) +(}) +type(class) class(StoreTransaction) directive(implements) ident(Transaction) operator({) + directive(private) ident(val) + ident(StoreTransaction)operator(()ident(val)(\)) operator({) local_variable(this)operator(.)ident(val) operator(=) ident(val) (}) + type(void) ident(executeOn)operator(()ident(prevayler)operator(,) pre_type(Date) ident(ignored)(\)) operator({) ident(prevayler)operator(.)ident(putAt)operator(()ident(val)operator(,)ident(val)operator(*)integer(2)(\)) (}) +(}) +keyword(def) method(save)operator(()ident(n)(\))operator({) ident(store)operator(.)ident(execute)operator(()keyword(new) ident(StoreTransaction)operator(()ident(n)(\)\)) (}) +ident(store) operator(=) ident(PrevaylerFactory)operator(.)ident(createPrevayler)operator(()keyword(new) ident(ImportantHash)operator(()(\))operator(,) string(\)) +ident(hash) operator(=) ident(store)operator(.)ident(prevalentSystem)operator(()(\)) +keyword(for) operator(()ident(i) keyword(in) integer(0)operator(..)integer(1000)(\)) operator({) + ident(save)operator(()ident(i)(\)) +(}) +ident(println) ident(hash)operator([)integer(750)(]) comment(// => 1500) + +ident(store) operator(=) keyword(null)operator(;) ident(hash) operator(=) keyword(null) comment(// *** could shutdown here) + +ident(store) operator(=) ident(PrevaylerFactory)operator(.)ident(createPrevayler)operator(()keyword(new) ident(ImportantHash)operator(()(\))operator(,) string(\)) +ident(hash) operator(=) ident(store)operator(.)ident(prevalentSystem)operator(()(\)) +ident(println) ident(hash)operator([)integer(750)(]) comment(// => 1500) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_11.15) +comment(//----------------------------------------------------------------------------------) +comment(// bintree - binary tree demo program) +type(class) class(BinaryTree) operator({) + keyword(def) ident(value)operator(,) ident(left)operator(,) ident(right) + ident(BinaryTree)operator(()ident(val)(\)) operator({) + ident(value) operator(=) ident(val) + ident(left) operator(=) keyword(null) + ident(right) operator(=) keyword(null) + (}) + + comment(// insert given value into proper point of) + comment(// provided tree. If no tree provided,) + comment(// use implicit pass by reference aspect of @_) + comment(// to fill one in for our caller.) + keyword(def) method(insert)operator(()ident(val)(\)) operator({) + keyword(if) operator(()ident(val) operator(<) ident(value)(\)) operator({) + keyword(if) operator(()ident(left)(\)) ident(left)operator(.)ident(insert)operator(()ident(val)(\)) + keyword(else) ident(left) operator(=) keyword(new) ident(BinaryTree)operator(()ident(val)(\)) + (}) keyword(else) keyword(if) operator(()ident(val) operator(>) ident(value)(\)) operator({) + keyword(if) operator(()ident(right)(\)) ident(right)operator(.)ident(insert)operator(()ident(val)(\)) + keyword(else) ident(right) operator(=) keyword(new) ident(BinaryTree)operator(()ident(val)(\)) + (}) keyword(else) ident(println) string comment(// ignore double values) + (}) + + comment(// recurse on left child,) + comment(// then show current value,) + comment(// then recurse on right child.) + keyword(def) method(inOrder)operator(()(\)) operator({) + keyword(if) operator(()ident(left)(\)) ident(left)operator(.)ident(inOrder)operator(()(\)) + ident(print) ident(value) operator(+) string + keyword(if) operator(()ident(right)(\)) ident(right)operator(.)ident(inOrder)operator(()(\)) + (}) + + comment(// show current value,) + comment(// then recurse on left child,) + comment(// then recurse on right child.) + keyword(def) method(preOrder)operator(()(\)) operator({) + ident(print) ident(value) operator(+) string + keyword(if) operator(()ident(left)(\)) ident(left)operator(.)ident(preOrder)operator(()(\)) + keyword(if) operator(()ident(right)(\)) ident(right)operator(.)ident(preOrder)operator(()(\)) + (}) + + comment(// show current value,) + comment(// then recurse on left child,) + comment(// then recurse on right child.) + keyword(def) method(dumpOrder)operator(()(\)) operator({) + ident(print) local_variable(this)operator(.)ident(dump)operator(()(\)) operator(+) string + keyword(if) operator(()ident(left)(\)) ident(left)operator(.)ident(dumpOrder)operator(()(\)) + keyword(if) operator(()ident(right)(\)) ident(right)operator(.)ident(dumpOrder)operator(()(\)) + (}) + + comment(// recurse on left child,) + comment(// then recurse on right child,) + comment(// then show current value.) + keyword(def) method(postOrder)operator(()(\)) operator({) + keyword(if) operator(()ident(left)(\)) ident(left)operator(.)ident(postOrder)operator(()(\)) + keyword(if) operator(()ident(right)(\)) ident(right)operator(.)ident(postOrder)operator(()(\)) + ident(print) ident(value) operator(+) string + (}) + + comment(// find out whether provided value is in the tree.) + comment(// if so, return the node at which the value was found.) + comment(// cut down search time by only looking in the correct) + comment(// branch, based on current value.) + keyword(def) method(search)operator(()ident(val)(\)) operator({) + keyword(if) operator(()ident(val) operator(==) ident(value)(\)) operator({) + keyword(return) local_variable(this)operator(.)ident(dump)operator(()(\)) + (}) keyword(else) keyword(if) operator(()ident(val) operator(<) ident(value)(\)) operator({) + keyword(return) ident(left) operator(?) ident(left)operator(.)ident(search)operator(()ident(val)(\)) operator(:) keyword(null) + (}) keyword(else) operator({) + keyword(return) ident(right) operator(?) ident(right)operator(.)ident(search)operator(()ident(val)(\)) operator(:) keyword(null) + (}) + (}) +(}) + +comment(// first generate 20 random inserts) +ident(test) operator(=) keyword(new) ident(BinaryTree)operator(()integer(500)(\)) +ident(rand) operator(=) keyword(new) pre_type(Random)operator(()(\)) +integer(20)operator(.)ident(times)operator({) + ident(test)operator(.)ident(insert)operator(()ident(rand)operator(.)ident(nextInt)operator(()integer(1000)(\)\)) +(}) + +comment(// now dump out the tree all three ways) +ident(print) stringoperator(;) ident(test)operator(.)ident(preOrder)operator(()(\))operator(;) ident(println) string +ident(print) stringoperator(;) ident(test)operator(.)ident(inOrder)operator(()(\))operator(;) ident(println) string +ident(print) stringoperator(;) ident(test)operator(.)ident(postOrder)operator(()(\))operator(;) ident(println) string + +ident(println) string +keyword(while) operator(()operator(()ident(item) operator(=) pre_type(System)operator(.)ident(in)operator(.)ident(readLine)operator(()(\))operator(?)operator(.)ident(trim)operator(()(\)\)) operator(!=) keyword(null)(\)) operator({) + ident(println) ident(test)operator(.)ident(search)operator(()ident(item)operator(.)ident(toInteger)operator(()(\)\)) + ident(println) string +(}) +comment(// Randomly produces a tree such as:) +comment(// -------- 500 ------) +comment(// / \\ +// 181 847) +comment(// / \\ / \\ +// 3 204 814 970) +comment(// \\ / \\ /) +comment(// 126 196 414 800) +comment(// / \\ /) +comment(// 353 438 621) +comment(// / / \\ +// 423 604 776) +comment(// / /) +comment(// 517 765) +comment(// /) +comment(// 646) +comment(// /) +comment(// 630) +comment(// Pre order:) +comment(// 500 181 3 126 204 196 414 353 438 423 847 814 800 621 604 517 776 765 646 630 970) +comment(// In order:) +comment(// 3 126 181 196 204 353 414 423 438 500 517 604 621 630 646 765 776 800 814 847 970) +comment(// Post order:) +comment(// 126 3 196 353 423 438 414 204 181 517 604 630 646 765 776 621 800 814 970 847 500) +comment(//) +comment(// Search?) +comment(// 125) +comment(// null) +comment(//) +comment(// Search?) +comment(// 126) +comment(// ) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.0) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy adopts many of the Java structuring conventions and terminology) +comment(// and adds some concepts of its own.) +comment(// Code-reuse can occur at the script, class, library, component or framework level.) +comment(// Source code including class file source and scripts are organised into packages.) +comment(// These can be thought of as like hierarchical folders or directories. Two class) +comment(// with the same name can be distinguished by having different packages. Compiled) +comment(// byte code and sometimes source code including scripts can be packaged up into) +comment(// jar files. Various conventions exist for packaging classes and resources in) +comment(// such a way to allow them to be easily reused. Some of these conventions allow) +comment(// reusable code to be placed within repositories for easy use by third parties.) +comment(// One such repository is the maven repository, e.g.: ibiblio.org/maven2) +comment(// When reusing classes, it is possible to compartmentalise knowledge of) +comment(// particular packages using multiple (potentially hierarchical\) classloaders.) +comment(// By convention, package names are all lowercase. Class names are capitalized.) +comment(// Naming examples:) +comment(// package my.package1.name // at most one per source file - at top of file) +comment(// class MyClass ... // actually defines my.package1.name.MyClass) +comment(// import my.package1.name.MyClass // allows package to be dropped within current file) +comment(// import my.package2.name.MyClass // if class basenames are the same, can't) +comment(// // import both, leave one fully qualified) +comment(// import my.package.name.* // all classes in package can drop package prefix) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.1) +comment(//----------------------------------------------------------------------------------) +comment(// No equivalent export process exists for Groovy.) + +comment(// If you have some Groovy functionality that you would like others to use) +comment(// you either make the source code available or compile it into class files) +comment(// and package those up in a jar file. Some subset of your class files will) +comment(// define the OO interface to your functionality, e.g. public methods,) +comment(// interfaces, etc. Depending on the circumstances, various conventions are) +comment(// used to indicate this functionality including Manifest files, javadocs,) +comment(// deployment descriptors, project metadata and dependency management files.) +comment(// See 12.18 for an example.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.2) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy supports both static and dynamic (strong\) typing. When trying to) +comment(// compile or run files using static typing, the required classes referenced) +comment(// must be available. Classes used in more dynamic ways may be loaded (or) +comment(// created\) at runtime. Errors in loading such dynamic cases are handled) +comment(// using the normal exception handling mechanisms.) + +comment(// attempt to load an unknown resource or script:) +keyword(try) operator({) + ident(evaluate)operator(()keyword(new) pre_type(File)operator(()string(\)\)) +(}) keyword(catch) operator(()pre_type(Exception) pre_type(FileNotFoundException)(\)) operator({) + ident(println) string +(}) +comment(// => File not found, skipping ...) + +comment(// attempt to load an unknown class:) +keyword(try) operator({) + pre_type(Class)operator(.)ident(forName)operator(()string(\)) +(}) keyword(catch) operator(()pre_type(ClassNotFoundException) ident(ex)(\)) operator({) + ident(println) string +(}) +comment(// -> Class not found, skipping ...) + +comment(// dynamicallly look for a database driver (slight variation to original cookbook\)) +comment(// Note: this hypothetical example ignores certain issues e.g. different url) +comment(// formats for configuration when establishing a connection with the driver) +ident(candidates) operator(=) operator([) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + stringoperator(,) + string +(]) +ident(loaded) operator(=) keyword(null) +keyword(for) operator(()ident(driver) keyword(in) ident(candidates)(\)) operator({) + keyword(try) operator({) + ident(loaded) operator(=) pre_type(Class)operator(.)ident(forName)operator(()ident(driver)(\))operator(.)ident(newInstance)operator(()(\)) + keyword(break) + (}) keyword(catch) operator(()pre_type(Exception) ident(ex)(\)) operator({) comment(/* ignore */) (}) +(}) +ident(println) ident(loaded)operator(?)operator(.)ident(class)operator(?)operator(.)ident(name) comment(// => sun.jdbc.odbc.JdbcOdbcDriver) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.3) +comment(//----------------------------------------------------------------------------------) +comment(// In Groovy (like Java\), any static reference to an external class within) +comment(// your class will cause the external class to be loaded from the classpath.) +comment(// You can dynamically add to the classpath using:) +comment(// this.class.rootLoader.addURL(url\)) +comment(// To delay loading of external classes, use Class.forName(\) or evaluate(\)) +comment(// the script separately as shown in 12.2.) + +comment(// For the specific case of initialization code, here is another example:) +comment(// (The code within the anonymous { ... } block is called whenever the) +comment(// class is loaded.\)) +type(class) class(DbHelper) operator({) + keyword(def) method(driver) + operator({) + keyword(if) operator(()pre_type(System)operator(.)ident(properties)operator(.)string operator(==) string(\)) + ident(driver) operator(=) pre_type(Class)operator(.)ident(forName)operator(()string(\)) + keyword(else) + ident(driver) operator(=) pre_type(Class)operator(.)ident(forName)operator(()string(\)) + (}) +(}) +ident(println) keyword(new) ident(DbHelper)operator(()(\))operator(.)ident(driver)operator(.)ident(name) comment(// => sun.jdbc.odbc.JdbcOdbcDriver) +comment(// call program with -Ddriver=oracle to swap to other driver) + +comment(// A slightly related feature: If you want to load a script (typically in a) +comment(// server environment\) whenever the source file changes, use GroovyScriptEngine(\)) +comment(// instead of GroovyShell(\) when embedding groovy.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.4) +comment(//----------------------------------------------------------------------------------) +comment(// class variables are private unless access functions are defined) +type(class) class(Alpha) operator({) + keyword(def) ident(x) operator(=) integer(10) + directive(private) ident(y) operator(=) integer(12) +(}) + +ident(println) keyword(new) ident(Alpha)operator(()(\))operator(.)ident(x) comment(// => 10) +ident(println) keyword(new) ident(Alpha)operator(()(\))operator(.)ident(y) comment(// => 12 when referenced inside source file, error outside) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.5) +comment(//----------------------------------------------------------------------------------) +comment(// You can examine the stacktrace to determine the calling class: see 10.4) +comment(// When executing a script from a groovy source file, you can either:) +ident(println) ident(getClass)operator(()(\))operator(.)ident(classLoader)operator(.)ident(resourceLoader)operator(.)ident(loadGroovySource)operator(()ident(getClass)operator(()(\))operator(.)ident(name)(\)) +comment(// => file:/C:/Projects/GroovyExamples/Pleac/classes/pleac12.groovy) +comment(// or for the initially started script when started using the standard .bat/.sh files) +ident(println) pre_type(System)operator(.)ident(properties)operator(.)string +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.6) +comment(//----------------------------------------------------------------------------------) +comment(// For code which executes at class startup, see the initialization code block) +comment(// mechanism mentioned in 12.3. For code which should execute during shutdown) +comment(// see the finalize(\) method discussed (including limitations\) in 13.2.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.7) +comment(//----------------------------------------------------------------------------------) +comment(// Each JVM process may have its own classpath (and indeed its own version of Java) +comment(// runtime and libraries\). You "simply" supply a classpath pointing to different) +comment(// locations to obtain different modules.) +comment(// Groovy augments the JVM behaviour by allowing individuals to have a ~/.groovy/lib) +comment(// directory with additional libraries (and potentially other resources\).) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.8) +comment(//----------------------------------------------------------------------------------) +comment(// To make your code available to others could involve any of the following:) +comment(// (1\) make your source code available) +comment(// (2\) if you are creating a standard class, use the jar tool to package the) +comment(// compiled code into a jar - this is then added to the classpath to use) +comment(// (3\) if the jar relies on additional jars, this is sometimes specified in) +comment(// a special manifest file within the jar) +comment(// (4\) if the code is designed to run within a container environment, there) +comment(// might be additional packaging, e.g. servlets might be packaged in a war) +comment(// file - essentially a jar file with extra metadata in xml format.) +comment(// (5\) you might also supply your package to a well known repository such as the) +comment(// maven repository - and you will add dependency information in xml format) +comment(// (6\) you may use platform specific installers to produce easily installable) +comment(// components (e.g. windows .exe files or linux rpm's\)) +comment(// (7\) you may spackage up your components as a plugin (e.g. as an eclipse plugin\)) +comment(// this is also typically in jar/zip like format with additional metadata) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.9) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy has no SelfLoader. Class loading can be delayed using external scripts) +comment(// and by using the Class.forName(\) approach discussed in 12.2/12.3. If you have) +comment(// critical performance issues, you can use these techniques and keep your class) +comment(// size small to maximise the ability to defer loading. There are other kinds of) +comment(// performance tradeoffs you can make too. Alot of work has been done with JIT) +comment(// (just in time\) compilers for bytecode. You can pre-compile Groovy source files) +comment(// into bytecode using the groovy compiler (groovyc\). You can also do this on) +comment(// the fly for scripts you know you are going to need shortly.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.10) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy has no AutoLoader. See the discussion in 12.9 for some techniques to) +comment(// impact program performance. There are many techniques available to speed up) +comment(// program performance (and in particular load speed\). Some of these utilise) +comment(// techniques similar in nature to the technique used by the AutoLoader.) +comment(// As already mentioned, when you load a class into the JVM, any statically) +comment(// referenced class is also loaded. If you reference interfaces rather than) +comment(// concrete implementations, only the interface need be loaded. If you must) +comment(// reference a concrete implementation you can use either a Proxy class or) +comment(// classloader tricks to delay the loading of a full class (e.g. you supply a) +comment(// Proxy class with just one method implemented or a lazy-loading Proxy which) +comment(// loads the real class only when absolutely required\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.11) +comment(//----------------------------------------------------------------------------------) +comment(// You can use Categories to override Groovy and Java base functionality.) +ident(println) keyword(new) pre_type(Date)operator(()(\))operator(.)ident(time) comment(// => 1169019557140) + +type(class) class(DateCategory) operator({) comment(// the class name by convention ends with category) + comment(// we can add new functionality) + directive(static) type(float) ident(getFloatTime)operator(()pre_type(Date) ident(self)(\)) operator({) + keyword(return) operator(()type(float)(\)) ident(self)operator(.)ident(getTime)operator(()(\)) + (}) + comment(// we can override existing functionality (now seconds since 1970 not millis\)) + directive(static) type(long) ident(asSeconds)operator(()pre_type(Date) ident(self)(\)) operator({) + keyword(return) operator(()type(long)(\)) operator(()ident(self)operator(.)ident(getTime)operator(()(\))operator(/)integer(1000)(\)) + (}) +(}) + +ident(use) operator(()ident(DateCategory)(\)) operator({) + ident(println) keyword(new) pre_type(Date)operator(()(\))operator(.)ident(floatTime) comment(// => 1.1690195E12) + ident(println) keyword(new) pre_type(Date)operator(()(\))operator(.)ident(asSeconds)operator(()(\)) comment(// => 1169019557) +(}) + +comment(// We can also use the 'as' keyword) +type(class) class(MathLib) operator({) + keyword(def) method(triple)operator(()ident(n)(\)) operator({) ident(n) operator(*) integer(4) (}) + keyword(def) method(twice)operator(()ident(n)(\)) operator({) ident(n) operator(*) integer(2) (}) +(}) +keyword(def) ident(m) operator(=) keyword(new) ident(MathLib)operator(()(\)) +ident(println) ident(m)operator(.)ident(twice)operator(()integer(10)(\)) comment(// => 20) +ident(println) ident(m)operator(.)ident(triple)operator(()integer(10)(\)) comment(// => 40 (Intentional Bug!\)) +comment(// we might want to make use of some funtionality in the math) +comment(// library but want to later some of its features slightly or fix) +comment(// some bugs, we can simply import the original using a different name) +keyword(import) include(MathLib) keyword(as) class(BuggyMathLib) +comment(// now we could define our own MathLib which extended or had a delegate) +comment(// of the BuggyMathLib class) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.12) +comment(//----------------------------------------------------------------------------------) +comment(// Many Java and Groovy programs emit a stacktrace when an error occurs.) +comment(// This shows both the calling and called programs (with line numbers if) +comment(// supplied\). Groovy pretties up stacktraces to show less noise. You can use -d) +comment(// or --debug on the commandline to force it to always produce full stacktraces.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.13) +comment(//----------------------------------------------------------------------------------) +comment(// already have log10, how to create log11 to log100) +operator(()integer(11)operator(..)integer(100)(\))operator(.)ident(each) operator({) type(int) ident(base) operator(->) + ident(binding)operator(.)stringdelimiter(")> operator(=) operator({) type(int) ident(n) operator(->) pre_type(Math)operator(.)ident(log)operator(()ident(n)(\)) operator(/) pre_type(Math)operator(.)ident(log)operator(()ident(base)(\)) (}) +(}) +ident(println) ident(log20)operator(()integer(400)(\)) comment(// => 2.0) +ident(println) ident(log100)operator(()integer(1000000)(\)) comment(// => 3.0 (displays 2.9999999999999996 using doubles\)) + +comment(// same thing again use currying) +keyword(def) ident(logAnyBase) operator(=) operator({) ident(base)operator(,) ident(n) operator(->) pre_type(Math)operator(.)ident(log)operator(()ident(n)(\)) operator(/) pre_type(Math)operator(.)ident(log)operator(()ident(base)(\)) (}) +operator(()integer(11)operator(..)integer(100)(\))operator(.)ident(each) operator({) type(int) ident(base) operator(->) + ident(binding)operator(.)stringdelimiter(")> operator(=) ident(logAnyBase)operator(.)ident(curry)operator(()ident(base)(\)) +(}) +ident(println) ident(log20)operator(()integer(400)(\)) comment(// => 2.0) +ident(println) ident(log100)operator(()integer(1000000)(\)) comment(// => 3.0 (displays 2.9999999999999996 using doubles\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.14) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy intefaces with C in the same way as Java: using JNI) +comment(// For this discussion we will ignoring platform specific options and CORBA.) +comment(// This tutorial here describes how to allow Java (and hence Groovy\) to) +comment(// call a C program which generates UUIDs:) +comment(// http://ringlord.com/publications/jni-howto/) +comment(// Here's another useful reference:) +comment(// http://weblogs.java.net/blog/kellyohair/archive/2006/01/compilation_of_1.html) +comment(// And of course, Sun's tutorial:) +comment(// http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jni.html) + +comment(// You might also want to consider SWIG which simplifies connecting) +comment(// C/C++ to many scripting languages including Java (and hence Groovy\)) +comment(// More details: http://www.swig.org/) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.15) +comment(//----------------------------------------------------------------------------------) +comment(// See discussion for 12.14) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.16) +comment(//----------------------------------------------------------------------------------) +comment(// The standard documentation system for Java is JavaDoc.) +comment(// Documentation for JavaDoc is part of a Java installation.) +comment(// Groovy has a GroovyDoc tool planned which expands upon the JavaDoc tool) +comment(// but work on the tool hasn't progressed much as yet.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.17) +comment(//----------------------------------------------------------------------------------) +comment(// Most libraries for Java (and hence Groovy\) come precompiled. You simply download) +comment(// the jar and place it somewhere on your CLASSPATH.) + +comment(// If only source code is available, you need to download the source and follow any) +comment(// instuctions which came with the source. Most projects use one of a handful of) +comment(// build tools to compile, test and package their artifacts. Typical ones are Ant) +comment(// and Maven which you need to install according to their respective instructions.) + +comment(// If using Ant, you need to unpack the source files then type 'ant'.) + +comment(// If using Maven, you need to unpack the source files then type 'maven'.) + +comment(// If you are using Maven or Ivy for dependency management you can add) +comment(// the following lines to your project description file.) +comment(/* + + commons-collections + commons-collections + 3.2 + +*/) +comment(// This will automatically download the particular version of the referenced) +comment(// library file and also provide hooks so that you can make this automatically) +comment(// available in your classpath.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.18) +comment(//----------------------------------------------------------------------------------) +comment(// example groovy file for a "module") +keyword(import) include(org.apache.commons.lang.WordUtils) + +type(class) class(Greeter) operator({) + keyword(def) ident(name) + ident(Greeter)operator(()ident(who)(\)) operator({) ident(name) operator(=) ident(WordUtils)operator(.)ident(capitalize)operator(()ident(who)(\)) (}) + keyword(def) method(salute)operator(()(\)) operator({) stringcontent(!)delimiter(")> (}) +(}) + +comment(// test class) +type(class) class(GreeterTest) directive(extends) ident(GroovyTestCase) operator({) + keyword(def) method(testGreeting)operator(()(\)) operator({) + keyword(assert) keyword(new) ident(Greeter)operator(()string(\))operator(.)ident(salute)operator(()(\)) + (}) +(}) + +comment(// Typical Ant build file (could be in Groovy instead of XML\):) +comment(/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + +*/) + +comment(// Typical dependency management file) +comment(/* + + + 4.0.0 + groovy + module + Greeter + 1.0 + jar + Greeter Module/description> + + + commons-lang + commons-lang + 2.2 + + + +*/) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_12.19) +comment(//----------------------------------------------------------------------------------) +comment(// Searching available modules in repositories:) +comment(// You can browse the repositories online, e.g. ibiblio.org/maven2 or various) +comment(// plugins are available for IDEs which do this for you, e.g. JarJuggler for IntelliJ.) + +comment(// Searching currently "installed" modules:) +comment(// Browse your install directory, view your maven POM file, look in your ~/.groovy/lib) +comment(// directory, turn on debug modes and watch classloader messages ...) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.0) +comment(//----------------------------------------------------------------------------------) +comment(// Classes and objects in Groovy are rather straigthforward) +type(class) class(Person) operator({) + comment(// Class variables (also called static attributes\) are prefixed by the keyword static) + directive(static) ident(personCounter)operator(=)integer(0) + keyword(def) ident(age)operator(,) ident(name) comment(// this creates setter and getter methods) + directive(private) ident(alive) + + comment(// object constructor) + ident(Person)operator(()ident(age)operator(,) ident(name)operator(,) ident(alive) operator(=) keyword(true)(\)) operator({) comment(// Default arg like in C++) + local_variable(this)operator(.)ident(age) operator(=) ident(age) + local_variable(this)operator(.)ident(name) operator(=) ident(name) + local_variable(this)operator(.)ident(alive) operator(=) ident(alive) + ident(personCounter) operator(+=) integer(1) + comment(// There is a '++' operator in Groovy but using += is often clearer.) + (}) + + keyword(def) method(die)operator(()(\)) operator({) + ident(alive) operator(=) keyword(false) + ident(println) stringcontent( has died at the age of )inlinecontent(.)delimiter(")> + ident(alive) + (}) + + keyword(def) method(kill)operator(()ident(anotherPerson)(\)) operator({) + ident(println) stringcontent( is killing )inlinecontent(.name.)delimiter(")> + ident(anotherPerson)operator(.)ident(die)operator(()(\)) + (}) + + comment(// methods used as queries generally start with is, are, will or can) + comment(// usually have the '?' suffix) + keyword(def) method(isStillAlive)operator(()(\)) operator({) + ident(alive) + (}) + + keyword(def) method(getYearOfBirth)operator(()(\)) operator({) + keyword(new) pre_type(Date)operator(()(\))operator(.)ident(year) operator(-) ident(age) + (}) + + comment(// Class method (also called static method\)) + directive(static) ident(getNumberOfPeople)operator(()(\)) operator({) comment(// accessors often start with get) + comment(// in which case you can call it like) + comment(// it was a field (without the get\)) + ident(personCounter) + (}) +(}) + +comment(// Using the class:) +comment(// Create objects of class Person) +ident(lecter) operator(=) keyword(new) ident(Person)operator(()integer(47)operator(,) string(\)) +ident(starling) operator(=) keyword(new) ident(Person)operator(()integer(29)operator(,) stringoperator(,) keyword(true)(\)) +ident(pazzi) operator(=) keyword(new) ident(Person)operator(()integer(40)operator(,) stringoperator(,) keyword(true)(\)) + +comment(// Calling a class method) +ident(println) stringcontent(.numberOfPeople Person objects.)delimiter(")> + +ident(println) stringcontent(.name is )inlinecontent(.)delimiter(")> +ident(lecter)operator(.)ident(kill)operator(()ident(pazzi)(\)) +ident(println) stringcontent(.name is )inlinecontent(.)delimiter(")> + +ident(println) stringcontent(.name was born in )inlinecontent(.yearOfBirth.)delimiter(")> +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.1) +comment(//----------------------------------------------------------------------------------) +comment(// Classes may have no constructor.) +type(class) class(MyClass) operator({) (}) + +ident(aValidButNotVeryUsefulObject) operator(=) keyword(new) ident(MyClass)operator(()(\)) + +comment(// If no explicit constructor is given a default implicit) +comment(// one which supports named parameters is provided.) +type(class) class(MyClass2) operator({) + keyword(def) ident(start) operator(=) keyword(new) pre_type(Date)operator(()(\)) + keyword(def) ident(age) operator(=) integer(0) +(}) +ident(println) keyword(new) ident(MyClass2)operator(()key(age)operator(:)integer(4)(\))operator(.)ident(age) comment(// => 4) + +comment(// One or more explicit constructors may also be provided) +type(class) class(MyClass3) operator({) + keyword(def) ident(start) + keyword(def) ident(age) + ident(MyClass3)operator(()ident(date)operator(,) ident(age)(\)) operator({) + ident(start) operator(=) ident(date) + local_variable(this)operator(.)ident(age) operator(=) ident(age) + (}) +(}) +ident(println) keyword(new) ident(MyClass3)operator(()keyword(new) pre_type(Date)operator(()(\))operator(,) integer(20)(\))operator(.)ident(age) comment(// => 20) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.2) +comment(//----------------------------------------------------------------------------------) +comment(// Objects are destroyed by the JVM garbage collector.) +comment(// The time of destroying is not predicated but left up to the JVM.) +comment(// There is no direct support for destructor. There is a courtesy) +comment(// method called finalize(\) which the JVM may call when disposing) +comment(// an object. If you need to free resources for an object, like) +comment(// closing a socket or killing a spawned subprocess, you should do) +comment(// it explicitly - perhaps by supporting your own lifecycle methods) +comment(// on your class, e.g. close(\).) + +type(class) class(MyClass4)operator({) + type(void) ident(finalize)operator(()(\)) operator({) + ident(println) stringcontent(] is dying at )inlinedelimiter(")> + (}) +(}) + +comment(// test code) +integer(50)operator(.)ident(times) operator({) + keyword(new) ident(MyClass4)operator(()(\)) +(}) +integer(20)operator(.)ident(times) operator({) + pre_type(System)operator(.)ident(gc)operator(()(\)) +(}) +comment(// => (between 0 and 50 lines similar to below\)) +comment(// Object [internal id=10884088] is dying at Wed Jan 10 16:33:33 EST 2007) +comment(// Object [internal id=6131844] is dying at Wed Jan 10 16:33:33 EST 2007) +comment(// Object [internal id=12245160] is dying at Wed Jan 10 16:33:33 EST 2007) +comment(// ...) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.3) +comment(//----------------------------------------------------------------------------------) +comment(// You can write getter and setter methods explicitly as shown below.) +comment(// One convention is to use set and get at the start of method names.) +type(class) class(Person2) operator({) + directive(private) ident(name) + keyword(def) method(getName)operator(()(\)) operator({) ident(name) (}) + keyword(def) method(setName)operator(()ident(name)(\)) operator({) local_variable(this)operator(.)ident(name) operator(=) ident(name) (}) +(}) + +comment(// You can also just use def which auto defines default getters and setters.) +type(class) class(Person3) operator({) + keyword(def) ident(age)operator(,) ident(name) +(}) + +comment(// Any variables marked as final will only have a default getter.) +comment(// You can also write an explicit getter. For a write-only variable) +comment(// just write only a setter.) +type(class) class(Person4) operator({) + directive(final) ident(age) comment(// getter only) + keyword(def) ident(name) comment(// getter and setter) + directive(private) ident(color) comment(// private) + keyword(def) method(setColor)operator(()(\)) operator({) local_variable(this)operator(.)ident(color) operator(=) ident(color) (}) comment(// setter only) +(}) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.4) +comment(//----------------------------------------------------------------------------------) +type(class) class(Person5) operator({) + comment(// Class variables (also called static attributes\) are prefixed by the keyword static) + directive(static) ident(personCounter) operator(=) integer(0) + + directive(static) ident(getPopulation)operator(()(\)) operator({) + ident(personCounter) + (}) + ident(Person5)operator(()(\)) operator({) + ident(personCounter) operator(+=) integer(1) + (}) + type(void) ident(finalize)operator(()(\)) operator({) + ident(personCounter) operator(-=) integer(1) + (}) +(}) +ident(people) operator(=) type([]) +integer(10)operator(.)ident(times) operator({) + ident(people) operator(+=) keyword(new) ident(Person5)operator(()(\)) +(}) +ident(println) stringcontent( people alive)delimiter(")> +comment(// => There are 10 people alive) + +ident(alpha) operator(=) keyword(new) ident(FixedArray)operator(()(\)) +ident(println) stringcontent(.maxBounds)delimiter(")> + +ident(beta) operator(=) keyword(new) ident(FixedArray)operator(()(\)) +ident(beta)operator(.)ident(maxBounds) operator(=) integer(50) +ident(println) stringcontent(.maxBounds)delimiter(")> + +type(class) class(FixedArray) operator({) + directive(static) ident(maxBounds) operator(=) integer(100) + + keyword(def) method(getMaxBounds)operator(()(\)) operator({) + ident(maxBounds) + (}) + keyword(def) method(setMaxBounds)operator(()ident(value)(\)) operator({) + ident(maxBounds) operator(=) ident(value) + (}) +(}) +comment(// =>) +comment(// Bound on alpha is 100) +comment(// Bound on alpha is 50) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.5) +comment(//----------------------------------------------------------------------------------) +comment(// The fields of this struct-like class are dynamically typed) +type(class) class(DynamicPerson) operator({) keyword(def) ident(name)operator(,) ident(age)operator(,) ident(peers) (}) +ident(p) operator(=) keyword(new) ident(DynamicPerson)operator(()(\)) +ident(p)operator(.)ident(name) operator(=) string +ident(p)operator(.)ident(age) operator(=) integer(13) +ident(p)operator(.)ident(peers) operator(=) operator([)stringoperator(,) stringoperator(,) string(]) +ident(p)operator(.)ident(setPeers)operator(()operator([)stringoperator(,) stringoperator(,) string(]\)) comment(// alternative using implicit setter) +ident(p)operator([)string(]) operator(=) operator([)stringoperator(,) stringoperator(,) string(]) comment(// alternative access using name of field) +ident(println) stringcontent(.age, )inlinecontent(.name's first friend is )inlinedelimiter(")> +comment(// => At age 13, Jason Smythe's first friend is Wilbur) + +comment(// The fields of this struct-like class are statically typed) +type(class) class(StaticPerson) operator({) pre_type(String) ident(name)operator(;) type(int) ident(age)operator(;) pre_type(List) ident(peers) (}) +ident(p) operator(=) keyword(new) ident(StaticPerson)operator(()key(name)operator(:)stringoperator(,) key(age)operator(:)integer(14)operator(,) key(peers)operator(:)operator([)stringoperator(,)stringoperator(,)string(]\)) +ident(println) stringcontent(.age, )inlinecontent(.name's first friend is )inlinedelimiter(")> +comment(// => At age 14, Jason's first friend is Fred) + + +type(class) class(Family) operator({) keyword(def) ident(head)operator(,) ident(address)operator(,) ident(members) (}) +ident(folks) operator(=) keyword(new) ident(Family)operator(()key(head)operator(:)keyword(new) ident(DynamicPerson)operator(()key(name)operator(:)stringoperator(,)key(age)operator(:)integer(34)(\)\)) + +comment(// supply of own accessor method for the struct for error checking) +type(class) class(ValidatingPerson) operator({) + directive(private) ident(age) + keyword(def) method(printAge)operator(()(\)) operator({) ident(println) string operator(+) ident(age) (}) + keyword(def) method(setAge)operator(()ident(value)(\)) operator({) + keyword(if) operator(()operator(!)operator(()ident(value) keyword(instanceof) pre_type(Integer)(\)\)) + keyword(throw) keyword(new) pre_type(IllegalArgumentException)operator(()stringcontent(' isn't an Integer)delimiter(")>(\)) + keyword(if) operator(()ident(value) operator(>) integer(150)(\)) + keyword(throw) keyword(new) pre_type(IllegalArgumentException)operator(()stringcontent( is unreasonable)delimiter(")>(\)) + ident(age) operator(=) ident(value) + (}) +(}) + +comment(// test ValidatingPerson) +keyword(def) method(tryCreate)operator(()ident(arg)(\)) operator({) + keyword(try) operator({) + keyword(new) ident(ValidatingPerson)operator(()key(age)operator(:)ident(arg)(\))operator(.)ident(printAge)operator(()(\)) + (}) keyword(catch) operator(()pre_type(Exception) ident(ex)(\)) operator({) + ident(println) ident(ex)operator(.)ident(message) + (}) +(}) + +ident(tryCreate)operator(()integer(20)(\)) +ident(tryCreate)operator(()string(\)) +ident(tryCreate)operator(()integer(200)(\)) +comment(// =>) +comment(// Age=20) +comment(// Argument 'Youngish' isn't an Integer) +comment(// Age 200 is unreasonable) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.6) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy objects are (loosely speaking\) extended Java objects.) +comment(// Java's Object class provides a clone(\) method. The conventions of) +comment(// clone(\) are that if I say a = b.clone(\) then a and b should be) +comment(// different objects with the same type and value. Java doesn't) +comment(// enforce a class to implement a clone(\) method at all let alone) +comment(// require that one has to meet these conventions. Classes which) +comment(// do support clone(\) should implement the Cloneable interface and) +comment(// implement an equals(\) method.) +comment(// Groovy follows Java's conventions for clone(\).) + +type(class) class(A) directive(implements) pre_type(Cloneable) operator({) + keyword(def) ident(name) + type(boolean) ident(equals)operator(()pre_type(Object) ident(other)(\)) operator({) + ident(other) keyword(instanceof) ident(A) operator(&&) local_variable(this)operator(.)ident(name) operator(==) ident(other)operator(.)ident(name) + (}) +(}) +ident(ob1) operator(=) keyword(new) ident(A)operator(()key(name)operator(:)string(\)) + +ident(ob2) operator(=) ident(ob1)operator(.)ident(clone)operator(()(\)) +keyword(assert) operator(!)ident(ob1)operator(.)ident(is)operator(()ident(ob2)(\)) +keyword(assert) ident(ob1)operator(.)ident(class) operator(==) ident(ob2)operator(.)ident(class) +keyword(assert) ident(ob2)operator(.)ident(name) operator(==) ident(ob1)operator(.)ident(name) +keyword(assert) ident(ob1) operator(==) ident(ob2) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.7) +comment(//----------------------------------------------------------------------------------) +type(class) class(CanFlicker) operator({) + keyword(def) method(flicker)operator(()ident(arg)(\)) operator({) keyword(return) ident(arg) operator(*) integer(2) (}) +(}) +ident(methname) operator(=) string +keyword(assert) keyword(new) ident(CanFlicker)operator(()(\))operator(.)ident(invokeMethod)operator(()ident(methname)operator(,) integer(10)(\)) operator(==) integer(20) +keyword(assert) keyword(new) ident(CanFlicker)operator(()(\))operator(.)stringdelimiter(")>operator(()integer(10)(\)) operator(==) integer(20) + +type(class) class(NumberEcho) operator({) + keyword(def) method(one)operator(()(\)) operator({) integer(1) (}) + keyword(def) method(two)operator(()(\)) operator({) integer(2) (}) + keyword(def) method(three)operator(()(\)) operator({) integer(3) (}) +(}) +ident(obj) operator(=) keyword(new) ident(NumberEcho)operator(()(\)) +comment(// call methods on the object, by name) +keyword(assert) operator([)stringoperator(,) stringoperator(,) stringoperator(,) stringoperator(,) string(])operator(.)ident(collect)operator({) ident(obj)operator(.)stringdelimiter(")>operator(()(\)) (})operator(.)ident(join)operator(()(\)) operator(==) string +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.8) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy can work with Groovy objects which inherit from a common base) +comment(// class called GroovyObject or Java objects which inherit from Object.) + +comment(// the class of the object) +keyword(assert) stringoperator(.)ident(class) operator(==) ident(java)operator(.)ident(lang)operator(.)ident(String) + +comment(// Groovy classes are actually objects of class Class and they) +comment(// respond to methods defined in the Class class as well) +keyword(assert) stringoperator(.)ident(class)operator(.)ident(class) operator(==) ident(java)operator(.)ident(lang)operator(.)ident(Class) +keyword(assert) operator(!)stringoperator(.)ident(class)operator(.)ident(isArray)operator(()(\)) + +comment(// ask an object whether it is an instance of particular class) +ident(n) operator(=) float(4.7f) +ident(println) operator(()ident(n) keyword(instanceof) pre_type(Integer)(\)) comment(// false) +ident(println) operator(()ident(n) keyword(instanceof) pre_type(Float)(\)) comment(// true) +ident(println) operator(()ident(n) keyword(instanceof) pre_type(Double)(\)) comment(// false) +ident(println) operator(()ident(n) keyword(instanceof) pre_type(String)(\)) comment(// false) +ident(println) operator(()ident(n) keyword(instanceof) ident(StaticPerson)(\)) comment(// false) + +comment(// ask if a class or interface is either the same as, or is a) +comment(// superclass or superinterface of another class) +ident(println) ident(n)operator(.)ident(class)operator(.)ident(isAssignableFrom)operator(()pre_type(Float)operator(.)ident(class)(\)) comment(// true) +ident(println) ident(n)operator(.)ident(class)operator(.)ident(isAssignableFrom)operator(()pre_type(String)operator(.)ident(class)(\)) comment(// false) + +comment(// can a Groovy object respond to a particular method?) +keyword(assert) keyword(new) ident(CanFlicker)operator(()(\))operator(.)ident(metaClass)operator(.)ident(methods)operator(*.)ident(name)operator(.)ident(contains)operator(()string(\)) + +type(class) class(POGO)operator({)(}) +ident(println) operator(()ident(obj)operator(.)ident(metaClass)operator(.)ident(methods)operator(*.)ident(name) operator(-) keyword(new) ident(POGO)operator(()(\))operator(.)ident(metaClass)operator(.)ident(methods)operator(*.)ident(name)(\)) +comment(// => ["one", "two", "three"]) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.9) +comment(//----------------------------------------------------------------------------------) +comment(// Most classes in Groovy are inheritable) +type(class) class(Person6)operator({) keyword(def) ident(age)operator(,) ident(name) (}) +ident(dude) operator(=) keyword(new) ident(Person6)operator(()key(name)operator(:)stringoperator(,) key(age)operator(:)integer(23)(\)) +ident(println) stringcontent(.name is age )inlinecontent(.age.)delimiter(")> + +comment(// Inheriting from Person) +type(class) class(Employee) directive(extends) ident(Person6) operator({) + keyword(def) ident(salary) +(}) +ident(empl) operator(=) keyword(new) ident(Employee)operator(()key(name)operator(:)stringoperator(,) key(age)operator(:)integer(23)operator(,) key(salary)operator(:)integer(200)(\)) +ident(println) stringcontent(.name is age )inlinecontent(.age and has salary )inlinecontent(.salary.)delimiter(")> + +comment(// Many built-in class can be inherited the same way) +type(class) class(WierdList) directive(extends) pre_type(ArrayList) operator({) + keyword(def) method(size)operator(()(\)) operator({) comment(// size method in this class is overridden) + local_variable(super)operator(.)ident(size)operator(()(\)) operator(*) integer(2) + (}) +(}) +ident(a) operator(=) keyword(new) ident(WierdList)operator(()(\)) +ident(a)operator(.)ident(add)operator(()string(\)) +ident(a)operator(.)ident(add)operator(()string(\)) +ident(println) ident(a)operator(.)ident(size)operator(()(\)) comment(// => 4) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.10) +comment(//----------------------------------------------------------------------------------) +type(class) class(Person7) operator({) keyword(def) ident(firstname)operator(,) ident(surname)operator(;) keyword(def) method(getName)operator(()(\))operator({) ident(firstname) operator(+) string operator(+) ident(surname) (}) (}) +type(class) class(Employee2) directive(extends) ident(Person7) operator({) + keyword(def) ident(employeeId) + keyword(def) method(getName)operator(()(\))operator({) string operator(+) ident(employeeId) (}) + keyword(def) method(getRealName)operator(()(\))operator({) local_variable(super)operator(.)ident(getName)operator(()(\)) (}) +(}) +ident(p) operator(=) keyword(new) ident(Person7)operator(()key(firstname)operator(:)stringoperator(,) key(surname)operator(:)string(\)) +ident(println) ident(p)operator(.)ident(name) +comment(// =>) +comment(// Jason Smythe) +ident(e) operator(=) keyword(new) ident(Employee2)operator(()key(firstname)operator(:)stringoperator(,) key(surname)operator(:)stringoperator(,) key(employeeId)operator(:)integer(12349876)(\)) +ident(println) ident(e)operator(.)ident(name) +ident(println) ident(e)operator(.)ident(realName) +comment(// =>) +comment(// Employee Number 12349876) +comment(// Jason Smythe) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.11) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy's built in constructor and auto getter/setter features) + comment(// give you the required functionalty already but you could also) + comment(// override invokeMethod(\) for trickier scenarios.) +type(class) class(Person8) operator({) + keyword(def) ident(name)operator(,) ident(age)operator(,) ident(peers)operator(,) ident(parent) + keyword(def) method(newChild)operator(()ident(args)(\)) operator({) keyword(new) ident(Person8)operator(()key(parent)operator(:)local_variable(this)operator(,) operator(*)operator(:)ident(args)(\)) (}) +(}) + +ident(dad) operator(=) keyword(new) ident(Person8)operator(()key(name)operator(:)stringoperator(,) key(age)operator(:)integer(23)(\)) +ident(kid) operator(=) ident(dad)operator(.)ident(newChild)operator(()key(name)operator(:)stringoperator(,) key(age)operator(:)integer(2)(\)) +ident(println) stringdelimiter(")> +comment(// => Kid's parent is Jason) + +comment(// additional fields ...) +type(class) class(Employee3) directive(extends) ident(Person8) operator({) keyword(def) ident(salary)operator(,) ident(boss) (}) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.12) +comment(//----------------------------------------------------------------------------------) +comment(// Fields marked as private in Groovy can't be trampled by another class in) +comment(// the class hierarchy) +type(class) class(Parent) operator({) + directive(private) ident(name) comment(// my child's name) + keyword(def) method(setChildName)operator(()ident(value)(\)) operator({) ident(name) operator(=) ident(value) (}) + keyword(def) method(getChildName)operator(()(\)) operator({) ident(name) (}) +(}) +type(class) class(GrandParent) directive(extends) ident(Parent) operator({) + directive(private) ident(name) comment(// my grandchild's name) + keyword(def) method(setgrandChildName)operator(()ident(value)(\)) operator({) ident(name) operator(=) ident(value) (}) + keyword(def) method(getGrandChildName)operator(()(\)) operator({) ident(name) (}) +(}) +ident(g) operator(=) keyword(new) ident(GrandParent)operator(()(\)) +ident(g)operator(.)ident(childName) operator(=) string +ident(g)operator(.)ident(grandChildName) operator(=) string +ident(println) ident(g)operator(.)ident(childName) comment(// => Jason) +ident(println) ident(g)operator(.)ident(grandChildName) comment(// => Rachel) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.13) +comment(//----------------------------------------------------------------------------------) +comment(// The JVM garbage collector copes with circular structures.) +comment(// You can test it with this code:) +type(class) class(Person9) operator({) + keyword(def) ident(friend) + type(void) ident(finalize)operator(()(\)) operator({) + ident(println) stringcontent(] is dying at )inlinedelimiter(")> + (}) +(}) + +keyword(def) method(makeSomeFriends)operator(()(\)) operator({) + keyword(def) ident(first) operator(=) keyword(new) ident(Person9)operator(()(\)) + keyword(def) ident(second) operator(=) keyword(new) ident(Person9)operator(()key(friend)operator(:)ident(first)(\)) + keyword(def) ident(third) operator(=) keyword(new) ident(Person9)operator(()key(friend)operator(:)ident(second)(\)) + keyword(def) ident(fourth) operator(=) keyword(new) ident(Person9)operator(()key(friend)operator(:)ident(third)(\)) + keyword(def) ident(fifth) operator(=) keyword(new) ident(Person9)operator(()key(friend)operator(:)ident(fourth)(\)) + ident(first)operator(.)ident(friend) operator(=) ident(fifth) +(}) + +ident(makeSomeFriends)operator(()(\)) +integer(100)operator(.)ident(times)operator({) + pre_type(System)operator(.)ident(gc)operator(()(\)) +(}) +comment(// =>) +comment(// Object [internal id=24478976] is dying at Tue Jan 09 22:24:31 EST 2007) +comment(// Object [internal id=32853087] is dying at Tue Jan 09 22:24:31 EST 2007) +comment(// Object [internal id=23664622] is dying at Tue Jan 09 22:24:31 EST 2007) +comment(// Object [internal id=10630672] is dying at Tue Jan 09 22:24:31 EST 2007) +comment(// Object [internal id=25921812] is dying at Tue Jan 09 22:24:31 EST 2007) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.14) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy provides numerous methods which are automatically associated with) +comment(// symbol operators, e.g. here is '<=>' which is associated with compareTo(\)) +comment(// Suppose we have a class with a compareTo operator, such as:) +type(class) class(Person10) directive(implements) pre_type(Comparable) operator({) + keyword(def) ident(firstname)operator(,) ident(initial)operator(,) ident(surname) + ident(Person10)operator(()ident(f)operator(,)ident(i)operator(,)ident(s)(\)) operator({) ident(firstname) operator(=) ident(f)operator(;) ident(initial) operator(=) ident(i)operator(;) ident(surname) operator(=) ident(s) (}) + type(int) ident(compareTo)operator(()ident(other)(\)) operator({) ident(firstname) operator(<=)operator(>) ident(other)operator(.)ident(firstname) (}) +(}) +ident(a) operator(=) keyword(new) ident(Person10)operator(()stringoperator(,) stringoperator(,) string(\)) +ident(b) operator(=) keyword(new) ident(Person10)operator(()stringoperator(,) stringoperator(,) string(\)) +ident(println) ident(a) operator(<=)operator(>) ident(b) +comment(// => -1) + +comment(// we can override the existing Person10's <=> operator as below) +comment(// so that now comparisons are made using the middle initial) +comment(// instead of the fisrtname:) +type(class) class(Person11) directive(extends) ident(Person10) operator({) + ident(Person11)operator(()ident(f)operator(,)ident(i)operator(,)ident(s)(\)) operator({) local_variable(super)operator(()ident(f)operator(,)ident(i)operator(,)ident(s)(\)) (}) + type(int) ident(compareTo)operator(()ident(other)(\)) operator({) ident(initial) operator(<=)operator(>) ident(other)operator(.)ident(initial) (}) +(}) + +ident(a) operator(=) keyword(new) ident(Person11)operator(()stringoperator(,) stringoperator(,) string(\)) +ident(b) operator(=) keyword(new) ident(Person11)operator(()stringoperator(,) stringoperator(,) string(\)) +ident(println) ident(a) operator(<=)operator(>) ident(b) +comment(// => 1) + +comment(// we could also in general use Groovy's categories to extend class functionality.) + +comment(// There is no way to directly overload the '""' (stringify\)) +comment(// operator in Groovy. However, by convention, classes which) +comment(// can reasonably be converted to a String will define a) +comment(// 'toString(\)' method as in the TimeNumber class defined below.) +comment(// The 'println' method will automatcally call an object's) +comment(// 'toString(\)' method as is demonstrated below. Furthermore,) +comment(// an object of that class can be used most any place where the) +comment(// interpreter is looking for a String value.) + +comment(//---------------------------------------) +comment(// NOTE: Groovy has various built-in Time/Date/Calendar classes) +comment(// which would usually be used to manipulate time objects, the) +comment(// following is supplied for educational purposes to demonstrate) +comment(// operator overloading.) +type(class) class(TimeNumber) operator({) + keyword(def) ident(h)operator(,) ident(m)operator(,) ident(s) + ident(TimeNumber)operator(()ident(hour)operator(,) ident(min)operator(,) ident(sec)(\)) operator({) ident(h) operator(=) ident(hour)operator(;) ident(m) operator(=) ident(min)operator(;) ident(s) operator(=) ident(sec) (}) + + keyword(def) method(toDigits)operator(()ident(s)(\)) operator({) ident(s)operator(.)ident(toString)operator(()(\))operator(.)ident(padLeft)operator(()integer(2)operator(,) string(\)) (}) + pre_type(String) ident(toString)operator(()(\)) operator({) + keyword(return) ident(toDigits)operator(()ident(h)(\)) operator(+) string operator(+) ident(toDigits)operator(()ident(m)(\)) operator(+) string operator(+) ident(toDigits)operator(()ident(s)(\)) + (}) + + keyword(def) method(plus)operator(()ident(other)(\)) operator({) + ident(s) operator(=) ident(s) operator(+) ident(other)operator(.)ident(s) + ident(m) operator(=) ident(m) operator(+) ident(other)operator(.)ident(m) + ident(h) operator(=) ident(h) operator(+) ident(other)operator(.)ident(h) + keyword(if) operator(()ident(s) operator(>=) integer(60)(\)) operator({) + ident(s) operator(%=) integer(60) + ident(m) operator(+=) integer(1) + (}) + keyword(if) operator(()ident(m) operator(>=) integer(60)(\)) operator({) + ident(m) operator(%=) integer(60) + ident(h) operator(+=) integer(1) + (}) + keyword(return) keyword(new) ident(TimeNumber)operator(()ident(h)operator(,) ident(m)operator(,) ident(s)(\)) + (}) + +(}) + +ident(t1) operator(=) keyword(new) ident(TimeNumber)operator(()integer(0)operator(,) integer(58)operator(,) integer(59)(\)) +ident(sec) operator(=) keyword(new) ident(TimeNumber)operator(()integer(0)operator(,) integer(0)operator(,) integer(1)(\)) +ident(min) operator(=) keyword(new) ident(TimeNumber)operator(()integer(0)operator(,) integer(1)operator(,) integer(0)(\)) +ident(println) ident(t1) operator(+) ident(sec) operator(+) ident(min) operator(+) ident(min) + +comment(//-----------------------------) +comment(// StrNum class example: Groovy's builtin String class already has the) +comment(// capabilities outlined in StrNum Perl example, however the '*' operator) +comment(// on Groovy's String class acts differently: It creates a string which) +comment(// is the original string repeated N times.) +comment(//) +comment(// Using Groovy's String class as is in this example:) +ident(x) operator(=) stringoperator(;) ident(y) operator(=) string +ident(z) operator(=) ident(x)operator(+)ident(y) +ident(r) operator(=) ident(z)operator(*)integer(3) comment(// r is "RedBlackRedBlackRedBlack") +ident(println) stringcontent(, )inlinecontent(, )inlinecontent(, and )inlinedelimiter(")> +ident(println) stringcontent( is )inlinecontent( )inlinedelimiter(")> +comment(// prints:) +comment(// values are Red, Black, RedBlack, and RedBlackRedBlackRedBlack) +comment(// Red is GE Black) + +comment(//-----------------------------) +type(class) class(FixNum) operator({) + keyword(def) ident(REGEX) operator(=) regexp + directive(static) directive(final) ident(DEFAULT_PLACES) operator(=) integer(0) + keyword(def) type(float) ident(value) + keyword(def) type(int) ident(places) + ident(FixNum)operator(()ident(value)(\)) operator({) + ident(initValue)operator(()ident(value)(\)) + keyword(def) ident(m) operator(=) ident(value)operator(.)ident(toString)operator(()(\)) operator(=~) ident(REGEX) + keyword(if) operator(()ident(m)(\)) ident(places) operator(=) ident(m)operator([)integer(0)(])operator([)integer(1)(])operator(.)ident(size)operator(()(\)) operator(-) integer(1) + keyword(else) ident(places) operator(=) ident(DEFAULT_PLACES) + (}) + ident(FixNum)operator(()ident(value)operator(,) ident(places)(\)) operator({) + ident(initValue)operator(()ident(value)(\)) + local_variable(this)operator(.)ident(places) operator(=) ident(places) + (}) + directive(private) ident(initValue)operator(()ident(value)(\)) operator({) + local_variable(this)operator(.)ident(value) operator(=) ident(value) + (}) + + keyword(def) method(plus)operator(()ident(other)(\)) operator({) + keyword(new) ident(FixNum)operator(()ident(value) operator(+) ident(other)operator(.)ident(value)operator(,) operator([)ident(places)operator(,) ident(other)operator(.)ident(places)(])operator(.)ident(max)operator(()(\)\)) + (}) + + keyword(def) method(multiply)operator(()ident(other)(\)) operator({) + keyword(new) ident(FixNum)operator(()ident(value) operator(*) ident(other)operator(.)ident(value)operator(,) operator([)ident(places)operator(,) ident(other)operator(.)ident(places)(])operator(.)ident(max)operator(()(\)\)) + (}) + + keyword(def) method(div)operator(()ident(other)(\)) operator({) + ident(println) stringdelimiter(")> + keyword(def) ident(result) operator(=) keyword(new) ident(FixNum)operator(()ident(value)operator(/)ident(other)operator(.)ident(value)(\)) + ident(result)operator(.)ident(places) operator(=) operator([)ident(places)operator(,)ident(other)operator(.)ident(places)(])operator(.)ident(max)operator(()(\)) + ident(result) + (}) + + pre_type(String) ident(toString)operator(()(\)) operator({) + comment(//m = value.toString(\) =~ /(\\d\)/ + REGEX) + pre_type(String)operator(.)ident(format)operator(()stringcontent(f)delimiter(")>operator(,) operator([)local_variable(this)operator(.)ident(class)operator(.)ident(name)operator(,) ident(value) keyword(as) type(float)(]) keyword(as) pre_type(Object)type([])(\)) + (}) +(}) + +ident(x) operator(=) keyword(new) ident(FixNum)operator(()integer(40)(\)) +ident(y) operator(=) keyword(new) ident(FixNum)operator(()integer(12)operator(,) integer(0)(\)) + +ident(println) stringcontent( and )inlinecontent( is )inlinedelimiter(")> +ident(println) stringcontent( and )inlinecontent( is )inlinedelimiter(")> + +ident(z) operator(=) ident(x)operator(/)ident(y) +ident(println) stringcontent( has )inlinecontent(.places places)delimiter(")> +ident(z)operator(.)ident(places) operator(=) integer(2) +ident(println) stringcontent( now has )inlinecontent(.places places)delimiter(")> + +ident(println) stringcontent( by )inlinecontent( is )inlinedelimiter(")> +ident(println) stringdelimiter(")> +comment(// =>) +comment(// sum of STRFixNum: 40 and STRFixNum: 12 is STRFixNum: 52) +comment(// product of STRFixNum: 40 and STRFixNum: 12 is STRFixNum: 480) +comment(// DEUG: Divide = 3.3333333333333335) +comment(// STRFixNum: 3 has 0 places) +comment(// STRFixNum: 3.33 now has 2 places) +comment(// div of STRFixNum: 40 by STRFixNum: 12 is STRFixNum: 3.33) +comment(// square of that is STRFixNum: 11.11) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_13.15) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy doesn't use the tie terminology but you can achieve) +comment(// similar results with Groovy's metaprogramming facilities) +type(class) class(ValueRing) operator({) + directive(private) ident(values) + keyword(def) method(add)operator(()ident(value)(\)) operator({) ident(values)operator(.)ident(add)operator(()integer(0)operator(,) ident(value)(\)) (}) + keyword(def) method(next)operator(()(\)) operator({) + keyword(def) ident(head) operator(=) ident(values)operator([)integer(0)(]) + ident(values) operator(=) ident(values)operator([)integer(1)operator(..)operator(-)integer(1)(]) operator(+) ident(head) + keyword(return) ident(head) + (}) +(}) +ident(ring) operator(=) keyword(new) ident(ValueRing)operator(()key(values)operator(:)operator([)stringoperator(,) string(]\)) +keyword(def) method(getColor)operator(()(\)) operator({) ident(ring)operator(.)ident(next)operator(()(\)) (}) +type(void) ident(setProperty)operator(()pre_type(String) ident(n)operator(,) ident(v)(\)) operator({) + keyword(if) operator(()ident(n) operator(==) string(\)) operator({) ident(ring)operator(.)ident(add)operator(()ident(v)(\))operator(;) keyword(return) (}) + local_variable(super)operator(.)ident(setProperty)operator(()ident(n)operator(,)ident(v)(\)) +(}) + +ident(println) stringcontent( )inlinecontent( )inlinecontent( )inlinecontent( )inlinecontent( )inlinedelimiter(")> +comment(// => red blue red blue red blue) + +ident(color) operator(=) string +ident(println) stringcontent( )inlinecontent( )inlinecontent( )inlinecontent( )inlinecontent( )inlinedelimiter(")> +comment(// => green red blue green red blue) + +comment(// Groovy doesn't have the $_ implicit variable so we can't show an) +comment(// example that gets rid of it. We can however show an example of how) +comment(// you could add in a simplified version of that facility into Groovy.) +comment(// We use Groovy's metaProgramming facilities. We execute our script) +comment(// in a new GroovyShell so that we don't affect subsequent examples.) +comment(// script:) +ident(x) operator(=) integer(3) +ident(println) stringdelimiter(")> +ident(y) operator(=) string operator(*) ident(x) +ident(println) stringdelimiter(")> + +comment(// metaUnderscore:) +type(void) ident(setProperty)operator(()pre_type(String) ident(n)operator(,) ident(v)(\)) operator({) + local_variable(super)operator(.)ident(setProperty)operator(()stringoperator(,)ident(v)(\)) + local_variable(super)operator(.)ident(setProperty)operator(()ident(n)operator(,)ident(v)(\)) +(}) + +keyword(new) ident(GroovyShell)operator(()(\))operator(.)ident(evaluate)operator(()ident(metaUnderscore) operator(+) ident(script)(\)) +comment(// =>) +comment(// 3) +comment(// catcatcat) + +comment(// We can get a little bit fancier by making an UnderscoreAware class) +comment(// that wraps up some of this functionality. This is not recommended) +comment(// as good Groovy style but mimicks the $_ behaviour in a sinple way.) +type(class) class(UnderscoreAware) directive(implements) ident(GroovyInterceptable) operator({) + directive(private) ident(_saved) + type(void) ident(setProperty)operator(()pre_type(String) ident(n)operator(,) ident(v)(\)) operator({) + ident(_saved) operator(=) ident(v) + local_variable(this)operator(.)ident(metaClass)operator(.)ident(setProperty)operator(()local_variable(this)operator(,) ident(n)operator(,) ident(v)(\)) + (}) + keyword(def) method(getProperty)operator(()pre_type(String) ident(n)(\)) operator({) + keyword(if) operator(()ident(n) operator(==) string(\)) keyword(return) ident(_saved) + local_variable(this)operator(.)ident(metaClass)operator(.)ident(getProperty)operator(()local_variable(this)operator(,) ident(n)(\)) + (}) + keyword(def) method(invokeMethod)operator(()pre_type(String) ident(name)operator(,) pre_type(Object) ident(args)(\)) operator({) + keyword(if) operator(()ident(name)operator(.)ident(startsWith)operator(()string(\)) operator(&&) ident(args)operator(.)ident(size)operator(()(\)) operator(==) integer(0)(\)) + ident(args) operator(=) operator([)ident(_saved)(]) keyword(as) pre_type(Object)type([]) + local_variable(this)operator(.)ident(metaClass)operator(.)ident(invokeMethod)operator(()local_variable(this)operator(,) ident(name)operator(,) ident(args)(\)) + (}) +(}) + +type(class) class(PerlishClass) directive(extends) ident(UnderscoreAware) operator({) + directive(private) ident(_age) + keyword(def) method(setAge)operator(()ident(age)(\))operator({) ident(_age) operator(=) ident(age) (}) + keyword(def) method(getAge)operator(()(\))operator({) ident(_age) (}) + keyword(def) method(test)operator(()(\)) operator({) + ident(age) operator(=) integer(25) + ident(println) stringdelimiter(")> comment(// explicit $_ supported) + ident(age)operator(++) + ident(println)operator(()(\)) comment(// implicit $_ will be injected) + (}) +(}) + +keyword(def) ident(x) operator(=) keyword(new) ident(PerlishClass)operator(()(\)) +ident(x)operator(.)ident(test)operator(()(\)) +comment(// =>) +comment(// 25) +comment(// 26) + +comment(// Autoappending hash:) +type(class) class(AutoMap) directive(extends) pre_type(HashMap) operator({) + type(void) ident(setProperty)operator(()pre_type(String) ident(name)operator(,) ident(v)(\)) operator({) + keyword(if) operator(()ident(containsKey)operator(()ident(name)(\)\)) operator({) + ident(put)operator(()ident(name)operator(,) ident(get)operator(()ident(name)(\)) operator(+) ident(v)(\)) + (}) keyword(else) operator({) + ident(put)operator(()ident(name)operator(,) operator([)ident(v)(]\)) + (}) + (}) +(}) +ident(m) operator(=) keyword(new) ident(AutoMap)operator(()(\)) +ident(m)operator(.)ident(beer) operator(=) string +ident(m)operator(.)ident(food) operator(=) string +ident(m)operator(.)ident(food) operator(=) string +ident(println) ident(m) +comment(// => ["food":["potatoes", "peas"], "beer":["guinness"]]) + +comment(// Case-Insensitive Hash:) +type(class) class(FoldedMap) directive(extends) pre_type(HashMap) operator({) + type(void) ident(setProperty)operator(()pre_type(String) ident(name)operator(,) ident(v)(\)) operator({) + ident(put)operator(()ident(name)operator(.)ident(toLowerCase)operator(()(\))operator(,) ident(v)(\)) + (}) + keyword(def) method(getProperty)operator(()pre_type(String) ident(name)(\)) operator({) + ident(get)operator(()ident(name)operator(.)ident(toLowerCase)operator(()(\)\)) + (}) +(}) +ident(tab) operator(=) keyword(new) ident(FoldedMap)operator(()(\)) +ident(tab)operator(.)ident(VILLAIN) operator(=) string +ident(tab)operator(.)ident(herOine) operator(=) string +ident(tab)operator(.)ident(villain) operator(+=) string +ident(println) ident(tab) +comment(// => ["heroine":"red riding hood", "villain":"big bad wolf"]) + +comment(// Hash That "Allows Look-Ups by Key or Value":) +type(class) class(RevMap) directive(extends) pre_type(HashMap) operator({) + type(void) ident(setProperty)operator(()pre_type(String) ident(n)operator(,) ident(v)(\)) operator({) ident(put)operator(()ident(n)operator(,)ident(v)(\))operator(;) ident(put)operator(()ident(v)operator(,)ident(n)(\)) (}) + type(void) ident(remove)operator(()ident(n)(\)) operator({) local_variable(super)operator(.)ident(remove)operator(()ident(get)operator(()ident(n)(\)\))operator(;) local_variable(super)operator(.)ident(remove)operator(()ident(n)(\)) (}) +(}) +ident(rev) operator(=) keyword(new) ident(RevMap)operator(()(\)) +ident(rev)operator(.)ident(Rojo) operator(=) string +ident(rev)operator(.)ident(Azul) operator(=) string +ident(rev)operator(.)ident(Verde) operator(=) string +ident(rev)operator(.)ident(EVIL) operator(=) operator([) stringoperator(,) string (]) +ident(rev)operator(.)ident(remove)operator(()string(\)) +ident(rev)operator(.)ident(remove)operator(()string(\)) +ident(println) ident(rev) +comment(// =>) +comment(// [["No way!", "Way!!"]:"EVIL", "EVIL":["No way!", "Way!!"], "Verde":"Green", "Green":"Verde"]) + +comment(// Infinite loop scenario:) +comment(// def x(n\) { x(++n\) }; x(0\)) +comment(// => Caught: java.lang.StackOverflowError) + +comment(// Multiple Strrams scenario:) +type(class) class(MultiStream) directive(extends) pre_type(PrintStream) operator({) + keyword(def) ident(streams) + ident(MultiStream)operator(()pre_type(List) ident(streams)(\)) operator({) + local_variable(super)operator(()ident(streams)operator([)integer(0)(]\)) + local_variable(this)operator(.)ident(streams) operator(=) ident(streams) + (}) + keyword(def) method(println)operator(()pre_type(String) ident(x)(\)) operator({) + ident(streams)operator(.)ident(each)operator({) local_variable(it)operator(.)ident(println)operator(()ident(x)(\)) (}) + (}) +(}) +ident(tee) operator(=) keyword(new) ident(MultiStream)operator(()operator([)pre_type(System)operator(.)ident(out)operator(,) pre_type(System)operator(.)ident(err)(]\)) +ident(tee)operator(.)ident(println) operator(()string(\)) +comment(// =>) +comment(// This goes two places) +comment(// This goes two places) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.0) +comment(//----------------------------------------------------------------------------------) +ident(As) ident(discussed) keyword(in) float(14.1)operator(,) ident(many) ident(database) ident(options) ident(exist)operator(,) ident(one) ident(of) ident(which) ident(is) ident(JDBC)operator(.) +ident(Over) integer(200) ident(JDBC) ident(drivers) ident(are) ident(listed) ident(at) ident(the) ident(following) pre_type(URL)operator(:) +key(http)operator(:)comment(//developers.sun.com/product/jdbc/drivers/browse_all.jsp) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.1) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy can make use of various Java persistence libraries and has special) +comment(// support built-in (e.g. datasets\) for interacting wth RDBMS systems.) +comment(// Some of the options include:) +comment(// object serialization (built in to Java\)) +comment(// pbeans: pbeans.sf.net) +comment(// prevayler: http://www.prevayler.org) +comment(// Berkeley DB Java edition: http://www.oracle.com/database/berkeley-db/je/) +comment(// JDBC: Over 200 drivers are listed at http://developers.sun.com/product/jdbc/drivers) +comment(// Datasets (special Groovy support\)) +comment(// XML via e.g. xstream or JAXB or XmlBeans or ...) +comment(// ORM: over 20 are listed at http://java-source.net/open-source/persistence) +comment(// JNI: can be used directly on a platform that supports e.g. DBM or via) +comment(// a cross platform API such as Apache APR which includes DBM routines:) +comment(// http://apr.apache.org/docs/apr-util/0.9/group__APR__Util__DBM.html) +comment(// jmork: used for Firefox/Thunderbird databases, e.g. address books, history files) +comment(// JDBC or Datasets would normally be most common for all examples in this chapter.) + + +comment(// Example shown using berkeley db Java edition - not quite as transparent as) +comment(// cookbook example as Berkeley DB Java addition makes transactions visible.) +keyword(import) include(com.sleepycat.je.*) +ident(tx) operator(=) keyword(null) +ident(envHome) operator(=) keyword(new) pre_type(File)operator(()string(\)) + +ident(myEnvConfig) operator(=) keyword(new) ident(EnvironmentConfig)operator(()(\)) +ident(myEnvConfig)operator(.)ident(setAllowCreate)operator(()keyword(true)(\)) +ident(myEnv) operator(=) keyword(new) ident(Environment)operator(()ident(envHome)operator(,) ident(myEnvConfig)(\)) + +ident(myDbConfig) operator(=) keyword(new) ident(DatabaseConfig)operator(()(\)) +ident(myDbConfig)operator(.)ident(setAllowCreate)operator(()keyword(true)(\)) +ident(myDb) operator(=) ident(myEnv)operator(.)ident(openDatabase)operator(()ident(tx)operator(,) stringoperator(,) ident(myDbConfig)(\)) + +ident(theKey) operator(=) keyword(new) ident(DatabaseEntry)operator(()stringoperator(.)ident(getBytes)operator(()string(\)\)) +ident(theData) operator(=) keyword(new) ident(DatabaseEntry)operator(()stringoperator(.)ident(getBytes)operator(()string(\)\)) +ident(myDb)operator(.)ident(put)operator(()ident(tx)operator(,) ident(theKey)operator(,) ident(theData)(\)) +keyword(if) operator(()ident(myDb)operator(.)ident(get)operator(()ident(tx)operator(,) ident(theKey)operator(,) ident(theData)operator(,) ident(LockMode)operator(.)ident(DEFAULT)(\)) operator(==) ident(OperationStatus)operator(.)ident(SUCCESS)(\)) operator({) + ident(key) operator(=) keyword(new) pre_type(String)operator(()ident(theKey)operator(.)ident(data)operator(,) string(\)) + ident(foundData) operator(=) keyword(new) pre_type(String)operator(()ident(theData)operator(.)ident(data)operator(,) string(\)) + ident(println) stringcontent(' found data: ')inlinecontent('.)delimiter(")> +(}) +ident(myDb)operator(.)ident(delete)operator(()ident(tx)operator(,) ident(theKey)(\)) +ident(myDb)operator(.)ident(close)operator(()(\)) +ident(myEnv)operator(.)ident(close)operator(()(\)) + + +comment(// userstats using pbeans) +keyword(import) include(net.sourceforge.pbeans.*) +comment(// on *nix use: whotext = "who".execute(\).text) +ident(whotext) operator(=) string + +type(class) class(LoginInfo) directive(implements) ident(Persistent) operator({) + ident(LoginInfo)operator(()(\)) operator({)(}) + ident(LoginInfo)operator(()ident(name)(\)) operator({) local_variable(this)operator(.)ident(name) operator(=) ident(name)operator(;) ident(loginCount) operator(=) integer(1) (}) + pre_type(String) ident(name) + type(int) ident(loginCount) +(}) + +keyword(def) method(printAllUsers)operator(()ident(store)(\)) operator({) + ident(printUsers)operator(()ident(store)operator(,) ident(store)operator(.)ident(select)operator(()ident(LoginInfo)operator(.)ident(class)(\))operator(.)ident(collect)operator({)local_variable(it)operator(.)ident(name)(})operator(.)ident(sort)operator(()(\)\)) +(}) + +keyword(def) method(printUsers)operator(()ident(store)operator(,) ident(list)(\)) operator({) + ident(list)operator(.)ident(each)operator({) + ident(println) stringcontent( )inlinedelimiter(")> + (}) +(}) + +keyword(def) method(addUsers)operator(()ident(store)(\)) operator({) + ident(whotext)operator(.)ident(trim)operator(()(\))operator(.)ident(split)operator(()string(\))operator(.)ident(each)operator({) + ident(m) operator(=) local_variable(it) operator(=~) regexp + ident(name) operator(=) ident(m)operator([)integer(0)(])operator([)integer(1)(]) + ident(item) operator(=) ident(store)operator(.)ident(selectSingle)operator(()ident(LoginInfo)operator(.)ident(class)operator(,) stringoperator(,) ident(name)(\)) + keyword(if) operator(()ident(item)(\)) operator({) + ident(item)operator(.)ident(loginCount)operator(++) + ident(store)operator(.)ident(save)operator(()ident(item)(\)) + (}) keyword(else) operator({) + ident(store)operator(.)ident(insert)operator(()keyword(new) ident(LoginInfo)operator(()ident(name)(\)\)) + (}) + (}) +(}) + +keyword(def) ident(ds) operator(=) keyword(new) ident(org)operator(.)ident(hsqldb)operator(.)ident(jdbc)operator(.)ident(jdbcDataSource)operator(()(\)) +ident(ds)operator(.)ident(database) operator(=) string +ident(ds)operator(.)ident(user) operator(=) string +ident(ds)operator(.)ident(password) operator(=) string +ident(store) operator(=) keyword(new) ident(Store)operator(()ident(ds)(\)) +keyword(if) operator(()ident(args)operator(.)ident(size)operator(()(\)) operator(==) integer(0)(\)) operator({) + ident(addUsers)operator(()ident(store)(\)) +(}) keyword(else) keyword(if) operator(()ident(args) operator(==) operator([)string(]\)) operator({) + ident(printAllUsers)operator(()ident(store)(\)) +(}) keyword(else) operator({) + ident(printUsers)operator(()ident(store)operator(,) ident(args)(\)) +(}) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.2) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy would normally use JDBC here (see 14.1 for details\)) +keyword(import) include(com.sleepycat.je.*) +ident(tx) operator(=) keyword(null) +ident(envHome) operator(=) keyword(new) pre_type(File)operator(()string(\)) + +ident(myEnvConfig) operator(=) keyword(new) ident(EnvironmentConfig)operator(()(\)) +ident(myEnvConfig)operator(.)ident(setAllowCreate)operator(()keyword(true)(\)) +ident(myEnv) operator(=) keyword(new) ident(Environment)operator(()ident(envHome)operator(,) ident(myEnvConfig)(\)) + +ident(myDbConfig) operator(=) keyword(new) ident(DatabaseConfig)operator(()(\)) +ident(myDbConfig)operator(.)ident(setAllowCreate)operator(()keyword(true)(\)) +ident(myDb) operator(=) ident(myEnv)operator(.)ident(openDatabase)operator(()ident(tx)operator(,) stringoperator(,) ident(myDbConfig)(\)) + +ident(theKey) operator(=) keyword(new) ident(DatabaseEntry)operator(()stringoperator(.)ident(getBytes)operator(()string(\)\)) +ident(theData) operator(=) keyword(new) ident(DatabaseEntry)operator(()stringoperator(.)ident(getBytes)operator(()string(\)\)) +ident(myDb)operator(.)ident(put)operator(()ident(tx)operator(,) ident(theKey)operator(,) ident(theData)(\)) +ident(myDb)operator(.)ident(close)operator(()(\)) +comment(// clear out database) +ident(returnCount) operator(=) keyword(true) +ident(println) ident(myEnv)operator(.)ident(truncateDatabase)operator(()ident(tx)operator(,) stringoperator(,) ident(returnCount)(\)) operator(+) string +comment(// remove database) +ident(myEnv)operator(.)ident(removeDatabase)operator(()ident(tx)operator(,) string(\)) +ident(myEnv)operator(.)ident(close)operator(()(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.3) +comment(//----------------------------------------------------------------------------------) +comment(// Original cookbook example not likely in Groovy.) +comment(// Here is a more realistic example, copying pbeans -> jdbc) +comment(// Creation of pbeans database not strictly needed but shown for completion) + +keyword(import) include(net.sourceforge.pbeans.*) +keyword(import) include(groovy.sql.Sql) + +keyword(def) ident(ds) operator(=) keyword(new) ident(org)operator(.)ident(hsqldb)operator(.)ident(jdbc)operator(.)ident(jdbcDataSource)operator(()(\)) +ident(ds)operator(.)ident(database) operator(=) string +ident(ds)operator(.)ident(user) operator(=) string +ident(ds)operator(.)ident(password) operator(=) string +ident(store) operator(=) keyword(new) ident(Store)operator(()ident(ds)(\)) + +type(class) class(Person) directive(implements) ident(Persistent) operator({) + pre_type(String) ident(name) + pre_type(String) ident(does) + pre_type(String) ident(email) +(}) + +comment(// populate with test data) +ident(store)operator(.)ident(insert)operator(()keyword(new) ident(Person)operator(()key(name)operator(:)stringoperator(,) key(does)operator(:)stringoperator(,) key(email)operator(:)string(\)\)) +ident(store)operator(.)ident(insert)operator(()keyword(new) ident(Person)operator(()key(name)operator(:)stringoperator(,) key(does)operator(:)stringoperator(,) key(email)operator(:)string(\)\)) + +ident(people) operator(=) ident(store)operator(.)ident(select)operator(()ident(Person)operator(.)ident(class)(\)) + +ident(db) operator(=) keyword(new) ident(Sql)operator(()ident(ds)(\)) + +ident(db)operator(.)ident(execute) string +ident(people)operator(.)ident(each)operator({) ident(p) operator(->) + ident(db)operator(.)ident(execute) stringcontent(.name,)inlinecontent(.does,)inlinecontent(.email\);)delimiter(")> +(}) +ident(db)operator(.)ident(eachRow)operator(()string(\))operator({) + ident(println) stringcontent(.name, )inlinecontent(.does, )inlinecontent(.email)delimiter(")> +(}) +ident(db)operator(.)ident(execute) string +comment(// => Tom Christiansen, book author, tchrist@perl.com) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.4) +comment(//----------------------------------------------------------------------------------) +comment(// Groovy would normally use JDBC here (see 14.1 for details\)) +keyword(import) include(com.sleepycat.je.*) + +keyword(def) method(copyEntries)operator(()ident(indb)operator(,) ident(outdb)(\)) operator({) + ident(cursor) operator(=) ident(indb1)operator(.)ident(openCursor)operator(()keyword(null)operator(,) keyword(null)(\)) + keyword(while) operator(()ident(cursor)operator(.)ident(getNext)operator(()ident(foundKey)operator(,) ident(foundData)operator(,) ident(LockMode)operator(.)ident(DEFAULT)(\)) operator(==) ident(OperationStatus)operator(.)ident(SUCCESS)(\)) + ident(outdb)operator(.)ident(out)operator(()ident(tx)operator(,) ident(foundKey)operator(,) ident(foundData)(\)) + ident(cursor)operator(.)ident(close)operator(()(\)) +(}) + +ident(tx) operator(=) keyword(null) +ident(envHome) operator(=) keyword(new) pre_type(File)operator(()string(\)) + +ident(myEnvConfig) operator(=) keyword(new) ident(EnvironmentConfig)operator(()(\)) +ident(myEnvConfig)operator(.)ident(setAllowCreate)operator(()keyword(true)(\)) +ident(myEnv) operator(=) keyword(new) ident(Environment)operator(()ident(envHome)operator(,) ident(myEnvConfig)(\)) + +ident(myDbConfig) operator(=) keyword(new) ident(DatabaseConfig)operator(()(\)) +ident(myDbConfig)operator(.)ident(setAllowCreate)operator(()keyword(true)(\)) +ident(indb1) operator(=) ident(myEnv)operator(.)ident(openDatabase)operator(()ident(tx)operator(,) stringoperator(,) ident(myDbConfig)(\)) +ident(indb2) operator(=) ident(myEnv)operator(.)ident(openDatabase)operator(()ident(tx)operator(,) stringoperator(,) ident(myDbConfig)(\)) +ident(outdb) operator(=) ident(myEnv)operator(.)ident(openDatabase)operator(()ident(tx)operator(,) stringoperator(,) ident(myDbConfig)(\)) +ident(foundKey) operator(=) keyword(new) ident(DatabaseEntry)operator(()(\)) +ident(foundData) operator(=) keyword(new) ident(DatabaseEntry)operator(()(\)) +ident(copyEntries)operator(()ident(indb1)operator(,) ident(outdb)(\)) +ident(copyEntries)operator(()ident(indb2)operator(,) ident(outdb)(\)) +ident(cursor) operator(=) ident(indb2)operator(.)ident(openCursor)operator(()keyword(null)operator(,) keyword(null)(\)) +keyword(while) operator(()ident(cursor)operator(.)ident(getNext)operator(()ident(foundKey)operator(,) ident(foundData)operator(,) ident(LockMode)operator(.)ident(DEFAULT)(\)) operator(==) ident(OperationStatus)operator(.)ident(SUCCESS)(\)) + ident(outdb)operator(.)ident(out)operator(()ident(tx)operator(,) ident(foundKey)operator(,) ident(foundData)(\)) +ident(cursor)operator(.)ident(close)operator(()(\)) +ident(indb1)operator(.)ident(close)operator(()(\)) +ident(indb2)operator(.)ident(close)operator(()(\)) +ident(outdb)operator(.)ident(close)operator(()(\)) +ident(myEnv)operator(.)ident(close)operator(()(\)) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.5) +comment(//----------------------------------------------------------------------------------) +comment(// If you are using a single file based persistence mechanism you can) +comment(// use the file locking mechanisms mentioned in 7.11 otherwise the) +comment(// database itself or the ORM layer will provide locking mechanisms.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.6) +comment(//----------------------------------------------------------------------------------) +comment(// N/A for most Java/Groovy persistent technologies.) +comment(// Use indexes for RDBMS systems.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.7) +comment(//----------------------------------------------------------------------------------) + comment(// We can write a category that allows the ArrayList class) + comment(// to be persisted as required.) + type(class) class(ArrayListCategory) operator({) + directive(static) ident(file) operator(=) keyword(new) pre_type(File)operator(()string(\)) + directive(public) directive(static) type(void) ident(save)operator(()pre_type(ArrayList) ident(self)(\)) operator({) + keyword(def) ident(LS) operator(=) pre_type(System)operator(.)ident(getProperty)operator(()string(\)) + ident(file)operator(.)ident(withWriter)operator({) ident(w) operator(->) + ident(self)operator(.)ident(each)operator({) ident(w)operator(.)ident(write)operator(()local_variable(it) operator(+) ident(LS)(\)) (}) + (}) + (}) + (}) + + ident(lines) operator(=) stringoperator(.)ident(trim)operator(()(\))operator(.)ident(split)operator(()string(\)) keyword(as) pre_type(ArrayList) + + ident(use)operator(()ident(ArrayListCategory)(\)) operator({) + ident(println) string + keyword(for) operator(()ident(i) keyword(in) integer(0)operator(..<)ident(lines)operator(.)ident(size)operator(()(\)\)) + ident(println) stringcontent(: )inlinedelimiter(")> + + ident(a) operator(=) ident(lines)operator([)operator(-)integer(1)(]) + ident(lines)operator([)operator(-)integer(1)(]) operator(=) string + ident(println) stringcontent(])delimiter(")> + + ident(a) operator(=) ident(lines)operator([)integer(0)(]) + ident(lines) operator(=) operator([)string(]) operator(+) ident(lines)operator([)integer(1)operator(..)operator(-)integer(1)(]) + ident(println) stringcontent(])delimiter(")> + + ident(lines)operator(.)ident(add)operator(()integer(3)operator(,) string(\)) + ident(lines)operator(.)ident(add)operator(()integer(1)operator(,) string(\)) + + ident(lines)operator(.)ident(remove)operator(()integer(3)(\)) + + ident(println) string + operator(()ident(lines)operator(.)ident(size)operator(()(\)) operator(-) integer(1)(\))operator(.)ident(downto)operator(()integer(0)(\))operator({) ident(i) operator(->) + ident(println) stringcontent(: )inlinedelimiter(")> + (}) + ident(lines)operator(.)ident(save)operator(()(\)) + (}) + comment(// =>) + comment(// ORIGINAL) + comment(// 0: zero) + comment(// 1: one) + comment(// 2: two) + comment(// 3: three) + comment(// 4: four) + comment(// The last line was [four]) + comment(// The first line was [zero]) + comment(// REVERSE) + comment(// 5: last) + comment(// 4: three) + comment(// 3: Newbie) + comment(// 2: one) + comment(// 1: New One) + comment(// 0: first) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.8) +comment(//----------------------------------------------------------------------------------) +comment(// example using pbeans) +keyword(import) include(net.sourceforge.pbeans.*) +keyword(def) ident(ds) operator(=) keyword(new) ident(org)operator(.)ident(hsqldb)operator(.)ident(jdbc)operator(.)ident(jdbcDataSource)operator(()(\)) +ident(ds)operator(.)ident(database) operator(=) string +ident(ds)operator(.)ident(user) operator(=) string +ident(ds)operator(.)ident(password) operator(=) string +ident(store) operator(=) keyword(new) ident(Store)operator(()ident(ds)(\)) + +type(class) class(Person) directive(implements) ident(Persistent) operator({) + pre_type(String) ident(name) + pre_type(String) ident(does) + pre_type(String) ident(email) +(}) + +ident(name1) operator(=) string +ident(name2) operator(=) string + +ident(store)operator(.)ident(insert)operator(()keyword(new) ident(Person)operator(()key(name)operator(:)ident(name1)operator(,) key(does)operator(:)stringoperator(,) key(email)operator(:)string(\)\)) +ident(store)operator(.)ident(insert)operator(()keyword(new) ident(Person)operator(()key(name)operator(:)ident(name2)operator(,) key(does)operator(:)stringoperator(,) key(email)operator(:)string(\)\)) + +ident(tom1) operator(=) ident(store)operator(.)ident(selectSingle)operator(()ident(Person)operator(.)ident(class)operator(,) stringoperator(,) ident(name1)(\)) +ident(tom2) operator(=) ident(store)operator(.)ident(selectSingle)operator(()ident(Person)operator(.)ident(class)operator(,) stringoperator(,) ident(name2)(\)) + +ident(println) stringcontent( )inlinedelimiter(")> + +keyword(if) operator(()ident(tom1)operator(.)ident(name) operator(==) ident(tom2)operator(.)ident(name) operator(&&) ident(tom1)operator(.)ident(does) operator(==) ident(tom2)operator(.)ident(does) operator(&&) ident(tom1)operator(.)ident(email) operator(==) ident(tom2)operator(.)ident(email)(\)) + ident(println) string +keyword(else) + ident(println) string + +ident(tom2)operator(.)ident(does) operator(=) string +ident(store)operator(.)ident(save)operator(()ident(tom2)(\)) +comment(// =>) +comment(// Two Toming: Person@12884e0 Person@8ab708) +comment(// No two Toms are ever alike) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.9) +comment(//----------------------------------------------------------------------------------) +comment(// Use one of the mechanisms mentioned in 14.1 to load variables at the start) +comment(// of the script and save them at the end. You can save the binding, individual) +comment(// variables, maps of variables or composite objects.) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.10) +comment(//----------------------------------------------------------------------------------) +keyword(import) include(groovy.sql.Sql) + +ident(users) operator(=) operator([)stringoperator(:)stringoperator(,) stringoperator(:)stringoperator(,) stringoperator(:)string(]) + +keyword(def) ident(source) operator(=) keyword(new) ident(org)operator(.)ident(hsqldb)operator(.)ident(jdbc)operator(.)ident(jdbcDataSource)operator(()(\)) +ident(source)operator(.)ident(database) operator(=) string +ident(source)operator(.)ident(user) operator(=) string +ident(source)operator(.)ident(password) operator(=) string +ident(db) operator(=) keyword(new) ident(Sql)operator(()ident(source)(\)) + +ident(db)operator(.)ident(execute) string +ident(users)operator(.)ident(each)operator({) ident(uid)operator(,) ident(login) operator(->) + ident(db)operator(.)ident(execute) stringcontent(,)inlinecontent(\);)delimiter(")> +(}) +ident(db)operator(.)ident(eachRow)operator(()string(\))operator({) + ident(println) stringcontent(.uid )inlinecontent(.login)delimiter(")> +(}) +ident(db)operator(.)ident(execute) string +comment(// =>) +comment(// 20 Joe Bloggs) +comment(// 40 Bill Clinton) +comment(//----------------------------------------------------------------------------------) + + +comment(// @@PLEAC@@_14.11) +comment(//----------------------------------------------------------------------------------) +comment(// variation to cookbook: uses Firefox instead of Netscape, always assumes) +comment(// argument is a regex, has some others args, retains no args to list all) + +comment(// uses jmork mork dbm reading library:) +comment(// http://www.smartwerkz.com/projects/jmork/index.html) +keyword(import) include(mork.*) +keyword(def) ident(cli) operator(=) keyword(new) ident(CliBuilder)operator(()(\)) +ident(cli)operator(.)ident(h)operator(()key(longOpt)operator(:) stringoperator(,) string(\)) +ident(cli)operator(.)ident(e)operator(()key(longOpt)operator(:) stringoperator(,) string