{"id":13,"date":"2014-08-18T12:38:21","date_gmt":"2014-08-18T16:38:21","guid":{"rendered":"http:\/\/www.jmdawson.net\/blog\/?p=13"},"modified":"2014-08-18T12:38:21","modified_gmt":"2014-08-18T16:38:21","slug":"using-functions-from-one-groovy-script-in-another","status":"publish","type":"post","link":"https:\/\/www.jmdawson.net\/blog\/2014\/08\/18\/using-functions-from-one-groovy-script-in-another\/","title":{"rendered":"Using Functions From One Groovy Script In Another"},"content":{"rendered":"<h3>The Problem<\/h3>\n<p>A coworker and I spent a while on Thursday evening beating our heads against this issue. \u00a0We&#8217;d written a few functions in a separate file so that we could get them working without affecting the rest of what we&#8217;d done. \u00a0Once it was working, we went to use it elsewhere in the project, but were stuck with how to make it available to our script.<\/p>\n<p>Take the following function:<\/p>\n<p><strong>getThing.groovy<\/strong><\/p>\n<pre>def getThingList() {\r\n  return [\"thing\",\"thin2\",\"thing3\"]\r\n}\r\n<\/pre>\n<p>We want to use it in another script like this:<\/p>\n<p><strong>badPrintThing.groovy<\/strong><\/p>\n<pre>println getThingList()\r\n<\/pre>\n<p>The result?<\/p>\n<pre>$ groovy badPrintThing.groovy \r\nCaught: groovy.lang.MissingMethodException: No signature of \r\n  method: badPrintThing.getThingList() is applicable for \r\n  argument types: () values: []\r\ngroovy.lang.MissingMethodException: No signature of method: \r\n  badPrintThing.getThingList() is applicable for argument \r\n  types: () values: []\r\n\tat badPrintThing.run(badPrintThing.groovy:2)\r\n<\/pre>\n<h3>Exploration<\/h3>\n<p>Obviously, the error message isn&#8217;t what we wanted out of this, so we tried the following:<\/p>\n<pre>import getThing.groovy\r\nprintln getThingList()\r\n<\/pre>\n<p>More of the same. Tried to ingest the file with something I found over on stackOverflow:<\/p>\n<pre>evaluate(new File(\"getThing.groovy\"))\r\nprintln getThingList()\r\n<\/pre>\n<p>Yet again, no dice.<\/p>\n<h3>Solution<\/h3>\n<p>Reflecting on the problem that evening, I recalled\u00a0that every groovy script\u00a0is more or less a class\u00a0with the name of the file in which the script resides\u00a0((This behavior is hinted at in the <a title=\"Groovy Scripts and Classes\" href=\"http:\/\/groovy.codehaus.org\/Scripts+and+Classes\" target=\"_blank\">Scripts and Classes<\/a>\u00a0section of the Groovy documentation: <em>&#8220;If you compile the above script to bytecode using groovyc, you get a single class named after the name of the script. e.g. if this was saved in Foo.script you&#8217;d get a Foo.class file. \u00a0<\/em><em>You can run this Java code on the command line (assuming you&#8217;re classpath has groovy.jar and asm.jar) <\/em>&#8230;<em>\u00a0<\/em><em>This will execute the autogenerated main(String[] args) method in the bytecode which instantiates the Foo class, which extends the\u00a0<\/em><em>class and then call its run() method.&#8221;<\/em>)). With that in mind, and the observation that all the files in the same folder will be part of the same package and thus available to each other without any work, I ended up with the following, which worked as I&#8217;d hoped:<\/p>\n<p><strong>printThing.groovy<\/strong><\/p>\n<pre>thing = new getThing()\r\nprintln thing.getThingList()\r\n<\/pre>\n<pre>$ groovy printThing.groovy\r\n[thing, thin2, thing3]\r\n<\/pre>\n<h3>Final Thoughts<\/h3>\n<p>The naming of the getThing class is bad form, now that we&#8217;re actually treating it like a class. \u00a0If you&#8217;re going to write something like this, keep in mind how you&#8217;ll be using it and\u00a0give the file\u00a0a name more like ThingGetter.<\/p>\n<p>We ended up using this arrangement several times in the project, which suggests to me that there might be a pattern to tease out of this. \u00a0We have a copy of <a title=\"Design Patterns: Elements of Reusable Object-Oriented Software\" href=\"http:\/\/en.wikipedia.org\/wiki\/Design_Patterns\" target=\"_blank\">Design Patterns<\/a>\u00a0around the office, so this\u00a0should probably be my next stop.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Problem A coworker and I spent a while on Thursday evening beating our heads against this issue. \u00a0We&#8217;d written a few functions in a separate file so that we could get them working without affecting the rest of what &hellip; <a href=\"https:\/\/www.jmdawson.net\/blog\/2014\/08\/18\/using-functions-from-one-groovy-script-in-another\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,2,4],"tags":[],"class_list":["post-13","post","type-post","status-publish","format-standard","hentry","category-development","category-groovy","category-scripting"],"_links":{"self":[{"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/posts\/13","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/comments?post=13"}],"version-history":[{"count":7,"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/posts\/13\/revisions"}],"predecessor-version":[{"id":35,"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/posts\/13\/revisions\/35"}],"wp:attachment":[{"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/media?parent=13"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/categories?post=13"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jmdawson.net\/blog\/wp-json\/wp\/v2\/tags?post=13"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}