Skip to content

Add disabled? as syntax sugar for !enabled?#994

Open
loqimean wants to merge 1 commit intoflippercloud:mainfrom
loqimean:loqimean/add-a-method-disabled-like-enabled
Open

Add disabled? as syntax sugar for !enabled?#994
loqimean wants to merge 1 commit intoflippercloud:mainfrom
loqimean:loqimean/add-a-method-disabled-like-enabled

Conversation

@loqimean
Copy link
Copy Markdown

@loqimean loqimean commented Apr 23, 2026

Motivation

When checking whether a feature is off, you currently have to write:

if !Flipper.enabled?(:my_feature)
  # ...
end

or the slightly more idiomatic but still awkward:

unless Flipper.enabled?(:my_feature)
  # ...
end

Both read backwards — you're asking "is it enabled?" when you really want to express "is it disabled?". This gets noisy in call sites that deal primarily with the disabled state, and the negation adds cognitive overhead on every read.

Change

Adds disabled? as the inverse of enabled? on Feature, DSL, and the top-level Flipper module:

# Before
if !Flipper.enabled?(:my_feature, current_user)
  redirect_to upgrade_path
end

# After
if Flipper.disabled?(:my_feature, current_user)
  redirect_to upgrade_path
end

disabled? accepts the same actor arguments as enabled? and simply returns !enabled?(*actors), so all existing gate semantics are preserved.

Test plan

  • Feature#disabled? specs covering single actor, multiple actors, and enabled/disabled states
  • Flipper.disabled? delegation spec
  • Full suite passes (bundle exec rspec spec/flipper/feature_spec.rb spec/flipper_spec.rb — 205 examples, 0 failures)

Avoids the repetitive and noisy !flipper.enabled?(:feature) pattern everywhere feature flags are checked in a disabled state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jnunemaker
Copy link
Copy Markdown
Collaborator

Hi, appreciate the PR but this is intentional. I talked about it in the past on similar PRs. #94 (comment)

Flipper is only about allowing people in, not blocking people but disabled? gives the vibe that someone can be blocked.

@loqimean
Copy link
Copy Markdown
Author

Hi, appreciate the PR but this is intentional. I talked about it in the past on similar PRs. #94 (comment)

Flipper is only about allowing people in, not blocking people but disabled? gives the vibe that someone can be blocked.

Hey, thanks for the context and linking the previous discussion — I did find #94 after looking more carefully, so I can see this has come up a few times!

I totally get the concern about the mental model. The framing of "flipper only opens gates, never closes them" makes sense architecturally. But I'd argue disabled? doesn't necessarily imply that individual actors can be blocked — it's just a readability convenience for the inverse check, same way Ruby's zero? doesn't mean you set something to zero.

The practical case I keep running into is negative conditionals in real product code. Something like:

if !Flipper.enabled?(:gdpr_consent_collected, user)
  show_consent_wall
elsif !Flipper.enabled?(:age_verified, user)
  show_age_gate
else
  show_full_content
end

You can't really reach for unless here, and stacking ! negations in elsif chains is considered a code smell in a lot of teams (including mine, where unless is also discouraged). The result is that developers end up writing harder-to-read code not because of their logic, but because the gem nudges them that way.

The fact that this has surfaced in at least 3 independent PRs over the years suggests it's a genuine friction point, not just a personal preference. Maybe a note in the docs that disabled? is intentionally absent and here's why would at least save future contributors the confusion?

Either way, appreciate you taking the time to explain the reasoning!

@jnunemaker
Copy link
Copy Markdown
Collaborator

The only thing I can think of is not_enabled? which feels so clunky but still holds the line of the intent/meaning. I tried claude and that is the best they came up with as well.

@jnunemaker
Copy link
Copy Markdown
Collaborator

jnunemaker commented Apr 24, 2026

this is also important because i'm working on permit/deny which will actually be checked before enabled? so adding disabled? would be even more confusing in a few weeks. :)

@loqimean
Copy link
Copy Markdown
Author

The only thing I can think of is not_enabled? which feels so clunky but still holds the line of the intent/meaning. I tried claude and that is the best they came up with as well.

Okay, got it 😄. So, what if I rename it disabled? to 'not_enabled?'? At least that's better than nothing 😆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants