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
WIP: ENV access clean ups #39765
WIP: ENV access clean ups #39765
Conversation
Here are the benchmarks: (credit: https://sikac.hu/fetch-vs-bracket-or-for-default-value-in-ruby-9bfd3b4cc37e)
Ideally we should be using: |
I believe this counts as a cosmetic change, but if this is a style we want to enforce, we can upgrade to RuboCop v0.86 and activate the (Note that an upgrade to RuboCop v0.85 is currently in progress: #39527.) |
@hahmed Thank you for pointing me to the benchmarks. Clearly, we want to avoid fetch with block. :-) The 10% between "fetch with default value" and "[] || default" is a shame. Since @jonathanhefner Thank you for mentioning the recent cop. I tried it just now, and unfortunately it has a bug with empty blocks (e.g., Rubocop (>0.87) will work with empty blocks. However, not all receivers of |
a7492ef
to
bf79700
Compare
ec266af
to
c48be30
Compare
The cop generates false-positives on use of ActiveSupport::Cache#fetch() ActiveRecord::Type::TypeMap#fetch() because those methods do not implement the Hash#fetch() API. Specifically, those `#fetch()` methods do not accept the value to be returned upon a missing key as the second parameter. Therefore, inline disable the cop on those calls.
c48be30
to
a6c52ac
Compare
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
Summary
ENV.fetch(k) { "fish" }
toENV.fetch(k, "fish"
)There are numerous calls to
ENV#fetch()
which use a single expression block to specify the return value if the key is missing. Block creation is unnecessary in this situation, because the return value can be given tofetch()
directly. In my opinion, specifying the default value directly is a simpler use of the Hash-like ENV API. In the YAML files immediately encountered by a Rails developer, an opportunity is presented to teach the API for this common use-case (i.e., get keya
, elseb
). There are occurrences of#fetch(a, 'other')
elsewhere in Rails code, so the change here also makes Rails code more consistent.ENV[k] || "fish"
toENV.fetch(k, "fish")
(leaveENV[k] || "fish" || "other"
alone)In code where an
ENV
key accessed and||
is used for a value if it missing, preferENV#fetch()
with a default value. ObviouslyENV[k] || "fish"
is not equivalent toENV.fetch(k, "fish")
whenENV[k] == false
, butENV
values are usually (always?) string and so in practice they are equivalent, as no Ruby string is falsy. However, in an "or-chain" (i.e.,a || b || c
) do not adjust the first two terms, because intent is clearer and the value ofb
makes this usage more complicated. Let's wait to see what the Rails test-suite reports.Other Information
Ran rubocop locally, with no violations. Waiting on the Rails testsuite via the PR.