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 implicit receiver support to Object#with_options
#16339
Conversation
In my opinion this make the readability worse and my cause confusion where these call are being made. Depending on the code I don't know if the has_many contains that options or not. But it is just my opinion. @tenderlove @jeremy @chancancode @dhh WDYT? |
Ah, forgot to say, thank you for the pull request |
I'm on the fence. I like the improved readability, but I'm generally very hesitant to use implicit receiver outside of narrowly defined DSLs, like routing. But on the other hand, how likely are you to have other calls inside the with_options call that doesn't want that receiver? Rafael, do you have any code that does that? |
Yeah, I think IMO, the first example only looks ugly because of the large |
Actually, doesn't this change the scope for any blocks defined therein? That seems bad. |
Just theoretic code. Depending on the size of the block the only thing that will say you if the call of the method use the option is the indentation. Of course text editors will help with code highlight but say you have: class Account < ActiveRecord::Base
with_options dependent: :destroy do
has_many :customers
has_many :products
has_many :invoices
has_many :expenses
has_many :cars
has_many :books
has_many :pages
has_many :articles
end
has_many :users
has_many :pirates
has_many :ships
end It is really hard to know what has applied options and what doesn't have. |
@rafaelfranca the old syntax is still supported and nothing prevents you from using it. On the other hand, there are cases where implicit receiver syntax gives clear readability advantages. I as a developer prefer to have an option to use implicit/explicit rather than being forced to use explicit only. |
Actually, I think that settles it for me. Since you can still use explicit, when you are mixing things that won’t just use implicit receiver, this covers it. I’m On Jul 29, 2014, at 11:24, Pavel Pravosud notifications@github.com wrote:
|
|
|
yield ActiveSupport::OptionMerger.new(self, options) | ||
def with_options(options, &block) | ||
merger = ActiveSupport::OptionMerger.new(self, options) | ||
block.arity == 1 ? block.call(merger) : merger.instance_eval(&block) |
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.
Even though we don't support more than 1 arity, under the principle of least surprise, I'd flip these around (so that if someone for whatever reason passes more than one, behavior won't change).
block.arity.zero? ? merger.instance_eval(&block) : block.call(merger)
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.
@egilburg good point, thanks.
Add implicit receiver support to `Object#with_options`
I've noticed that 99% of the cases I use
Object#with_options
to define a bunch of associations or validations in my models. The code could be much cleaner if we wouldn't have to pass explicit receiver towith_options
block all the time, especially if it's gonna be the only receiver.So, this pull request makes it possible. It's also fully backwards compatible and old syntax still works as expected.
Before:
After: