I think this fixes it:
type SelfReferential
obj::SelfReferential
SelfReferential() = (x = new(); x.obj = x)
end
function Base.deepcopy_internal(sr::SelfReferential, oidd::ObjectIdDict)
if haskey(oidd,sr)
print("X")
return oidd[sr]
end
print("Y")
new_sr = SelfReferential() # fix .obj after recursive call
oidd[sr] = new_sr
new_obj = Base.deepcopy_internal(sr,oidd)
new_sr.obj = new_obj
return new_sr
end
sr = SelfReferential()
deepcopy_sr = deepcopy(sr)
sr == deepcopy_sr # false
sr === deepcopy_sr # false
I'll have to go back and rethink what I am doing in my module now that I
have a better understanding.
Thank all,
Chris
On Wednesday, August 24, 2016 at 4:34:20 AM UTC-4, Tommy Hofmann wrote:
>
> OK, I now see that I misunderstood the question. After rereading it, I
> noticed something important. I think your deepcopy_internal version is
> broken, but you did not notice it since you did _not_ define
> Base.deepcopy_internal(::SelfReferential, ::ObjectIdDict).
>
> You should do the following:
>
> import Base: deepcopy_internal
>
> type SelfReferential
> obj::SelfReferential
>
> SelfReferential() = (x = new(); x.obj = x)
> end
>
> function deepcopy_internal(sr::SelfReferential, oidd::ObjectIdDict)
> # if haskey(oidd,sr)
> # return oidd[sr]
> # else
> new_obj = deepcopy_internal(sr,oidd)
> new_sr = sr(new_obj)
> oidd[sr] = new_sr
> return new_sr
> # end
> end
>
> sr = SelfReferential()
> deepcopy_sr = deepcopy(sr)
>
> Now this will break, since it runs in into an infinite recursion. Even if
> you enable the lines which are commented out, it still breaks, but I don't
> know why.
>
> But as Yichao Yu has pointed out, the builtin deepcopy function works out
> of the box for your custom type.
>
> On Wednesday, August 24, 2016 at 9:02:19 AM UTC+2, Yichao Yu wrote:
>>
>>
>>
>> On Tue, Aug 23, 2016 at 5:19 PM, Tommy Hofmann <[email protected]> wrote:
>>
>>> Why do you think that deepcopy works on SelfReferential without defining
>>> deepcopy_internal? Line 8 of deepcopy.jl is: deepcopy(x) =
>>> deepcopy_internal(x, ObjectIdDict())
>>>
>>
>> Because `deepcopy_internal` already handles this.
>>
>> You shouldn't need to define deepcopy_internal for custom types in
>> general, unless your type needs special serialization support (e.g. if it
>> has pointer to C memory)
>>
>>
>>>
>>>
>>> On Tuesday, August 23, 2016 at 10:52:35 AM UTC+2, Chris Stook wrote:
>>>>
>>>> I created this simple example to try to understand deepcopy_internal.
>>>>
>>>> type SelfReferential
>>>> obj::SelfReferential
>>>>
>>>> SelfReferential() = (x = new(); x.obj = x)
>>>> end
>>>>
>>>> function deepcopy_internal(sr::SelfReferential, oidd::ObjectIdDict)
>>>> # if haskey(oidd,sr)
>>>> # return oidd[sr]
>>>> # else
>>>> new_obj = deepcopy_internal(sr,oidd)
>>>> new_sr = sr(new_obj)
>>>> oidd[sr] = new_sr
>>>> return new_sr
>>>> # end
>>>> end
>>>>
>>>> sr = SelfReferential()
>>>> deepcopy_sr = deepcopy(sr)
>>>>
>>>> This works, but deepcopy works on SelfReferential without defining
>>>> deepcopy_internal, so this isn't a good
>>>> example.
>>>>
>>>> How should this be modified so deepcopy_internal is required?
>>>>
>>>> Are the commented out lines of code necessary?
>>>>
>>>> Thanks,
>>>> Chris
>>>>
>>>>
>>