Search code examples
eiffel

Deep copy always fails in workbench system


I have found one case that does not make sense.

I have following feature:

test_array_deep_copy: BOOLEAN
        local
            imp, old_imp: ARRAY[STRING]
        do
            comment("Test of a deep copy.")
            create {ARRAY[STRING]} imp.make_empty
            imp.force ("Alan", 1)
            imp.force ("Mark", 2)
            imp.force ("Tom", 3)

            old_imp := imp.deep_twin
            imp[2] := "Jim"

            Result :=
                across
                    1 |..| imp.count as j
                all
                    j.item /= 2 implies imp [j.item] = old_imp [j.item]
                end
            check not Result end
        end

Since it is deep copy, that means address of imp and old_imp are different, as well as that its attributes in both two also refers to different address.

So, this "Result" after across loop, it should be false because addresses in imp and old_imp at same index are different.

So when I debug this code, it say Result is set to be false after finishing across loop.

The problem is that "check not Result" does not make false to true.

If I run workbench system, it says following: enter image description here

I do not know why. "not" before "Result" in "check not Result" statement should make its whole check true, so it should say "PASSED" in workbench system, but it fails.

why is that?


Solution

  • Your reasoning is correct and the test query as written should return False. Most probably, the system reports FAILED as soon as the query returns False. So, what needs to be done is to fix the query itself.

    The items of the array are cloned and therefore the equality = used in the loop gives False for all elements. To get True from the loop, a different equality operator has to be used: ~. It compares objects rather than references. After that change the query gives True and the test should pass.

    An alternative would be to replace the equality operator with a call to the feature is_deep_equal:

    imp [j.item].is_deep_equal (old_imp [j.item])
    

    Unlike the operator ~ that uses the user-defined feature is_equal to compare objects – strings in the example – is_deep_equal performs "deep" equality test by traversing the whole object tree. The test should pass in this case as well. But deep equality is rarely used in practice.