Open hadley opened 1 year ago
Since I've now realised that #250 admits a much simpler solution, I think this should take on more of a shape of new_external_generic()
, with an explicit package argument. I think this will still need to switch to a dynamic constructor (i.e. take ...
and do argument dispatch at run time) but hopefully that won't require too much refactoring of the existing code to determine which arguments go where.
And then we can automatically use that when parent
has a package
that isn't equal to the current package, so there's little user intervention required (except if you want to extend a class in a suggested package, which is likely to be relatively rare).
To do:
class@properties
with a call to a helper.@DavisVaughan @t-kalinowski this will need discussion with the full committee before we merge it, but I'd love to get your initial thoughts on both the overall idea and the implementation.
An alternative approach would be to record in the namespace every parent class passed to new_class()
that is from another package. At namespace load, we simply check whether all of the cached classes are the same (by whatever definition we want) as those currently defined in their original package. If the check fails, we ask the user to reinstall the package. It's the safest approach, because it might be that the package needs to be updated anyway.
This is similar to how some C programs check for ABI breakage by comparing struct sizes with those compiled into a library.
Prior to this PR, if class A in package A extends class B in package B, class A will include a copy of the definition of class B at build-time. Methods are not also copied, so if class B is later updated and package B reinstalled, it's possible to end up with in an inconsistent state where you have the class definition from version 1 and the methods from version 2.
This PR adds a new "external class" object designed to ameliorate this problem by doing more work at run-time rather at build-time. For example, the constructor of class B will now have arguments
...
and it will figure out which arguments go to which constructor at run-time (we prefer to do this at build time in order to generate a constructor with named arguments that can be auto-completed etc).Fixes #317