-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
106 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
--- | ||
layout: post | ||
title: "Announcing Jactl 1.3.0" | ||
date: 2023-11-10 15:11:44 +1100 | ||
categories: blog | ||
author: "James Crawford" | ||
--- | ||
|
||
Jactl 1.3.0 fixes a few minor bugs and adds some language features. | ||
The main new feature is to support the ability to checkpoint script instance execution state and have it | ||
restored and resumed on another instance after a failure. | ||
|
||
## Enhancements | ||
|
||
### Native support for JSON encoding and decoding ([#16](https://github.com/jaccomoc/jactl/issues/16)) | ||
|
||
Jactl can convert objects into JSON using the `toJson()` method: | ||
```groovy | ||
def x = [a:1,b:[x:3,y:4],c:['a','b','c']] | ||
x.toJson() // {"a":1,"b":{"x":3,"y":4},"c":["a","b","c"]} | ||
``` | ||
|
||
The corresponding `fromJson()` method on strings will convert back from JSON to simple objects: | ||
```groovy | ||
def json = '{"a":1,"b":{"x":3,"y":4},"c":["a","b","c"]}' | ||
json.fromJson() // [a:1, b:[x:3, y:4], c:['a', 'b', 'c']] | ||
``` | ||
|
||
For user defined classes, Jactl will generate a `toJson()` method and a class static method `fromJson()`: | ||
```groovy | ||
class X { int i; String s } | ||
X x = new X(i:3, s:'abc') | ||
x.toJson() // {"i":3,"s":"abc"} | ||
x = X.fromJson('{"i":3,"s":"abc"}') | ||
``` | ||
|
||
### Native array support ([#17](https://github.com/jaccomoc/jactl/issues/17)) | ||
|
||
Jactl now supports array types, including multidimensional arrays. | ||
Previously, lists were used in place of arrays but for performance sensitive code, arrays can now be used instead. | ||
```groovy | ||
int[] someInts = [1,2,3,4] | ||
``` | ||
|
||
The usual list methods (`each()`, `filter()`, `map()`, etc.) also apply to arrays: | ||
```groovy | ||
String[] strArr = ['abc', 'xyz', 'x'] | ||
strArr.map{ it.size() }.sum() // result is 7 | ||
``` | ||
|
||
### List-specific versions of min(), max(), sum(), and avg() ([#19](https://github.com/jaccomoc/jactl/issues/19)) | ||
|
||
This enhancement was just an optimisation to improve the performance of these methods when applied to simple lists. | ||
|
||
### Support checkpointing of execution state ([#20](https://github.com/jaccomoc/jactl/issues/20)) | ||
|
||
This enhancement leveraged the existing ability suspends script execution and resume later when scripts perform | ||
blocking operations. | ||
Scripts can now perform a `checkpoint()` call whenever they want to checkpoint their current state. | ||
The application in which Jactl is embedded can then persist or repicate this state so that if a failure occurs the | ||
state can be restored and the script can continue running from where it left off. | ||
|
||
See the [Jactl Integration Guide](/integration-guide) for information on how to integrate this feature with your application. | ||
|
||
The [Jactl Language Guide](/language-guide#checkpointing) for information about the `checkpoint()` function. | ||
|
||
There is also a blog post that discusses a [Proof of Concept]({{ site.baseurl }}{% link _posts/2023-11-10-checkpoint-poc.md %}) project where checkpoint | ||
persistence and replication was implemented, along with tests showing the restoration and resumption of scripts that | ||
were running when failures occurred. | ||
|
||
### Substring and subList functions should support 0 as end index when start index is negative ([#22](https://github.com/jaccomoc/jactl/issues/22)) | ||
|
||
This enhancement allows you to use negative indexes with the `substring()` and `subList()` functions that are interpreted | ||
as being relative to the end of the string/list: | ||
```groovy | ||
'abcde'.substring(-2) // result is 'de' | ||
'abcde'.substring(-3,-1) // result is 'cd' | ||
[1,2,3,4].subList(-2,0) // result is [3, 4] | ||
``` | ||
|
||
### New '??' operator for existence test ([#23](https://github.com/jaccomoc/jactl/issues/23)) | ||
|
||
A new `??` operator allows you to test for existence: | ||
```groovy | ||
def x | ||
?? x.a.b.c // returns false rather than giving an error | ||
``` | ||
|
||
### Add byte and byte[] types to support binary data ([#24](https://github.com/jaccomoc/jactl/issues/24)) | ||
|
||
Jactl now supports `byte` and `byte[]` data types to better support binary data. | ||
Jactl also supports appropriate conversions: | ||
```groovy | ||
'abc' as byte[] // result is [97, 98, 99] | ||
``` | ||
|
||
## Bug fixes | ||
|
||
* [#18:](https://github.com/jaccomoc/jactl/issues/18) Non-numeric operand error using 'new' immediately after newline | ||
* [#21:](https://github.com/jaccomoc/jactl/issues/21) Regex capture variable usage can sometimes lead to "No match found" error | ||
* [#26:](https://github.com/jaccomoc/jactl/issues/26) className() method on instances cannot be passed by value | ||
* [#27:](https://github.com/jaccomoc/jactl/issues/27) Base class field initialisers not being invoked when using named arg constructor | ||
* [#30:](https://github.com/jaccomoc/jactl/issues/30) JSON decoding is not initialising missing fields in base classes | ||
* [#31:](https://github.com/jaccomoc/jactl/issues/31) Inner class of base class should be visible to child class | ||
* [#32:](https://github.com/jaccomoc/jactl/issues/32) Null for string in regex match should return false |