Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Blocks by Lachs Cox

710 views

Published on

A beginner's guide to Ruby blocks. It might be a bit hard to follow w/o the talk to go along with it.

From April 2007

Published in: Technology, Business
  • Be the first to comment

  • Be the first to like this

Blocks by Lachs Cox

  1. 1. blocks Lachs Cox 11th April
  2. 2. block, aka closure lambda proc anonymous first-class function function
  3. 3. Ruby <3s Blocks
  4. 4. 1. Reiterating the Wisdom of Blocking
  5. 5. canonical use: iterator (cliché?)
  6. 6. Do something with each element of an Array
  7. 7. an_array.each do |e| something end
  8. 8. index = 0 ['hello', 'world!'].each do |word| puts quot;#{index += 1} #{word}quot; end
  9. 9. # >> 1 hello # >> 2 world!
  10. 10. a block! index = 0 ['hello', 'world!'].each do |word| puts quot;#{index += 1} #{word}quot; end
  11. 11. code container
  12. 12. code index = 0 ['hello', 'world!'].each do |word| puts quot;#{index += 1} #{word}quot; end
  13. 13. block arguments index = 0 ['hello', 'world!'].each do |word| puts quot;#{index += 1} #{word}quot; end
  14. 14. iterator = Proc.new do...end tangible (carry it in your pocket)
  15. 15. iterator = Proc.new do...end portable (carry it in your pocket)
  16. 16. refactor index = 0 iterator = Proc.new do |word| puts quot;#{index += 1} #{word}quot; end ['hello', 'world!'].each(&iterator)
  17. 17. refactor index = 0 iterator = Proc.new do |word| special syntax puts quot;#{index += 1} #{word}quot; end ['hello', 'world!'].each(&iterator)
  18. 18. remembers (its own state)
  19. 19. remembers (its own state) (binding to creation context)
  20. 20. binding index = 0 ['hello', 'world!'].each do |word| puts quot;#{index += 1} #{word}quot; end
  21. 21. self local vars ['hello', 'world!'].each do |word| puts quot;#{index += 1} #{word}quot; end
  22. 22. block return arguments code value binding
  23. 23. a block: a portable code container which remembers its state and creation context.
  24. 24. pssst...! for word in words puts word end words.each do |word| puts word end
  25. 25. equivalent for word in words puts word end words.each do |word| puts word identical end
  26. 26. pssst...! binding
  27. 27. pssst...! Kernel#binding binding (use it for evil)
  28. 28. 2. TMTOWTDI
  29. 29. style array.each {|word| puts word} array.each do |word| puts word index += 1 end
  30. 30. Basics + Syntax sugar.
  31. 31. Proc#new Kernel#proc Kernel#lambda
  32. 32. block = Proc.new do |action| puts quot;#{self} #{action}s #{beer}quot; end
  33. 33. block = lambda do |action| puts quot;#{self} #{action}s #{beer}quot; end
  34. 34. Syntax sugar. (the real power)
  35. 35. def perform_action(action,block) block.call(action) end beer = quot;beez neezquot; block = lambda do |action| puts quot;#{self} #{action}s #{beer}quot; end perform_action(:drink,block) # >> main drinks beez neez
  36. 36. def perform_action(action) yield action end beer = quot;beez neezquot; perform_action(:drink) do |action| puts quot;#{self} #{action}s #{beer}quot; end # >> main drinks beez neez
  37. 37. def perform_action(action,block) block.call(action) end
  38. 38. def perform_action(action,&block) yield action if block_given? end
  39. 39. def perform_action(action) yield action if block_given? end
  40. 40. def perform_action(action) yield action end
  41. 41. & captures implicit blocks
  42. 42. & def foo(...,&block) last arg
  43. 43. & def foo(...,&block) last arg only one per method
  44. 44. def foo(&block) block.class # => Proc, Proc, Proc block.arity # => -1, 0, 1 end foo { nil } foo { || nil } foo { |a| nil }
  45. 45. nuances go here
  46. 46. argument pattern matching perform_action([:drink,:eat,:be_merry]) do |(a,*b)| a # => :drink b # => [:eat, :be_merry] end perform_action([:ignore,:regard]) do |(_,a)| a # => :regard end
  47. 47. 3. The Building Blocks of a Perfect Meal
  48. 48. Roll your own Enumerable
  49. 49. Roll your own Enumerable you implement each(&block)
  50. 50. Roll your own Enumerable you implement each(&block) def each(&block) (Hpricot(open(url)) / quot;aquot;) .map {|a| a['href']} .each(&block) end
  51. 51. Roll your own Enumerable you implement each(&block) def each(&block) @brewery_visitor.rewind while brewery = @brewery_visitor.next yield brewery end end
  52. 52. Roll your own Enumerable include Enumerable
  53. 53. Roll your own Enumerable include Enumerable you get all?, any?, collect, detect, each_cons, each_slice, each_with_index, entries, enum_cons, enum_slice, enum_with_index, find, find_all, grep, include?, inject, map, max, member?, min, partition, reject, select, sort, sort_by, to_a, to_set, zip
  54. 54. Customised Behaviour & Callbacks class BeerController < ApplicationController append_before_filter do @beer = Beer.find(params[:id]) end end
  55. 55. Refactoring Ideas
  56. 56. Refactoring Ideas mixin module
  57. 57. Refactoring Ideas mixin module extract subclass
  58. 58. Refactoring Ideas mixin module extract subclass template pattern
  59. 59. Refactoring Ideas mixin module extract subclass template pattern logic blocks
  60. 60. bonus 1 4. Yielding Secrets of Erb
  61. 61. def __render_...(local_vars) # copy local vars template template Erb code rhtml String end render eval template method
  62. 62. send(:__render..., local_assigns) do |*name| instance_variable_get quot;@content_for_#{name.first || 'layout'}quot; end <%= yield %> # => @content_for_layout <%= yield :clean %> # => @content_for_clean <%= yield :clean, :dirty %> # => @content_for_clean
  63. 63. bonus 2 5. An Empirical Approach Using Text–mate
  64. 64. + xmpfilter by mfp http://eigenclass.org/hiki/rcodetools
  65. 65. explore [:a,:b,:c].each do |c| c puts c end
  66. 66. explore [:a,:b,:c].each do |c| c # => puts c # => end
  67. 67. #⇥ # =>
  68. 68. Execute and Update ‘# =>’ Markers ⌃⇧⌘E
  69. 69. explore [:a,:b,:c].each do |c| c # => :a, :b, :c puts c # => nil, nil, nil end # >> a # >> b # >> c

×