🚀 Ruby Introduction

🎯 Complete Definition

Ruby is a dynamic, open-source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write. Created by Yukihiro "Matz" Matsumoto and released in 1995, Ruby's design philosophy emphasizes that "everything is an object" and prioritizes developer happiness. It combines features from Perl, Smalltalk, Eiffel, Ada, and Lisp.

🔬 Core Characteristics

  • Pure Object-Oriented: Everything is an object, including numbers and booleans
  • Dynamic Typing: Types are checked at runtime, variables have no type
  • Interpreted: Executed via MRI (Matz's Ruby Interpreter), YARV, or alternative VMs
  • Flexible Syntax: Parentheses optional, powerful blocks/closures
  • Automatic Memory Management: Garbage collection (mark & sweep, incremental)
  • Mixins: Modules provide multiple inheritance-like behavior
  • Metaprogramming: Code that writes code at runtime (open classes, method_missing)

📊 Industry Usage

Ruby on Rails revolutionized web development. Used by GitHub, Shopify, Airbnb, Basecamp, Stripe, and thousands of startups. Ruby ranks consistently in top 10 languages (TIOBE, RedMonk). Powers massive e-commerce platforms, automation scripts, and prototyping. RubyGems hosts over 150,000 libraries.

puts "💎 Ruby 3.2 - CodeOrbitPro Pro Track" puts "Version: #{RUBY_VERSION}" puts "Platform: #{RUBY_PLATFORM}" puts "Everything is an object: #{1.class}" # Integer

📊 Variables & Data Types

🎯 Complete Definition

Variables in Ruby are references to objects. Ruby uses dynamic typing: variable types are determined by the object they reference. Variable names indicate scope: local (lowercase/underscore), instance (@), class (@@), global ($), and constants (Uppercase). Ruby's core data types include Numbers (Integer, Float), Strings, Symbols, Booleans, Arrays, Hashes, Ranges, and nil.

🏷️ Core Data Types

  • Integer: Arbitrary precision (Fixnum/Bignum merged into Integer)
  • Float: Double-precision floating point
  • String: Mutable sequence of characters (UTF-8 by default)
  • Symbol: Immutable, interned identifiers (:symbol)
  • Array: Ordered, zero-based, dynamically growing collection
  • Hash: Key-value dictionary (ordered since 1.9)
  • TrueClass / FalseClass / NilClass: true, false, nil
  • Range: (1..10) inclusive, (1...10) exclusive

🔧 Advanced Features

Parallel assignment, swapping variables: a,b = b,a. Everything returns a value. Constants emit warnings when reassigned. Symbol immutability saves memory and speeds up hash lookups. Freezing objects with .freeze makes them immutable.

name = "CodeOrbitPro" # local variable @points = 2500 # instance variable $debug = true # global variable MAX_SCORE = 100 # constant age = 30; pi = 3.14159; active = true puts "#{name}, #{age}, #{pi}, #{active}" puts name.class # String puts age.class # Integer # Symbol status = :active puts status.object_id # Parallel assignment x, y = 10, 20 x, y = y, x # swap

🔢 Operators

🎯 Complete Definition

Operators are actually method calls in Ruby (syntactic sugar). Most operators like +, -, == are methods invoked on the left object. Ruby provides a rich set of operators with defined precedence and associativity. All operators can be overridden in custom classes except a few (&&, ||, .., ...).

📋 Operator Categories

  • Arithmetic: +, -, *, /, %, ** (exponentiation)
  • Comparison: ==, !=, >, <, >=, <=, <=> (spaceship), .eql?, equal?
  • Logical: &&, ||, !, and, or, not (low precedence versions)
  • Bitwise: &, |, ^, ~, <<, >> (for integers)
  • Assignment: =, +=, -=, *=, /=, %=, **=, &=, |=, ^=, <<=, >>=
  • Range: .. (inclusive), ... (exclusive)
  • Ternary: condition ? true_expr : false_expr
  • Misc: defined?, :: (scope), . (method call)

⚡ Precedence (high to low)

[] []= > ** > ! ~ + (unary) > * / % > + - > << >> > & > | ^ > > < >= <= > <=> == === != =~ !~ > && > || > .. ... > ?: > = += ... > defined? > not > and or

puts 10 + 5, 10 / 5, 2 ** 8 # arithmetic puts 10 == 5, 10 <=> 5 # -1 (spaceship) puts (1..5).include?(3) # range # Logical puts true && false, true || false # Ternary score = 85 grade = score >= 60 ? "Pass ✅" : "Fail ❌" puts grade # Operator as method puts 5.+ (3) # 8

🔀 Control Flow

🎯 Complete Definition

Control flow in Ruby uses if/unless/case. Everything is an expression (returns a value). Modifier forms (puts "x" if x) allow concise syntax. Ruby also has until as opposite of while, and case with === operator (case equality).

🏗️ Control Structures

  • if / elsif / else: Traditional conditional
  • unless: Execute if condition is false
  • case / when: Multi-way branch using ===
  • ternary: inline condition ? a : b
  • statement modifiers: action if condition, action unless condition
  • defined?: Check if expression defined

🔍 Truthiness

Only false and nil are falsy; everything else is truthy (including 0, "", []). This is different from many languages.

score = 85 if score >= 90 grade = "A ⭐⭐⭐" elsif score >= 80 grade = "B ⭐⭐" else grade = "C ⭐" end puts grade # unless puts "Low score" unless score > 70 # case case score when 90..100 then puts "Excellent" when 80...90 then puts "Good" else puts "Work harder" end # modifier puts "Pass" if score >= 60

🔄 Loops & Iterators

🎯 Complete Definition

Ruby provides traditional loops (while, until) and powerful iterator methods (each, times, upto, step). for is syntactic sugar for each. Loop control: break, next, redo, retry. Most idiomatic Ruby uses iterators.

🏗️ Loop Types

  • while condition: Execute while condition truthy
  • until condition: Execute while condition falsy
  • for item in collection: (uses each internally)
  • Integer.times: Iterate block n times
  • upto/downto: Range iteration
  • each: Basic iterator for collections
  • loop: Infinite loop (break to exit)

⚡ Loop Controls

break: exits loop. next: jumps to next iteration. redo: repeats current iteration. retry: restarts loop (works in certain contexts).

# while i = 0 while i < 3 puts "while: #{i}" i += 1 end # times 5.times { |i| print i, ' ' } # 0 1 2 3 4 # each [10, 20, 30].each do |num| puts "each: #{num}" end # upto 1.upto(3) { |n| puts "upto: #{n}" } # loop with break x = 0 loop do x += 1 break if x > 3 puts "loop: #{x}" end

⚙️ Methods

🎯 Complete Definition

Methods define behavior for objects. Defined with def keyword, end with end. Return last evaluated expression unless explicit return. Methods can have default arguments, variable arguments (*args), keyword arguments, and block arguments (&block). Methods names can end with ? (predicate), ! (dangerous/bang), = (setter).

🏗️ Method Features

  • def name(params): Standard definition
  • default parameters: def greet(name="Ruby")
  • *args: Splat operator captures variable args
  • **kwargs: Keyword args (Ruby 2.0+)
  • &block: Capture block as Proc
  • return: Explicit return (optional)

🔧 Method Visibility

public (default), protected, private. Private methods cannot be called with explicit receiver. Methods are objects (can be stored) via method(:name).

def greet(name="Student") "Hello #{name}! Welcome to Ruby 💎" end def sum(*numbers) numbers.reduce(0, :+) end def tagged(name:, level:) "#{name} level: #{level}" end puts greet("CodeOrbitPro") puts sum(1,2,3,4) puts tagged(name: "Ruby", level: "Pro") # Predicate method def valid?(score) score.between?(0,100) end puts valid?(95) # true

📋 Arrays

🎯 Complete Definition

Array is an ordered, integer-indexed collection of objects. Arrays can hold any type (heterogeneous). Indexing starts at 0, negative indexes count from end. Arrays are dynamic (grow/shrink). Rich set of methods: stack/queue operations, set operations, filtering, sorting.

🏗️ Array Operations

  • [] / at: element access
  • << / push / unshift: add elements
  • pop / shift: remove from end/start
  • concat / +: concatenation
  • each / map / select / reject: iterators
  • join / split: string conversion
  • include? / index / rindex: search
  • sort / reverse / uniq: transformation

⚡ Performance

Array access O(1), amortized push O(1), insertion/deletion O(n). Ruby 3.x optimizes small arrays.

languages = ["Ruby", "Python", "Java"] languages << "Rust" languages[1] = "Go" puts languages.inspect # ["Ruby", "Go", "Java", "Rust"] # Stack stack = [] stack.push 1, 2, 3 puts stack.pop # 3 # Queue queue = [] queue.unshift 1, 2, 3 puts queue.pop # 1 # Iterators numbers = [1,2,3,4,5] squares = numbers.map { |x| x**2 } evens = numbers.select(&:even?) puts squares.inspect puts evens.inspect

🔑 Hashes

🎯 Complete Definition

Hash is a dictionary-like collection of unique keys and their values. Keys can be any object (Symbols preferred). Hashes maintain insertion order (since Ruby 1.9). Default values can be provided. Hashes are often used for named parameters, data structures.

🏗️ Hash Operations

  • {} / Hash.new: create
  • [] / fetch: value access
  • []= / store: assign
  • keys / values: get keys/values arrays
  • each / map: iteration
  • merge / update: combine hashes
  • transform_keys / transform_values: Ruby 2.4+
  • dig: nested access (Ruby 2.3+)

🔧 Advanced

Symbol keys: hash = {name: "Ruby", age: 25} (new syntax). fetch raises or returns default. default_proc for dynamic defaults.

# Classic syntax student = { "name" => "CodeOrbitPro", "xp" => 2500 } # Symbol syntax (modern) student = { name: "CodeOrbitPro", xp: 2500, active: true } puts student[:name] # Iteration student.each do |key, value| puts "#{key}: #{value}" end # Default value counts = Hash.new(0) counts[:ruby] += 1 puts counts[:python] # 0 (default) # merge info = { country: "USA" } puts student.merge(info)

📝 Strings

🎯 Complete Definition

String in Ruby is a mutable sequence of characters (encoding-aware). Supports interpolation ("#{}"), concatenation (+), repetition (*), and a huge standard library. Strings are objects with over 100 methods. %Q and %q provide alternative quoting. Heredocs support multiline.

🏗️ String Operations

  • length / size / empty?: size info
  • + / << / concat: concatenation
  • split / join: convert to/from arrays
  • strip / chomp / chop: trimming
  • upcase / downcase / capitalize: case
  • gsub / sub: substitution
  • include? / index / start_with?: search
  • to_i / to_f / to_sym: conversion

⚡ Performance

Strings are mutable (can be changed). Use "" for mutable, '' for literal (no interpolation). Frozen strings (Ruby 3+) optimize memory via # frozen_string_literal: true.

text = " Ruby Pro Track " puts text.strip puts text.upcase puts text.split # ["Ruby", "Pro", "Track"] # Interpolation name = "CodeOrbitPro" puts "Hello #{name}! Score: #{95.678.round(1)}" # gsub code = "puts 'hello'" puts code.gsub("'", "\"") # Encoding puts "💎".encoding # UTF-8

💾 File I/O

🎯 Complete Definition

File class provides interface to filesystem. Open modes: "r", "w", "a", "r+", "w+", "a+", with binary modifier ("b"). Block form auto-closes file. IO superclass provides low-level I/O. FileUtils for file operations (cp, mv, rm). Pathname for path manipulation.

🏗️ File Operations

  • File.open(filename, mode): open file
  • file.read / readlines: read content
  • file.write / <<: write
  • file.close: manual close
  • File.exist? / file? / directory?: checks
  • Dir.glob / Dir.entries: directory listing
  • FileUtils.mv / cp / rm: high-level ops

🔧 Advanced

IO#each_line yields lines. File.read slurps entire file. File.foreach streams line by line. Tempfile for temporary files.

# Write (block auto-closes) File.open("codeorbit.txt", "w") do |f| f.puts "CodeOrbitPro Ruby Master!" f.puts "Line 2" end # Read entire file content = File.read("codeorbit.txt") puts content # Read lines File.foreach("codeorbit.txt").with_index do |line, idx| puts "#{idx+1}: #{line.chomp}" end # Check existence puts File.exist?("codeorbit.txt") # true # Directory listing Dir.glob("*.txt").each { |f| puts f }

🛡️ Exceptions

🎯 Complete Definition

Exceptions handle errors. Hierarchy: Exception (parent) -> StandardError (common) -> subclasses. begin/rescue/else/ensure/end block. raise triggers exception. rescue can specify exception classes. ensure runs always (cleanup). retry in rescue repeats begin block.

🏗️ Exception Handling

  • begin ... rescue ... end: basic block
  • rescue => e: capture exception object
  • rescue TypeError, ArgumentError: specific types
  • else: runs if no exception
  • ensure: runs always
  • raise "msg": raise RuntimeError

🔧 Custom Exceptions

Define subclass of StandardError. $! global contains last exception. backtrace method shows stack.

begin result = 10 / 0 rescue ZeroDivisionError => e puts "Error: #{e.message}" rescue TypeError => e puts "Type error" else puts "No error!" ensure puts "Cleanup" end # Custom exception class LowScoreError < StandardError; end def check_score(score) raise LowScoreError, "Too low" if score < 60 "Pass" end begin puts check_score(55) rescue LowScoreError => e puts e.message end

🏗️ Object Oriented Programming

🎯 Complete Definition

Ruby is pure OOP — every object is an instance of a class. Classes define state (instance variables) and behavior (methods). Supports single inheritance, mixins (modules), and open classes. attr_accessor creates getters/setters. initialize is constructor. self refers to current object.

🏗️ OOP Features

  • class Name ... end: class definition
  • initialize(params): constructor
  • @var: instance variable
  • @@var: class variable
  • attr_reader / attr_writer / attr_accessor: shortcuts
  • self.method: class method
  • inheritance: class Child < Parent
  • super: call parent method

🔧 Advanced

method_missing, define_method, send, respond_to?. Open classes allow monkey patching. prepend for method wrapping.

class RubyPro attr_reader :name, :xp attr_accessor :level @@count = 0 def initialize(name, xp=0) @name = name @xp = xp @level = 1 @@count += 1 end def gain_xp(points) @xp += points @level = 1 + @xp / 1000 "#{@name} level #{@level}" end def self.count @@count end end class RubyMaster < RubyPro def initialize(name, xp=0) super(name, xp) @rank = "Master ⭐⭐⭐" end end coder = RubyMaster.new("CodeOrbitPro", 2500) puts coder.gain_xp(1500) puts RubyPro.count

📦 Modules

🎯 Complete Definition

Modules are collections of methods and constants. They cannot be instantiated. Used as namespaces and mixins. include adds module methods as instance methods. extend adds them as class methods. prepend prepends methods (Ruby 2.0+). require loads external files/gems.

🏗️ Module Features

  • module M ... end: definition
  • include M: mixin as instance methods
  • extend M: mixin as class methods
  • prepend M: method lookup before class
  • require 'file': load library
  • include Comparable / Enumerable: standard mixins

🔧 Standard Modules

Kernel (puts, require), Comparable (requires <=>), Enumerable (requires each), Math, FileUtils. Load path: $LOAD_PATH.

module Trackable def track "Tracking #{self.name}" end end module Rankable def rank "Pro" end end class Course include Trackable include Rankable attr_reader :name def initialize(name) @name = name end end course = Course.new("Ruby") puts course.track puts course.rank # Namespace module CodeOrbit VERSION = "1.0" class Pro end end puts CodeOrbit::VERSION

⚡ Blocks & Advanced

🎯 Complete Definition

Blocks are anonymous chunks of code passed to methods (do...end or {...}). Procs are block objects (reusable). Lambdas are Procs with strict arity and return behavior. Closures capture surrounding variables. yield calls passed block. &block captures block as Proc.

🏗️ Advanced Concepts

  • yield: invoke block
  • block_given?: check if block passed
  • Proc.new / proc: create Proc
  • lambda: create lambda
  • &: & converts symbol to proc (e.g., &:to_s)
  • Enumerable: map, select, inject
  • method_missing: dynamic dispatch
  • define_method: dynamic method creation

🔥 Metaprogramming

send, define_method, method_missing, class_eval, instance_eval — Ruby's power to write code that writes code.

# Block def timer start = Time.now yield puts "Elapsed: #{Time.now - start}s" end timer { sleep 0.1 } # Proc square = Proc.new { |x| x**2 } puts square.call(5) # Lambda cube = lambda { |x| x**3 } puts cube.call(3) # Symbol to proc puts [1,2,3].map(&:to_s) # ["1","2","3"] # Closure def multiplier(factor) Proc.new { |n| n * factor } end double = multiplier(2) puts double.call(5) # 10 # method_missing class Dynamic def method_missing(name, *args) "Called #{name} with #{args}" end end d = Dynamic.new puts d.hello("ruby")