Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly implement dup and clone. Fixes #2627 #2694

Merged
merged 1 commit into from
May 31, 2016
Merged

Conversation

asterite
Copy link
Member

This implements all of the points from this comment, basically:

  • Remove dup and clone from Object
  • Implement dup for Reference by memcpy of the underlying bytes
  • Implement dup for Value by returning self (because that returns a copy)
  • Implement clone for primitive types (Int, Float, Nil, Bool, Char) as returning self, because they are immutable
  • We don't implement clone for Reference or Struct: that's logic that is specific to each subclass. We of course implement it for some types in the standard library, like Array, Hash, Set, etc.

Additionally, there's a macro Object#def_clone that defines a clone method that invokes clone on all instance variables, which can be handy. The name is similar to other macros that define methods, like def_equals and def_hash.

This makes dup's default behaviour consistent, as it returns a new, different object for Reference types (before this PR it would return self).

clone is also improved: it doesn't exist by default so invoking clone on a method that doesn't define it is a compile error, and at that point one must define its correct behaviour. So, this is a breaking change if someone was relying on this behaviour, but it's a breaking change that will likely spot bugs (or misuses of clone, I found one in the compiler's source code).

@jhass
Copy link
Member

jhass commented May 30, 2016

Nice work!

Can we still define an abstract clone and dup in Object, to have a place to document their expected contracts (should return shallow/deep copy)?

@asterite
Copy link
Member Author

@jhass Nope, because abstract methods are checked by the compiler.

I thought about adding some docs in Object about the conventions the standard library follows, which should also be followed by 3rd party libraries. What do you think?

@@ -55,4 +55,9 @@ struct Bool
def to_s(io)
io << to_s
end

# Returns `self`
Copy link
Member

@jhass jhass May 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the "Return self" comment everywhere should be a bit more verbose, pointing out that this is a Value type and thus assignment creates a copy.

Perhaps just "Returns self, assignment of this type creates a copy, see Value."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't want to expand them, best just drop them IMO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I forgot to enhance comments for clone. Do you think "Returns self (Bool is immutable)" and similar comments in other types would make this clearer?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "Returns self, see Value#dup" ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this is for clone, I'm not sure we should refer to dup. I think clone for primitive types is expected to return the same value. Maybe it's better to just mark it as :nodoc:? "Returns self" doesn't look bad to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't hide them from the API docs, but no comment is fine with me. "Returns self" is misleading if you come from a pass by reference only language IMO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess no docs is fine too, one should expect Bool#clone to return a bool with the same value any way, and saying "returns self" can be misleading indeed.

@jhass
Copy link
Member

jhass commented May 30, 2016

I thought about adding some docs in Object about the conventions the standard library follows, which should also be followed by 3rd party libraries. What do you think?

Better than nothing!

@luislavena
Copy link
Contributor

Implement dup for Reference by memcpy of the underlying bytes

Is this safe (aka: if we move to a different GC or CoW strategy). Wouldn't be better avoid the low level aspect and perform a regular initialization with the same values?

Pardon my ignorance regarding that item, but please feel free to correct me, will love to better understand pro vs cons vs portability.

Thank you.

@asterite
Copy link
Member Author

@luislavena if we later change the GC strategy we can change that method too :-)

A bigger worry is maybe object_id, which right now is the pointer's address. If we later decide to use a moving GC some things will break. We'll find out once we implement a GC of our own.

@asterite asterite force-pushed the feature/dup_clone branch from 861ae94 to a0e21bf Compare May 31, 2016 15:26
@asterite
Copy link
Member Author

I've updated the code a bit. I noticed dup is implemented for all types so added an abstract def dup in Object. Right there I also mention about the convention of using clone for "deep copy", explaining why it's not defined by default.

Then I also mentioned why some dup and clone return self, mostly because some types are immutable. And then I documented dup in Value to explain why it returns self (passed by value).

Verified

This commit was signed with the committer’s verified signature.
jhass Jonne Haß
@asterite asterite force-pushed the feature/dup_clone branch from a0e21bf to e7bc74b Compare May 31, 2016 20:45
@asterite
Copy link
Member Author

Removed all the "Return self" comments

@jhass jhass merged commit d33e0a8 into master May 31, 2016
@asterite asterite deleted the feature/dup_clone branch June 1, 2016 18:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants