-
-
Notifications
You must be signed in to change notification settings - Fork 46
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
Add attribute readers for unknown attributes #89
base: main
Are you sure you want to change the base?
Conversation
* default behavior remains unchanged. Unknown params and options are ignored but stored in their own attr_reader * rest params and rest options names are configurable * rest params and rest options can be turned off for strict mode
spec/several_assignments_spec.rb
Outdated
option :bar, proc(&:to_s), optional: true | ||
option :"some foo", as: :bar, optional: true | ||
option :bar, proc(&:to_s), optional: true | ||
option :some_foo, as: :bar, optional: true |
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.
String keyword argument names aren't allowed in 2.6. This is perhaps a very small breaking change but frankly its unlikely anyone on 2.6 was taking advantage of it.
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 think here is a potential for the backward incompatibility. This test is about not string, but symbol keys. What is essential is that the keys don't need to be a valid ruby methods.
For example, we should can handle this assignment:
class Foo
extend Dry::Initializer
option :"!!! my weird key", as: :weird_key
end
foo = Foo.new("!!! my weird key": 1) # notice the key is a symbol, not a string
foo.weird_key # => 1
The goal of this feature to make it possible handling any keys in the income hash (maybe with a forced symbolization like below)
data = { 1 => 2 }.transform_keys { |k| k.to_s.to_sym }
Rubocop linting is needed but I'm loath to do that first as the class/module nesting changes lead to every line of the files getting whitespace changes that would obscure the code really being touched. |
cc @nepalez perhaps for a reivew? |
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 the feature and it looks to me that the implementation is good enough (I mean it shouldn't cause an essential loss in performance). But I'd like to be sure that it is backward compatible to processing all the keys which fall short of the requirements to the Ruby method names.
spec/several_assignments_spec.rb
Outdated
option :bar, proc(&:to_s), optional: true | ||
option :"some foo", as: :bar, optional: true | ||
option :bar, proc(&:to_s), optional: true | ||
option :some_foo, as: :bar, optional: true |
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 think here is a potential for the backward incompatibility. This test is about not string, but symbol keys. What is essential is that the keys don't need to be a valid ruby methods.
For example, we should can handle this assignment:
class Foo
extend Dry::Initializer
option :"!!! my weird key", as: :weird_key
end
foo = Foo.new("!!! my weird key": 1) # notice the key is a symbol, not a string
foo.weird_key # => 1
The goal of this feature to make it possible handling any keys in the income hash (maybe with a forced symbolization like below)
data = { 1 => 2 }.transform_keys { |k| k.to_s.to_sym }
spec/several_assignments_spec.rb
Outdated
@@ -27,7 +29,7 @@ class Test::Foo | |||
end | |||
|
|||
context "when renamed" do | |||
subject { Test::Foo.new "some foo": :BAZ } | |||
subject { Test::Foo.new some_foo: :BAZ } |
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.
And the same problem is here
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.
Not sure why I originally made this change. Perhaps some intermediate state. I've reverted its and specs still pass. Can you approve the actions here so we can get spec output?
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.
Nope, I meant a different change. The original version got a space inside "some foo"
to empasize this is not a proper Ruby method name. In your version you just switched from symbol :some_foo
to the string "some_foo"
, but both satisfy the metnod name requirements.
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.
OK I missed that. The challenge with supporting that is we can't have options like that explicitly defined in the signature. We'd have to bury that logic in unpacking the **
arguments. Honestly I find this feature pretty surprising - I'm unclear on the real world use cases for it. Aliasing just in the constructor call when all other interactions are through the legal ruby method name passed to as
is a little peculiar. Can you explain more?
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.
The particular challenge being Introspecting the dry initializer doesn't accurately return the constructor arguments my_foo.method(:__dry_initializer_initialize__).parameters
Hi there 😊 Was this idea abandoned? It would be a really great addition! |
I'd also like to see this idea revived. Is there any way I can help? |
Any news on this feature? Or do we have any other way to restrict unknown params/options currently? |
default behavior remains unchanged
Unknown params and options are ignored but stored in their own attr_reader
rest params and rest options names are configurable
rest params and rest options can be turned off for strict mode
This adds support for strict checking of params and options: #68