Skip to Content
Course content

167: Solargraph for Language Server Support

Click on the "Edit" button in the top corner of the screen to edit your slide content.

You've probably experienced this: you're deep in a project, you call a method on an object that you know exists, but your editor is stubbornly underlining it in red or refusing to show you the documentation when you hover over it. You run the code, and it works perfectly. The "bug" isn't in your Ruby code—it's in your tooling. This is where Solargraph comes in.

class Invoice
  attr_reader :client

  def initialize(client)
    @client = client
  end

  def generate_bill(amount)
    # Your editor is likely flagging this as an 'undefined method'
    # or giving you zero autocomplete options for .send_notification
    client.send_notification("Your bill is #{amount}")
  end
end

class Client
  def send_notification(msg)
    puts "Emailing client: #{msg}"
  end
end

# This runs fine, but the IDE is blind
Invoice.new(Client.new).generate_bill(50)

The Blind Spot in Dynamic Typing

In the example above, the Invoice#generate_bill method takes a client object. Because Ruby is dynamically typed, Solargraph (the Language Server) looks at client and sees... nothing. It doesn't know if client is a Client object, a String, or a Hash. It can't look inside the Client class to find send_notification because there is no explicit link between the variable and the class.

I used to just ignore these warnings and rely on my memory, but as projects grow to thousands of lines, that's a recipe for burnout. You want your editor to be your external brain, not a source of false alarms.

Teaching Solargraph via YARD Tags

The fix isn't to change how your code runs, but to provide "hints" that Solargraph can read. Solargraph relies heavily on YARD (Yay! A Ruby Documentation tool). By adding a specific type tag to your method documentation, you bridge the gap between the dynamic nature of Ruby and the static requirements of a language server.

class Invoice
  attr_reader :client

  # @param client [Client] The client object handling notifications
  def initialize(client)
    @client = client
  end

  def generate_bill(amount)
    # Now, when you type 'client.', Solargraph knows it's a Client object
    # and will suggest .send_notification automatically.
    client.send_notification("Your bill is #{amount}")
  end
end

By adding @param client [Client], you're telling Solargraph: "Hey, whenever you see the variable client in this context, treat it as an instance of the Client class." The red underlines vanish, and the autocomplete starts working. It's a small investment in documentation that saves hours of jumping between files to check method names.

Fixing Missing Core Library Definitions

Sometimes, even standard Ruby methods (like those in Enumerable or BigDecimal) won't show up in your autocomplete. This usually happens because Solargraph's internal index of the Ruby core library is out of sync with the version of Ruby you're actually running.

If you find that Array#map or String#strip aren't being suggested, don't waste time debugging your config file. Instead, run this in your terminal:

solargraph download-core

This command forces Solargraph to pull down the latest signatures for the Ruby core and standard libraries. I usually run this immediately after updating my Ruby version via rbenv or rvm. It's the "turn it off and on again" of the Ruby LSP world.




📋 Practical Task

Implementing Type Hinting for a Payment Gateway Interface

You are working on a payment processing system. You have a PaymentProcessor class that accepts different gateway objects (e.g., StripeGateway, PayPalGateway). Currently, your editor cannot provide autocomplete for the process_payment method because it doesn't know which gateway is being used.

Your Task:

  • Create a StripeGateway class with a method called charge(amount).
  • Create a PaymentProcessor class with an initialize method that accepts a gateway.
  • Use a YARD @param tag in the initialize method to tell Solargraph that gateway is an instance of StripeGateway.
  • Add a method execute(amount) to PaymentProcessor that calls gateway.charge(amount).

Verify your solution by ensuring that when you type gateway. inside the execute method, your editor suggests the charge method.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.