Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cloning Objects in Raku

Tags:

object

clone

raku

What is the best way to clone objects in raku? I know the clone method exists, but It does not seem to work with nested objects.

For example, in this script:

#!/usr/bin/env perl6

class Group {
    has Int @!group = Array[Int].new;

    method add-item(Int $int) {
        @!group.push($int);
    }

    method print {
        say @!group;
    }
}

class GroupOfGroups {
    has Group @!multi-group = Array[Group].new;

    method add-group(Group $group) {
        @!multi-group.push($group);
    }

    method print {
        for ^@!multi-group.elems -> $i {
            @!multi-group[$i].print;
        }
    }
}

my $group = Group.new;
$group.add-item(1);
$group.add-item(2);
$group.add-item(3);

my $group-of-groups = GroupOfGroups.new;
$group-of-groups.add-group($group.clone);
$group.add-item(4);
$group.add-item(5);
$group.add-item(6);

$group-of-groups.add-group($group.clone);

$group-of-groups.print;

The output is:

[1 2 3 4 5 6]
[1 2 3 4 5 6]

But I was expecting it to be:

[1 2 3]
[1 2 3 4 5 6]
like image 955
Julio Avatar asked Jul 14 '20 23:07

Julio


People also ask

How to clone an object in Java?

The clone () method of Object class is used to clone an object. The java.lang.Cloneable interface must be implemented by the class whose object clone we want to create. If we don't implement Cloneable interface, clone () method generates CloneNotSupportedException. The clone () method is defined in the Object class.

What is the use of the clone () method?

The clone() method is defined in the Object class. Syntax of the clone() method is as follows: The clone() method saves the extra processing task for creating the exact copy of an object. If we perform it by using the new keyword, it will take a lot of processing time to be performed that is why we use object cloning.

What are the disadvantages of the clone () method?

Following is a list of some disadvantages of clone () method: To use the Object.clone () method, we have to change a lot of syntaxes to our code, like implementing a Cloneable interface, defining the clone () method and handling CloneNotSupportedException, and finally, calling Object.clone () etc.

How to implement Cloneable interface in Java?

The java.lang.Cloneable interface must be implemented by the class whose object clone we want to create. If we don't implement Cloneable interface, clone () method generates CloneNotSupportedException . The clone () method is defined in the Object class.


Video Answer


2 Answers

I wouldn't use anything other than clone to clone objects. clone is a proto method defined by Mu, but it's up to its subtypes to implement its behaviour in this case, as cloning the object does clone the array attributes, but not in the way you want. As such, you can write your own clone multis that behave like you expect:

# Group
multi method clone(::?CLASS:D: --> ::?CLASS:D) {
    my ::?CLASS:D $clone .= new;
    $clone.add-item: .clone for @!group;
    $clone
}

# GroupOfGroups
multi method clone(::?CLASS:D: --> ::?CLASS:D) {
    my ::?CLASS:D $clone .= new;
    $clone.add-group: .clone for @!multi-group;
    $clone
}

::?CLASS here is a symbol that, when used in classes, is an alias for the class itself, with :D restricting the type to instances only.

like image 110
Kaiepi Avatar answered Oct 19 '22 22:10

Kaiepi


Hi @julio a careful reading of the docs led me to this ... works like a charm:

method clone { nextwith :foo(@!foo.clone), :bar(%!bar.clone), |%_  }

(this also helped me to understand the rational behind “restricted” language help for deep cloning)

like image 45
p6steve Avatar answered Oct 19 '22 22:10

p6steve