Upload
matthieusegret
View
4.779
Download
3
Embed Size (px)
DESCRIPTION
En tant que formateur Ruby, je rencontre régulièrement des développeurs manipulant les block, Proc et lambda sans toujours comprendre comment cela fonctionne. J'ai donc eu l'idée de faire cette présentation au Meetup Paris.rb. (10 décembre 2012)
Citation preview
Block, Proc and, lambda
2
Formateur Ruby on Rails @human_coders
Matthieu Segret
1
Block
3
Block
names.each do |name| puts name end
names.each { |name| puts name }
names = ["Matz","DHH","Aaron"]
4
yield
def call_this_block_twice yield yieldend
MatzMatzcall_this_block_twice { puts "Matz" }
5
def call_this_block yield("Matz")end
Matz
yield - Arguments
call_this_block {|name| puts name}
6
yield - Return value
def puts_this_block block_result = yield puts block_resultend
puts_this_block {"Matz"} Matz
7
def call_this_block yield("Matz")end
no block given
yield - Optional block
call_this_block
8
def call_this_block yield("Matz") if block_given?end
yield - Optional block
call_this_block
9
yield - Scope 1
def call_this_block yieldend
x = 5puts "value of x before: #{x}"call_this_block { x += 1 }puts "value of x after: #{x}" value of x after: 6
value of x before: 5
10
yield - Scope 2
def call_this_block x = 100 yield puts "value of x at end of call_this_block_x: #{x}"end
x = 5call_this_block { x += 1 }
puts "value of x after: #{x}" value of x after: 6
value of x at end of call_this_block_x: 100
11
{|name| puts name}
What if we wanted to store this block, for execution later?
12
Proc & lambda
13
Proc & lambda
my_proc = Proc.new {|x| puts x}my_proc.call("Matz")
Proc
Matz
my_lambda = lambda {|x| puts x}my_lambda.call("DHH")
Lambda
DHH
my_lambda = ->(x) {puts x}my_lambda.call("Aaron")
Lambda Ruby 1.9
Aaron
14
def bar f = lambda { return "return from inside lambda" } f.call return "return from bar" endputs bar
Lambda
def foo f = Proc.new { return "return from inside proc" } f.call return "return from foo" endputs foo
Proc
Proc vs lambda : return
return from bar
return from inside proc
15
Proc vs lambda : arity
my_proc = Proc.new {|x,y| puts "(#{x},#{y})"}my_proc.call(1,2,3)my_proc.call(1)
Proc
(1,2)(1,)
my_lambda = lambda {|x,y| puts "(#{x},#{y})"}my_lambda.call(1,2,3)my_lambda.call(1)
Lambda
wrong number of arguments ...
16
Multiple lambda
def post(success, error) ... if ... success.call else error.call end end
post(-> {puts "Sent!"}, -> {raise 'Auth Error'})
17
Lambda to block
names = ["Matz","DHH","Aaron"]names.each do |name| puts nameend
names = ["Matz","DHH","Aaron"]printer = lambda {|name| puts name}names.each( printer)& lambda to block
18
Proc to block
names = ["Matz","DHH","Aaron"]names.each do |name| puts nameend
names = ["Matz","DHH","Aaron"]printer = Proc.new {|name| puts name}names.each( printer)& Proc to block
19
Block to Proc
def call_this_block yield("Matz")end
def call_this_block(&block) block.call("Matz")end
block to Proc
20
Symbol#to_proc
tweets.map { |tweet| tweet.user }
tweets.map(&:user) Symbol to Proc
21
Method#to_proc
def method_user(tweet) tweet.userend
tweets.map(&method(:method_user)) Method to Proc
method(:method_user)
22
23
Thanks@matthieusegret
24