{"id":1502,"date":"2010-09-26T11:32:13","date_gmt":"2010-09-26T20:32:13","guid":{"rendered":"https:\/\/www.kellyrob99.com\/blog\/?p=1502"},"modified":"2010-09-26T11:32:13","modified_gmt":"2010-09-26T20:32:13","slug":"groovy-inspecteval-for-externalizing-data","status":"publish","type":"post","link":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/","title":{"rendered":"Groovy inspect()\/Eval for Externalizing Data"},"content":{"rendered":"<p>One of the things I love about Groovy is how easy it makes reading and writing text files. I&#8217;ve written Groovy scripts for everything from parsing log files for extracting timing information to finding (and replacing with selectors) in-line css blocks. Often there&#8217;s a piece of information extracted from a file that I want to keep for further examination, or just for future reference. The Groovy <a href=\"http:\/\/groovy.codehaus.org\/api\/org\/codehaus\/groovy\/runtime\/DefaultGroovyMethods.html#inspect%28java.lang.Object%29\">inspect()<\/a> method provides a nice easy way to take simple results that are stored in variables and write them to a file. Then the Groovy <a href=\"http:\/\/groovy.codehaus.org\/api\/groovy\/util\/Eval.html\">Eval<\/a> class provides convenience methods to parse that information back from the file in a single line. Here&#8217;s examples of test code that creates Lists and Maps, writes them out to a file and then asserts that evaluating the stored Groovy code results in the same data structures.<\/p>\n<pre class=\"brush: groovy; title: ; notranslate\" title=\"\">\r\n    private static final Closure RANDOM_STRING = RandomStringUtils.&amp;randomAlphanumeric\r\n    private static final String TMP_DIR = System.getProperty('java.io.tmpdir')\r\n\r\n    @Test\r\n    public void testSerializeListToFile()\r\n    {\r\n        List&lt;String&gt; accumulator = &#x5B;]\r\n        100.times { int i -&gt;\r\n            accumulator &lt;&lt; RANDOM_STRING(i + 1)\r\n        }\r\n        File file = new File(&quot;$TMP_DIR\/inspectListTest.groovy&quot;)\r\n        file.deleteOnExit()\r\n        file &lt;&lt; accumulator.inspect()\r\n        assertThat(accumulator, equalTo(Eval.me(file.text)))\r\n    }\r\n\r\n    @Test\r\n    public void testSerializeMapToFile()\r\n    {\r\n        Map&lt;String, String&gt; accumulator = &#x5B;:]\r\n        100.times { int i -&gt;\r\n            accumulator&#x5B;RANDOM_STRING(i + 1)] = RANDOM_STRING(i + 1)\r\n        }\r\n        File file = new File(&quot;$TMP_DIR\/inspectMapTest.groovy&quot;)\r\n        file.deleteOnExit()\r\n        file &lt;&lt; accumulator.inspect()\r\n        assertThat(accumulator, equalTo(Eval.me(file.text)))\r\n    }\r\n<\/pre>\n<p>Two little tidbits of goodness embedded in this example are the ability to capture a method as a closure, in this case RandomStringUtils.randomAlphanumeric(), and the <a href=\"http:\/\/download-llnw.oracle.com\/javase\/6\/docs\/api\/java\/io\/File.html#deleteOnExit%28%29\">File.deleteOnExit()<\/a> method &#8211; which is only cool because I never noticed it in the API before and it turns out to be a great way to clean up after tests.<br \/>\n\ud83d\ude42<\/p>\n<p>A particular usage of this technique I&#8217;ve been using lately has been sparked by a shift of tools at work. I&#8217;ve worked with the Atlassian stack of web applications for years now, and have always enjoyed the rich feedback Bamboo gives for build history. But now I&#8217;m using Hudson as the primary continuous integration tool and one of the things I&#8217;ve been sorely missing is the &#8216;Top 10 Longest Running Tests&#8217;.  If you&#8217;re not familiar with this view in Bamboo, stroll on over to <a href=\"http:\/\/bamboo.ci.codehaus.org\/browse\/GROOVY-DEF17J6EX\/test\">the Groovy build results page<\/a> and click on the tab.<br \/>\nOne of my present priorities at work is to speed up build times and rooting out slow or inefficient tests is one way to do this. It&#8217;s possible to elicit this information from JUnit test reports using xsl(<a href=\"http:\/\/stackoverflow.com\/questions\/277923\/longest-running-unit-tests\">see this link for an example<\/a>)  but I came up with a nice way to incorporate similar functionality into a Gradle build. Following the <a href=\"http:\/\/gradle.org\/\">Gradle<\/a> project-report conventions, this task simply uses the inspect() method to write out a results file in the &#8216;reportsDir&#8217;. I&#8217;ve captured this output(manually) over time to track the progress of speeding up test times, and the format makes it easy to read back in results and do deeper analysis and aggregation &#8211; such as the creation of csv reports and simple graphs for instance.<\/p>\n<pre class=\"brush: groovy; title: ; notranslate\" title=\"\">\r\ntolerance = 2.0\r\ntask findLongRunningTests &lt;&lt; {\r\n    description= &quot;find all tests that take over $tolerance seconds to run&quot;\r\n    String testDir = &quot;${project.reportsDir}\/tests&quot;.toString()\r\n    file(testDir).mkdirs()\r\n    File file = file(&quot;$testDir\/longRunningTests.txt&quot;)\r\n    file.createNewFile()\r\n    BufferedWriter writer = file.newWriter()\r\n    writer &lt;&lt; parseTestResults('**\/TESTS-TestSuites.xml', tolerance)\r\n    writer.close()\r\n}\r\n\r\n\/**\r\n * Read in xml files in the junit format and extract test names and times\r\n * @includePattern ant pattern describing junit xml reports to inspect, recursively gathered from the rootDir\r\n * @tolerance the number of seconds over which tests should be included in the report\r\n *\/\r\nprivate String parseTestResults(includePattern, float tolerance)\r\n{\r\n    def resultMap = &#x5B;:]\r\n    fileTree(dir: rootDir, include: includePattern).files.each {\r\n        def testResult = new XmlSlurper().parse(it)\r\n        testResult.depthFirst().findAll {it.name() == 'testcase'}.each { testcase -&gt;\r\n            def key = &#x5B;testcase.@classname.text(), testcase.@name.text()].join(':')\r\n            def value = testcase.@time.text() as float\r\n            resultMap&#x5B;(key)] = value\r\n        }\r\n    }\r\n    return resultMap.findAll {it.value &gt; tolerance}.sort {-it.value}.inspect()\r\n}\r\n<\/pre>\n<p>Note that this works recursively from the &#8216;rootDir&#8217; of a <a href=\"http:\/\/www.gradle.org\/latest\/docs\/javadoc\/org\/gradle\/api\/Project.html\">Project<\/a>, so it is effective for multi-project Gradle builds. Source code for this simple example <a href=\"http:\/\/github.com\/kellyrob99\/groovy-inspect-eval\">is available on github<\/a> if you want to check it out yourself.<\/p>\n<p>Here&#8217;s a sample result drawn from examining some test output in the Gradle build itself. Only one of the tests executed in WrapperTest takes more than 2 seconds to execute.<\/p>\n<pre class=\"brush: groovy; title: ; notranslate\" title=\"\">\r\n&#x5B;&quot;org.gradle.api.tasks.wrapper.WrapperTest:testWrapper&quot;:2.37]\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>One of the things I love about Groovy is how easy it makes reading and writing text files. I&#8217;ve written Groovy scripts for everything from parsing log files for extracting timing information to finding (and replacing with selectors) in-line css blocks. Often there&#8217;s a piece of information extracted from a file that I want to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[6],"tags":[265,222,219,257,221,223,220,112,113],"class_list":["post-1502","post","type-post","status-publish","format-standard","hentry","category-dev","tag-bamboo","tag-eval","tag-gradle","tag-groovy","tag-hudson","tag-inspect","tag-junit","tag-kellyrob99","tag-thekaptain"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"TheKaptain\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"The Kaptain on ... stuff | Tales of development, life and the folly that goes along with both\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Groovy inspect()\/Eval for Externalizing Data | The Kaptain on ... stuff\" \/>\n\t\t<meta property=\"og:description\" content=\"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2010-09-26T20:32:13+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2010-09-26T20:32:13+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Groovy inspect()\/Eval for Externalizing Data | The Kaptain on ... stuff\" \/>\n\t\t<meta name=\"twitter:description\" content=\"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#article\",\"name\":\"Groovy inspect()\\\/Eval for Externalizing Data | The Kaptain on ... stuff\",\"headline\":\"Groovy inspect()\\\/Eval for Externalizing Data\",\"author\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/#organization\"},\"datePublished\":\"2010-09-26T11:32:13-09:00\",\"dateModified\":\"2010-09-26T11:32:13-09:00\",\"inLanguage\":\"en-US\",\"commentCount\":3,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#webpage\"},\"articleSection\":\"Development, Bamboo, Eval, Gradle, Groovy, Hudson, inspect(), Junit, kellyrob99, theKaptain\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/category\\\/dev\\\/#listItem\",\"name\":\"Development\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/category\\\/dev\\\/#listItem\",\"position\":2,\"name\":\"Development\",\"item\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/category\\\/dev\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#listItem\",\"name\":\"Groovy inspect()\\\/Eval for Externalizing Data\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#listItem\",\"position\":3,\"name\":\"Groovy inspect()\\\/Eval for Externalizing Data\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/category\\\/dev\\\/#listItem\",\"name\":\"Development\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/#organization\",\"name\":\"The Kaptain on ... stuff\",\"description\":\"Tales of development, life and the folly that goes along with both\",\"url\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"TheKaptain\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/e41f09f3548f065fe6967ac904d3ea2a638614c16d879cac47cfad64e5b1426a?s=96&d=monsterid&r=g\",\"width\":96,\"height\":96,\"caption\":\"TheKaptain\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#webpage\",\"url\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/\",\"name\":\"Groovy inspect()\\\/Eval for Externalizing Data | The Kaptain on ... stuff\",\"description\":\"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/2010\\\/09\\\/26\\\/groovy-inspecteval-for-externalizing-data\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2010-09-26T11:32:13-09:00\",\"dateModified\":\"2010-09-26T11:32:13-09:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/\",\"name\":\"The Kaptain on ... stuff\",\"description\":\"Tales of development, life and the folly that goes along with both\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.kellyrob99.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Groovy inspect()\/Eval for Externalizing Data | The Kaptain on ... stuff","description":"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files.","canonical_url":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#article","name":"Groovy inspect()\/Eval for Externalizing Data | The Kaptain on ... stuff","headline":"Groovy inspect()\/Eval for Externalizing Data","author":{"@id":"https:\/\/www.kellyrob99.com\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/www.kellyrob99.com\/blog\/#organization"},"datePublished":"2010-09-26T11:32:13-09:00","dateModified":"2010-09-26T11:32:13-09:00","inLanguage":"en-US","commentCount":3,"mainEntityOfPage":{"@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#webpage"},"isPartOf":{"@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#webpage"},"articleSection":"Development, Bamboo, Eval, Gradle, Groovy, Hudson, inspect(), Junit, kellyrob99, theKaptain"},{"@type":"BreadcrumbList","@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.kellyrob99.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.kellyrob99.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.kellyrob99.com\/blog\/category\/dev\/#listItem","name":"Development"}},{"@type":"ListItem","@id":"https:\/\/www.kellyrob99.com\/blog\/category\/dev\/#listItem","position":2,"name":"Development","item":"https:\/\/www.kellyrob99.com\/blog\/category\/dev\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#listItem","name":"Groovy inspect()\/Eval for Externalizing Data"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.kellyrob99.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#listItem","position":3,"name":"Groovy inspect()\/Eval for Externalizing Data","previousItem":{"@type":"ListItem","@id":"https:\/\/www.kellyrob99.com\/blog\/category\/dev\/#listItem","name":"Development"}}]},{"@type":"Organization","@id":"https:\/\/www.kellyrob99.com\/blog\/#organization","name":"The Kaptain on ... stuff","description":"Tales of development, life and the folly that goes along with both","url":"https:\/\/www.kellyrob99.com\/blog\/"},{"@type":"Person","@id":"https:\/\/www.kellyrob99.com\/blog\/author\/admin\/#author","url":"https:\/\/www.kellyrob99.com\/blog\/author\/admin\/","name":"TheKaptain","image":{"@type":"ImageObject","@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/e41f09f3548f065fe6967ac904d3ea2a638614c16d879cac47cfad64e5b1426a?s=96&d=monsterid&r=g","width":96,"height":96,"caption":"TheKaptain"}},{"@type":"WebPage","@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#webpage","url":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/","name":"Groovy inspect()\/Eval for Externalizing Data | The Kaptain on ... stuff","description":"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.kellyrob99.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/#breadcrumblist"},"author":{"@id":"https:\/\/www.kellyrob99.com\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/www.kellyrob99.com\/blog\/author\/admin\/#author"},"datePublished":"2010-09-26T11:32:13-09:00","dateModified":"2010-09-26T11:32:13-09:00"},{"@type":"WebSite","@id":"https:\/\/www.kellyrob99.com\/blog\/#website","url":"https:\/\/www.kellyrob99.com\/blog\/","name":"The Kaptain on ... stuff","description":"Tales of development, life and the folly that goes along with both","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.kellyrob99.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"The Kaptain on ... stuff | Tales of development, life and the folly that goes along with both","og:type":"article","og:title":"Groovy inspect()\/Eval for Externalizing Data | The Kaptain on ... stuff","og:description":"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files.","og:url":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/","article:published_time":"2010-09-26T20:32:13+00:00","article:modified_time":"2010-09-26T20:32:13+00:00","twitter:card":"summary","twitter:title":"Groovy inspect()\/Eval for Externalizing Data | The Kaptain on ... stuff","twitter:description":"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files."},"aioseo_meta_data":{"post_id":"1502","title":"Groovy inspect()\/Eval for Externalizing Data | #site_title","description":"An example of using Groovy inspect() and Eval to store and recover Groovy variables in files.","keywords":[{"label":"Bamboo","value":"Bamboo"},{"label":"Gradle","value":"Gradle"},{"label":"Groovy","value":"Groovy"},{"label":"Hudson","value":"Hudson"},{"label":"Junit","value":"Junit"},{"label":"kellyrob99","value":"kellyrob99"},{"label":"theKaptain","value":"theKaptain"},{"label":"Eval","value":"Eval"},{"label":"inspect()","value":"inspect()"},{"label":"inspect","value":"inspect"}],"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[],"defaultGraph":"","defaultPostTypeGraph":""},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-02-09 05:15:21","updated":"2025-11-29 20:27:59","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.kellyrob99.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.kellyrob99.com\/blog\/category\/dev\/\" title=\"Development\">Development<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tGroovy inspect()\/Eval for Externalizing Data\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.kellyrob99.com\/blog"},{"label":"Development","link":"https:\/\/www.kellyrob99.com\/blog\/category\/dev\/"},{"label":"Groovy inspect()\/Eval for Externalizing Data","link":"https:\/\/www.kellyrob99.com\/blog\/2010\/09\/26\/groovy-inspecteval-for-externalizing-data\/"}],"jetpack_publicize_connections":[],"jetpack_shortlink":"https:\/\/wp.me\/prjtg-oe","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/posts\/1502","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/comments?post=1502"}],"version-history":[{"count":18,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/posts\/1502\/revisions"}],"predecessor-version":[{"id":1520,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/posts\/1502\/revisions\/1520"}],"wp:attachment":[{"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/media?parent=1502"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/categories?post=1502"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kellyrob99.com\/blog\/wp-json\/wp\/v2\/tags?post=1502"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}