blocks
Lachs Cox
11th April
block, aka
 closure            lambda
            proc

anonymous          first-class
 function           function
Ruby
 <3s
Blocks
1. Reiterating the
Wisdom of
Blocking
canonical use:
   iterator
     (cliché?)
Do something
with each element
   of an Array
an_array.each do |e|
  something
end
index = 0

['hello', 'world!'].each do |word|

  puts quot;#{index += 1} #{word}quot;

end
# >> 1 hello
# >> 2 world!
a block!
index = 0

['hello', 'world!'].each do |word|

  puts quot;#{index += 1} #{word}quot;

end
code container
code
index = 0

['hello', 'world!'].each do |word|

  puts quot;#{index += 1} #{word}quot;

end
block arguments
index = 0

['hello', 'world!'].each do |word|

  puts quot;#{index += 1} #{word}quot;

end
iterator = Proc.new do...end



       tangible
      (carry it in your pocket)
iterator = Proc.new do...end



       portable
      (carry it in your pocket)
refactor
index = 0

iterator = Proc.new do |word|

  puts quot;#{index += 1} #{word}quot;

end

['hello', 'world!'].each(&...
refactor
index = 0

iterator = Proc.new do |word|
                                 special
                               ...
remembers
  (its own state)
remembers
       (its own state)
(binding to creation context)
binding
index = 0

['hello', 'world!'].each do |word|

  puts quot;#{index += 1} #{word}quot;

end
self                local vars
['hello', 'world!'].each do |word|

  puts quot;#{index += 1} #{word}quot;

end
block

                      return
arguments    code
                       value


            binding
a block:
a portable code container
which remembers its state
  and creation context.
pssst...!
for word in words
  puts word
end

words.each do |word|
  puts word
end
equivalent
for word in words
  puts word
end

words.each do |word|
  puts word

identical
end
pssst...!



            binding
pssst...!
Kernel#binding
             binding



        (use it for evil)
2. TMTOWTDI
style
array.each {|word| puts word}



array.each do |word|
  puts word
  index += 1
end
Basics

    +
Syntax sugar.
Proc#new
 Kernel#proc
Kernel#lambda
block = Proc.new do |action|



  puts quot;#{self} #{action}s #{beer}quot;


end
block = lambda do |action|



  puts quot;#{self} #{action}s #{beer}quot;


end
Syntax sugar.
   (the real power)
def perform_action(action,block)
  block.call(action)
end

beer = quot;beez neezquot;

block = lambda do |action|
  puts q...
def perform_action(action)
  yield action
end

beer = quot;beez neezquot;

perform_action(:drink) do |action|
  puts quot;...
def perform_action(action,block)
  block.call(action)
end
def perform_action(action,&block)
  yield action if block_given?
end
def perform_action(action)
  yield action if block_given?
end
def perform_action(action)
  yield action
end
&
captures implicit
     blocks
&
def foo(...,&block)

     last arg
&
 def foo(...,&block)

      last arg
only one per method
def foo(&block)
  block.class # => Proc, Proc, Proc
  block.arity # => -1, 0, 1
end

foo { nil }
foo { || nil }
foo { |a| ...
nuances
go here
argument pattern matching
perform_action([:drink,:eat,:be_merry]) do |(a,*b)|
  a # => :drink
  b # => [:eat, :be_merry]
e...
3. The Building
   Blocks of a
  Perfect Meal
Roll your own
 Enumerable
Roll your own
      Enumerable
you implement each(&block)
Roll your own
         Enumerable
you implement each(&block)
def each(&block)
  (Hpricot(open(url)) / quot;aquot;)
    .ma...
Roll your own
         Enumerable
you implement each(&block)
 def each(&block)
   @brewery_visitor.rewind
   while brewery...
Roll your own
  Enumerable
include Enumerable
Roll your own
         Enumerable
     include Enumerable
           you get
all?, any?, collect, detect, each_cons, each_...
Customised Behaviour
       & Callbacks

class BeerController < ApplicationController
  append_before_filter do
    @beer ...
Refactoring
   Ideas
Refactoring
   Ideas
mixin module
Refactoring
   Ideas
 mixin module
extract subclass
Refactoring
    Ideas
  mixin module
 extract subclass
template pattern
Refactoring
    Ideas
  mixin module
 extract subclass
template pattern
  logic blocks
bonus 1
4. Yielding Secrets
      of Erb
def __render_...(local_vars)
                     # copy local vars


                         template
template
         ...
send(:__render..., local_assigns) do |*name|
  instance_variable_get quot;@content_for_#{name.first || 'layout'}quot;
end
...
bonus 2
  5. An Empirical
  Approach Using
     Text–mate
+
        xmpfilter              by mfp


http://eigenclass.org/hiki/rcodetools
explore
[:a,:b,:c].each do |c|

  c
  puts c

end
explore
[:a,:b,:c].each do |c|

  c # =>
  puts c # =>

end
#⇥

# =>
Execute and Update ‘# =>’ Markers


          ⌃⇧⌘E
explore
[:a,:b,:c].each do |c|

 c # => :a, :b, :c
 puts c # => nil, nil, nil

end
# >> a
# >> b
# >> c
Blocks by Lachs Cox
Blocks by Lachs Cox
Upcoming SlideShare
Loading in …5
×

Blocks by Lachs Cox

601 views
573 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
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
601
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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

×