-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Refactor Internal module #1772
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?
Refactor Internal module #1772
Conversation
I believe the code that used callback_names was removed in 7cfa233
| @items.key?(name) | ||
| end | ||
|
|
||
| def reset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now this class has both clear and reset, which redefines the ivar or calls clear on it. Should we call clear instead of reset? I don't have a strong opinion on either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh good question 🤔 I implemented the #reset method to break up behavior previously found in Internal#reset_configuration; in doing so, I had overlooked that there was a #clear here.
At the outset of considering the two methods, I don't have a strong opinion for using one over the other. I do believe we should normalize and standardize things for clarity.
- Ruby core classes like
HashandArrayhave a#clearmethod.- So a
#clearmethod would seem to be a more idiomatic name to use.
- So a
- the performance difference between
Hash.newandHash#clearis likely negligible for most use cases. I'm not quite clear on what the impact on garbage collection would be. I'll assume any impact there is also negligible. - Considering the behavior nuances between the two methods: nothing outside of the Registry should be keeping a reference to the
@itemsivar.- So in this regard, I think either
#resetor#clearis fine to use. - When
Hash#clearis invoked, the hash itself is returned. YetRegistry#cleardoesn't return self, but the result of@items.clear(which is@items). It is theoretically possible for something to callRegistry.clearand then store a reference to the hash that's referenced by@items. - This is relevant because when using
Registry#clear, all references to the hash value will be cleared. Registry#reset, on the other hand, sets@itemsto be a new Hash, and all references to the previous hash will remain unaffected.- once again, however, nothing should be keeping a reference to
@itemsand we don't do this inside FactoryBot.
- So in this regard, I think either
∴ I'd go with #clear over #reset
# create a new hash
irb(main):001> a = { a: 1 }
=> {a: 1}
# set b as a reference to the hash after it is cleared
irb(main):002> b = a.clear
=> {}
# a and b now reference the same hash value
irb(main):003> a[:c] = 3
=> 3
irb(main):004> a
=> {c: 3}
irb(main):005> b
=> {c: 3}
# setting a to be a new Hash leaves be unaffected
irb(main):006> a = { b: 2 }
=> {b: 2}
irb(main):007> a
=> {b: 2}
irb(main):008> a.clear
=> {}
irb(main):009> a
=> {}
irb(main):010> b
=> {c: 3}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it overall. There are more module variables to think about now, but I think it's worth it.
I experimented with refactoring the
FactoryBot::InternalandFactoryBot::Configurationcode:Internalhad to reach intoConfigurationto access the registry instances and other config state. These methods also had low cohesion as they all used distinct subsets of the configuration state.Internalmodule remains as a proxy/facade/aggregated type interface to minimize the impact on other modules throughout FactoryBotConfigurationclass and create an instance of it.Constructor#initialize_withwas a alias/delegation ofDefinition#define_constructorsoinitialize_withis now an alias inside theDefinition