-
Notifications
You must be signed in to change notification settings - Fork 37
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
Allow "seed" arguments to constructors #420
Comments
As I implement this feature, an interesting design question has come up: How should we handle cases where a user provides both a One approach could be to allow both, treating the explicit properties as overrides to the Using function(.seed = Foo@constructor(), y = numeric(), ...) {
parent_props <- list(...)
for (i in seq_along(parent_props)) {
prop(.seed, names(parent_props)[i], check = FALSE) <- parent_props[[i]]
}
new_object(.seed, y = y)
} Or including parent properties as function(.seed = Foo@constructor(), y = numeric(), x) {
if (!missing(x)) {
prop(.seed, "x", check = FALSE) <- x
}
new_object(.seed, y = y)
} What do you think about these approaches? Are there other solutions we should consider? |
Meeting notes:
|
We will also need to rename the accessor |
One potential drawback of this change is that parent arguments become less transparent when placed within While we could potentially address some issues that What do you think about introducing a separate method for this? Here's how it could work: Foo <- new_class("Foo", properties = list(x = class_numeric))
Bar <- new_class("Bar", Foo, properties = list(y = class_numeric))
# Constructor signatures would remain clear:
# formals(Foo) == alist(x = integer())
# formals(Bar) == alist(x = integer(), y = integer())
foo <- Foo(x = 1)
bar <- Bar@from_parent(foo, y = 2)
# The new method would have an explicit .parent parameter:
# formals(Bar@from_parent) == alist(.parent = Foo(), y = integer(), ...) Another approach could be to use foo <- Foo(x = 1)
bar <- convert(foo, to = Bar, y = 2) What do you think about these alternatives? |
Related to #376 but deserves its own issue.
One problem with default constructors right now is that they do not take their first argument to be an instance of the class, or superclass, to be used as a basis for construction. Experience in S4 shows that it is extremely useful to be able to add properties on top of an instance of the superclass to create an instance of the subclass.
For example:
Since this is close to the behavior of
new_object()
now, it obviously wouldn't be hard to support this. User-specified constructors already need to follow this convention (I was surprised to find that the default constructor did not). The default constructorBar
would look something like this:Classes that inherit from a base class already have this feature, since they get a
.data
argument. In those cases,.data
would be generalized to.parent
.This change would break compatibility though, because people may be passing unnamed arguments to the constructor (which I would consider pretty bad practice). Code should not be making assumptions about the order of the properties in the object (and thus constructor). It just seems too brittle. Users should expect things to break at this stage.
If we really wanted to avoid breaking compatibility, we could just add the
.parent
argument at the end. The caller would likely have to name.parent
in the call, but the feature would at least exist.We could even go a step further and support merging of all unnamed arguments passed to the constructor, like the methods package does. Related to #409,
new_object()
does not check for whether it has unnamed arguments in...
. If we're not going to support unnamed arguments, then there should be an informative error.The text was updated successfully, but these errors were encountered: