A language designed for happiness. Rails, gems, and elegant syntax. Matz made it for fun.
puts "Hello, World!"
puts 42.class # Integer
puts "hi".class # String
# Variables
name = "Mayank"
age = 15
puts "#{name} is #{age}"
# Run: ruby file.rb
Dynamic typing. No declarations needed. String, Integer, Float, Boolean, Array, Hash, Symbol.
name = "Mayank" # String
age = 15 # Integer
pi = 3.14 # Float
alive = true # TrueClass
nothing = nil # NilClass
nums = [1, 2, 3, 4, 5] # Array
hash = {name: "Mayank", age: 15} # Hash with symbol keys
puts name.class # String
puts nums.class # Array
puts hash.class # Hash
# String interpolation
greeting = "Hello, #{name}!"
puts greeting
# Multiline string
html = <<~HTML
<h1>Hello</h1>
<p>World</p>
HTML
puts html
puts 10 + 3 # 13
puts 10 - 3 # 7
puts 10 * 3 # 30
puts 10 / 3 # 3 (integer division)
puts 10 % 3 # 1
puts 10 ** 3 # 1000
# String concatenation
puts "Hello" + " " + "World"
puts "Hello" << " World"
# Spaceship operator
puts (1 <=> 2) # -1
puts (2 <=> 2) # 0
puts (3 <=> 2) # 1
# Range
puts (1..5).to_a # [1, 2, 3, 4, 5]
puts (1...5).to_a # [1, 2, 3, 4]
# Regex
puts "hello123".match?(/\d+/) # true
score = 85
if score >= 90
puts 'A'
elsif score >= 80
puts 'B'
else
puts 'C'
end
# Unless (opposite of if)
unless score < 50
puts 'You passed'
end
# Case
day = 3
case day
when 1 then puts 'Monday'
when 2 then puts 'Tuesday'
when 3 then puts 'Wednesday'
else puts 'Other'
end
# Loops
5.times { |i| puts i }
1.upto(5) { |i| puts i }
[1,2,3,4,5].each { |n| puts n }
# Iterator methods
[1,2,3,4,5].select { |n| n.even? } # [2, 4]
[1,2,3,4,5].map { |n| n * 2 } # [2, 4, 6, 8, 10]
[1,2,3,4,5].reduce(:+) # 15
def add(a, b)
a + b
end
puts add(3, 4)
# Default params
def greet(name, prefix = 'Hello')
"#{prefix}, #{name}!"
end
puts greet('Mayank')
puts greet('World', 'Hi')
# Yield (pass block)
def timer
start = Time.now
yield
puts "Took #{Time.now - start}s"
end
timer { sleep 0.1 }
# Block
[1,2,3].each do |n|
puts n * 10
end
# Lambda
square = ->(x) { x * x }
puts square.call(5)
# Proc
double = Proc.new { |x| x * 2 }
puts [1,2,3].map(&double)
class Dog
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
def bark
"#{@name}: Woof!"
end
def to_s
"Dog(#{@name}, #{@age})"
end
end
d = Dog.new('Rex', 5)
puts d.bark
puts d.name
puts d
Modules group methods. Include them in classes for shared behavior. Like traits in other languages.
module Swimmable
def swim
"#{@name} is swimming!"
end
end
class Duck
include Swimmable
def initialize(name) @name = name end
end
class Fish
include Swimmable
def initialize(name) @name = name end
end
puts Duck.new('Donald').swim
puts Fish.new('Nemo').swim
# Module as namespace
module Math
def self.circle_area(r)
Math::PI * r * r
end
end
puts Math.circle_area(5)
each, map, select, reject, reduce, sort_by. Ruby collections are incredibly powerful.
nums = [5, 3, 1, 4, 2]
puts nums.sort
puts nums.reverse
puts nums.select { |n| n > 2 }
puts nums.reject { |n| n > 2 }
puts nums.map { |n| n * 10 }
puts nums.reduce(:+)
puts nums.min
puts nums.max
puts nums.include?(3)
puts nums.count
# Hash iteration
hash = {a: 1, b: 2, c: 3}
hash.each { |k, v| puts "#{k}=#{v}" }
puts hash.keys
puts hash.values
# Chaining
result = (1..100)
.select(&:odd?)
.map { |n| n ** 2 }
.select { |n| n > 100 }
.first(5)
puts result.inspect
Symbols are interned strings. define_method, method_missing, send โ Ruby can modify itself at runtime.
# Symbols
s1 = :hello
s2 = :hello
puts s1.object_id == s2.object_id # true (same object)
# Metaprogramming
class Dynamic
def method_missing(name, *args)
if name.to_s.start_with?('say_')
msg = name.to_s[4..]
define_singleton_method(name) { "#{msg}!" }
send(name)
else
super
end
end
end
d = Dynamic.new
dputs d.say_hello # "hello!"
puts d.say_world # "world!"
# define_method
class Greeter
define_method(:greet) { |name| "Hello, #{name}" }
end
puts Greeter.new.greet('Mayank')
# File operations
File.write('test.txt', 'Hello Ruby!\n')
puts File.read('test.txt')
# Line by line
File.foreach('test.txt') { |line| puts line }
# Append
File.open('log.txt', 'a') { |f| f.puts "#{Time.now} event" }
# Shell commands
output = `ls -la`
puts output
system('echo "Hello from shell"')
# Dir operations
puts Dir.glob('*.rb')
Dir.mkdir('test_dir') unless Dir.exist?('test_dir')
# Path
require 'pathname'
puts Pathname.new(__FILE__).dirname
class CustomError < StandardError; end
def risky_operation(n)
raise CustomError, "Bad value: #{n}" if n < 0
Math.sqrt(n)
end
begin
puts risky_operation(16)
puts risky_operation(-1)
rescue CustomError => e
puts "Error: #{e.message}"
rescue => e
puts "Other: #{e.message}"
ensure
puts "Always runs"
end
# Retry
attempts = 0
begin
attempts += 1
raise 'fail' if attempts < 3
puts 'success'
rescue
retry if attempts < 3
end
Ruby packages are gems. Gemfile manages dependencies. bundle install sets everything up.
# Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 7.0'
gem 'rspec', '~> 3.12'
gem 'pry', '~> 0.14'
# Terminal:
# bundle install
# bundle exec rspec
# Creating a gem
# gem build mygem.gemspec
# gem push mygem-1.0.0.gem
# Using gems
require 'json'
data = { name: 'Mayank' }.to_json
puts data
require 'date'
puts Date.today
puts DateTime.now
# Popular gems:
# rails - web framework
# sinatra - lightweight web
# rspec - testing
# pry - debugging
# nokogiri - HTML parsing
# sidekiq - background jobs