user1559625
user1559625

Reputation: 2673

What is the .with() method for Map in Groovy?

I came across the below code in a Groovy project:

payloadDetails?.with {
    payloadDetails.ardome.material_id = testAsset.materialId.trim()
    payloadDetails.ardome.itm_id = testAsset.itemId.trim()
    payloadDetails.ardome.mob_id = testAsset.mobId.trim()
    payloadDetails.ardome.min_id = testAsset.minId.trim()
    payloadDetails.ardome.original_ardome_filename = testAsset.originalFileName.trim()
}

where 'payloadDetails' variable is the return value of below (Map I assume):

static Map getCreateIndexPayload(String payloadName = 'CreateIndexPayload') {
     //some code
}

So ? is the null safe operator, but what is the .with() method?

It looks like it's a method that allows reassigning Map's all or partial value member one by one. But I am not able to find this .with() definition in Map's interface document, or is it a method of Collection interface?

Is API documentation available for this method?

Upvotes: 5

Views: 2169

Answers (1)

Object#with is a Groovy extension method that is available on any object. It takes a closure as a parameter and returns the closure's value. (For an equivalent that returns the original object, use tap; this is useful for nested initializations.)

In this case, the value of the closure (testAsset.originalFileName.trim()) is discarded, so the with simply has the effect of executing the closure against the object.

Note that the with and tap methods delegate to the target (that is, any assignments or method calls are resolved against it first), so the payloadDetails inside the closure is unnecessary and potentially a bug. Instead, you should be able to just say

payloadDetails?.with {
  ardome.material_id = testAsset.materialId.trim()
  ardome.itm_id = testAsset.itemId.trim()
  ardome.mob_id = testAsset.mobId.trim()
  ardome.min_id = testAsset.minId.trim()
  ardome.original_ardome_filename = testAsset.originalFileName.trim()
}

or, if ardome is a POJO and not a nested map*,

payloadDetails?.ardome?.with {
  material_id = testAsset.materialId.trim()
  itm_id = testAsset.itemId.trim()
  mob_id = testAsset.mobId.trim()
  min_id = testAsset.minId.trim()
  original_ardome_filename = testAsset.originalFileName.trim()
}

* or maybe if it is a nested map; you would need to try this yourself

Upvotes: 4

Related Questions