{ puts 'Hello' } do puts 'Hello' end
def call_block puts 'Beginning' yield puts 'End' end call_block { puts 'In the block' }
def who_says_what yield('Dave, 'hello') yield('Andy, 'goodbye') end who_says_what { |person, phrase| puts "#{person} says #{phrase}" }
def some_method(&block) yield if block_given? end some_method { puts 'Hello' } some_method
Blocks are not objects, but they can be converted into objects of class Proc. There are four ways of converting a block into a Proc object.
def method_with_block(p1, p2, &block) puts block.inspect end method_with_block(1,2) { 'a block' } => #Proc:0x007ff4a4663621@prog.rb:1 block = Proc.new { 'block' } => #Proc:0x007fd4a4064638@prog.rb:1 block = lambda { 'a block' } => #Proc:0x007f9d4c12c5c8@prog.rb:1 (lambda) lam = ->(p1, p2) { p1 + p2 } lam.call(4, 3) # => 7
def proc_method p = Proc.new { return 99 } p.call puts 'Never get here' end proc_method # => 99 def lambda_method p = lambda { return 99 } res = p.call puts "The block returned #{res}" end lambda_method # => "The block returned 99"
Metaprogramming — writing code that writes code. Most advanced Ruby programmers will use metaprogramming techniques to simplify their code.
Singletons - methods that are specific to a particular object.
animal = "cat" def animal.speak puts "The #{self} says miaow" end animal.speak
class Base def a_method puts "Got here" end private :a_method end class Derived1 < Base; end class Derived2 < Base public :a_method end
class Printer def print_a puts 'a' end private def print_b puts 'b' end end Printer.new.print_a => #a Printer.new.print_b => #NoMethodError: private method 'print_b' called Printer.new.send(:print_a) => #a Printer.new.send(:print_b) => #b
def method_missing(name, *args, &block) puts "Called #{name} with #{args.inspect} and #{block}" end wurble(3, 4) { stuff } => #Called wurble with [3, 4] and Proc:0x007fd7d910fb18@prog.rb:7
statuses = ['initial', 'active', 'canceled', 'expired'] statuses.each do |status| define_method(status) do puts "current status is #{status}" end end initial active ...
class MyCustomError < RuntimeError; end
begin #some code that may raise an exception rescue SyntaxError, NameError => boom print "String doesn't compile: " + boom rescue StandardError => bang print "Error running script: " + bang end
f = File.open("testfile") begin # .. process rescue # .. handle error ensure f.close end
raise => #RuntimeError Exception will be triggered raise 'bad mp3 encoding' raise InterfaceException, 'Keyboard failure', caller
word_list = File.open("wordlist") catch (:done) do result = [] while line = word_list.gets word = line.chomp throw :done unless word =~ /^\w+$/ result << word end puts result.reverse end
Created by Vasyl Lasiak / @vlasiak