skip to content

Object Anatomy

How Ruby classes build and describe their instances: initialize and accessors, visibility, inheritance, class state, equality, Struct and Data, and copying. Interviewers probe them all.

on this pageshow

explore

questions

page 2 of 2

In Ruby, how would you deep-freeze a nested document template, and which objects does a hand-written recursive freeze miss or wrongly freeze?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Ruby's freeze is shallow, so you recurse yourself: freeze the object, then walk Hash keys and values and Array elements. Such a helper misses state inside custom objects' instance variables, and can wrongly freeze objects the caller still shares and mutates.

open as a page

A Ruby Hash keyed by Point objects stops finding an entry after that point's x is changed in place; why, and how do you prevent or repair it?

level: seniorimportance: should knowfreq 35%

basics

~20 s

The Hash placed the entry using the key's hash at insertion. Changing x changes that hash, so lookups search the wrong place and miss. Hash#rehash repairs the index; frozen keys, such as Data instances, prevent it.

open as a page

In a Ruby base class such as Vehicle, how do you declare a method every subclass must implement, and what does raising NotImplementedError actually guarantee?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Ruby has no abstract keyword, so the base class defines a stub that raises NotImplementedError naming the class and method. It only guarantees a clear error when the stub is called; nothing is checked at load time.

open as a page

In Ruby, when is an explicit is_a? check still the right choice over duck typing, and what do class checks break?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Check the class when duck typing cannot tell shapes apart (one Hash vs an Array of rows, both with each), when validating parsed input, or in comparisons with other. Class checks reject proxies, decorators and custom collections that would work.

open as a page

In Ruby, how does private_class_method :new force Salary objects through factory methods, and what can still create one without them?

level: seniorimportance: should knowfreq 34%

basics

~20 s

private_class_method :new makes Salary.new private, so outside calls raise NoMethodError while class methods such as Salary.from_cents call new without a receiver. Salary.allocate, send, and dup or clone of an existing Salary still bypass the factories.

open as a page

Since Ruby 3.0, what RuntimeErrors do class variables raise when overtaken by an ancestor's definition or accessed from the top level?

level: middleimportance: nice to knowfreq 22%

basics

~20 s

Since Ruby 3.0, accessing a class variable that both a class and one of its ancestors define raises RuntimeError (overtaken by the ancestor), and any @@ access at top level raises RuntimeError: class variable access from toplevel.

open as a page

In CRuby 3.2 and later, why does assigning every instance variable in initialize, even to nil, keep instance-variable access fast?

level: seniorimportance: nice to knowfreq 22%

basics

~20 s

CRuby 3.2 introduced object shapes: objects that add the same instance variables in the same order share a shape, so inline caches hit. Assigning all of them in initialize keeps one shape per class; lazy or conditional assignments branch the tree and slow reads.

open as a page

In Ruby, how do you give a Data.define class default values and validation so that new, [] and with all enforce them?

level: seniorimportance: nice to knowfreq 32%

basics

~20 s

Override initialize with keyword parameters carrying defaults and checks, then call super with keywords. new and [] turn positional arguments into keywords first, and with reruns initialize for its copy, so every path hits the same checks.

open as a page

showing 31–38 of 38