Date post: | 28-Nov-2014 |
Category: |
Technology |
Upload: | matthieusegret |
View: | 4,772 times |
Download: | 3 times |
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