-
Notifications
You must be signed in to change notification settings - Fork 2
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 an option for indicating a direct replacement of a deprecated variable. #53
Comments
/cc @ezzatron I would appreciate your thoughts on this. Note this is specifically about the new The |
I guess that way could work. So I suppose that might make the regular if self is defined {
if self is valid {
return self value
}
return error
}
if self is replacing x {
if x is valid {
return x value
}
return error
}
return nil In this approach you might start with this: old := ferrite.Duration("OLD", "example duration variable")
func main() {
fmt.Println(old.Value())
} Do the majority of the work to set up and use the new variable in one change: old := ferrite.Duration("OLD", "example duration variable")
+ .Deprecated(
+ WithDirectReplacement(new),
+ )
+
+ new := ferrite.Duration("NEW", "example duration variable")
func main() {
- fmt.Println(old.Value())
+ fmt.Println(new.Value())
} Then future you doesn't have much mental overhead when it's time to remove the deprecated variable: - old := ferrite.
- Duration("OLD", "example duration variable").
- Deprecated(
- WithDirectReplacement(new),
- )
-
new := ferrite.Duration("NEW", "example duration variable")
func main() {
fmt.Println(new.Value())
} It probably also depends what you consider a "direct replacement". I would only expect Ferrite to manage all of this for me if the type of values being produced were identical. If the new variable doesn't produce the same type but is still conceptually a replacement, I might want some way to indicate that so that it's documented, but I don't think I'd expect Ferrite to handle the fallback logic for me, and this might be a case where adding some free-form notes to a variable would suffice. |
Thanks man! ❤️ Wall of text incoming, apologies! We can chat about this in person, but I'll still get my thoughts down here. I think the key take away here is that rather than surfacing the Perhaps the deprecated variable could also look at the value of
I don't think it matters whether the replacement is the same type, as ultimately the input is always a string. Consider for example, migrating from a So I'd define a direct replacement as:
So perhaps logic as follows: if self is defined {
if self is valid {
return self value
}
return error
}
if self is replacing x {
if x is defined {
if x is valid as per self's definition {
return x value
}
}
}
if self is required {
return error
}
return nil In summary, fallback to
Yep, definitely want to be able to do this. Was thinking also of allowing a The rest of this reply is just me trying to get my thoughts down about the
This is definitely the intent. Ferrite using the The With that in mind, a change from Anyway, this makes more sense with the pseudo code you suggested, as best I can tell :) |
Yep, that was my main thought.
Yeah, okay. I can see why that would be desirable.
An issue I see with this logic is in the case where:
The user is going to see a message saying that You could work around this as an implementor by making them both optional and validating that one is set correctly in consuming code, but that kind of undermines the goals of making it easy to remove deprecated stuff later. I think I'd prefer, when falling back to the deprecated variable, that if that variable doesn't match the new schema, it produced an error indicating as much. Now, I guess that's still a BC break technically, but you could argue in cases like string to URL transition, it was always supposed to be a valid URL, so if you were able to supply a poorly-formatted URL string before, that was a bug, not a feature. At least the user gets an error message that clearly explains what's actually happening. |
In other words, I'm just advocating for this change: if self is defined {
if self is valid {
return self value
}
return error
}
if self is replacing x {
if x is defined {
if x is valid as per self's definition {
return x value
}
+
+ return error
}
}
if self is required {
return error
}
return nil |
This doesn't have to be the case, the information is available to explain exactly what happened.
I like this, I think this has to be one of the main design considerations of
Yep, that makes sense. Otherwise, for optional variables at least, it would introduce the first case where a provided value is ignored completely.
For sure. This is the exact thing I want to avoid, because it's not introspectable, and therefore I can't explain it to the user automatically. |
I've added a |
Moving out of v1.0.0 milestone. As discussed this particular approach adds a situation where a variable spec is modified after it has already been "finalized" (and perhaps already used by the application in uncommon cases). I would still like to explore other options for achieving the same thing here, but we don't have a pressing need ourselves anymore. |
The goal here is twofold:
old.DeprecatedValue()
methodResolution logic for
old.DeprecatedValue()
pseudo codeThe behavior of
NEW
is unaffected, it is unaware that it is the replacement forOLD
.The text was updated successfully, but these errors were encountered: