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 pageshowhide
explore
- Allocate & Initialize4 questions
- Attribute Accessors4 questions
- Public, Private & Protected4 questions
- Subclassing & Super Calls4 questions
- Class-Level State4 questions
- Equality & Hash Keys4 questions
- Struct & Data Classes5 questions
- Dup, Clone & Freeze5 questions
- Type Checks & Duck Typing4 questions
questions
page 2 of 2In Ruby, how would you deep-freeze a nested document template, and which objects does a hand-written recursive freeze miss or wrongly freeze?
basics
~20 sRuby'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.
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?
basics
~20 sThe 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.
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?
basics
~20 sRuby 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.
In Ruby, when is an explicit is_a? check still the right choice over duck typing, and what do class checks break?
basics
~20 sCheck 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.
In Ruby, how does private_class_method :new force Salary objects through factory methods, and what can still create one without them?
basics
~20 sprivate_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.
Since Ruby 3.0, what RuntimeErrors do class variables raise when overtaken by an ancestor's definition or accessed from the top level?
basics
~20 sSince 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.
In CRuby 3.2 and later, why does assigning every instance variable in initialize, even to nil, keep instance-variable access fast?
basics
~20 sCRuby 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.
In Ruby, how do you give a Data.define class default values and validation so that new, [] and with all enforce them?
basics
~20 sOverride 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.
showing 31–38 of 38