-
Notifications
You must be signed in to change notification settings - Fork 220
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
Support attr readers for fields with names conflicting with Object and Kernel methods #18
Conversation
test/test_query_result.rb
Outdated
@@ -243,7 +243,7 @@ def test_define_simple_query_result | |||
GRAPHQL | |||
|
|||
response = @client.query(Temp::Query) | |||
refute response.data.me.respond_to?(:name) | |||
assert response.data.me.respond_to?(:name) |
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.
this feels wrong, I'll try to understand why this behaved differently when method is explicitly defined
@rmosolgo what do you think? |
Maybe it'd be even simpler if we just deleted the methods with |
e97cb5b
to
b7b12e6
Compare
Considering these classes are specifically created for GraphQL responses, I think it's fine to override the built-in methods. If a consumer really wanted to use these classes for other purposes (which I'm not sure is "correct") then they could build another representation from the hash. I do think it's weird to use |
For my part, I agree the implementation is unusual Ruby, but then again, the existing implementation is pretty weird too. There's like a re-implementation of methods and inheritance here ... for my part, I'm included to include this with the expectation that that the interface (method calls retrieve fetched graphql values) will stay intact. But I'm hoping to refactor the implementation to be more "plain Ruby" soon, as part of a performance audit. Any objections or other considerations before continuing with that approach? |
Unless there's a strong performance or maintainability benefits of changing that interface (I can not think of one), I'd keep the interface of retrieving fetched graphql values via method calls. |
0e782ce
to
334a841
Compare
334a841
to
06f8483
Compare
self.class::METHODS_TO_UNDEF.each do |method_name| | ||
begin | ||
singleton_class.undef_method(method_name) | ||
rescue; end |
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 tried checking with single_class.method_defined?(method_name)
but while it was returning true for i.e :method
, it was returning false for :test
. I'm not sure what else to try here to avoid the exception handling.
Closing this as I think this approach creates more headache than it solves and also introduces yet another magic. At our company, we instead updated the clients to use |
We currently rely on
method_missing
to provide attr readers for the fields. However, when a field has the same name as one of base Ruby methods such asmethod
,test
,method_missing
method isn't triggered and instead Ruby invokes the corresponding base method. One can avoid this byto_h
ing first and then accessing the data like.to_h["method"]
.This PR tries to implement the same access pattern for such conflicting keywords.
I am not fully convinced this is the right approach (overriding base methods and turning them into field accessor feels wrong), what if we explicitly define methods for all fields instead of relying on
method_missing
? Thinking out loud, while implementation-wise it would be improvement, we would still be overriding base methods. Alternatively, we can introduce a convention where we append_value
suffix when there's a conflict, what do you think?EDIT: on a second thought, seems like it's common in Ruby to override pre-existing methods like this?