Hot Take

Why Your Ruby Variables Should Be Full English Sentences

Ruby was designed to read like English. Matz built it for developer happiness. So why are we still naming variables like it's 1987 and we're paying by the character?

Dimitar Smilyanov
Dimitar Smilyanov April 1, 2026 · 10 min read

The Ruby community prides itself on writing code that reads like English. Matz designed the language around developer happiness. Rails gave us 5.days.ago and user.has_many :posts. And yet, most Ruby developers still name their variables like it's 1987 and they're paying by the character.

I'm going to make an argument that will feel extreme at first: your Ruby variables, modules, and classes should be as long as they need to be to form complete, unambiguous English descriptions. Not abbreviated. Not truncated. Not clever. Complete.

The Case Against Short Names

Look at any production Ruby codebase and you'll find names like these:

Rubyusr = User.find(params[:id])
txn = usr.transactions.last
amt = txn.amount
proc_result = PaymentProcessor.charge(usr, amt)

Every single name here is a tiny puzzle. What's usr? Probably a user. But is it the current user? An admin user? The user being edited? What's txn? A transaction, but which one and why? What's proc_result? A processor result? A procedure result? A process result?

Now consider:

Rubyuser_whose_payment_is_being_processed = User.find(params[:id])
most_recent_transaction_for_this_user = user_whose_payment_is_being_processed.transactions.last
dollar_amount_to_charge = most_recent_transaction_for_this_user.amount
result_of_charging_the_users_credit_card = PaymentProcessor.charge(
  user_whose_payment_is_being_processed,
  dollar_amount_to_charge
)

Every variable is self-documenting. There is zero ambiguity. A new team member can read this code and understand exactly what's happening without checking a single other file. This isn't just readable — it's unreadable wrong. You literally cannot misinterpret what any of these variables contain.

Ruby Was Built for This

Ruby has no character limit on identifiers. The language was explicitly designed so that method_name_with_many_words would be natural and idiomatic. Matz's original thesis emphasizes that code is read far more often than it's written, and that the reader's experience should take priority over the writer's convenience.

And yet, the community stopped halfway. We write validates_presence_of in our DSLs but then turn around and name our variables v and tmp. We write methods called authenticate_user_from_session_token and then store the result in auth. We're being expressive in our APIs and cryptic in our implementations.

The "It's Too Long" Objection

The number one pushback I get is: "But the lines will be too long!" Let's examine this.

First: Ruby has no line length limit. Rubocop's default 120-character limit is a convention, not a law. And it's a convention inherited from the days of 80-column terminals — hardware that hasn't existed in decades. Modern monitors display 200+ characters comfortably. If your variable name makes a line 150 characters, your monitor can handle it.

Second: long lines force better structure. If a method is so complex that long variable names make it unreadable, the method is too complex. Long names are a forcing function for decomposition. When every variable is a full sentence, methods naturally stay small because the cognitive weight of each line increases, pushing you toward simpler logic.

Rubyclass UserAccountDeactivationDueToNonPaymentService
  def permanently_deactivate_account_and_notify_user_via_email(
    user_account_to_be_deactivated:,
    reason_for_deactivation_as_human_readable_string:,
    email_template_to_use_for_notification: default_deactivation_email_template
  )
    record_of_the_deactivation_event = DeactivationEventLog.create_new_entry_for(
      account: user_account_to_be_deactivated,
      reason: reason_for_deactivation_as_human_readable_string,
      initiated_at: Time.current
    )

    user_account_to_be_deactivated.update_status_to_permanently_deactivated!

    EmailDeliveryService.send_deactivation_notification_to_account_holder(
      recipient: user_account_to_be_deactivated.primary_email_address,
      template: email_template_to_use_for_notification,
      deactivation_details: record_of_the_deactivation_event
    )

    record_of_the_deactivation_event
  end
end

Read that code. Tell me you don't understand exactly what it does. Tell me you need a comment. Tell me you need to check the implementation of any called method. You can't — because the names tell you everything.

Modules and Classes: Don't Be Afraid of Length

This principle applies doubly to modules and classes. Short class names are the root of most namespace confusion in large Rails applications.

Ruby# Bad: What does this process? What kind of service? For whom?
class ProcessorService; end

# Good: No ambiguity whatsoever
class CreditCardPaymentProcessorForSubscriptionRenewals; end
Ruby# Bad: Which users? What kind of notifications?
module UserNotifications; end

# Good: Crystal clear scope and purpose
module EmailNotificationsForUsersWhoseTrialPeriodIsExpiring; end

When you see CreditCardPaymentProcessorForSubscriptionRenewals in a stack trace, you know exactly where to look. When you see ProcessorService, you're grepping.

The Measurable Impact

I introduced this naming convention on a team of eight Ruby developers. We tracked several metrics over a three-month period:

Metric Before (short names) After (descriptive names)
Avg time to understand unfamiliar method 8.4 minutes 2.1 minutes
PR review turnaround time 6.2 hours 2.8 hours
"What does this variable mean?" Slack messages ~15/week 0/week
Onboarding time for new developer 3 weeks 1.5 weeks
Average method length (lines) 24 11

Every metric improved. And the most surprising finding: average method length halved. The long names made developers instinctively write shorter, more focused methods. The naming convention improved the architecture without anyone explicitly trying to improve the architecture.

Addressing the Skeptics

"But what about iteration variables? Am I supposed to write each_individual_user_in_the_collection?"

Yes. Or at minimum, current_user_being_processed. The convention of using i, j, k, or single-letter block variables is a relic of C and Fortran. Ruby is not C. In Ruby, |each_active_subscription_that_needs_renewal| is perfectly valid and infinitely more useful than |s|.

"This will make my tests impossibly long."

Good. If your test setup requires so many long-named variables that it becomes unwieldy, your test is testing too many things. Long names in tests are a code smell detector for free.

"My team will never agree to this."

Start with a single PR. Name everything descriptively. Watch the code review: people will understand your code faster than any PR they've reviewed in months. Results sell themselves.

A Style Guide

After a year of practicing this, here are my guidelines:

  1. Variables: Should answer "what is this and why do we have it?" in the name itself. Minimum three words. user becomes currently_authenticated_user. count becomes total_number_of_failed_login_attempts.
  2. Methods: Should describe the complete action including the object and any important qualifiers. process becomes process_pending_refund_requests_and_notify_finance_team.
  3. Classes: Should describe what the class does, for whom, and under what circumstances. Two to six words minimum.
  4. Modules: Should describe the full scope of the namespace's responsibility.
  5. Constants: Should be even more descriptive than variables, since they're globally accessible and more likely to be encountered out of context.

Ruby gave us a language designed to read like English. It's time we actually wrote English with it.


This is an April 1st post. Please don't actually do any of this. No production codebases were harmed in the making of this post. Probably.


More Posts