{"id":1047,"date":"2014-11-13T17:12:06","date_gmt":"2014-11-13T22:12:06","guid":{"rendered":"http:\/\/cs4760.csl.mtu.edu\/2015\/?page_id=1047"},"modified":"2019-03-27T12:39:06","modified_gmt":"2019-03-27T16:39:06","slug":"groovy-programming","status":"publish","type":"page","link":"http:\/\/cs4760.csl.mtu.edu\/2020\/lectures\/groovy-programming\/","title":{"rendered":"Groovy Programming"},"content":{"rendered":"<p>You do not need to be a groovy expert to complete your apps, but you&#8217;ll have to learn some groovy. My motivation for this lecture is to introduce you to the most commonly used syntax and operators in Groovy, so you can get started quickly. Another reason is that when I started using Grails, a lot of what I wrote seemed like magic, especially editing the configuration files. Sure, you can copy and paste a\u00a0line and then edit it. you&#8217;ll probably get the app running, but it is not very satisfying. If an error should happen, you are not well prepared to fix it. So, I hope that this lecture can\u00a0also demystify some of the groovy aspects that appear like magic.<\/p>\n<p>Much of the\u00a0material for\u00a0the lecture comes from the first chapter of Programming Grails by Burt Beckwith and the Groovy User Guide page.<\/p>\n<p><a href=\"http:\/\/groovy-lang.org\/documentation.html\">http:\/\/groovy-lang.org\/documentation.html<\/a><\/p>\n<p>A reason why I chose Groovy and Grails framework for your projects is because Groovy is a scripting language built on top of Java, so I thought that the language should be somewhat familiar to you, but that is not always true. You can almost always use Java syntax and commands, but to do that would lose the power of Groovy.<\/p>\n<h1>Some Mysteries of Groovy Unraveled<\/h1>\n<p>The groovy compiler, groovyc, makes byte code similar to what javac does, but its parser is LL(3), which implies it can look ahead three tokens instead of two tokens as in a LL(2) parser. This allows it to parse &#8220;===&#8221; and I believe to do away with many brackets that delineate function argument list, maps and arrays.<\/p>\n<p>During bye code generation the groovy compiler adds methods and properties to your classes. But, it also adds a MetaClass to the MetaClassRegistry for the execution context. There is only one MetaClassRegistry for a context, and it associates the MetaClass to the class defined in your code.<\/p>\n<p>Method invocation is the term for how a compiler setups the method calls in your code. The method invocation in groovy is that the MetaClass for your class is called first. This permits the objects of your class to appear to be more dynamic, meaning that properties and methods can be added at run time.<\/p>\n<h1>Groovy Console<\/h1>\n<p>You can run groovy code in your web app and test them with the Grails console. The Groovy Console is shipped with GGTS and IntelliJ IDEA. It allows you to run isolated groovy code. It is useful for developing algorithms or learning groovy.<\/p>\n<p><a href=\"http:\/\/groovy-lang.org\/groovyconsole.html\">http:\/\/groovy-lang.org\/groovyconsole.html<\/a><\/p>\n<p>Make a &#8220;Groovy Project&#8221; in IntelliJ and then\u00a0 select Tools\u00a0-&gt; &#8220;Groovy Console&#8221; will open a groovy console. \u00a0You can open as many as you like.<\/p>\n<p><a href=\"https:\/\/www.jetbrains.com\/help\/idea\/2016.3\/launching-groovy-interactive-console.html\">https:\/\/www.jetbrains.com\/help\/idea\/2016.3\/launching-groovy-interactive-console.html<\/a><\/p>\n<h1>Preliminary Groovy<\/h1>\n<p>Groovy has some nice groovy features that simplify your code.<\/p>\n<ul>\n<li>No need for semi colons.<\/li>\n<li>No need for functions or methods to have \u00a0(\u2026) to delineate arguments.<\/li>\n<li>No need for the return statement. The value of the last line of code is the return value.<\/li>\n<\/ul>\n<h3>Groovy Reading Hint<\/h3>\n<p>If you see missing parentheses assume it is a method call and the arguments of the methods are the variables following the method name.<\/p>\n<h2>Optional Typing<\/h2>\n<p>Groovy is a dynamic language which means that objects do not have to be typed and can appear to change their type. Groovy enables this by using &#8220;def&#8221; keyword to define an object, such as<\/p>\n<pre>def person = new Person()<\/pre>\n<p>the compiler replaces the definition with<\/p>\n<pre>Object person = new Person()<\/pre>\n<p>In java, this would cause problems later in your code when you want to call a Person method on \u00a0a person object, you would have to cast person to the Person type<\/p>\n<pre>(Person)person.personName()<\/pre>\n<p>But in groovy you do not have to make the cast because the MetaClass for\u00a0 the person object is\u00a0called first, so the compiler knows the class of the object. Of course if you declare the object with &#8220;def&#8221; then the precompiler cannot warn you of potential syntax errors. I advise to type declare objects whenever you can.<\/p>\n<p>The MetaClass also allows you to dynamically invoke methods or access properties, for example<\/p>\n<pre>String propertName = \"presonName\"\r\ndef name = person.\"$propertyName\"\r\n<\/pre>\n<p>In the above example the personName property of the person class is assessed using a string variable.<\/p>\n<h2>Arrays and Maps<\/h2>\n<h3>Declaring Collections<\/h3>\n<p>When you make an array in groovy, the compiler implements it as an ArrayList. The example below<\/p>\n<pre>List&lt;String&gt; names = [\"Robert\", \"Nancy\", \"Bill\"]<\/pre>\n<p>is implemented as<\/p>\n<pre>List&lt;String&gt; names = new ArrayList&lt;String&gt;();\r\nnames.add(\"Robert\");\r\nnames.add(\"Nancy\");\r\nnames.add(\"Bill\");\r\n<\/pre>\n<p>Maps (key-value pairs) are implemented with a LinkedHashMap. You can make a Map using square bracket and colon notation.<\/p>\n<pre>name = [\"first name\": \"Robert\", \"last name\": \"Pastel\"]<\/pre>\n<p>In this case both the key and the value are Strings. Keys are always Strings, so if the key is a single word you can omit the quotation marks around the key.<\/p>\n<pre>name = [first: 'Robert', last: 'Pastel']<\/pre>\n<p>Note groovy does not care if you use single or double quotation marks to represent strings. Items in a Map can be accessed by the key, index or using dot notation.<\/p>\n<pre>assert name['first'] == 'Robert'\r\nassert name[0] == 'Robert'\r\nassert name[-1] == 'Pastel'\r\nassert name.last == 'Pastel'\r\n<\/pre>\n<h3>Groovy Reading Hint<\/h3>\n<p>Whenever you see square brackets think, &#8220;The object being represented is a Collection, either a List, Set or Map.&#8221; If it is a Map you&#8217;ll also see colons.<\/p>\n<h2>Using Collections<\/h2>\n<p>Lists and Maps has many new groovy operators. You can see examples in the documentation.<\/p>\n<p><a href=\"http:\/\/www.groovy-lang.org\/groovy-dev-kit.html\">http:\/\/www.groovy-lang.org\/groovy-dev-kit.html<\/a><\/p>\n<p>Some of the more popular operators are &#8216;&lt;&lt;&#8216; and &#8216;+&#8217; for adding to a collection. The star dot, &#8216;*.&#8217; or &#8216;.each{\u2026}&#8217; for traversing the collection.<\/p>\n<p><a href=\"http:\/\/www.groovy-lang.org\/operators.html\">http:\/\/www.groovy-lang.org\/operators.html<\/a><\/p>\n<h2>Plain Old Groovy Object (POGO)<\/h2>\n<p>Many classes are simple and are composed of only attributes with getter and setter methods and have empty constructor. These are called Plain Old Groovy Objects (POGO). For example the Person class.<\/p>\n<pre>class Person {\r\n\r\n\/\/ class attributes\r\n    private String firstName;\r\n    private String lastName;\r\n\r\n    \/\/ class setters and getters\r\n    public String setFirstName(String name){this.firstName = name;}\r\n    public String getFirstName(String name){return firstName;}\r\n    public String setLastName(String name){this.lastName = name;}\r\n    public String getLastName(String name){return lastName;}\r\n}\r\n<\/pre>\n<p>In groovy you would just code the class attributes without the scoping qualification, i.e. &#8220;private&#8221;.<\/p>\n<pre>class Person{\r\n   String firstName\r\n   String lastName\r\n}\r\n<\/pre>\n<p>The groovy compiler will make the class attributes private and write the setter and getter methods for you. If you needed to do something special in either of the setters and getters you would just overwrite the method.<\/p>\n<pre>class Person{\r\n   String firstName\r\n   String lastName\r\n   String gender\r\n\r\n   public setGender(String g){\r\n      \/\/ check that gender is male or female\r\n      \u2026\r\n     this.gender = g\r\n   }\r\n}\r\n<\/pre>\n<p>You can control the auto generation of setters and getters by using private or final and overloading the get and set methods.<\/p>\n<p>This automation can sometimes cause problems. If you make methods in a groovy class with prefix &#8220;set&#8221; or &#8220;get&#8221; then groovy will add the field to the class. For example, suppose you code<\/p>\n<pre>class Person{\r\n   String firstName\r\n   String lastName\r\n\r\n   def setMiddleName(){\r\n       \/\/ do something, perhaps save in a hashmap.\r\n   }\r\n}<\/pre>\n<p>Groovy will make class like<\/p>\n<pre>class Person {\r\n\r\n\/\/ class attributes\r\n    private String firstName;\r\n    private String lastName;\r\n    private String middleName;\r\n\r\n    \/\/ class setters and getters\r\n    public String setFirstName(String name){this.firstName = name;}\r\n    public String getFirstName(String name){return firstName;}\r\n    public String setLastName(String name){this.lastName = name;}\r\n    public String getLastName(String name){return lastName;}\r\n   \r\n   public void setMiddleName{\r\n       \/\/ do something\r\n   }\r\n   public String getLastName(String name) {return middleName;}   \r\n}<\/pre>\n<p>Frequently this is not a problem, but it might lead to unaccepted behavior. Especially, if Person is a domain object then GORM and Hibernate will not see the &#8220;middleName&#8221;\u00a0field and give an error trying to setup the database.<\/p>\n<h2>Constructors<\/h2>\n<p>Groovy like Java makes the empty constructor, but groovy also makes a constructor which accepts a map of the attributes and values. A Person instance can be made as below.<\/p>\n<pre>def me = new Person([firstName: \"Robert\", lastName: \"Pastel\"])<\/pre>\n<p>The above can be shorter.<\/p>\n<pre>def me = new Person(firstName: \"Robert\", lastName: \"Pastel\")<\/pre>\n<p>Note that there is no need for both square brackets delinting the map. The map constructor is implemented by the MettaClass by first calling the default constructor and then calling the set methods for each key of the map.<\/p>\n<h3>Groovy Reading Hint<\/h3>\n<p>Whenever you see colons, &#8216;:&#8217;, even without the square brackets think map.<\/p>\n<h1>Closures<\/h1>\n<h2>Defining and Calling<\/h2>\n<p>The term closure is probably new to you and will appear mysterious. The formal definition of closure is that it is a segment of code that is\u00a0defined before it is\u00a0invoked and has\u00a0scope at the time that they are defined.<\/p>\n<p><a href=\"http:\/\/www.groovy-lang.org\/closures.html\">http:\/\/www.groovy-lang.org\/closures.html<\/a><\/p>\n<p>Think of them as functions, and generally you just use them like autonomous classes. Closures can be assigned to a variable so you can throw them around like any object.<\/p>\n<pre>def myClosure = {println \"Hello World\"}<\/pre>\n<p>You can later call the closure.<\/p>\n<pre>myClosure.call()\r\nmyClosure()\r\n<\/pre>\n<p>Closures can have parameters and use the arrow, &#8216;-&gt;&#8217;, to separate the argument list from the body.<\/p>\n<pre>def printFirstLastName = {first, last -&gt; println first+\" \"+last}<\/pre>\n<p>and use it thus<\/p>\n<pre>printFristLastName(\"Robert\", \"Pastel\")<\/pre>\n<p>Frequently closures have only one argument then the argument&#8217;s name is &#8216;it&#8217;.<\/p>\n<pre>def printWord{println it}<\/pre>\n<h2>In a Closure this, owner and delegate<\/h2>\n<p>The &#8220;this&#8221;\u00a0 in a closure refers to the instance of the enclosing class.<\/p>\n<p>The &#8220;owner&#8221; refers to the enclosing object. It can be the same as &#8220;this&#8221; or reference an enclosing closure.<\/p>\n<p>The &#8220;delegate&#8221; is by default &#8220;owner&#8221; but can be set.<\/p>\n<p><a href=\"http:\/\/www.groovy-lang.org\/closures.html#closure-owner\">http:\/\/www.groovy-lang.org\/closures.html#closure-owner<\/a><\/p>\n<p>Grails makes use of setting delegates of closures. Below is an example of a static closure for a Domain class.<\/p>\n<pre>   \r\nclass PersonName{\r\n   String firstName\r\n   String lastName\r\n   static mapping = {\r\n      version false\r\n      table 'person'\r\n   }\r\n}\r\n<\/pre>\n<p>It might appear that calling the above &#8220;mapping&#8221; closure should fail because the methods <em>version<\/em> and <em>table<\/em> are not defined in the PersonName. But, Grails expects the closure &#8216;mapping&#8217; and will assign the mapping closure a delegate which then redefines the scope of <em>version<\/em> and <em>table<\/em>.<\/p>\n<h3>Groovy Reading Hint<\/h3>\n<p>Whenever you see curly brackets think closure, function or method. Recall that the scope can be redefined.<\/p>\n<h1>Groovy Truth<\/h1>\n<p>Groovy will return true on more than a boolean object. It returns true for object that have value and false for null objects. Non empty arrays and maps return true, empty arrays and maps return false. This is very useful when checking if you can make a call.<\/p>\n<pre>def myCollection = makeMe(\u2026)\r\nif (myCollection) { \/\/ then do something}\r\n<\/pre>\n<h1>Groovy Strings<\/h1>\n<p>Groovy uses the dollar sign, &#8220;$&#8221;, like many scripting languages, to represent the value of a\u00a0variable. But\u00a0in groovy it is only used as a string representation of the value.<\/p>\n<pre>String fullname = \"$person.fistName $person.lastName\"<\/pre>\n<p>These types of strings are called GStrings.<\/p>\n<p><a href=\"http:\/\/docs.groovy-lang.org\/latest\/html\/documentation\/index.html#all-strings\">http:\/\/docs.groovy-lang.org\/latest\/html\/documentation\/index.html#all-strings<\/a><\/p>\n<p>The complete syntax includes curly brackets ${expression}. So you can do.<\/p>\n<pre>def v1 = 2\r\ndef v2 = 3\r\nprintln \"$v1 plus $v2 is ${v1 + v2}\"\r\n<\/pre>\n<h1>Groovy Operators<\/h1>\n<p>Groovy adds lots of operator to make your code appear cleaner.<\/p>\n<p><a href=\"http:\/\/www.groovy-lang.org\/operators.html\">http:\/\/www.groovy-lang.org\/operators.html<\/a><\/p>\n<h2>Null-Safe<\/h2>\n<p>Very frequently you need to check that an object is not null before calling a method. In groovy this is easy with the &#8220;?.&#8221; navigation safe operator.<\/p>\n<pre>String name = person?.firstName<\/pre>\n<p>Groovy will check that the person object is not null before calling the getFirstName method.<\/p>\n<h2>Elivis<\/h2>\n<p>While setting a value, you may want a defaults value if the object is null. This can be done by Using groovy truth and the Elvis operator, &#8220;?:&#8221;, for example:<\/p>\n<pre>String name = person.firstName ?: defaultName<\/pre>\n<p>Instead of<\/p>\n<pre>String name = preson.firstName ? person.firstName : defaultName<\/pre>\n<p>In Java you would write.<\/p>\n<pre>if(person != null ) preson.firstName ? person.firstName : defaultName;<\/pre>\n<h2>Spread<\/h2>\n<p>The spread operator, &#8220;*.&#8221;, traverses a collection and invokes the action. For example<\/p>\n<pre>assert [\"Bob\", \"Billy\"]*.size() == [3, 5]<\/pre>\n<h2>Spaceship<\/h2>\n<p>The spaceship operation, &#8220;&lt;=&gt;&#8221; is used in comparisons.<\/p>\n<pre>left &lt;=&gt; right<\/pre>\n<p>returns<\/p>\n<ul>\n<li>-1 if left &lt; right<\/li>\n<li>0 if left == right<\/li>\n<li>1 if left &gt; right<\/li>\n<\/ul>\n<h2>as<\/h2>\n<p>The &#8220;as&#8221; operator is groovy&#8217;s type casting.<\/p>\n<pre>def animalType = ['cat', 'dog', 'bird'] as Set<\/pre>\n<p>Forces the array to be a type Set.<\/p>\n<h2>in<\/h2>\n<p>The &#8220;in&#8221; operator is a shorthand for contains<\/p>\n<pre>assert 1 in [1, 2, 3]<\/pre>\n<h1>Review Groovy Read Hints<\/h1>\n<ul>\n<li>See<strong> {\u2026}<\/strong> think closure<\/li>\n<li>See<strong> [ ]<\/strong> think collection<\/li>\n<li>See<strong> :<\/strong> think map<\/li>\n<li>See <strong>$variable<\/strong> or <strong>${expression}<\/strong> think GString<\/li>\n<li>See <strong>&#8220;command variable<\/strong>&#8221; think function call, i.e.<strong> command(variable)<\/strong><\/li>\n<li>See the end of a method think return<\/li>\n<li>See <strong>variable?.method<\/strong> think null checking<\/li>\n<li>See <strong>variable?: default<\/strong> think Elvis, the shorten of the ternary operator<\/li>\n<\/ul>\n<p>In no time you&#8217;ll be reading and writing groovy like you do Java.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You do not need to be a groovy expert to complete your apps, but you&#8217;ll have to learn some groovy. My motivation for this lecture is to introduce you to the most commonly used syntax and operators in Groovy, so you can get started quickly. Another reason is that when I started using Grails, a [&hellip;]<\/p>\n","protected":false},"author":61,"featured_media":0,"parent":112,"menu_order":13,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1047","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/pages\/1047","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/users\/61"}],"replies":[{"embeddable":true,"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/comments?post=1047"}],"version-history":[{"count":21,"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/pages\/1047\/revisions"}],"predecessor-version":[{"id":2396,"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/pages\/1047\/revisions\/2396"}],"up":[{"embeddable":true,"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/pages\/112"}],"wp:attachment":[{"href":"http:\/\/cs4760.csl.mtu.edu\/2020\/wp-json\/wp\/v2\/media?parent=1047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}