Ruby
Breakdown of Ruby Syntax
Ruby is a dynamic, open-source, object-oriented programming language known for its simplicity and elegance. It was designed with an emphasis on developer happiness and productivity. Ruby is widely used for web development, particularly with the Ruby on Rails framework.
1. Basic Structure of a Ruby Program
A basic Ruby program typically consists of functions and classes, and the syntax is clean and minimal.
puts "Hello, World!"
puts: A method that prints a string to the console, followed by a new line.- Ruby doesn't need explicit declaration of entry points (like
mainin other languages). You just run the script.
2. Variables and Data Types
Ruby uses dynamic typing, meaning variables don’t need explicit type declarations.
Variables
name = "Alice" # String
age = 25 # Integer
height = 5.5 # Float
is_active = true # Boolean
- Variables are assigned without type declarations. The interpreter determines the type.
- Ruby uses snake_case for variable names.
Data Types
string = "Hello" # String
integer = 10 # Integer
float = 10.5 # Float
boolean = true # Boolean
array = [1, 2, 3] # Array
hash = { name: "Alice", age: 25 } # Hash (key-value pairs)
- String: Sequences of characters.
- Integer: Whole numbers.
- Float: Decimal numbers.
- Boolean:
trueorfalse. - Array: Ordered collection of items.
- Hash: Collection of key-value pairs, similar to a dictionary.
3. Methods
Ruby uses methods to define functions, and they are invoked with arguments. Methods are defined using the def keyword.
def greet(name)
puts "Hello, #{name}!"
end
greet("Alice") # Calling the method
def: Defines a method.end: Marks the end of a method (and most other blocks).- String interpolation:
#{}inside a string allows embedding variable values.
Return Values
By default, the last evaluated expression is returned from a method.
def add(a, b)
a + b
end
result = add(5, 10)
puts result # 15
4. Control Flow
Ruby has standard control flow constructs like if, unless, case, and loops.
Conditional Statements
x = 10
if x > 5
puts "Greater than 5"
elsif x == 5
puts "Equal to 5"
else
puts "Less than 5"
end
if,elsif,else: Conditional statements.elsifis Ruby's version ofelse if.
Ternary Operator
x = 10
puts x > 5 ? "Greater than 5" : "Less than or equal to 5"
- Ternary operator: One-line shorthand for
if-else.
Loops
# While loop
i = 0
while i < 5
puts i
i += 1
end
# For loop (iterates over a range)
for i in 0..4
puts i
end
# Times loop (repeats a block n times)
5.times { |i| puts i }
while: Loops as long as the condition is true.for: Iterates over a collection, range, or array.times: Repeats the block a specified number of times.
Break and Next
# Break exits the loop
for i in 0..5
break if i == 3
puts i
end
# Next skips the current iteration
for i in 0..5
next if i == 3
puts i
end
break: Exits the loop.next: Skips the current iteration and moves to the next one.
5. Classes and Objects
Ruby is object-oriented, and everything in Ruby is an object, including numbers and booleans.
Defining a Class
class Person
attr_accessor :name, :age # Creates getter and setter methods
def initialize(name, age)
@name = name
@age = age
end
def greet
puts "Hello, my name is #{@name} and I'm #{@age} years old."
end
end
person = Person.new("Alice", 25)
person.greet
class: Defines a class.attr_accessor: Automatically creates getter and setter methods for instance variables.initialize: Constructor method that is called when a new object is instantiated.@variable: Instance variables (local to an object).new: Used to create a new instance of the class.
1. Basic Class Definition
class Person
# Class body goes here
end
class: Keyword to define a class (always PascalCase).-
end: Closes the class definition.
2. Instance Variables & Accessors (Getters/Setters)
Ruby provides shortcuts to generate getters/setters automatically.
(a) Manual Getters/Setters
class Person
# Constructor (initializes instance variables)
def initialize(name, age)
@name = name # @ denotes instance variables
@age = age
end
# Getter for @name
def name
@name
end
# Setter for @name (note the '=')
def name=(new_name)
@name = new_name
end
# Getter for @age
def age
@age
end
# Setter for @age
def age=(new_age)
@age = new_age
end
end
@variable: Instance variable (private by default).- Getter: Method name matches variable (e.g.,
name).- Setter: Method name ends with
= (e.g., name=).
(b) Automated Accessors (Recommended)
Ruby provides macros to generate getters/setters:
class Person
attr_reader :name, :age # Generates getters
attr_writer :name, :age # Generates setters
attr_accessor :name, :age # Generates both getters and setters
def initialize(name, age)
@name = name
@age = age
end
end
attr_reader: Auto-generates getters.-
attr_writer: Auto-generates setters.-
attr_accessor: Generates both.
3. Constructors (initialize)
Ruby uses initialize as the constructor (called when new is invoked).
class Person
attr_accessor :name, :age
# Constructor
def initialize(name, age)
@name = name
@age = age
end
end
# Usage
person = Person.new("Alice", 30)
puts person.name # => "Alice" (getter)
person.age = 31 # => 31 (setter)
4. Custom Factory Methods (Class Methods)
Define methods on the class itself (not instances) using self..
class Person
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
# Class method (factory)
def self.from_birth_year(name, birth_year)
age = Time.now.year - birth_year
new(name, age) # Calls initialize
end
end
# Usage
person = Person.from_birth_year("Bob", 1990)
puts person.age # => 34 (if current year is 2024)
self.: Defines a class-level method.-
new: Calls the constructor.
5. Complete Example
Class Definition
class Person
attr_accessor :name, :age
# Constructor
def initialize(name, age)
@name = name
@age = age
end
# Instance method
def greet
puts "Hello, I'm #{@name}!"
end
# Class method (factory)
def self.from_birth_year(name, birth_year)
age = Time.now.year - birth_year
new(name, age)
end
end
Usage
# Default construction
p1 = Person.new("Alice", 25)
p1.greet # => "Hello, I'm Alice!"
p1.age = 26 # Uses setter
# Factory method
p2 = Person.from_birth_year("Bob", 1990)
puts p2.age # => 34 (in 2024)
6. Blocks and Procs
Ruby has a powerful block and proc system to pass chunks of code as arguments to methods.
Blocks
def greet(name)
yield(name)
end
greet("Alice") { |name| puts "Hello, #{name}!" }
yield: Invokes the block passed to the method.- Blocks are a powerful feature in Ruby, allowing you to write more flexible and reusable code.
Procs (Procedure Objects)
my_proc = Proc.new { |x| puts x * 2 }
my_proc.call(5) # Outputs 10
Proc.new: Defines a proc (a block of code stored as an object).call: Invokes the proc.
Lambdas (Special type of Proc)
my_lambda = ->(x) { puts x * 2 }
my_lambda.call(5) # Outputs 10
->: Defines a lambda.- Lambdas are similar to procs, but they check the number of arguments strictly.
7. Arrays
Arrays are ordered collections of objects.
arr = [1, 2, 3, 4, 5]
puts arr[0] # Outputs 1
puts arr.length # Outputs 5
arr.each { |num| puts num * 2 }
each: Iterates over the array.[]: Accesses an element in the array by index.length: Returns the number of elements in the array.
8. Hashes
Hashes are collections of key-value pairs.
person = { name: "Alice", age: 25 }
puts person[:name] # Outputs "Alice"
person[:age] = 26 # Modifies the value
{}: Defines a hash.[]: Accesses the value associated with the key.:key: Symbol keys are commonly used in Ruby.
9. Error Handling
Ruby uses begin-rescue-end blocks to handle exceptions.
begin
# Code that might raise an error
1 / 0
rescue ZeroDivisionError => e
puts "Error: #{e.message}"
else
puts "No errors"
ensure
puts "This will always run"
end
begin: Starts a block of code that might raise an error.rescue: Catches exceptions and handles them.else: Runs if no error occurs.ensure: Always runs, whether or not an error occurred.
10. Modules
Modules are used for grouping related methods and constants, and they provide mixins (similar to interfaces or abstract classes).
module Greetable
def greet
puts "Hello!"
end
end
class Person
include Greetable
end
person = Person.new
person.greet # Outputs "Hello!"
module: Defines a module.include: Mixes the module into the class, making its methods available in instances of the class.
Summary of Key Points:
- Ruby is an object-oriented language with a focus on simplicity and developer happiness.
- Everything in Ruby is an object, and it uses dynamic typing.
- Control flow is straightforward, with standard constructs like
if,while,for, and blocks. - Methods and classes are fundamental to Ruby’s design, with an elegant syntax that minimizes boilerplate.
- Error handling is clean and efficient with
begin-rescue-endblocks. - Ruby has powerful features like blocks, procs, and lambdas for functional programming.
- Modules allow for grouping related functionality and can be used as mixins.
Ruby’s simplicity, along with its powerful object-oriented and functional programming features, makes it a very productive language, especially for web development with frameworks like Ruby on Rails.