Ruby Interview Questions and Answers

Blocks, modules, metaprogramming and Ruby on Rails basics.

Practise 10 random 6 peer-reviewed questions
Ruby Interview Syllabus & Preparation Strategy

Whether you are preparing for entry-level Ruby interview questions for freshers or senior software engineer interview questions addressing concurrency, scalability, and system architecture, this track provides peer-reviewed model answers with syntax walkthroughs, edge cases, and practical interview tips.

1 How does truthiness work in Ruby, and what is nil? Medium

In Ruby only nil and false are falsy. Everything else, including 0, "", empty arrays and empty hashes, is truthy. This differs from many languages and is a common source of bugs.

puts "truthy" if 0        # prints, 0 is truthy
puts "yes" if []          # prints, [] is truthy

value = nil
value ||= 10              # assign if nil or false
puts value.inspect        # 10

nil is the single instance of NilClass and responds to nil?; Object#nil? returns false for everything else. Test emptiness explicitly with empty? or, in Rails, present?. ||= assigns when the variable is nil or false.

Calling a method on nil raises NoMethodError, but safe navigation short-circuits: user&.profile&.name. nil.to_s is an empty string and nil.to_a is an empty array, which is why Array(nil) and String(nil) are useful conversions.

2 What is the difference between a block, a proc and a lambda? Medium

All three are chunks of code, but they differ in argument checking and how return behaves.

  • A block is passed to a method with do...end or braces and is not a standalone object unless converted with &.
  • A proc does not check argument count: missing arguments become nil and extras are dropped. A return returns from the enclosing method and can raise LocalJumpError if that method already returned.
  • A lambda checks arity strictly, and return returns only from the lambda.
def run(callable)
  callable.call
  :after
end

l = -> { return :from_lambda }
puts run(l)                 # :after

pr = proc { return :from_proc }
# run(pr) raises LocalJumpError

Lambdas are usually preferred because they behave like methods. Check with lambda?. Blocks are typically yielded once and converted to a Proc through the &block parameter.

3 What are modules and mixins used for? Medium

A module is a collection of methods and constants. It cannot be instantiated, but it can be mixed in to add behaviour, which is Ruby's alternative to multiple inheritance.

  • include adds the module's methods as instance methods of the class.
  • extend adds them to the object or class itself as singleton methods.
  • prepend inserts the module before the class in the lookup chain, so it can override methods and call super.
module Greetable
  def greet = "Hello, #{name}"
end

class User
  include Greetable
  attr_accessor :name
end

Modules are also used for namespacing, as in Admin::User. In Rails, ActiveSupport::Concern manages mixin dependencies and class methods.

Because lookup follows the ancestor chain, Module#ancestors is the key to predicting which method wins. Keep mixins cohesive and relatively state-light to avoid surprising interactions.

4 How does metaprogramming and method_missing work in Ruby? Medium

Ruby programs can define methods and classes at runtime. Common tools include define_method, send, respond_to?, instance_variable_get, class_eval and hooks such as included, inherited and method_added.

method_missing intercepts calls to undefined methods:

class Recorder
  def method_missing(name, *args)
    if name.to_s.start_with?("record_")
      key = name.to_s.sub("record_", "")
      puts "recording #{key}: #{args}"
    else
      super
    end
  end

  def respond_to_missing?(name, include_private = false)
    name.to_s.start_with?("record_") || super
  end
end

Always call super for names you do not handle, and define respond_to_missing? so respond_to? stays accurate. Metaprogramming enables expressive DSLs such as Rails routes and RSpec, but it hurts readability, tooling and performance. Prefer define_method for known methods.

5 How does Rails follow MVC and convention over configuration? Medium

Rails is an MVC framework: a request hits the router, maps to a controller action, the controller works with models, and renders a view. Models use ActiveRecord for the database, controllers orchestrate and views present.

Convention over configuration replaces boilerplate with defaults. The User model maps to the users table with an id primary key and pluralised naming. UsersController lives in app/controllers, views in app/views/users/, and RESTful routes come from resources :users.

class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end
end

Other essentials are strong parameters, so you write params.require(:user).permit(:name), database migrations, the asset pipeline or importmap, and per-environment configuration. The trade-off is hidden magic and a learning curve, but productivity and consistency for CRUD applications are high.

6 How does self work, and what is the difference between class and instance methods? Medium

self is the current object. Inside an instance method it is the receiver, inside a class body it is the class, and inside a class method it is the class as well.

class Widget
  def initialize(name)
    @name = name
  end

  def self.default
    new("default")            # class method
  end

  class << self
    def count
      @count ||= 0            # class-level instance variable
    end
  end
end

Widget.default

Defining def self.foo adds a singleton method to the class object, so it is called on the class rather than an instance. Instance variables differ by context: @name in an instance method belongs to the instance, while @count in a class method belongs to the class object.

self is also required to call an attribute writer, as in self.name = value, because a bare name = value would create a local variable instead.

Frequently Asked Questions About Ruby Interviews

What do hiring managers evaluate in Ruby technical rounds?

Technical interviewers look for foundational fluency, idiomatic syntax, clarity when communicating complex logic, and awareness of performance trade-offs (e.g. memory footprint, render performance, and network latency) in production environments.

What are the best interview tips for practicing Ruby questions?

Use active recall: summarize each answer in your own words before revealing the model solution. Focus on explaining why a certain approach is chosen rather than just memorizing code syntax.