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