💎

Ruby MCQ

Test your Ruby knowledge with 100 multiple choice questions covering fundamentals to advanced concepts, with instant feedback and explanations.

100 Questions 40 Beginner 40 Intermediate 20 Advanced

How This Practice Test Works

Every question below expands right on this page — click a question to reveal its four options, pick the one you think is correct, and you'll get instant feedback along with the correct answer and a short explanation of the reasoning. Questions are grouped by difficulty, so start with the 40 beginner questions to confirm your fundamentals, work through the 40 intermediate ones, and finish with the 20 advanced questions that mirror what exams and technical screenings actually ask. There's no sign-up, no timer, and no limit — retake the test as often as you like.

Curated by Tech Baithak Editorial Team  ·  Last updated: June 2026

1

Which command prints text to the console with a newline at the end in Ruby?

B

Correct Answer

puts

Explanation

puts outputs its argument followed by a newline; print does not automatically add a newline.

2

How do you create a comment in Ruby?

C

Correct Answer

# comment

Explanation

The "#" symbol starts a single-line comment in Ruby.

3

Which keyword is used to define a method in Ruby?

B

Correct Answer

def

Explanation

Methods in Ruby are defined using "def methodname ... end".

4

What is the correct way to create a variable named name with value "Alice"?

C

Correct Answer

name = "Alice"

Explanation

Ruby variables are dynamically typed and assigned simply with "=", without any declaration keyword.

5

Which symbol is used to denote a Symbol literal in Ruby, e.g. :name?

C

Correct Answer

:

Explanation

A colon prefix denotes a Symbol, an immutable, interned identifier commonly used as hash keys or method names.

6

How do you create an array containing the numbers 1, 2, and 3?

B

Correct Answer

[1, 2, 3]

Explanation

Arrays in Ruby are created using square brackets containing comma-separated elements.

7

Which method returns the number of elements in an array?

B

Correct Answer

size or length

Explanation

Both size and length (aliases of each other) return the number of elements in an array; count also works similarly.

8

What does the "each" method do when called on an array?

B

Correct Answer

Iterates over each element, yielding it to a block

Explanation

each iterates over a collection, calling the given block once per element without modifying the collection.

9

How do you create a hash (dictionary) mapping "name" to "Alice"?

A

Correct Answer

{"name" => "Alice"} or {name: "Alice"}

Explanation

Ruby hashes can be created with the "key => value" syntax or, for symbol keys, the shorthand "key: value" syntax.

10

Which keyword starts a conditional statement in Ruby?

C

Correct Answer

if

Explanation

"if condition ... end" is the standard conditional statement syntax in Ruby.

11

What does "nil" represent in Ruby?

C

Correct Answer

The absence of a value or object

Explanation

nil is Ruby's representation of "nothing" or "no value", distinct from false, 0, or an empty string.

12

How do you define a class named "Dog" in Ruby?

A

Correct Answer

class Dog ... end

Explanation

Classes are defined with "class ClassName ... end", with class names conventionally in CamelCase.

13

What is the special variable name used to reference the current object instance inside a method?

B

Correct Answer

self

Explanation

"self" refers to the current object (instance) within instance methods, similar to "this" in other languages.

14

Which symbol prefix denotes an instance variable in Ruby?

B

Correct Answer

@

Explanation

Instance variables are prefixed with a single "@", e.g. "@name", and are scoped to the object instance.

15

How do you concatenate two strings "Hello" and "World" with a space between them?

A

Correct Answer

"Hello" + " " + "World"

Explanation

The "+" operator concatenates strings in Ruby; "<<" can also append in place.

16

What is the result of "3 ** 2" in Ruby?

B

Correct Answer

9

Explanation

The "**" operator performs exponentiation, so 3 ** 2 equals 9 (3 squared).

17

Which loop construct repeats code a fixed number of times, e.g. 5 times?

A

Correct Answer

5.times do ... end

Explanation

The Integer#times method, e.g. "5.times do |i| ... end", executes the block 5 times.

18

What does the "<=>" operator (spaceship operator) return?

B

Correct Answer

-1, 0, or 1 depending on whether the left operand is less than, equal to, or greater than the right

Explanation

The spaceship operator returns -1, 0, or 1 for less than, equal, or greater than respectively, and is used to implement Comparable.

19

How do you check if a string is empty?

A

Correct Answer

str.empty?

Explanation

Methods ending in "?" conventionally return booleans; String#empty? returns true if the string has zero length.

20

What is the file extension for Ruby source files?

A

Correct Answer

.rb

Explanation

Ruby source files conventionally use the ".rb" extension.

21

How do you create a range from 1 to 5 (inclusive)?

B

Correct Answer

1..5

Explanation

".." creates an inclusive range (1 to 5 includes 5), while "..." creates an exclusive range (excludes the last value).

22

Which method converts a string "42" to an integer?

A

Correct Answer

"42".to_i

Explanation

String#to_i converts a string to an integer, returning 0 if conversion is not possible.

23

What does "attr_accessor :name" generate for a class?

B

Correct Answer

Both a getter and setter method for the @name instance variable

Explanation

attr_accessor generates both a reader (getter) and writer (setter) method for the given instance variable, saving boilerplate.

24

How do you start an interactive Ruby shell from the command line?

B

Correct Answer

irb

Explanation

irb (Interactive Ruby) launches a REPL where Ruby code can be executed interactively.

25

What is the result of "nil.to_s"?

B

Correct Answer

""

Explanation

nil.to_s returns an empty string "", while nil.inspect returns the string "nil".

26

Which keyword is used to handle exceptions in Ruby?

B

Correct Answer

rescue

Explanation

Ruby uses "begin ... rescue => e ... end" to catch and handle exceptions.

27

What does "1.0 / 3" return in Ruby?

C

Correct Answer

A floating-point approximation like 0.3333333333333333

Explanation

Dividing a Float by an Integer yields a Float result; only Integer/Integer division truncates to an integer.

28

How do you define a constant in Ruby?

B

Correct Answer

A variable name starting with an uppercase letter, e.g. NAME = "value"

Explanation

In Ruby, identifiers starting with an uppercase letter are treated as constants by convention (modifiable but triggers a warning).

29

What does the "map" method do when called on an array?

B

Correct Answer

Returns a new array with the results of applying a block to each element

Explanation

map (alias collect) transforms each element via the given block and returns a new array of the results, leaving the original unchanged.

30

Which operator checks for equality of value in Ruby?

B

Correct Answer

==

Explanation

"==" checks if two objects have equal values; "=" is assignment, and "===" is used for case equality (often in case/when).

31

How do you require another file or library in Ruby?

C

Correct Answer

require "file"

Explanation

require loads a Ruby file or library, ensuring it is only loaded once per program.

32

What does "puts [1, 2, 3]" output?

B

Correct Answer

Each element printed on its own line

Explanation

When puts is given an array, it prints each element on its own line rather than the array literal representation.

33

What is a "block" in Ruby?

B

Correct Answer

A chunk of code enclosed in do...end or {} that can be passed to methods

Explanation

Blocks are anonymous pieces of code passed to methods, commonly used with iterators like each, map, and select.

34

Which method removes the last element from an array and returns it?

B

Correct Answer

pop

Explanation

Array#pop removes and returns the last element, while Array#shift does the same for the first element.

35

What does "String#upcase" do?

B

Correct Answer

Converts all characters in the string to uppercase

Explanation

upcase returns a copy of the string with all lowercase letters converted to uppercase.

36

How do you define a method with a default parameter value?

A

Correct Answer

def greet(name = "World") ... end

Explanation

Default parameter values are specified with "=" in the parameter list, used when the caller omits the argument.

37

What does "unless condition" do in Ruby?

B

Correct Answer

Executes the block only if the condition is false

Explanation

"unless" is the inverse of "if" — the associated code runs only when the condition evaluates to false.

38

What does ".freeze" do to an object?

B

Correct Answer

Prevents further modifications to the object

Explanation

freeze makes an object immutable; attempting to modify a frozen object raises a FrozenError.

39

Which keyword is used to create a module in Ruby?

A

Correct Answer

module

Explanation

"module ModuleName ... end" defines a module, used for namespacing and as mixins via include.

40

What is the purpose of "Gemfile" in a Ruby project?

B

Correct Answer

It declares the gem (library) dependencies for the project, managed by Bundler

Explanation

A Gemfile lists the gems a project depends on; Bundler reads it to install and lock dependency versions in Gemfile.lock.

1

What is the difference between a Proc and a Lambda in Ruby?

B

Correct Answer

Lambdas enforce strict argument count and "return" only exits the lambda, while Procs are more lenient with arguments and "return" exits the enclosing method

Explanation

Lambdas check the number of arguments strictly and a "return" inside returns from the lambda itself, whereas Procs are lenient about arity and "return" returns from the enclosing method context.

2

What does the "&block" parameter syntax do in a method definition?

B

Correct Answer

It captures the block passed to the method as an explicit Proc object that can be called with .call or yielded

Explanation

Prefixing the last parameter with "&" converts an implicit block argument into an explicit Proc object, which can be stored, passed around, or invoked with call/yield.

3

What is "duck typing" in Ruby?

B

Correct Answer

A design philosophy where an object's suitability is determined by the presence of certain methods, rather than its class

Explanation

Duck typing means "if it walks like a duck and quacks like a duck, it's a duck" — Ruby cares whether an object responds to the needed methods, not its actual class.

4

What does "include" do when used inside a class definition with a module?

B

Correct Answer

Mixes the module's instance methods into the class, making them available as instance methods of the class

Explanation

include mixes a module's instance methods into a class, inserting the module into the class's ancestor chain.

5

What is the difference between "extend" and "include" with modules?

B

Correct Answer

include adds module methods as instance methods, while extend adds them as methods of the specific object or as class methods when used at the class level

Explanation

include mixes module methods in as instance methods of the including class; extend adds module methods directly to the singleton class of an object (or class, making them class methods).

6

What does "method_missing" allow a class to do?

B

Correct Answer

Intercept calls to undefined methods and handle them dynamically, e.g. for dynamic proxies or DSLs

Explanation

method_missing is invoked when a method that doesn't exist is called on an object, allowing dynamic handling of arbitrary method calls.

7

What is the purpose of "yield" inside a method?

B

Correct Answer

To execute the block passed to the method at that point

Explanation

yield invokes the block associated with the current method call, optionally passing arguments to it.

8

What does "Array#inject" (also known as reduce) do?

B

Correct Answer

Combines all elements into a single value by repeatedly applying a binary operation, carrying an accumulator

Explanation

inject (alias reduce) takes an optional initial value and a block, applying the block cumulatively to reduce the collection to a single result.

9

What is the difference between "==", "equal?", and "eql?" in Ruby?

B

Correct Answer

== checks value equality (often overridable), equal? checks object identity (same object_id), and eql? checks value and type equality (used by Hash keys)

Explanation

== is typically overridden for value comparison, equal? checks if two references point to the same object, and eql? additionally requires the same type (e.g. 1.eql?(1.0) is false).

10

What does "Comparable" module provide when a class implements "<=>"?

B

Correct Answer

Comparison operators like <, >, <=, >=, ==, and the between? method, derived from the <=> implementation

Explanation

Including Comparable and defining <=> gives the class all standard comparison operators and helper methods like clamp and between? for free.

11

What is the purpose of "Enumerable" module?

B

Correct Answer

It provides traversal, search, sort, and other collection-related methods (map, select, reduce, etc.) to any class that defines "each"

Explanation

Any class that includes Enumerable and defines an "each" method gains access to a wide range of iteration methods like map, select, sort, and reduce.

12

What does "case/when" provide that an if/elsif chain also does, and how does it differ semantically?

B

Correct Answer

case/when uses the "===" operator (case equality) for each "when" clause, which allows matching against ranges, classes, regexes, and more, not just direct equality

Explanation

case/when calls "===" on each candidate, which different classes implement differently (e.g. Range#=== checks membership, Class#=== checks instance, Regexp#=== checks match), giving more flexible matching than plain equality.

13

What is the effect of "private" keyword in a class definition?

A

Correct Answer

It makes all subsequent methods accessible only without an explicit receiver (cannot be called as obj.method from outside)

Explanation

Methods declared after "private" cannot be called with an explicit receiver from outside the object (with rare exceptions for setters), restricting them to internal use.

14

What does "Array#select" (alias filter) return?

B

Correct Answer

A new array containing only the elements for which the block returns true

Explanation

select (filter) returns a new array with only the elements that satisfy the block's condition, leaving the original array unchanged.

15

What is the purpose of "respond_to?" method?

A

Correct Answer

To check if an object responds to (defines/inherits) a given method name

Explanation

respond_to?(:method_name) returns true if the object has a method with that name, often used to support duck typing checks.

16

What does "class << self" inside a class definition do?

B

Correct Answer

Opens the singleton class of self, commonly used to define class-level (static) methods

Explanation

"class << self" opens the singleton (eigenclass) of the current object/class, a common idiom for defining multiple class methods at once.

17

What does "Object#dup" do compared to "Object#clone"?

B

Correct Answer

Both create a shallow copy of an object, but clone also copies the frozen state and singleton methods, while dup does not

Explanation

dup and clone both produce shallow copies, but clone preserves frozen status and singleton class methods of the original object, whereas dup resets these.

18

What is the purpose of keyword arguments in method definitions, e.g. "def greet(name:, greeting: 'Hello')"?

B

Correct Answer

They allow arguments to be passed by name in any order, with optional default values for those not marked as required

Explanation

Keyword arguments let callers specify arguments by name (e.g. greet(name: "Bob")), improving readability and allowing any order, with defaults for optional ones.

19

What does the splat operator "*" do in "def foo(*args)"?

B

Correct Answer

Collects any number of remaining positional arguments into an array named args

Explanation

The splat operator "*args" gathers any number of extra positional arguments passed to the method into an array.

20

What is the difference between "load" and "require" for including external Ruby files?

B

Correct Answer

require loads a file only once (tracking loaded files), while load executes the file every time it is called, even if previously loaded

Explanation

require keeps track of files already loaded and skips re-loading them, while load re-executes the file content each time it is called.

21

What does "Hash#each_pair" (or "each") yield when iterating over a hash?

B

Correct Answer

Both the key and value for each entry as a pair

Explanation

Iterating a hash with each yields [key, value] pairs, often destructured as "|key, value|" in the block parameters.

22

What does "Object.new.tap { |o| puts o }" demonstrate about the "tap" method?

B

Correct Answer

tap yields the object to the block (for side effects like logging/debugging) and then returns the original object unchanged

Explanation

tap passes self to the given block and returns self, useful for inserting debugging or side-effect code into a method chain without breaking it.

23

What is "monkey patching" in Ruby?

B

Correct Answer

Modifying or extending existing classes (including built-in ones like String or Array) at runtime by reopening them

Explanation

Because classes can be reopened at any time, developers can add or override methods on existing classes — a powerful but potentially risky technique called monkey patching.

24

What does "ObjectSpace" allow in Ruby (conceptually)?

B

Correct Answer

Introspecting and iterating over all live objects in the Ruby heap, often used for debugging memory issues

Explanation

ObjectSpace provides interfaces for examining the object graph, including iterating over all currently allocated objects, useful for memory profiling.

25

What is the purpose of "Struct.new" in Ruby?

B

Correct Answer

To quickly define a simple class with named attributes and automatically generated accessors

Explanation

Struct.new(:a, :b) creates a new class with attribute accessors for :a and :b, plus useful methods like == and to_a, reducing boilerplate for simple data objects.

26

What does "begin ... rescue ... ensure ... end" guarantee about the "ensure" block?

B

Correct Answer

It always runs, whether or not an exception was raised or rescued, similar to "finally" in other languages

Explanation

The ensure clause executes regardless of whether an exception occurred, was rescued, or the method returned normally — typically used for cleanup.

27

What does "String#gsub(pattern, replacement)" do?

B

Correct Answer

Replaces all occurrences of pattern in the string with replacement, returning a new string

Explanation

gsub (global substitution) replaces every match of the pattern (string or regex) with the replacement, returning a new string; sub replaces only the first match.

28

What does "Kernel#freeze" combined with constants help prevent?

B

Correct Answer

Accidental mutation of objects assigned to constants, since constants themselves can still be reassigned but their referenced object can be frozen against mutation

Explanation

Even though Ruby constants can technically be reassigned (with a warning), freezing the object they reference prevents in-place mutation of that object's state.

29

What is the purpose of the "protected" access modifier compared to "private"?

B

Correct Answer

protected methods can be called with an explicit receiver as long as the caller is an instance of the same class or subclass, while private methods generally cannot be called with an explicit receiver at all

Explanation

protected allows calling the method on another object of the same class hierarchy (e.g. comparing two instances), whereas private restricts calls to implicit self only.

30

What does "Array#flatten" do?

B

Correct Answer

Recursively flattens nested arrays into a single-level array

Explanation

flatten returns a new array with all nested arrays recursively merged into a single, flat array; an optional depth argument limits recursion.

31

What does "Object#send" allow you to do?

B

Correct Answer

Call a method on an object dynamically by name, including private methods

Explanation

send(:method_name, *args) invokes the named method dynamically, bypassing normal access control (unlike public_send which respects it).

32

What is the difference between "Array#map!" and "Array#map"?

B

Correct Answer

map returns a new array with transformed elements, while map! mutates the original array in place and returns it

Explanation

Methods ending with "!" conventionally mutate the receiver in place; map! transforms and replaces the elements of the original array rather than returning a new one.

33

What does "Comparable#clamp(min, max)" do?

B

Correct Answer

Returns the value constrained to lie within [min, max], returning min or max if the value falls outside the range

Explanation

clamp restricts a value to a given range, returning the boundary value if the original value is below the minimum or above the maximum.

34

What does "Hash#fetch(key, default)" do differently from "hash[key]"?

B

Correct Answer

fetch raises a KeyError if the key is missing and no default/block is given, while hash[key] simply returns nil for missing keys

Explanation

fetch provides safer access by raising an error (or returning a specified default/block result) for missing keys, while [] silently returns nil.

35

What is the role of "Module#prepend" compared to "include"?

B

Correct Answer

prepend inserts the module before the class in the ancestor chain, so the module's methods can override and call "super" to reach the class's own methods

Explanation

Unlike include (which places the module after the class in the method lookup chain), prepend places the module before the class, allowing the module to intercept and wrap the class's methods via super.

36

What does "Object#instance_variable_get(:@name)" do?

B

Correct Answer

Returns the value of the instance variable @name even if there is no accessor method defined for it

Explanation

instance_variable_get allows reading an instance variable's value by name dynamically, bypassing the need for a getter method.

37

What is the purpose of "Array#each_with_index"?

B

Correct Answer

It iterates over the array yielding both each element and its index to the block

Explanation

each_with_index yields each element along with its zero-based index, useful when both the value and its position are needed.

38

What does "String#split(",")" return for the string "a,b,c"?

B

Correct Answer

["a", "b", "c"]

Explanation

split divides a string into an array of substrings based on the given delimiter, here producing ["a", "b", "c"].

39

What does "Object#is_a?(SomeClass)" check, and how does it relate to "kind_of?"?

B

Correct Answer

is_a? and kind_of? are aliases that check whether an object is an instance of a class or one of its ancestors/included modules

Explanation

is_a? and kind_of? are synonyms that return true if the object's class, superclass chain, or included modules include the given class/module.

40

What does "Array#uniq" do?

B

Correct Answer

Returns a new array with duplicate elements removed, preserving the order of first occurrence

Explanation

uniq removes duplicate values from an array, keeping the first occurrence of each unique element and preserving relative order.

1

What is the Ruby "ancestors" chain and how does method resolution order (MRO) work with multiple included modules?

B

Correct Answer

Ruby searches the ancestors array (class, then included/prepended modules, then superclass and its modules, etc.) in order, with later includes taking precedence over earlier ones for method lookup

Explanation

The ancestors method shows the linearized lookup order; when multiple modules are included, the most recently included one takes precedence (appears earlier in the chain) for method resolution.

2

What is the difference between "Object#instance_eval" and "Object#class_eval" (also "module_eval")?

B

Correct Answer

instance_eval evaluates a block with self set to the receiver (useful for singleton methods or accessing privates), while class_eval evaluates a block in the context of a class/module, allowing instance method definitions

Explanation

instance_eval changes self to the receiver for the duration of the block, often used for DSLs or accessing privates; class_eval changes self to a class/module, allowing def to define instance methods on it dynamically.

3

How does Ruby's Garbage Collector (GC) generally manage memory, particularly with the "generational" GC introduced in later MRI versions?

B

Correct Answer

MRI uses a generational, incremental garbage collector that treats newly created ("young") objects differently from long-lived ("old") objects, scanning young objects more frequently to improve performance

Explanation

Modern MRI (Ruby) implements a generational GC that separates objects into young and old generations, focusing collection efforts on the young generation (which is collected more often) for efficiency.

4

What is the Global Interpreter Lock (GIL), also called GVL in MRI Ruby, and how does it affect threads?

B

Correct Answer

It ensures only one thread executes Ruby code at a time within a single process, meaning CPU-bound Ruby threads do not achieve true parallelism (though I/O-bound operations can release the lock)

Explanation

MRI's Global VM Lock means only one thread runs Ruby bytecode at a time, so CPU-bound multithreading does not provide parallel speedup, though threads can still interleave during I/O waits (and Ractors offer an alternative for parallelism).

5

What does "define_method" allow that a regular "def" does not?

B

Correct Answer

define_method accepts a block or Proc/Lambda, allowing methods to be defined dynamically (e.g. in a loop with closures capturing variables) which is not possible with the static "def" syntax

Explanation

define_method takes a block as the method body, which can close over local variables from the surrounding scope, enabling dynamic method generation that's difficult or impossible with literal def syntax.

6

What is "Refinements" in Ruby and how do they relate to monkey patching?

B

Correct Answer

Refinements allow scoped modifications to a class that only take effect within the lexical scope where "using" is called, avoiding the global side effects of traditional monkey patching

Explanation

Refinements (defined with refine, activated with using) provide a way to alter class behavior in a controlled, scoped manner, limiting the impact of changes compared to global monkey patches.

7

What is the purpose of "Fiber" in Ruby?

A

Correct Answer

A Fiber is a lightweight thread of execution that can be manually paused (yield) and resumed (resume), providing cooperative concurrency primitives often used to implement enumerators and coroutines

Explanation

Fibers provide manual, cooperative context-switching within a single thread; Enumerator and many async libraries are built on top of Fibers.

8

How does "Object#method_missing" combined with "respond_to_missing?" form a complete dynamic method pattern?

B

Correct Answer

method_missing handles the actual dynamic dispatch, while respond_to_missing? should be overridden so that respond_to? correctly reports true for the dynamically handled methods, keeping introspection consistent

Explanation

Without overriding respond_to_missing?, respond_to? would incorrectly return false for methods that method_missing actually handles, breaking duck-typing checks performed by other code.

9

What is the difference between "BasicObject" and "Object" as a superclass for a custom class?

B

Correct Answer

BasicObject has almost no methods defined (not even inspect or to_s), making it a blank-slate base for proxy or DSL classes where method_missing should intercept nearly everything, whereas Object includes Kernel methods

Explanation

BasicObject is intentionally minimal, lacking the Kernel module methods that Object provides, making it ideal for building proxy objects that rely heavily on method_missing without naming collisions.

10

What does "ObjectSpace::WeakMap" provide and why might it be used?

A

Correct Answer

A hash-like structure that holds weak references to its keys/values, allowing the garbage collector to reclaim them if no other strong references exist, useful for caches that should not prevent garbage collection

Explanation

WeakMap holds references that do not count toward an object's reachability for garbage collection purposes, making it suitable for caches or object registries that shouldn't leak memory.

11

What is the significance of "frozen_string_literal: true" magic comment at the top of a Ruby file?

B

Correct Answer

It causes all string literals in the file to be frozen by default, which can reduce object allocations and prevent accidental mutation, but requires explicit .dup if mutation is needed

Explanation

With this magic comment, every string literal becomes frozen automatically, improving performance by avoiding repeated allocation of identical immutable strings, though code that mutates string literals in place will need adjustment.

12

What problem do "Ractors" (introduced in Ruby 3.0) aim to solve?

B

Correct Answer

They provide an Actor-model-based concurrency abstraction that allows true parallel execution of Ruby code across multiple CPU cores by isolating mutable state between Ractors and communicating via message passing

Explanation

Ractors enable parallel execution by running independent Ruby VM instances that cannot directly share mutable objects, communicating instead through message passing, sidestepping the GVL limitation for parallelism.

13

What does "Kernel#binding" return and how is it commonly used?

B

Correct Answer

It returns a Binding object encapsulating the current execution context (local variables, self, etc.), which can later be used with eval to execute code in that captured context, useful for debugging tools

Explanation

binding captures the current scope (variables, self, method visibility context) as an object, which tools like debuggers (e.g. byebug, pry) use to evaluate expressions as if running at that exact point in the code.

14

How does Ruby's "===" (case equality) operator differ across different classes such as Range, Regexp, Class, and Proc when used in "case/when"?

B

Correct Answer

Each class defines "===" with custom semantics — Range checks inclusion, Regexp checks a pattern match, Class checks instance membership, and Proc calls itself with the value — making case/when extremely flexible

Explanation

The flexibility of case/when comes from each class providing its own meaningful "===" implementation, allowing a single case statement to match values against ranges, types, patterns, or even custom callable conditions.

15

What is "ObjectSpace.each_object" used for, and what is a caveat of using it in production code?

B

Correct Answer

It iterates over every live object in the Ruby VM, which can be useful for debugging/memory analysis, but is very slow and can have unpredictable side effects, so it is generally avoided in production code paths

Explanation

each_object provides powerful introspection across the entire object heap but comes with significant performance overhead and is typically reserved for debugging, profiling, or specialized tooling rather than everyday application logic.

16

What is the difference between "Module#const_get" with inheritance lookup versus directly accessing a constant via "::"?

B

Correct Answer

const_get by default also searches ancestors (included modules and superclasses) for the constant, similar to normal constant lookup, while a second boolean argument can disable ancestor search, giving finer control than "::" syntax

Explanation

const_get(name, inherit = true) by default follows the normal constant resolution including ancestors; passing false restricts the search to the receiver itself, offering programmatic control not directly expressible with "::" syntax.

17

What does "Comparable" combined with "<=>" returning nil signify, and how should methods like "<" handle it?

B

Correct Answer

nil from <=> indicates the two objects are not comparable (e.g. incompatible types), and Comparable-derived methods like < will raise an ArgumentError in that case rather than returning a boolean

Explanation

When <=> cannot meaningfully compare two objects (e.g. different incompatible types), it should return nil, and Comparable's derived operators raise an error rather than silently returning a misleading boolean.

18

What is "constant reassignment warning" behavior in Ruby, and how does this relate to "freeze" on classes/modules?

B

Correct Answer

Reassigning an already-initialized constant emits a warning (not an error) by default; freezing a class prevents adding new members, but the constant binding itself can still be reassigned unless its namespace is also frozen

Explanation

Ruby only warns (rather than errors) when a constant is reassigned, reflecting that "constant" is a naming convention rather than a hard guarantee; freeze affects the mutability of the referenced object/class, which is a related but distinct concept from the constant binding itself.

19

How does Ruby's "Method#unbind" and "UnboundMethod#bind" pair work, and what is a practical use case?

B

Correct Answer

unbind detaches a Method object from its receiver, producing an UnboundMethod that can later be bound to a compatible object via bind, useful for transplanting methods between objects of compatible classes (e.g. in module composition or testing)

Explanation

UnboundMethod represents a method definition independent of any particular object; binding it to a new (compatible) receiver allows reusing method implementations across otherwise unrelated class hierarchies in advanced metaprogramming scenarios.

20

What does it mean that Ruby's "Integer" class was unified (Fixnum and Bignum merged) in Ruby 2.4+, and what is the practical implication?

B

Correct Answer

Small and large integers are now both represented by the single Integer class, with the VM transparently switching internal representations as numbers grow, so code checking "is_a?(Fixnum)" became obsolete and was deprecated

Explanation

Before the unification, small integers (Fixnum) and arbitrarily large integers (Bignum) were separate classes; merging them into Integer simplified the type hierarchy since the distinction was an implementation detail that confused type checks.