Search code examples
ballerina

How to create a mutable copy of a `readonly` record in Ballerina for modifying purposes?"


I'm working on an integration project using Ballerina and leveraging the benefits of the readonly record to ensure immutability and concurrency safety. However, I've encountered a scenario where I need to duplicate a readonly record to make changes to the duplicated record.

I attempted to use the record.clone() method, but it seems that the cloned record remains readonly as well.

Is there a recommended approach or workaround to create a mutable copy of a readonly record? Any insights or examples would be greatly appreciated. Thank you!


Solution

  • Yes, clone() does not create copies of immutable values.

    You could use cloneWithType(), provided that the target type (and the corresponding type of any part of the structure that is required to be mutable) is not a subtype of readonly.

    import ballerina/io;
    
    type Record record {
        int[] a1;
        int[] & readonly a2;
    };
    
    public function main() returns error? {
        Record & readonly immRec = {a1: [1, 2], a2: []};
    
        Record mutRec = check immRec.cloneWithType();
    
        io:println(immRec is readonly); // true
        io:println(immRec.a1 is readonly); // true
        io:println(immRec.a2 is readonly); // true
    
        io:println(<any>mutRec is readonly); // false
        io:println(<any>mutRec.a1 is readonly); // false
        io:println(<any>mutRec.a2 is readonly); // true
    
        record {
            int[] a1;
            int[] a2; // also mutable
        } mutRec2 = check immRec.cloneWithType();
    
        io:println(<any>mutRec2 is readonly); // false
        io:println(<any>mutRec2.a1 is readonly); // false
        io:println(<any>mutRec2.a2 is readonly); // false
    }