class Person
def initialize(name)
@name = name
end
def say_hi
puts "#{@name} says hi"
end
end
andreas = Person.new("Andreas")
andreas.say_hi
require 'person_class'
class Programmer < Person
def initialize(name, favorite_ide)
super(name)
@favorite_ide = favorite_ide
end
# We are overriding say_hi in Person
def say_hi
super
puts "Favorite IDE is #{@favorite_ide}"
end
end
peter = Programmer.new("Peter", "TextMate")
peter.say_hi
class Person
def initialize(name)
self.name = name
end
def name
@name
end
def name=(name)
@name = name
end
end
person = Person.new("Andreas")
puts person.name
person.name = "David"
puts person.name
class Person
attr_accessor :name
def initialize(name)
self.name = name
end
end
person = Person.new("Andreas")
puts person.name
person.name = "David"
puts person.name
class Person
attr_accessor :paid
def initialize
@paid = false
end
def make_payment
puts "making payment..."
paid = true
end
end
person = Person.new
person.make_payment
puts "paid=#{person.paid}"
def square(number) number * number end square(2+2)*2 # => square(4)*2 = 32 square (2+2)*2 # => square(4*2) = 64
class MyClass def method1 # Methods are public by default end # Protected methods can be invoked by any instance of the same class or a # subclass of MyClass protected def method2 end # Private methods can only be invoked within an instance of MyClass or a subclass # of MyClass. The receiver of a private method is always self. private def method3 end end
class Person
def self.class_method
puts "class method invoked"
end
class << self
def class_method2; puts "class_method2"; end
def class_method3; puts "class_method3"; end
end
end
class << Person
def class_method4; puts "class_method4"; end
end
# Invocation of class method
Person.class_method
require 'person'
# Every object has two classes: the class of which it is an instance, and a singleton class. Methods
# of the singleton class are called singleton methods and can only be invoked on that particular object.
andreas = Person.new("Andreas")
def andreas.andreas_says_hi
"Andreas says hi"
end
andreas.andreas_says_hi
# Class methods are singleton methods on the class
# object and can be defined like this:
def Person.count
@@count ||= 0
end
puts Person.count
comment = Object.new
def comment.user
Object.new
end
# Overly verbose:
user_id = nil
if comment
if comment.user
user_id = comment.user.object_id
end
end
# Idiomatic:
user_id = comment && comment.user && comment.user.object_id
require 'person_class'
module HasAge
attr_accessor :age
end
class Person
include HasAge
end
peter = Person.new("Peter"); peter.age = 33; puts peter.age
module MyApp
class Person
attr_accessor :hometown
def initialize(hometown)
self.hometown = hometown
end
end
end
peter = MyApp::Person.new("Stockholm"); puts peter.hometown
andreas = Person.new("Andreas")
andreas.inspect # => #<Person:0x1cf34 @name="Andreas">
andreas.class # => Person
andreas.class.superclass # => Object
andreas.class.superclass.superclass # => nil
andreas.class.ancestors.join(", ") # Person, Object, Kernel
Person.instance_methods(false) # => say_hi
Kernel.methods.sort.join("\n") # => All methods in Kernel module
2.class == Fixnum Fixnum.superclass == Integer Integer.superclass == Numeric 3.0.class == Float Float.superclass == Numeric 2/3 == 0 2/3.0 # => 0.6666667 2 + 3.0 == 5.0 "2".to_i + "3.0".to_f == 5.0 10000000000.class == Bignum Bignum.superclass == Integer 2 + "3" # => TypeError: String can't be coerced into Fixnum
"ruby".upcase + " " + "rails".capitalize # => RUBY Rails
"time is: #{Time.now}\n second line"
'no interpolation "here" #{Time.now}' # => no interpolation "here" #{Time.now}
"I" << "Go" << "Ruby" # => IGoRuby
%Q{"C" and "Java"} # => "C" and "Java"
%q{single 'quoted'} # => single 'quoted'
<<-END
A here
document at #{Time.now}
END
a = ["Ruby", 99, 3.14]
a[1] == 99
a << "Rails"
['C', 'Java', 'Ruby'] == %w{C Java Ruby}
[1, 2, 3].map { |x| x**2 }.join(", ")
[1, 2, 3].select { |x| x % 2 == 0 }
[1, 2, 3].reject { |x| x < 3 }
[1, 2, 3].inject { |sum, i| sum + i }
[1, [2, 3]].flatten! # => [1, 2, 3]
%w{C Java Ruby}.include?("C") # => true
fruits = ['apple', 'banana']
fruits += ['apple'] unless fruits.include?('apple')
[1, 3, 5] & [1, 2, 3] # (intersection) => [1, 3]
[1, 3, 5] | [2, 4, 6] # (union) => [1, 3, 5, 2, 4, 6]
[1, 2, 3] - [2, 3] # (difference) => [1]
h = {:lang => 'Ruby', :framework => 'Rails'}
h[:lang] == 'Ruby'
h[:perl] == nil
puts h.inspect
env = {"USER" => "peter", "SHELL" => "/bin/bash"}
env.each {|k, v| puts "#{k}=#{v}" }
# Symbols start with a colon
:action.class == Symbol
:action.to_s == "action"
:action == "action".to_sym
# There is only one instance of every symbol
:action.equal?(:action) # => true
'action'.equal?('action') # => false
# Symbols are typically used as keys in hashes
my_hash = {:controller => "home", :action => "index"}
# Two dots is inclusive, i.e. 1 to 5
(1..5).each { |x| puts x**2 }
# Three dots excludes the last item, i.e. 1 to 4
(1...5).each { |x| puts x }
(1..3).to_a == [1, 2, 3]
Rating = Struct.new(:name, :ratings)
rating = Rating.new("Rails", [ 10, 10, 9.5, 10 ])
puts rating.name
puts rating.ratings
begin
raise(ArgumentError, "No file_name provided") if !file_name
content = load_blog_data(file_name)
raise "Content is nil" if !content
rescue BlogDataNotFound
STDERR.puts "File #{file_name} not found"
rescue BlogDataConnectError
@connect_tries ||= 1
@connect_tries += 1
retry if @connect_tries < 3
STDERR.puts "Invalid blog data in #{file_name}"
rescue Exception => exc
STDERR.puts "Error loading #{file_name}: #{exc.message}"
raise
end
message = if count > 10
"Try again"
elsif tries == 3
"You lose"
else
"Enter command"
end
raise "Unauthorized" if !current_user.admin?
raise "Unauthorized" unless current_user.admin?
status = input > 10 ? "Number too big" : "ok"
while count < 100
puts count
count += 1
end
payment.make_request while (payment.failure? and payment.tries < 3)
for user in @users
next if user.admin?
if user.paid?
break
end
end
until count > 5
puts count
count += 1
end
puts(count += 1) until count > 5
x = 11 case x when 0 when 1, 2..5 puts "Second branch" when 6..10 puts "Third branch" when *[11, 12] puts "Fourth branch" when String: puts "Fifth branch" when /\d+\.\d+/ puts "Sixth branch" when x.to_s.downcase == "peter" puts "Seventh branch" else puts "Eight branch" end
# Iteration
[1, 2, 3].each { |item| puts item }
# Resource Management
File.open("file.txt", "w") do |file|
file.puts "foobar"
end
# Callbacks
widget.on_button_press do
puts "Got button press"
end
# Convention: one-line blocks use {...} and multiline
# blocks use do...end
" ".empty? == true
IO.read(__FILE__).each_with_index { |line, i| puts "#{i}: #{line}" }
"abc".scan(/./).each { |char| char.upcase }
"we split words".split.join(", ")
" strip space ".strip
sprintf("value of %s is %.2f", "PI", 3.1416)
"I Go Ruby"[2, 2] == "I Go Ruby"[2..3] # => "Go"
# Methods that change their receiver end with an exclamation mark by convention.
# If you need to invoke an exclamation mark method on a method argument and you want
# to avoid the object from being changed, you can duplicate the object first
# with the Object#dup method. Core classes such as String, Hash, and Array all have
# meaningful implementations of the dup method. Here is an example from Rails:
class ActiveRecord::Base
def attributes=(new_attributes)
return if new_attributes.nil?
attributes = new_attributes.dup # duplicate argument to avoid changing it
attributes.stringify_keys! # modify the duplicated object
# ... method continues here
end
end"Ruby" =~ /^(ruby|python)$/i
"Go\nRuby" =~ /Go\s+(\w+)/m; $1 == "Ruby"
"I Go Ruby" =~ /go/i; $& == "Go"; $` == "I "; $' == " Ruby"
pattern = "."; Regexp.new(Regexp.escape(pattern))
"I Go Ruby"[/(go)/i, 1] == "Go"
puts "I Go Ruby".gsub(%r{Ruby}, '\0 or I go bananas')
"I Go Ruby".gsub(/ruby/i) { |lang| lang.upcase }
line = "I Go Ruby"
m, who, verb, what = *line.match(/^(\w+)\s+(\w+)\s+(\w+)$/)
# \s, \d, [0-9], \w - space, digit, and word character classes
# ?, *, +, {m, n}, {m,}, {m} - repetition
system("ls -l")
# $? is a predefined variable with the exit status
puts $?.exitstatus if !$?.success?
# The back ticks "`" return the output of the external program
standard_out = `ls -l`
#!/usr/bin/env ruby
# == Synopsis
# This script takes photographs living locally on my desktop or laptop
# and publishes them to my homepage at http://marklunds.com.
#
# == Usage
#
# Copy config file publish-photos.yml.template to publish-photos.yml and edit as appropriate.
# ruby publish-photos [ -h | --help ] <photo_dir1> ... <photo_dirN>
# Load the Rails environment
require File.dirname(__FILE__) + '/../config/environment'
require 'optparse'
require 'rdoc/usage'
opts = OptionParser.new
opts.on("-h", "--help") { RDoc::usage('usage') }
opts.on("-q", "--quiet") { Log::Logger.verbose = false }
opts.parse!(ARGV) rescue RDoc::usage('usage')
Photos::Publisher(ARGV)
# Query and replace ruby -pi.bak -e "gsub(/Perl/, 'Ruby')" *.txt # Grep ruby -n -e "print if /Ruby/" *.txt ruby -e "puts ARGF.grep(/Ruby/)" *.txt
class Peter
def say_hi
puts "Hi"
end
end
class Peter
alias_method :say_hi_orig, :say_hi
def say_hi
puts "Before say hi"
say_hi_orig
puts "After say hi"
end
end
Peter.new.say_hi
class Integer
def even?
(self % 2) == 0
end
end
p (1..10).select { |n| n.even? } # => [2, 4, 6, 8, 10]
class VCR
def initialize
@messages = []
end
def method_missing(method, *args, &block)
@messages << [method, args, block]
end
def play_back_to(obj)
@messages.each do |method, args, block|
obj.send(method, *args, &block)
end
end
end
require 'vcr' vcr = VCR.new vcr.gsub! /Ruby/, "Crazy" vcr.upcase! object = "I Go Ruby" vcr.play_back_to(object) puts object
def Object.const_missing(name)
@looked_for ||= {}
str_name = name.to_s
raise "Class not found: #{name}" if @looked_for[str_name]
@looked_for[str_name] = 1
file = str_name.downcase
require file
klass = const_get(name)
return klass if klass
raise "Class not found: #{name}"
end
def evaluate_code(code, binding)
a = 2
eval code, binding
end
a = 1
evaluate_code("puts a", binding) # => 1
require 'person_class'
andreas = Person.new("Andreas")
puts andreas.instance_eval { @name } # => Andreas
class Person
def self.add_method(method)
class_eval %Q{
def #{method}
puts "method #{method} invoked"
end
}
end
add_method(:say_hi)
end
Person.new.say_hi
class Array
{:second => 1, :third => 2}.each do |method,element|
define_method(method) do
self[element]
end
end
end
array = %w(A B C)
puts array.first # => A
puts array.second # => B
puts array.third # => C
# Using Class#superclass klass = Fixnum begin print klass klass = klass.superclass print " < " if klass end while klass # => Fixnum < Integer < Numeric < Object # Using Class#ancestors Fixnum.ancestors # => Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel # Inspecting methods and variables Fixnum.public_instance_methods(false) Fixnum.class_variables Fixnum.constants 1.instance_variables
class A
@@subclasses = {}
# Invoked when a new class is created that extends this class
def self.inherited(child)
puts "inherited"
@@subclasses[self] ||= []
@@subclasses[self] << child
end
def self.subclasses
@@subclasses[self]
end
end
class B < A
end
puts A.subclasses