๐ŸŒ The Odin Project ยท subject

The Odin Project Ruby Syllabus

The Ruby syllabus for The Odin Project in full: 8 chapters and 34 topics, every one listed below, plus 50 Ruby flashcards with answers.

8Chapters
34Topics
50Flashcards

Ruby syllabus: all 8 chapters

Expand any chapter to see its topics and sub-topics.

  1. Basic Ruby

    9 topics
    • Basic Data Types
    • Variables
    • Input and Output
    • Conditional Logic
    • Loops
    • Collections
    • Methods
    • Debugging
    • Enumerables
  2. Basic Ruby Projects

    4 topics
    • Caesar Cipher
    • Sub Strings
    • Stock Picker
    • Bubble Sort
  3. Object Oriented Programming Basics

    5 topics
    • Object Oriented Programming
    • Project Management
    • Linting and RuboCop
    • Project: Tic Tac Toe
    • Project: Mastermind
  4. Files and Serialization

    2 topics
    • Files and Serialization
    • Project: Hangman
  5. Advanced Ruby

    3 topics
    • Pattern Matching
    • Blocks
    • Custom Enumerables
  6. Testing Ruby with RSpec

    3 topics
    • Test Driven Development
    • Introduction to RSpec
    • Project: Connect Four
  7. Computer Science in Ruby

    7 topics
    • Recursive Methods
    • Time and Space Complexity
    • Common Data Structures and Algorithms
    • Project: Linked Lists
    • HashMap Data Structure
    • Project: Binary Search Trees
    • Project: Knights Travails
  8. Conclusion

    1 topic
    • Project: Chess

The Odin Project Ruby flashcards โ€” 50 questions with answers

  1. What are the main basic data types in Ruby, and what is special about how Ruby treats them?

    Integer, Float, String, Symbol, Boolean (true/false), and nil. Everything in Ruby is an object, so even literals like 5 or "hello" have methods (e.g., 5.times, "hello".upcase).

  2. In Ruby, what does the expression 17 / 5 evaluate to, and why?

    It evaluates to 3. When both operands are Integers, Ruby performs integer division and truncates the remainder. To get a Float result ($3.4$), at least one operand must be a Float, e.g., 17.0 / 5.

  3. Which operator does Ruby use for exponentiation, and what does 2 ** 5 return?

    The ** operator. 2 ** 5 returns 32, since $2^{5} = 32$. Fractional exponents give roots: 16 ** 0.5 returns 4.0 because $16^{\frac{1}{2}} = \sqrt{16} = 4$.

  4. What does the modulo operator % return in Ruby, e.g., 16 % 5?

    The remainder of division: 16 % 5 returns 1, because $16 = 3 \times 5 + 1$. It is commonly used to test even/odd (n % 2 == 0) and to wrap values around a range.

  5. What is the difference between a String and a Symbol in Ruby?

    A String is mutable and every literal creates a new object; a Symbol (e.g., :name) is immutable and the same symbol always references the same object in memory. Symbols are preferred as hash keys and identifiers because comparing them is faster.

  6. How do you convert between strings and numbers in Ruby, and what does "hello".to_i return?

    Use to_i, to_f, and to_s. "5".to_i returns 5; "hello".to_i returns 0 (no leading number); 5.to_s returns "5". These methods never raise errors on bad input, unlike Integer("hello").

  7. What naming convention do Ruby local variables use, and what does a variable actually store?

    snake_case (lowercase words separated by underscores, e.g., total_score). A variable stores a reference to an object, not the object itself โ€” so two variables can point to (and mutate) the same object.

  8. How are constants defined in Ruby, and what happens if you reassign one?

    A constant starts with a capital letter (conventionally ALL_CAPS, e.g., MAX_SPEED = 100). Ruby allows reassignment but prints a warning โ€” constants are not truly immutable, only by convention.

  9. What is string interpolation in Ruby and what is its key requirement?

    Embedding expressions inside a string with #{}, e.g., "Hello, #{name}!". It only works inside double-quoted strings; single quotes print the #{} characters literally.

  10. What is the difference between gets and gets.chomp in Ruby?

    gets reads a line of user input including the trailing newline (\n) added when the user presses Enter. gets.chomp removes that trailing newline, which is almost always what you want when comparing or storing input.

  11. Compare puts, print, and p in Ruby.

    puts prints the value plus a newline and returns nil; print prints without a newline and returns nil; p prints the raw inspect representation (showing quotes, nil, escape characters) and returns the object itself โ€” making p ideal for debugging.

  12. Which values are falsy in Ruby's conditional logic?

    Only false and nil. Everything else is truthy โ€” including 0, empty strings "", and empty arrays [] (unlike many other languages).

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

    == checks value equality (5 == 5.0 is true); .eql? checks value AND type (5.eql?(5.0) is false); .equal? checks object identity โ€” whether both references point to the exact same object in memory.

  14. What does Ruby's spaceship operator <=> return?

    It returns $-1$ if the left operand is less than the right, $0$ if they are equal, and $1$ if the left is greater. It is the basis of sorting โ€” Array#sort uses <=> to compare elements.

  15. What is the unless statement in Ruby and when should it be used?

    unless executes code when its condition is false โ€” the opposite of if. Use it when the negative phrasing reads more naturally (e.g., unless hungry then clean up), and avoid pairing it with else, which hurts readability.

  16. What is the syntax and purpose of Ruby's ternary operator?

    condition ? value_if_true : value_if_false. It is a one-line replacement for a simple if/else that returns a value, e.g., age >= 18 ? "adult" : "minor".

  17. How does a Ruby case statement work, and what operator does it use for matching?

    case takes a value and compares it against each when clause using the case-equality operator === (which lets ranges, classes, and regexps match), executing the first match; else handles no match. Each branch can return a value.

  18. How do && and || behave in Ruby, and what is short-circuit evaluation?

    && returns true only if both operands are truthy; || returns true if at least one is. Ruby stops evaluating as soon as the result is known: with &&, a falsy left side skips the right; with ||, a truthy left side skips the right.

  19. How do you create an infinite loop in Ruby and exit it?

    Use loop do ... end, and exit with break (usually inside an if condition, e.g., break if i > 10). loop is Ruby's simplest, idiomatic infinite loop construct.

  20. What is the difference between a while loop and an until loop in Ruby?

    while runs as long as its condition is true; until runs as long as its condition is false (it is the logical opposite). until avoids negated conditions, e.g., until done rather than while !done.

Show the other 30 Ruby flashcards
  1. What is the difference between break and next inside a Ruby loop?

    break exits the loop entirely; next skips the rest of the current iteration and jumps to the next one. Example: next if i.odd? skips odd numbers but keeps looping.

  2. How do the #times, #upto, and #downto methods work in Ruby?

    5.times { |i| ... } iterates with i from 0 to 4; 1.upto(5) counts 1,2,3,4,5; 5.downto(1) counts 5,4,3,2,1. They are the idiomatic replacements for C-style for loops when the number of iterations is known.

  3. What is a Ruby array, and how do you access its first and last elements?

    An ordered, integer-indexed collection that can hold mixed types. Access the first element with arr[0] or arr.first, and the last with arr[-1] or arr.last (negative indices count from the end).

  4. What do push, pop, shift, and unshift do to a Ruby array?

    push (or <<) adds to the end; pop removes and returns the last element; unshift adds to the front; shift removes and returns the first element. push/pop treat the array like a stack; shift/unshift work on the front like a queue.

  5. In a Ruby hash, what is the difference between hash[:key] and hash.fetch(:key)?

    hash[:key] returns nil if the key is absent, which can hide bugs; hash.fetch(:key) raises a KeyError, and hash.fetch(:key, default) returns the given default instead. fetch makes missing keys explicit.

  6. What is the difference between the ranges (1..5) and (1...5) in Ruby?

    Two dots are inclusive: (1..5) covers 1,2,3,4,5. Three dots exclude the end value: (1...5) covers 1,2,3,4. Both can be converted to arrays with to_a and used in case statements and iteration.

  7. What does a Ruby method return if there is no explicit return statement?

    The value of the last evaluated expression โ€” this is called implicit return, and it is the idiomatic Ruby style. An explicit return keyword is used mainly to exit a method early.

  8. What do the ? and ! suffixes conventionally mean on Ruby method names?

    A ? suffix marks a predicate method that returns true or false (e.g., even?, empty?). A ! suffix marks a bang method that mutates its caller in place (e.g., upcase! changes the original string, while upcase returns a new one) or is otherwise the 'dangerous' version.

  9. How do default parameters work in Ruby methods?

    A parameter can be given a default value in the definition, e.g., def greet(name = "stranger"). If the caller omits the argument, the default is used; if provided, the argument overrides it. Parameters with defaults should come after required ones.

  10. What does binding.pry do when debugging Ruby code?

    It pauses program execution at that line and opens an interactive REPL (from the pry-byebug gem) where you can inspect and change variables in the current scope, then continue stepping through with commands like next, step, and continue.

  11. When reading a Ruby stack trace, which line matters most and what does it tell you?

    The first (top) line โ€” it shows the file, line number, and method where the error was actually raised, plus the error type and message (e.g., NoMethodError: undefined method 'upcase' for nil). Lines below trace the chain of calls that led there.

  12. What are the three main ways to debug a Ruby program covered by The Odin Project?

    1) Read the stack trace to locate and understand the raised exception; 2) sprinkle puts/p statements to inspect values at runtime (p shows nil and types clearly); 3) use a debugger like pry-byebug to pause execution and step through code interactively.

  13. What is the key difference between #each and #map in Ruby?

    Both iterate over a collection, but #each returns the original collection unchanged (used for side effects like printing), while #map (alias #collect) returns a new array containing the block's return value for each element (used for transformation).

  14. What do the enumerable methods #select and #reject do?

    #select (alias #filter) returns a new collection containing only the elements for which the block returns true; #reject does the opposite, returning elements for which the block returns false. Neither mutates the original (their ! versions do).

  15. How does #reduce (alias #inject) work in Ruby, and how would you sum an array with it?

    It folds a collection into a single value using an accumulator: [1,2,3].reduce { |sum, n| sum + n } returns 6, computing $\sum_{i} a_{i}$. An optional argument sets the accumulator's initial value, e.g., reduce(10).

  16. What do the enumerable predicates #include?, #any?, #all?, and #none? return?

    #include?(x) โ€” true if the collection contains x; #any? โ€” true if the block is true for at least one element; #all? โ€” true if the block is true for every element; #none? โ€” true if the block is true for no elements. All return booleans.

  17. How do #each_with_index and #each_with_object differ in Ruby?

    #each_with_index yields each element along with its integer index (element, index). #each_with_object(obj) yields each element plus a memo object you build up (like a hash or array) and returns that object at the end โ€” similar to reduce but the memo is passed, not returned, by the block.

  18. In the Caesar Cipher, what is the formula for encrypting a letter, and what does it mean?

    $E(x) = (x + n) \bmod 26$, where $x$ is the letter's position in the alphabet ($0$โ€“$25$) and $n$ is the shift factor. Each letter is shifted $n$ positions forward, wrapping past 'z' back to 'a' thanks to the modulo.

  19. In the Odin Project Caesar Cipher, how do you handle wrap-around and non-letter characters?

    Wrap-around: apply modulo 26 to the shifted alphabet position (so 'z' with shift 1 becomes 'a'), handling uppercase and lowercase within their own ranges. Non-letter characters (spaces, punctuation) must pass through unchanged, and letter case must be preserved.

  20. What is the goal of the Odin Project Sub Strings exercise, and what is the standard approach?

    Write a method that takes a string and a dictionary array and returns a hash counting how many times each dictionary word appears as a substring, case-insensitively. Standard approach: downcase the input, then iterate the dictionary (e.g., with each_with_object or reduce), using String#scan or #include? to count matches โ€” "below" matches both "below" and "low".

  21. What is the rule and goal of the Odin Project Stock Picker exercise?

    Given an array of daily stock prices, return the pair of indices [buy_day, sell_day] that maximizes profit $= p_{sell} - p_{buy}$, with the constraint that you must buy before you sell ($buy < sell$). The efficient solution scans once, tracking the minimum price so far and the best profit found.

  22. Describe how the bubble sort algorithm works.

    Repeatedly step through the array comparing adjacent pairs; if a pair is out of order, swap them. After each full pass the largest unsorted element 'bubbles up' to its final position at the end. Repeat passes until a complete pass makes no swaps, meaning the array is sorted.

  23. What is the time complexity of bubble sort in the worst and best cases?

    Worst and average case: $O(n^{2})$, because up to $n$ passes each do up to $n$ comparisons. Best case (already sorted, with the no-swap early exit optimization): $O(n)$, one pass with zero swaps. Space complexity is $O(1)$ since it sorts in place.

  24. In a Ruby class, what is the initialize method and what are instance variables?

    initialize is the constructor that runs automatically when you call ClassName.new(args). Instance variables start with @ (e.g., @name) and hold state unique to each object instance; they are accessible from any instance method of the class but not from outside without accessor methods.

  25. What do attr_reader, attr_writer, and attr_accessor generate in a Ruby class?

    They auto-generate methods for instance variables: attr_reader :name creates a getter (name), attr_writer :name creates a setter (name=), and attr_accessor :name creates both. They replace hand-written trivial getter/setter methods.

  26. How do instance methods/variables differ from class methods/variables in Ruby?

    Instance methods are called on objects and use @variables unique to each instance. Class methods are defined with self. (def self.method) and called on the class itself; class variables use @@ and are shared by the class and all its instances (and subclasses, which makes @@ risky).

  27. How does inheritance work in Ruby, and what does super do?

    A subclass inherits with <, e.g., class Dog < Animal, gaining all of Animal's methods. super inside an overriding method calls the parent's version of that same method โ€” super passes the same arguments along, super() passes none.

  28. What does marking methods private in a Ruby class accomplish?

    Methods below the private keyword can only be called from within the object's other instance methods, not from outside (no explicit receiver). This enforces encapsulation: the public interface stays small while internal helper logic is hidden from users of the class.

  29. What is the difference between require and require_relative when organizing a multi-file Ruby project?

    require loads from Ruby's load path (installed gems and standard library), e.g., require 'json'. require_relative loads a file by its path relative to the current file, e.g., require_relative 'lib/board' โ€” the standard way to split your own project into multiple files.

  30. What is RuboCop and what do the commands rubocop and rubocop -a do?

    RuboCop is Ruby's standard linter and formatter that enforces the community Ruby Style Guide through rules called 'cops'. Running rubocop reports offenses; rubocop -a (autocorrect) safely fixes many of them automatically. Project-specific rules are configured in a .rubocop.yml file.

The Odin Project Ruby FAQ

What is in the The Odin Project Ruby syllabus?

The Odin Project Ruby is split into 8 chapters: Basic Ruby, Basic Ruby Projects, Object Oriented Programming Basics, Files and Serialization, Advanced Ruby, Testing Ruby with RSpec, Computer Science in Ruby and Conclusion. Together they contain 34 topics.

How many chapters are in The Odin Project Ruby?

8 chapters, containing 34 topics. The largest chapter is Basic Ruby, with 9 topics.

Are there flashcards for The Odin Project Ruby?

Yes โ€” a 50-card Ruby deck, printed in full in the flashcards section of this page and available in the Examius app with spaced repetition. The free plan covers one exam of your choice, including its flashcards; Examius Pro, a one-time purchase, unlocks every other exam and deck.