Ruby
Ruby makes everything an object, passes blocks everywhere and keeps classes open, from core types to metaprogramming and concurrency. Interviews probe both idiom and restraint.
on this pageshowhide
explore
- Interpreters & Releases20 questions
- Engine Variants4 questions
- Version Line & Upgrades5 questions
- Script Launch & Exit6 questions
- Require & Load Path5 questions
- Syntax & Naming22 questions
- Variables & Constants6 questions
- Conventions & Comments5 questions
- Printing & Inspection5 questions
- Operators & Precedence6 questions
- Control Structures27 questions
- If, Unless & Modifiers6 questions
- Case/When Dispatch5 questions
- Case/In Patterns6 questions
- Looping Constructs5 questions
- Break, Next & Catch5 questions
- Core Value Types19 questions
- Integers, Floats & Rationals6 questions
- Symbols & Interning3 questions
- Nil & Truthiness5 questions
- Conversion Protocols5 questions
- String Handling21 questions
- Mutability & Frozen Literals5 questions
- Heredocs & Formatting6 questions
- Encodings & Bytes5 questions
- Regexp Matching5 questions
- Standard Containers23 questions
- Arrays & Slicing5 questions
- Hashes & Defaults6 questions
- Ranges & Sets6 questions
- Stack, Queue & Search Idioms6 questions
- Enumerable Methods31 questions
- Each-Style Iterators5 questions
- Predicates & Selection5 questions
- Mapping & Reducing6 questions
- Sorting & Ordering5 questions
- Enumerators & Laziness5 questions
- Custom Collection Classes5 questions
- Methods & Arguments22 questions
- Return Values & Endless Def6 questions
- Positional & Splat Args5 questions
- Keyword Parameters5 questions
- Call Chains & Tap6 questions
- Callable Objects24 questions
- Yielding to Blocks5 questions
- Ampersand Conversion4 questions
- Proc vs Lambda Semantics4 questions
- Captured Scope & Binding5 questions
- Method & UnboundMethod6 questions
- Object Anatomy38 questions
- 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
- Modules & Mixins22 questions
- Namespaces & Constant Lookup5 questions
- Include, Extend & Prepend5 questions
- Method Lookup Order4 questions
- Inclusion Hooks4 questions
- Scoped Refinements4 questions
- Exceptions & Failures17 questions
- StandardError Hierarchy5 questions
- Rescue, Ensure & Retry6 questions
- Raising Custom Errors6 questions
- Metaprogramming Techniques41 questions
- Send & Dynamic Calls4 questions
- Defining Methods Dynamically5 questions
- Ghost Methods & Fallbacks4 questions
- Evaluation Contexts5 questions
- Introspection APIs6 questions
- Singleton Classes4 questions
- Monkey Patching5 questions
- DSL Construction4 questions
- Subclass & Definition Hooks4 questions
- Files & I/O22 questions
- Open Modes & Block Form5 questions
- Directories & Pathname5 questions
- Standard Streams & StringIO6 questions
- JSON, CSV & YAML6 questions
- Standard Library Tour24 questions
- Time, Date & Zones6 questions
- Processes & Shell Commands6 questions
- Outbound HTTP Calls6 questions
- Forwarding & Delegators6 questions
- Concurrency & Parallelism27 questions
- Threads & the GVL5 questions
- Mutex, Queue & Monitor5 questions
- Fibers & Schedulers4 questions
- Ractor Isolation4 questions
- Concurrent-Ruby Toolkit5 questions
- Forking & Processes4 questions
- Speed & Memory16 questions
- JIT Compilers5 questions
- Allocation Pressure & GC6 questions
- Profilers & Benchmarks5 questions
- Dangerous APIs & Secrets10 questions
- Code-Injection Sinks5 questions
- Randomness & Hashing5 questions
- Workflow Tools27 questions
- Interactive Console6 questions
- Breakpoints & Stepping5 questions
- Rake Tasks6 questions
- Documentation Markup5 questions
- Gradual Type Signatures5 questions
questions
453 · 19 sectionsIn Ruby, what does the `if __FILE__ == $0` guard do, and what do ARGV and $PROGRAM_NAME hold?
basics
~20 sFILE is the current file's path and $0 (alias $PROGRAM_NAME) names the script Ruby launched. They match only in that launched file, so guarded code runs when executed directly, not when required. ARGV holds the arguments after the script name.
In Ruby, what are CRuby (MRI), JRuby and TruffleRuby, and how does CRuby's YARV virtual machine run your source code?
basics
~20 sCRuby, also called MRI, is the reference Ruby written in C: it parses source with Prism, compiles it to YARV bytecode and interprets that bytecode. JRuby runs Ruby on the JVM; TruffleRuby runs it on GraalVM.
In Ruby, how do require, require_relative and load differ in how they find a file and how often they run it?
basics
~20 srequire searches $LOAD_PATH and runs a file once, returning true then false; require_relative resolves the path from the calling file's directory with the same once-only rule; load runs the named file on every call and returns true.
In Ruby, how do you check which version is running, and why is comparing RUBY_VERSION strings with < unreliable?
basics
~10 sRUBY_VERSION holds the running version as a String such as "4.0.7". Comparing it with < compares characters, so "3.4.10" < "3.4.9" is true; wrap both sides in Gem::Version, which compares numeric segments.
In Ruby, how do exit, exit! and abort differ in exit status, SystemExit, ensure clauses and at_exit handlers?
basics
~20 sexit raises SystemExit (default status 0), so ensure clauses and at_exit handlers run and it can be rescued. abort prints its message to $stderr and raises SystemExit with status 1. exit! ends the process at once (default status 1), skipping ensure and at_exit.
In Ruby, what do the trailing ? in overdue? and the trailing ! in renew! promise, and what do they not promise?
basics
~20 sBoth are conventions Ruby does not enforce. A ? method answers a yes/no question with a truthy or falsy value, not always true or false. A ! method is the more dangerous twin of a same-named method, often mutating or raising.
In Ruby, which naming rules for a LibraryLoan class are enforced by the parser, and which are only snake_case and CamelCase conventions?
basics
~20 sThe parser enforces only the first character: an uppercase initial makes a constant, so class and module names must be capitalised, while a lowercase or underscore initial makes a local or method. snake_case, CamelCase and SCREAMING_SNAKE_CASE are conventions.
In Ruby, what do 7 / 2, -7 / 2 and 7 / 2.0 return, and how do you split 100 cents three ways?
basics
~20 s7 / 2 is 3 and -7 / 2 is -4, because Integer division floors; 7 / 2.0 is 3.5, because a Float operand gives Float division. Split with 100.divmod(3), which returns [33, 1], and hand out the leftover cent.
In Ruby, how do puts, print, p and pp differ in what they write to standard output and what they return?
basics
~10 sputs and print write each argument's to_s (puts adds newlines, print does not) and return nil; p writes inspect plus a newline and returns its argument; pp is p with line-wrapped pretty-printing.
In Ruby, what do the sigils in total, @total, @@total and $total tell you about where each variable is visible?
basics
~20 sThe prefix is the scope: a bare name is a local limited to its current scope, @name belongs to the current object, @@name is shared by a class, its subclasses and instances, and $name is visible to the whole process.
In Ruby, how does a case/when expression decide which branch runs, and what value does the whole case return?
basics
~20 sRuby evaluates the case subject once, then for each when value in order calls when_value === subject; the first truthy result selects that branch. The case returns that branch's last expression, the else branch if nothing matched, or nil without an else.
In Ruby, what value does an if or unless expression return, including when no branch runs, and how do you use it?
basics
~20 sRuby's if and unless are expressions: they return the value of the last expression evaluated in the branch that ran, and nil when no branch runs, so the whole conditional can be assigned to a variable or returned from a method.
In Ruby, how do the x if y and x unless y statement modifiers work, and when should you prefer them over a full if block?
basics
~20 sA modifier puts the condition after the statement: Ruby evaluates the condition first and runs the statement only if it is truthy (if) or falsy (unless). Use it for a one-line body with a short condition, especially guard clauses.
In Ruby, what is the difference between `break` and `next` inside an `each` or `map` block, and what value can `next` carry?
basics
~20 sIn a Ruby block, next ends only the current call of the block and its argument (nil by default) becomes the block's result; break ends the whole iteration and makes the method that yielded, such as each or map, return immediately.
In Ruby, why is `for x in list` discouraged in favour of `list.each`, and what does the for loop leave behind?
basics
~20 sRuby's for...in calls each on the collection but opens no new scope, so its loop variable and body locals survive the loop and every closure made inside shares one variable; each gives every iteration a fresh block parameter.
In Ruby, why does "Qty: " + 6 raise TypeError, and what are the idiomatic ways to build that string?
basics
~20 sString#+ accepts only a String or an object with to_str, and Integer has no to_str, so Ruby raises TypeError: no implicit conversion of Integer into String. Convert explicitly with 6.to_s, or build the string with interpolation.
In Ruby, which values are falsy, and does a condition treat 0, an empty string or an empty array as true?
basics
~10 sOnly nil and false are falsy in Ruby. Every other object, including 0, 0.0, "", [], {} and the string "false", is truthy, so test emptiness or zero explicitly with empty?, zero? or nil?.
In Ruby, why does 0.1 + 0.2 == 0.3 return false, and how should you compare or compute such values instead?
basics
~20 sFloat stores IEEE 754 binary doubles, and 0.1, 0.2 and 0.3 have no exact binary form, so the sum is 0.30000000000000004. Compare Floats with a tolerance, or compute with Rational, BigDecimal or integer cents when exactness matters.
In Ruby, how does a Symbol such as :delivered differ from the String "delivered" in identity, mutability and typical use?
basics
~20 sA Symbol is an immutable, interned name: every :delivered is the same object with one object_id, while each evaluation of the literal "delivered" builds a new String. Use symbols for identifiers and fixed flags, strings for text.
In Ruby, how do Integer("12abc") and "12abc".to_i differ, and when should parsing a quantity raise instead of returning 0?
basics
~10 s"12abc".to_i returns 12 and returns 0 when nothing parses. Integer("12abc") raises ArgumentError, and Integer(nil) raises TypeError. Use Integer() or Float() when bad input must be reported; exception: false returns nil instead.
In Ruby, how do single-quoted and double-quoted string literals differ, and where do %q and %Q fit?
basics
~10 sDouble-quoted strings process escape sequences such as \n and \t and interpolate #{...}; single-quoted strings do neither, except for ' and \. %q(...) behaves like single quotes, %Q(...) and %(...) like double quotes.
In Ruby, why does calling name.strip! inside a method change the caller's string, while name = name.strip does not?
basics
~20 sRuby hands the method a reference to the caller's String object. strip! edits that object in place, so the caller sees it; name = name.strip builds a new string and rebinds only the method's local parameter.
In Ruby, how do the results of String#=~, String#match and String#match? differ, and which of them set $~ and $1?
basics
~20 s=~ returns the index where the match starts or nil, match returns a MatchData or nil, and match? returns true or false. =~ and match set $~, $1 and the other match variables; match? sets none of them.
In Ruby, what is the difference between String#encode and String#force_encoding, and when is each the right call?
basics
~20 sString#encode returns a new string whose bytes are converted so the same characters exist in the target encoding. String#force_encoding keeps the bytes and only relabels the receiver. Relabel when the label is wrong; encode when bytes must change.
In Ruby, how do <<~, <<- and plain << heredocs differ, and what does quoting the identifier change?
basics
~20 sPlain <<EOS needs its terminator at column 0 and keeps text as written; <<-EOS lets the terminator be indented; <<~EOS also removes the smallest common indentation from the body. Quoting the identifier as 'EOS' turns off interpolation and escapes.
In Ruby, what do row[-1], row[1, 2] and row[1..2] return, and what happens when an index is out of range?
basics
~20 srow[-1] is the last element; row[1, 2] and row[1..2] both return a new two-element array starting at index 1. An out-of-range index returns nil, and so does a slice whose start lies beyond the array's size.
In Ruby, how does Hash#fetch differ from Hash#[] when a key is missing, and what do fetch's default argument and block do?
basics
~20 sHash#[] returns the hash's default, nil unless one was set, for a missing key. Hash#fetch raises KeyError instead, or returns its second argument or its block's value, and it ignores the hash's default and default proc.
In Ruby, how do you use an Array as a stack and as a queue, and what do push, pop, shift and unshift return?
basics
~10 sIn single-threaded Ruby an Array is both: push with pop is last-in-first-out, push with shift is first-in-first-out. push and unshift return the array; pop and shift return the removed element, or nil when empty.
In Ruby, what is the difference between 1..10 and 1...10, and what do endless (5..) and beginless (..5) ranges mean?
basics
~20 s1..10 includes 10; 1...10 stops before it, and exclude_end? reports which. An endless range like (5..) has a nil end and never stops; a beginless range like (..5) has a nil begin and supports comparisons but not iteration.
In Ruby, what do each, map and other Enumerable methods return when called without a block, and how is that used?
basics
~20 sMost iterating methods return an Enumerator when no block is given: an object that remembers the receiver, the method and its arguments and runs them later. You chain it (each_with_index.map), iterate it elsewhere, or pull values with next.
In Ruby, what does Array#each return when called with a block, and why does assigning that result not collect the block's values?
basics
~20 sArray#each with a block returns the receiver itself, the very same array object, and throws away whatever the block returns. Assigning its result gives you the original array back, never the block's values; map is the method that collects them.
In Ruby, how do you number marathon finishers from 1 while iterating, and why does each_with_index(1) not do it?
basics
~10 sCall each.with_index(1): Enumerator#with_index takes a starting offset. each_with_index always counts from 0 and forwards its arguments to each, so on an Array each_with_index(1) raises ArgumentError instead of shifting the index.
In Ruby, how do find and select differ when looking for overdue invoices, and what does each return when nothing matches?
basics
~20 sfind (alias detect) returns the first element whose block is truthy and stops there, or nil when none matches. select (alias filter) walks the whole collection and returns an array of every match, empty when none.
In Ruby, how do map and flat_map differ when each franchise region returns an array of store totals?
basics
~20 smap returns a new array with one block result per element, so array results stay nested. flat_map concatenates array results one level into a single flat array, keeps non-array results unchanged, and never flattens deeper, unlike map followed by flatten.
In Ruby, what does a method return when it has no return keyword, and when is an explicit return still worth writing?
basics
~20 sA Ruby method returns the value of the last expression it actually evaluated, so no return keyword is needed. Explicit return earns its place for early exits such as guard clauses; return a, b returns one Array.
In Ruby, what does `def send_email(to:, subject: "(no subject)", cc: [])` declare, and what happens when a caller omits `to:` or adds `bcc:`?
basics
~20 sThe signature declares one required keyword, to:, and two optional keywords, subject: and cc:, that fall back to their defaults. Omitting to: raises ArgumentError (missing keyword: :to); an unlisted bcc: raises ArgumentError (unknown keyword: :bcc).
In Ruby, what does `def log(*messages)` collect, and how do `log(lines)` and `log(*lines)` differ when lines is an Array?
basics
~10 s*messages gathers every leftover positional argument into a new Array, empty when there are none. log(lines) passes one argument, so messages is [lines]; log(*lines) splats the Array into separate arguments first.
In Ruby, why does `title.strip!.squeeze!(" ")` raise NoMethodError for some product titles but not others, and how do you rewrite it?
basics
~20 sString#strip! returns nil when there was no surrounding whitespace to remove, so the next link calls squeeze! on nil. Titles that needed stripping pass; clean ones crash. Chain the non-bang forms, or call each bang method as its own statement.
In Ruby, what is the difference between `Kernel#tap` and `Kernel#then` in a method chain, and when would you use each?
basics
~20 sBoth yield the receiver to a block. tap returns the receiver itself, ignoring the block's value, so it suits side effects such as logging mid-chain; then (alias yield_self) returns the block's value, so it transforms or pipes the value onward.
In Ruby, what happens step by step when you write users.map(&:email), and what does the & do to the Symbol?
basics
~20 sThe & marks :email as the block for map. Because a Symbol is not a Proc, Ruby converts it with Symbol#to_proc, a lambda that calls email on each yielded user, so the result equals users.map { |user| user.email }.
In Ruby, which outer local variables can a block read and reassign, and why is a variable first assigned inside it gone afterwards?
basics
~20 sA Ruby block can read and reassign every local already assigned above it in the enclosing scope. A name first assigned inside the block is local to that block run, so using it after the block raises NameError.
In Ruby, how does a method run the block it was called with using yield, and what does block_given? protect against?
basics
~20 syield runs the block attached to the current method call, passes its arguments to the block's parameters and evaluates to the block's last value. With no block, yield raises LocalJumpError; block_given? lets the method check first.
In Ruby, what does an explicit &block parameter give a method, and how do you pass that block on to another method?
basics
~20 sAn &block parameter captures the call's block as a Proc object, or nil when no block was given. The method can call, store or test it, and forwards it to another method as a block by writing other(&block).
In Ruby, how can a lambda returned from a method keep incrementing a local variable after that method has returned?
basics
~20 sA Ruby lambda closes over the local variable itself, not a copy of its value. When the lambda is created, CRuby moves the method's locals into a heap environment, so the lambda can still read and reassign clicks after the method returns.
In Ruby, which methods do attr_reader, attr_writer and attr_accessor define, and what does each call return?
basics
~10 sattr_reader :temp defines temp, returning @temp; attr_writer :temp defines temp=, assigning @temp; attr_accessor defines both. Since Ruby 3.0 each call returns an Array of the defined method names as Symbols.
Inside a Ruby Thermostat method, why does target = 22 leave the target unchanged even though attr_accessor :target exists?
basics
~10 sRuby parses a bare target = 22 as assignment to a new local variable, not a call to target=. Writer methods always need a receiver, so inside the class write self.target = 22.
In Ruby, how do you define a class method such as Shape.build with def self., and how does it differ from an instance method?
basics
~20 sWrite def self.build inside the class body, where self is the class, and call it as Shape.build. Instances do not have it; they call self.class.build. Subclasses inherit it, and inside it self is whichever class received the call.
In Ruby, what does Object#freeze prevent, and why can a frozen constant Hash still see its nested Array change?
basics
~20 sfreeze stops changes to that one object's own state and returns the object; later writes raise FrozenError. It is shallow: objects it references stay mutable. Freezing a constant's value also does not stop the constant being reassigned, which only warns.
In Ruby, what is the difference between ==, eql? and equal?, and why is 1 == 1.0 true while 1.eql?(1.0) is false?
basics
~20 sequal? asks whether both are the same object; == compares values and is overridden per class; eql? is the stricter hash-key equality. Numeric == compares across types, so 1 == 1.0, but eql? requires the same class.
In Ruby, what is the difference between include and extend when you mix an Auditable module into a Product class?
basics
~20 sinclude Auditable makes the module's instance methods available on every Product instance. extend Auditable inside the class adds them to the Product class object itself, so they become class methods like Product.audited_fields, and instances do not get them.
In Ruby, what does Module#ancestors return for a class, and how does Ruby use that list to pick which log method runs?
basics
~20 sModule#ancestors returns the ordered list of classes and modules Ruby searches for an instance method: the class, its mixed-in modules, then the superclass chain down to BasicObject. Calling job.log runs the first log found walking that list.
In Ruby, how does a module serve as a namespace, and what does the leading :: in ::JSON change?
basics
~20 sA module is a container for constants, so Ingest::JSON::Parser and Ingest::CSV::Parser can coexist. :: walks into a module; a leading ::JSON starts the lookup at Object, the top level, bypassing a nested JSON that shadows it.
In Ruby, how does a mixin's self.included(base) hook combined with base.extend(ClassMethods) give the including class both instance and class methods?
basics
~10 sinclude only gives the host's instances the module's methods. The module's included hook calls base.extend(ClassMethods), mixing a nested module into the class itself, so its methods become class methods such as configuration macros.
In Ruby, how does prepend differ from include, and why does only prepend let an AuditSave module wrap Product#save through super?
basics
~20 sinclude places a module after the class in method lookup, so the class's own save wins. prepend places it before the class, so AuditSave#save runs first and its super calls Product#save, which makes wrapping possible.
In Ruby, which exceptions does a bare rescue clause catch, and which built-in exceptions slip past it?
basics
~10 sA bare rescue, like rescue => e, catches StandardError and its subclasses only. Classes outside that branch pass through: SignalException and its subclass Interrupt, SystemExit, ScriptError (LoadError, SyntaxError, NotImplementedError), NoMemoryError and SystemStackError.
In Ruby, what are the forms of raise with a message, a class or an instance, and what does a bare raise do inside rescue?
basics
~10 sraise "msg" raises a RuntimeError; raise Klass, "msg" builds the error through Klass.exception, which calls new; raise an_instance raises that object. A bare raise inside rescue re-raises the current exception with its original backtrace.
In Ruby, in what order do the begin, rescue, else and ensure clauses run, and what value does the whole expression return?
basics
~20 sThe body runs; on an exception the first matching rescue runs, otherwise else runs; ensure always runs last. The expression's value comes from the rescue, from else, or from the body when there is no else; ensure's value is discarded.
A Ruby worker loop wraps each job in rescue Exception => e and logs it; why can't Ctrl-C or a TERM signal stop it?
basics
~20 sBy default Ruby turns Ctrl-C into an Interrupt and TERM into a SignalException raised in the main thread, and exit raises SystemExit. All inherit from Exception, so rescue Exception catches them, logs them and the loop continues. Rescue StandardError instead.
In Ruby, how do you write a custom error class with extra fields and a default message that still works with raise Klass, "msg"?
basics
~10 sSubclass StandardError, define initialize(msg = "default text", field: nil), call super(msg) and store the field with attr_reader. raise Klass, "msg" then passes the message to new, while raise Klass.new(field: 30) sets the field.
In Ruby, why does obj.methods return dozens of names even for a tiny class, and how do you narrow that list while debugging?
basics
~10 sKernel#methods lists every public and protected method the object responds to, including everything inherited from Object, Kernel and BasicObject. Subtract Object.instance_methods, grep for a pattern, or ask the class for instance_methods(false).
In Ruby, what does writing `class String` with a new method do when String already exists, and which code sees that method?
basics
~20 sWriting class String again reopens the existing String class instead of creating one, so the def adds a method to String itself. Every string in the process, including older strings and strings inside gems, can then call it.
In Ruby, how do you call a method whose name is only known at run time, and how do send and public_send differ?
basics
~20 sPass the name as a Symbol or String to send or public_send, with any arguments after it. send calls the method even if it is private or protected; public_send calls only public methods and raises NoMethodError otherwise.
In Ruby, what does def gateway.charge(amount) do inside a test, and why do other Gateway instances keep the original charge method?
basics
~10 sdef gateway.charge defines a singleton method: it is stored in gateway's own singleton class, which Ruby checks before Gateway, so only that object uses it. Every other Gateway instance still finds Gateway#charge.
In Ruby, how does define_method differ from def in how the method name is chosen and what the method body can see?
basics
~20 sdef takes a literal name and starts a fresh local scope. define_method takes the name as a Symbol or String value and uses a block as the body, so the body is a closure that sees the defining scope's local variables.
In Ruby, why is File.open with a block preferred over opening and closing the file yourself, and what does the block form return?
basics
~20 sFile.open with a block yields the File, closes it when the block exits, even through an exception, and returns the block's value. Without a block it returns the File, and the caller must close it or leak the descriptor.
In Ruby, what does JSON.parse return for a JSON object, and why does data[:name] come back nil unless you pass symbolize_names: true?
basics
~20 sJSON.parse turns a JSON object into a Hash whose keys are Strings, arrays into Arrays and null into nil. data[:name] looks up a Symbol key that does not exist, so it returns nil; symbolize_names: true makes the keys Symbols.
In Ruby, why does a relative path like "config/settings.yml" break when a script runs from another directory, and how do __dir__ and File.expand_path fix it?
basics
~10 sRelative paths resolve against the process's current working directory, not the source file's location. dir returns the absolute directory of the current file, so File.expand_path("config/settings.yml", dir) or File.join(dir, "config", "settings.yml") works from anywhere.
In Ruby, what is the difference between $stdout and STDOUT, and which one should you reassign to redirect output?
basics
~10 s$stdout is a global variable holding the current standard output stream, and Kernel#puts writes to it; STDOUT is a constant holding the original stream. Redirect by reassigning $stdout; STDOUT stays as the way back.
In Ruby, how would you use Dir.glob to find old image thumbnails in nested directories, and what does it skip or sort by default?
basics
~10 sDir.glob("uploads/**/*_thumb.{jpg,png}") walks every subdirectory and returns matching paths, sorted by default since Ruby 3.0. It skips hidden entries unless File::FNM_DOTMATCH is passed, and returns an empty array when nothing matches.
In Ruby's Net::HTTP, what does Net::HTTP.get return compared with Net::HTTP.get_response, and how do you check the status code?
basics
~10 sNet::HTTP.get returns only the response body as a String, whatever the status, so a 404 page arrives without an exception. Net::HTTP.get_response returns a Net::HTTPResponse subclass whose class and String code carry the status.
In Ruby, what are the differences between system, backticks (%x), exec and spawn for running an external command?
basics
~20 ssystem runs a command, waits, and returns true, false or nil; backticks and %x run it, wait, and return its standard output as a String; exec replaces the Ruby process; spawn starts it and returns the pid without waiting.
In Ruby, how do you get the current time, turn a Unix timestamp into a Time, and format it with strftime or iso8601?
basics
~20 sTime.now returns the current instant in the local zone; Time.at(seconds) builds a Time from Unix epoch seconds and to_i converts back. strftime formats with directives such as %Y-%m-%d %H:%M, and iso8601 returns a machine-readable 2026-05-28T20:26:40Z string.
In Ruby, how do Forwardable's def_delegators and def_delegator expose selected methods of an inner object, and what do they generate?
basics
~10 sAfter extend Forwardable, def_delegators :@user, :name, :email defines real instance methods that call the same methods on @user, and def_delegator :@user, :name, :display_name forwards one method under a new name. Unlisted methods stay unavailable.
In Ruby, how does a UserPresenter < SimpleDelegator wrap a user object, and what do __getobj__ and __setobj__ do?
basics
~10 sSimpleDelegator.new(user) forwards every public method it does not define itself to user. A subclass adds or overrides presentation methods; getobj returns the wrapped user and setobj replaces it with another object.
In Ruby, what does Mutex#synchronize do and return, and why is it preferred over calling lock and unlock yourself?
basics
~10 sMutex#synchronize locks the mutex, runs the block, unlocks it even if the block raises, and returns the block's value. Manual lock/unlock can leave the mutex locked forever when an exception skips the unlock.
In CRuby, what is the GVL, and when do Ruby threads actually make a program run faster?
basics
~20 sThe GVL (Global VM Lock) lets only one thread per Ractor execute Ruby code at a time. Threads speed up I/O-bound work, because blocking I/O and sleep release the lock, but not CPU-bound Ruby code.
In Ruby, what do Thread.new, Thread#join and Thread#value return, and what happens to threads the main program never joins?
basics
~20 sThread.new starts a block in a new thread and returns the Thread. join waits and returns that thread, or nil when its limit expires; value returns the block's result or re-raises its exception. Unjoined threads die when main exits.
In Ruby, what is a zombie child process, and how do Process.wait, waitpid with WNOHANG and Process.detach each prevent one?
basics
~20 sA zombie is a child that has exited but whose status the parent never collected. Process.wait(pid) blocks and reaps it, Process.wait(pid, Process::WNOHANG) reaps only if it already exited, and Process.detach(pid) starts a thread that reaps it for you.
In CRuby, if the GVL runs one thread at a time, why can a shared hit counter updated with @hits += 1 still lose updates?
basics
~20 s@hits += 1 is a separate read, add and write. The GVL lets one thread run Ruby at a time but does not keep a thread running across those steps, so a switch between the read and the write loses an increment.
In Ruby, what do GC.start and GC.disable do, and why is calling them from application code usually a mistake?
basics
~20 sGC.start forces a garbage collection, a full blocking one by default; GC.disable stops automatic collection until GC.enable. Ruby already collects when it needs to, so forcing it wastes CPU and disabling it lets memory grow without limit.
In CRuby 4.0, what does the YJIT compiler do to your running Ruby code, and what does turning it on cost?
basics
~20 sYJIT is CRuby's built-in just-in-time compiler: once enabled, it turns frequently run Ruby methods from YARV bytecode into native machine code, falling back to the interpreter when needed. It is off by default and costs memory and compile time.
In Ruby 4.0, how do Benchmark.measure, Benchmark.realtime, Benchmark.bm and Benchmark.bmbm differ, and what changed about loading the library?
basics
~20 sBenchmark.measure returns a Benchmark::Tms of CPU and real time, Benchmark.realtime returns elapsed seconds, bm prints a labelled table and bmbm adds a rehearsal pass. Since Ruby 4.0 benchmark is a bundled gem, so Bundler apps must list it.
In Ruby, how do you reduce the objects a hot loop allocates, and how do you prove the change with GC.stat?
basics
~20 sStop building intermediate collections and per-iteration temporaries: aggregate with block forms such as sum, count and filter_map, append to strings with << rather than +=, and mutate in place where safe. Prove it with the GC.stat(:total_allocated_objects) delta before and after.
In Ruby 4.0, what are the ways to turn on YJIT, and how do you prove a running process really has it enabled?
basics
~10 sEnable YJIT with the --yjit flag, the RUBY_YJIT_ENABLE=1 environment variable, or RubyVM::YJIT.enable from Ruby code. Prove it with RubyVM::YJIT.enabled? returning true or +YJIT appearing in RUBY_DESCRIPTION, the string ruby -v prints.
In Ruby, which SecureRandom method would you use for a password-reset token in a URL, and what does its argument count?
basics
~10 sSecureRandom.urlsafe_base64(32): URL-safe characters, no padding, bytes from the operating system's secure source. The argument counts random bytes, not characters, so 32 bytes become 43 characters. rand and Random produce predictable output.
In Ruby, why are eval and the string forms of instance_eval and class_eval unsafe on request data, and what replaces them?
basics
~20 sEach of them parses its string argument as Ruby source and runs it with the process's full privileges, so request data that shapes the string can run any code. Replace them with lookup tables, real parsers and block-based metaprogramming.
With the bcrypt gem in Ruby, how do BCrypt::Password.create and BCrypt::Password#== store and check a password, and what does cost control?
basics
~20 sBCrypt::Password.create(password) returns a 60-character string holding version, cost, a random salt and the hash. To check, wrap the stored string with BCrypt::Password.new and call == with the candidate, which rehashes it with the stored salt and cost.
In Ruby 4.0, what changed about Kernel#open with a leading pipe, and why still prefer File.open or a checked URI.open for request data?
basics
~20 sRuby 4.0 removed process creation from Kernel#open and the IO class methods, so "|cmd" is now just a file name. A request path can still escape its directory, and URI.open still fetches any URL or reads a local file.
In Ruby, how do you compute and verify an HMAC-SHA256 signature on an incoming API request body with the standard library?
basics
~10 sCompute OpenSSL::HMAC.hexdigest("SHA256", secret, raw_body), digest name first, then key, then data, and compare it with the received signature using OpenSSL.secure_compare, never ==. Sign the raw body bytes, before any JSON parsing.
In Ruby, which comment does RDoc attach to a method, and how do you write it in RDoc markup or in Markdown?
basics
~20 sRDoc documents a class, module, method, constant or attribute with the comment block directly above its definition. That comment is RDoc markup by default (bold, italic, +code+); a # :markup: markdown line switches the file to Markdown.
In Ruby, what happens when execution reaches binding.irb, and how do you resume or stop the program afterwards?
basics
~20 sbinding.irb pauses the program at that line and opens an IRB prompt inside that scope, with its locals, self and instance variables live. exit (or Ctrl-D) resumes the program from that line; exit! ends the process.
In a Rakefile, how do you define a task with a description and prerequisites, and what do rake -T and the default task do?
basics
~20 sA Rakefile is Ruby: task release: %w[build tag] do ... end runs its prerequisites first, each at most once per run. desc describes the next task, rake -T lists only described tasks, and a bare rake runs the task named default.
In Ruby's debug gem, how do binding.break and the rdbg command start a debugging session, and what does require "debug" do?
basics
~20 sThe debug gem, bundled with Ruby since 3.1, defines binding.break (aliases binding.b and debugger) once require "debug" has started a session; execution stops there at an (rdbg) prompt. rdbg runs a script or, with -c, a command under the debugger without editing code.
In a Ruby gem documented with YARD, how do you describe a public method's parameters, return value, exceptions and usage with tags?
basics
~20 sYARD reads @tags from the comment above a method: @param name [Type] for each positional or keyword argument, @return [Type] for the result, @raise [ErrorClass] for exceptions and @example for indented usage code. yard doc renders them as structured HTML.