# Kim Persson ![Kim](https://raw.github.com/Lavinia/iYield/master/noting.png "Noting") .center[Github: [Lavinia](https://github.com/Lavinia/) Twitter: [@Lavinia666](https://twitter.com/Lavinia666) Ruby developer at Barsoom: [http://barsoom.se](http://barsoom.se)] --- # Nemah ## A real princess with a ###gigantic ## apetite ![Nemah](https://raw.github.com/Lavinia/iYield/master/Nemah.jpg "Om nom nom") --- # Rails ## layouts/application.html.erb ```ruby
Rubytalk
<%= stylesheet_link_tag "application", media: "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> <%= yield %> ``` --- # WAT !?? ![Nemah](https://raw.github.com/Lavinia/iYield/master/NemahNom.jpg "Om nom nom") --- # Blocks ```ruby hungry_horse { puts 'Omnomnom...' } hungry_horse do puts 'Omnomnom...' end def hungry_horse yield end ``` ```ruby # 'Omnomnom...' ``` --- # Blocks ## (cont.) ```ruby def doubler(number) yield number * 2 puts "doubled!" end doubler(5) do |result| puts result end ``` ```ruby # 10 # doubled! ``` --- # Blocks ## precedence ```ruby doubler 5 do |result| puts result end ``` ```ruby # 10 ``` --- # Blocks ## precedence ```ruby doubler 5 do |result| puts result end ``` ```ruby # 10 ``` ```ruby doubler 5 { |result| puts result } ``` ```ruby # SyntaxError: (irb):5: syntax error, unexpected '{', # expecting end-of-input ``` --- # Blocks ## (cont.) ```ruby def method_that_can_go_horribly_wrong #... raise StandardError, "OUCH!" rescue => error yield error end method_that_can_go_horribly_wrong do |error| #some error handling code end ``` --- # Blocks ## (cont.) ```ruby def method_that_can_go_horribly_wrong #... raise StandardError, "OUCH!" rescue => error yield error end method_that_can_go_horribly_wrong ``` ```ruby # LocalJumpError: no block given (yield) ``` --- # Blocks ## (cont.) ```ruby def method_that_can_go_horribly_wrong #... raise StandardError, "OUCH!" rescue => error yield error if block_given? end method_that_can_go_horribly_wrong do |error| #some error handling code end ``` --- # Blocks ## (cont.) ```ruby def method_that_can_go_horribly_wrong #... raise StandardError, "OUCH!" rescue => error if block_given? yield error else raise #reraise last error end end method_that_can_go_horribly_wrong do |error| #some error handling code end ``` --- # Proc ```ruby error_handler = Proc.new { |error| # error handling code... } error_handler = proc do |error| # error handling code... end ``` --- # Proc ```ruby error_handler = proc do |error| # error handling code... end def method_that_can_go_horribly_wrong(error_handler) #... raise StandardError, "OUCH!" rescue => error error_handler.call(error) end method_that_can_go_horribly_wrong(error_handler) ``` --- # Proc ```ruby error_handler = proc do |error| # error handling code... end def method_that_can_go_horribly_wrong(error_handler) #... raise StandardError, "OUCH!" rescue => error error_handler.call(error) end method_that_can_go_horribly_wrong(error_handler) ``` ```ruby error_handler.call(error) error_handler.yield(error) error_handler.(error) error_handler[error] ``` --- # Proc ## proc to block ```ruby error_handler = Proc.new { |error| # error handling code... } def method_that_can_go_horribly_wrong #... raise StandardError, "OUCH!" rescue => error if block_given? yield error else raise end end method_that_can_go_horribly_wrong(&error_handler) ``` --- # Proc ## #to_proc ```ruby [1,2,3].inject(&:+) ``` ```ruby # 6 ``` --- # Proc ## #to_proc ```ruby [1,2,3].inject(&:+) ``` ```ruby # 6 ``` ```ruby [1,2,3].inject do |sum, number| sum + number end ``` --- # Proc ## block to proc ```ruby def method_that_can_go_horribly_wrong(&error_handler) #... raise StandardError, "OUCH!" rescue => error error_handler.call(error) end method_that_can_go_horribly_wrong do |error| #some error handling code end ``` --- # Proc ```ruby null_value? = proc { |value| value.nil? } null_value?.call() ``` ```ruby # true ``` --- # Lambda ```ruby proc {} # #
lambda {} # #
``` --- # Lambda ```ruby proc {} # #
lambda {} # #
``` ```ruby feed = ->(horse, fodder) do puts "Feeding #{horse} with #{fodder}" end feed.call('Nemah') ``` ```ruby # ArgumentError: wrong number of arguments (1 for 2) ``` --- # Proc and Lambda ## utility methods ```ruby feed.arity ``` ```ruby # 2 ``` --- # Proc and Lambda ## utility methods ```ruby feed.arity ``` ```ruby # 2 ``` ```ruby feed.lambda? ``` ```ruby # true ``` --- # Proc and Lambda ## utility methods ```ruby lambda { |mandatory, optional = 1, *other| code }.parameters ``` ```ruby # [[:req, :mandatory], [:opt, :optional], [:rest, :other]] ``` --- # Proc and Lambda ## utility methods ```ruby lambda { |mandatory, optional = 1, *other| code }.parameters ``` ```ruby # [[:req, :mandatory], [:opt, :optional], [:rest, :other]] ``` ```ruby proc { |mandatory, optional = 1, *other| code }.parameters ``` ```ruby # [[:opt, :mandatory], [:opt, :optional], [:rest, :other]] ``` --- # Proc and Lambda ## break ```ruby printer = lambda do |x| puts x break end printer.call('Hi') ``` ```ruby # Hi ``` --- # Proc and Lambda ## break ```ruby printer = lambda do |x| puts x break end printer.call('Hi') ``` ```ruby # Hi ``` ```ruby printer = proc do |x| puts x break end printer.call('Hi') ``` ```ruby # Hi # LocalJumpError: break from proc-closure ``` --- # Proc and Lambda ## break and iterators ```ruby printer = proc do |x| puts x break end (1..3).each { |i| printer.call(i) } ``` ```ruby # 1 ``` --- # Proc and Lambda ## break and iterators ```ruby printer = proc do |x| puts x break end (1..3).each { |i| printer.call(i) } ``` ```ruby # 1 ``` ```ruby printer = lambda do |x| puts x break end (1..3).each { |i| printer.call(i) } ``` ```ruby # 1 # 2 # 3 ``` --- # Proc and Lambda ## return ```ruby def greeting_commander_riker name = proc { return 1 }.call puts "Hi there number #{name}!" end ``` ```ruby # 1 ``` --- # Proc and Lambda ## return ```ruby def greeting_commander_riker name = proc { return 1 }.call puts "Hi there number #{name}!" end ``` ```ruby # 1 ``` ```ruby def greeting_commander_riker name = lambda { return 1 }.call puts "Hi there number #{name}!" end ``` ```ruby # 'Hi there number 1!' ``` --- # Closures ```ruby def method_that_can_go_horribly_wrong(error_handler) # ... raise StandardError, "OUCH!" rescue => error error_handler.call(error) end ``` --- # Closures ```ruby def method_that_can_go_horribly_wrong(error_handler) # ... raise StandardError, "OUCH!" rescue => error error_handler.call(error) end class MagicLogger def self.logger(header_message) magic_logger = new lambda { |error| magic_logger.log(header_message, error) } end def log(header_message, error) puts header_message puts error.message end end error_handler = MagicLogger.logger('Something went wrong!') method_that_can_go_horribly_wrong(error_handler) ``` --- # We started with this... ```ruby
Rubytalk
<%= stylesheet_link_tag "application", media: "all" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> <%= yield %> ``` --- # WAT!?? ![Nemah](https://raw.github.com/Lavinia/iYield/master/NemahNom.jpg "Om nom nom") --- # ...and we still might feel a bit like WAT!?? ![Nemah](https://raw.github.com/Lavinia/iYield/master/NemahNom.jpg "Om nom nom") --- class: center, middle, white ![Barsoom](http://barsoom.se/barsoom.png) We are hiring! => [http://barsoom.se/job](http://barsoom.se/job) --- More on blocks, procs and lambdas: [http://www.codecademy.com/courses/ruby-beginner-en-L3ZCI/0/1](http://www.codecademy.com/courses/ruby-beginner-en-L3ZCI/0/1) [http://www.skorks.com/2010/05/ruby-procs-and-lambdas-and-the-difference-between-them/](http://www.skorks.com/2010/05/ruby-procs-and-lambdas-and-the-difference-between-them/)