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

Add Copy() and IsZero() methods #62

Closed
wants to merge 1 commit into from
Closed

Conversation

sjansen
Copy link

@sjansen sjansen commented Oct 5, 2020

These functions help to make custom marshalling and unmarshalling code easier to read.

These functions help to make custom marshalling and unmarshalling
code easier to read.
Copy link
Member

@peterbourgon peterbourgon left a comment

Choose a reason for hiding this comment

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

I'm not necessarily against these changes, but I wonder if they're valuable enough to expand the API surface area. @tsenart ?

@@ -454,6 +454,18 @@ func (id ULID) Compare(other ULID) int {
return bytes.Compare(id[:], other[:])
}

// Copy sets id equal to the value of other.
func (id *ULID) Copy(other ULID) {
Copy link
Member

Choose a reason for hiding this comment

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

It's confusing that a method named Copy would mutate the receiver — Copy should return a ULID value.

Copy link
Author

Choose a reason for hiding this comment

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

I'm implementing a third-party unmarshalling interface. Returning a value doesn't work, mutating an existing struct field is basically a requirement. However, as I was working on a simplified example I realized how to make my implementation sufficiently readable as is.

You have a good point about mutating the caller being surprising. I could either remove the method, or replace it with a function: Copy(dst &ULID, src ULID), if you think it could be helpful to future users.

I assume IsZero() is acceptable?

While neither change is strictly necessary, I do feel they improve readability and reduce coupling to the underlying byte array implementation.

Copy link
Member

Choose a reason for hiding this comment

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

Actually, on reflection, I don't think IsZero is a good idea, because a zero value ULID is still a valid ULID.

Copy link
Author

Choose a reason for hiding this comment

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

That's an odd opinion given IsZero isn't about invalid / valid but instead default / non-default, which users can choose to interpret as uninitialized / initialized.

As the system implementer, isn't it my prerogative to decide if the zero value is valid or not in my system?

@sjansen sjansen closed this Oct 6, 2020
@peterbourgon
Copy link
Member

That's an odd opinion given IsZero isn't about invalid / valid but instead default / non-default . . .

My understanding is that a type with an IsZero method is not usable in it's zero-value state, which is not the case for ULIDs. Is that understanding incorrect?

@sjansen
Copy link
Author

sjansen commented Oct 6, 2020

January 1st, year 1 is a perfectly valid date.
https://golang.org/pkg/time/#Time.IsZero

Perhaps you are confusing IsValid and IsZero.
https://golang.org/pkg/reflect/#Value.IsValid
https://golang.org/pkg/reflect/#Value.IsZero

Checking if id.IsZero is essentially that same as checking count == 0 or password == "", the values are valid but depending on business rules they may not be acceptable.

@peterbourgon
Copy link
Member

peterbourgon commented Oct 6, 2020

If that's true then why doesn't every type offer an IsZero method?

n.b. you don't need to use Compare to test equality

var u1, u2 ulid.ULID
println(u1 == u2) // prints true

@peterbourgon peterbourgon reopened this Oct 6, 2020
@peterbourgon
Copy link
Member

@sjansen

I'm implementing a third-party unmarshalling interface.

Can you say a bit more about your use case? I bet we can figure something out.

@sjansen
Copy link
Author

sjansen commented Oct 6, 2020

Can you say a bit more about your use case? I bet we can figure something out.

Thanks, but I've already got a solution I'm happy with and I've moved on.

@sjansen sjansen closed this Oct 6, 2020
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.

2 participants