Global constants in Groovy

groovy final variable
groovy constant naming convention
groovy declare variable global
global variable groovy soapui
groovy string variable
groovy static
groovy def
groovy boolean variable example

It is often desired to declare constants at the top of a script that can be referenced anywhere else in the script. In Groovy, it seems that if you declare a constant using final then it isnot accessible in child scopes. What is the solution for this very basic and common requirement? The workaround I have right now is to create an unbound variable but this is not a constant and is not elegant.

Groovy doesn't really have a global scope. When you have a groovy script that doesn't declare a class, it implicitly gets stuck in a class with the name of the script. So final variables at the top-level scope are really just fields of the implicit class. For example:

// foo.groovy
final MYCONSTANT = "foobar"
println MYCONSTANT

class Helper {
    def hello() { println MYCONSTANT }  // won't work
}
new Helper().hello()

Is more or less equivalent to:

class foo {
    def run() {
        final MYCONSTANT = "foobar"
        println MYCONSTANT
        new Helper().hello()
    }
    static main(args) {
        new foo().run()
    }
}

class Helper {
    def hello() { println MYCONSTANT }  // won't work
}

It's easy to see why it doesn't work expanded out. An easy work around is to declare your "globals" in a dummy class called e.g. Constants, and then just do a static import on it. It even works all in a single script. Example:

import static Constants.*

class Constants {
    static final MYCONSTANT = "foobar"
}

println MYCONSTANT

class Helper {
    def hello() { println MYCONSTANT } // works!
}
new Helper().hello()

EDIT:

Also, scripts are bit of a special case. If you declare a variable without def or any modifiers such as final, (i.e. just use it) it goes into a script-wide binding. So in this case:

CONSTANT = "foobar"
println "foobar"

CONSTANT is in the script-wide binding, but in:

final CONSTANT = "foobar"
println "foobar"

CONSTANT is a local variable in the script's run() method. More information on this can be found at https://web-beta.archive.org/web/20150108090004/http://groovy.codehaus.org/Scoping+and+the+Semantics+of+%22def%22

Groovy Goodness: Defining Public Accessible Constant Fields , This is also true if the field is static. So if we define a constant value as static final we must keep in mind that Groovy will generate a getter method  Defining constants as above is valid Groovy code and will compile, but the value of MY_CONSTANT will be null. Instead, for any global constants you’d like in your SmartApp or Device Handler, define a no-op getter method that returns the value:

In Groovy 1.8+, you can achieve this using the @Field annotation:

import groovy.transform.Field

@Field final String MY_CONSTANT = 'constant'

def printConstant() { println MY_CONSTANT }

printConstant()

Constant Field Values (Groovy 3.0.4), groovy.inspect.Inspector. Modifier and Type, Constant Field, Value. public static final int, CLASS_CLASS_IDX, 1. public static final int, CLASS_INTERFACE_IDX​  You then refer to it as a simple global string variable (ORANGE_PRO_PACKAGE) in your build.gradle: buildConfigField 'String', 'ORANGE_PRO_PACKAGE', '"' + ORANGE_PRO_PACKAGE + '"' it would be best if I could somehow group all these constants. Anything involving .properties files won't handle that.

The another efficient way to add the global application level constants are declare one interface in suitable package as

interface applicationConstants {
//All constants goes here.
    static final float PI = 3.14 
    String ADMIN_USER = "ADMIN"
    Map languages = [
        "en":   "English",
        "hi":   "Hindi",
        "mr":   "Marathi"

    ]
// Like above you can declare all application level code constants here.

}

Use of constants in any class as below,

 import packageNameContainingInterface.applicationConstants // import statement.
 def adminUser = applicationConstants.ADMIN_USER
 println adminUser

That Groovy Style Guide, That Groovy Style Guide - Constants 1. Specifiaclly, we didn't find a solid official guide on how to structure global constants for reference,  groovy.servlet.AbstractHttpServlet ; Modifier and Type Constant Field Value; public static final String: CONTENT_TYPE_TEXT_HTML "text/html" public static final String: INC_PATH_INFO

I personally wouldn't do it but technically you could do

Object.metaclass.MYCONSTANT = 'foobar'

Then every object has it

Groovy variable scope, It is often desired to declare constants at the top of a script that can be referenced anywhere else in the script. In Groovy, it seems that if you  9:46 PM Angular 5 Constant , Angular 5 Constant and Global variables , Angular Constant , angular Global variables , Global variables Edit How to CREATE constant in your Angular Apps? A constant is a value that can’t be changed by the program during normal execution.

Groovy - Data Type and Declaring Variables, By default variables are global. By assigning value to a new variable name we create that variable. Groovy does not require any special syntax or keyword to  groovy.servlet.AbstractHttpServlet ; Modifier and Type Constant Field Value; public static final String: CONTENT_TYPE_TEXT_HTML "text/html" public static final String: INC_PATH_INFO

Groovy - Variables, Groovy supports all Java types (primitive and reference types). All primitives Do not use any type (that will create a global variable): a = 2 The caller assembly would contain the copy of my constant which means if I have to change a constant value, I'll have to compile both my Common assembly and the caller assembly! 1) public const string ConstName = "a value"; 2) public readonly string ConstName = "a value"; 3) To be stored in a public resource file.

Groovy With SmartThings, Variables in Groovy can be defined in two ways − using the native syntax for the data type or the next is by using the def keyword. For variable definitions it is  As a Groovy Script test step. As a Setup or TearDown script on the project, test suite, or test case level in SoapUI. 1.3 Get the Project Name. To get the project name, use the following script in the Groovy Script test step: testRunner.testCase.testSuite.project.name. 1.4 Get the Test Step Name. To get the name of the test step that is being executed:

Comments
  • Constants should be enums in the Java 1.5+ world... :)
  • @Esko every type of constant should be an Enum? Even something like GRAVITY or PI? O_o
  • @tim_yates: No, an enum should contain all constants which are related to each other. In your example that'd be something like CelestialObjectAttributes.GRAVITY or MathematicConstants.PI. These can be imported too so that you don't have to repeat the name of the enum and enums are always VM (or classloader) global which makes them the perfect alternative for oldschool global constants.
  • @Esko I was trying to point out that your initial statement was not true for all constants
  • @tim_yates: Why didn't you say so, then? Although, maybe some clarification such as "Global constants should be expressed as enums..." would've been nice.
  • @Anentropic: don't miss the import above "import groovy.transform.Field"