-
Notifications
You must be signed in to change notification settings - Fork 12
Fix given_or_derived behavior in object initialization #38
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
base: main
Are you sure you want to change the base?
Fix given_or_derived behavior in object initialization #38
Conversation
I spent quite a bit of time reading through the code and Henrik's series of blog posts before I came to the decision this PR was the right direction. I'd love for @hlindberg to comment as to his thoughts, if he's so inclined. |
Oh dear, it was ages ago since I had all that current in my head. |
Byw, do you have access to the (very long) document about PCore? |
Here is the PCore design document, which was the presentation and motivation for the type system and PCore. Much of this was later turned into specs and implementation. I think the document is still a good read for getting the background and ideas behind the type system. The doc is open to anyone with the link: https://docs.google.com/document/d/1Oq4VFISrhU44nnKWsYNB_Q_OLnPnodJz67pB8d53jys/edit?tab=t.0 |
The PCore specification states "The given_or_derived attribute kind states that if the attribute is given when the object is instantiated this value is used, otherwise it is a computed value." and "It is allowed to give the value when instantiating in which case the given value overrides what would be the computed value." The current implementation treats an attribute with the kind given_or_derived as a required parameter during initialization (in the init_hash used in from_asserted_hash or in the generated `initialize` method). This change enforces an implicit `value` parameter of `nil` which causes the generated init_hash type check and the generated initialize method to treat given_or_derived attributes as optional.
a516476
to
74012d4
Compare
@hlindberg sure, thanks for responding! Thanks for the link to the PCore doc - I had it, somewhere, but forgot I did. I put together a simple (but dumb) example here: https://github.com/seanmil/example_given_or_derived Without this patch the given_or_derived argument is treated as required during initialization, which means that a conforming implementation would never be able to use the "derived" part. Given the PCore document (which is the clearest reference I've found) I believe this is the correct behavior. Here is the output of the example I linked without the patch:
And here it is with the patch:
Note that I just pushed an update that simplifies the fix and ensures it works with both hash and positional argument initialization (I had only considered hash initialization in the first version). I also tinkered with a patch that would have PCore enforce that a given value was returned in the event the Object attribute's Ruby method didn't, but while it was a good further learning experience with the code it wasn't quite as elegant as I would have liked and, more importantly, I'm not sure it is necessary. I couldn't find anywhere in the spec where the PCore implementation is required to make sure the given value is returned so I think it is okay to trust the method author to return the value given (if given). |
Thanks for the example! Agree that this is clearly a bug and that treating it as optional is the right thing to do. |
Thought a bit more, I am not sure that "given or derived" is stated to guarantee that the given value is returned - imagine an attribute where you want it to be derived from the given value. No idea if that is very useful or if it needs to guarantee the return of a given. |
That's an excellent point - okay, I'll shelve the other branch but it sounds like this fix is good to go. Thanks so much for your review & feedback! Cheers! |
Actually- after more thought, the behavior of changing a given value is like having a "setter" method for an attribute (e.g. making a string all upper case, trimming white space, etc). The "given or derived" is more of a "getter" style method. |
Currently, a given_or_derived attribute kind is treated as required in both the hash and positional argument initialization. As a required argument a value must always be given, thus preventing the "derived" half ever being used. This patch changes the behavior so that given_or_derived attributes are marked as optional in the initialization hash/arguments.