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
>>>>
>>>>
>>

Reply via email to