Presentation is loading. Please wait.

Presentation is loading. Please wait.

Robert W. Hasker, 2011-2016.  Previous uses of blocks  words.each { |w| puts “word: #{w}” }  words.find { |x| x.size > 2 }  words.select { |x| x.size.

Similar presentations


Presentation on theme: "Robert W. Hasker, 2011-2016.  Previous uses of blocks  words.each { |w| puts “word: #{w}” }  words.find { |x| x.size > 2 }  words.select { |x| x.size."— Presentation transcript:

1 Robert W. Hasker, 2011-2016

2  Previous uses of blocks  words.each { |w| puts “word: #{w}” }  words.find { |x| x.size > 2 }  words.select { |x| x.size % 2 == 0 }  Another use: infinite computations  Open irb and type nats = 0..(1.0/0) nats.take(100) nats.step(2).first(10)  Skipping: nats.step(2).lazy.drop(50).first(10) Blocked

3  Previous uses of blocks  words.each { |w| puts “word: #{w}” }  words.find { |x| x.size > 2 }  words.select { |x| x.size % 2 == 0 }  Another use: infinite computations  Open irb and type nats = 0..(1.0/0) nats.take(100) nats.step(2).first(10)  Skipping: nats.step(2).lazy.drop(50).first(10) Blocked Lazy list

4 Uses of infinity  squares = nats.lazy.map { |n| n * n }  Prime numbers:  require ‘prime’  Prime.first(10)  Prime.lazy.drop(1000). select { |x| (x+1)%3 == 0 }.first(5)

5 How does this work?  Ruby code to delay evaluation: class Promise def initialize(&block) @block = block @delayed = true end def force @value = @block.call if @delayed @delayed = false @value end

6 How does this work?  In general:  Delay: promise to provide value when requested  Force: call in the promise  Processing list:  force head when required, delay rest  Ruby implementation: blocks  Useful tool when want to delay execution in general

7 Yet more blockhead actions  Computing Fibonacci numbers: fibonacci = Hash.new{ |h,k| h[k] = k < 2 ? k : h[k-1] + h[k-2] }  From Ruby documentation:  If a block is specified, it will be called with the hash object and the key, and should return the default value. It is the block’s responsibility to store the value in the hash if required.

8 Using blocks creatively  From Eloquent Ruby by Russ Olsen, 2011  How to log events smoothly?  Consider: class WonderApplication def do_something doc = Document.load ‘masterwork.txt’ … doc.save end

9 Adding logging class WonderApplication def initialize(logger) @logger = logger end def do_something @logger.post ‘Starting load’ doc = Document.load ‘masterwork.txt’ @logger.post ‘Completed load’ … @logger.post ‘Starting save’ doc.save @logger.post ‘Completed save’ end

10 And rescues… def do_something begin @logger.post ‘Starting load’ doc = Document.load ‘masterwork.txt’ @logger.post ‘Completed load’ rescue @logger.post ‘Load failed’; raise end … begin @logger.post ‘Starting save’ doc.save @logger.post ‘Completed save’ rescue @logger.post ‘Save failed’; raise end

11 Fix: def with_logging(description) begin @logger.post “Starting #{description}” yield @logger.post “Completed #{description}” rescue @logger.post “#{description} failed”; raise end def do_something with_logging(‘load’) { @doc = Document.load ‘masterwork.txt’ } … with_logging(‘save’) { @doc.save } end

12 Fix: def with_logging(description) begin @logger.post “Starting #{description}” yield @logger.post “Completed #{description}” rescue @logger.post “#{description} failed”; raise end def do_something with_logging(‘load’) { @doc = Document.load ‘masterwork.txt’ } … with_logging(‘save’) { @doc.save } end “Execute around”

13 Blocks and initialization  Basic concept behind lazy lists: delayed initialization  Consider: class ArchivalDocument attr_reader :title, :author def initialize(title, author, path) @title = title @author = author @path = path end def content @content = @content || File.read(path) end

14 Blocks and initialization  Basic concept behind lazy lists: delayed initialization  Consider: class ArchivalDocument attr_reader :title, :author def initialize(title, author, path) @title = title @author = author @path = path end def content @content = @content || File.read(path) end

15 Blocks and initialization  Basic concept behind lazy lists: delayed initialization  Consider: class ArchivalDocument attr_reader :title, :author def initialize(title, author, path) @title = title @author = author @path = path end def content @content = @content || File.read(path) end

16 Blocks to the rescue: class ArchivalDocument attr_reader :title, :author def initialize(title, author, &reader_block) @title = title @author = author @reader = reader_block end def content if @reader @content = @reader.call @reader = nil end @content end

17 Usage simple_file_doc = ArchivalDocument.new(‘Rubies Forever’, ‘Tim’) do File.read(‘c:/books/rubies_forever.txt’) end google_doc = ArchivalDocument.new(‘Sherlock Holmes’, ‘Conan Doyle’) do Net::HTTP.get_response(‘books.google.com’, ‘/books?id=QhPgEq5ZeY8C’).body end boring_doc = ArchivalDocument.new(‘silly’, ‘Rob’) do ‘Ya’ * 100 end

18 Summary  Infinite ranges, lists  Generating streams  Execute around  Embed computations in a context  Lazy initialization  Application of lazy list concept to initialization  Basic principles:  Delayed execution  Stored behaviors


Download ppt "Robert W. Hasker, 2011-2016.  Previous uses of blocks  words.each { |w| puts “word: #{w}” }  words.find { |x| x.size > 2 }  words.select { |x| x.size."

Similar presentations


Ads by Google