Created
November 19, 2010 15:35
-
-
Save cassj/706651 to your computer and use it in GitHub Desktop.
Trying to understand Proc objects, Proc.new, proc, lambda etc.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# see http://mng.iop.kcl.ac.uk/site/node/617 for more notes | |
def anonymous_block_test() | |
if block_given? | |
yield | |
end | |
end | |
anonymous_block_test do | |
puts "yield runs an anonymous block param" | |
end | |
# => yield runs an anonymous block param | |
def named_block_test(&ablock) | |
if block_given? | |
yield | |
end | |
end | |
named_block_test do | |
puts "yeild also runs a named block param" | |
end | |
# => yeild also runs a named block param | |
def named_block_proc_test(&ablock) | |
ablock.call | |
puts ablock.class | |
end | |
named_block_proc_test do | |
puts "named block params can be run with .call" | |
end | |
# => named block params can be run with .call | |
# => Proc | |
doubler = Proc.new {|n| n * 2 } | |
puts doubler.class | |
# => Proc | |
puts doubler.call(10) | |
# => 20 | |
doubler_lambda = lambda {|n| n * 2 } | |
puts doubler_lambda.class | |
# => Proc | |
puts doubler_lambda.call(10) | |
# => 20 | |
doubler_proc = proc {|n| n * 2 } | |
puts doubler_proc.class | |
# => Proc | |
puts doubler_proc.call(10) | |
# => 20 | |
test_proc = proc {|n| puts "I can haz #{n}?"} | |
test_lambda = lambda {|n| puts "I can haz #{n}?"} | |
test_proc.call("proc") | |
# => I can haz proc? | |
test_lambda.call("lambda") | |
# => I can haz lambda? | |
begin | |
test_proc.call() | |
rescue => e | |
puts "Can't haz proc!" | |
puts e.message | |
end | |
# => I can haz ? | |
begin | |
test_lambda.call() | |
rescue => e | |
puts "Can't haz lambda" | |
puts e.message | |
end | |
# => Can't haz lambda | |
# => wrong number of arguments (0 for 1) | |
begin | |
test_proc.call("one","two") | |
rescue => e | |
puts "Can't haz proc!" | |
puts e.message | |
end | |
# => I can haz one? | |
begin | |
test_lambda.call("one", "two") | |
rescue => e | |
puts "Can't haz lambda" | |
puts e.message | |
end | |
# => Can't haz lambda | |
# => wrong number of arguments (2 for 1) | |
def block_bind | |
yield | |
end | |
x = 10 | |
puts block_bind {x+=10} | |
# => 20 | |
def named_block_bind(&prc) | |
prc.call() | |
end | |
puts named_block_bind {x +=10 } | |
# => 30 | |
def test_with_var | |
x = 100 | |
yield | |
puts "inner x: #{x}" | |
# => still 100, the block refers to its own x | |
end | |
x = 10 | |
test_with_var { x += 10} | |
puts "outer x: #{x}" | |
# => 20 | |
def proc_bind(param) | |
return Proc.new {} | |
end | |
param = "param value in calling context" | |
pb = proc_bind("param value in creation context") | |
puts eval("param", pb.binding) | |
# => param value in creation context | |
proc_returner = Proc.new {return} | |
begin | |
proc_returner.call() | |
puts "after calling return in a proc" | |
rescue => e | |
puts "Fails" | |
puts e.message | |
puts e.backtrace | |
end | |
# => Fails | |
# => unexpected return | |
# => ruby_proc_test.rb:209:in `block in <main>' | |
# => ruby_proc_test.rb:212:in `call' | |
# => ruby_proc_test.rb:212:in `<main>' | |
def return_test | |
proc_returner = Proc.new{ | |
puts caller() # just to show where we are | |
return()} | |
begin | |
proc_returner.call() | |
puts "Never gets here, the return in the Proc returns from the method" | |
rescue => e | |
puts "Fails" | |
puts e.message | |
end | |
end | |
return_test | |
# => ruby_proc_test.rb:234:in `call' | |
# => ruby_proc_test.rb:234:in `return_test' | |
# => ruby_proc_test.rb:241:in `<main>' | |
def return_test_two(prc) | |
begin | |
prc.call() | |
puts "After calling proc" | |
rescue => e | |
puts "Fails" | |
puts e.message | |
puts e.backtrace | |
end | |
end | |
return_test_two(proc_returner) | |
# => Fails | |
# => unexpected return | |
# => ruby_proc_test.rb:210:in `block in <main>' #block is in <main> not in return_test_two | |
# => ruby_proc_test.rb:255:in `call' | |
# => ruby_proc_test.rb:255:in `return_test_two' | |
# => ruby_proc_test.rb:263:in `<main>' | |
def make_a_returner | |
return Proc.new {return()} | |
end | |
prc = make_a_returner | |
begin | |
prc.call | |
rescue => e | |
puts "Fails" | |
puts e.message | |
puts e.backtrace | |
end | |
# => Fails | |
# => unexpected return | |
# => ruby_proc_test.rb:277:in `block in make_a_returner' #can't return from here, we're in <main> | |
# => ruby_proc_test.rb:281:in `call' | |
# => ruby_proc_test.rb:281:in `<main>' | |
def lambda_return_test | |
returner = lambda{return()} | |
begin | |
returner.call() | |
puts "returns from lambda and continues in method" | |
rescue => e | |
puts "Fails" | |
puts e.message | |
end | |
end | |
lambda_return_test | |
# => return() from the lambda scope and carries on | |
lam = lambda {return()} | |
def lambda_return_test_two(lam) | |
begin | |
lam.call() | |
puts "returns from lambda and continues in method" | |
rescue => e | |
puts "Fails" | |
puts e.message | |
puts e.backtrace | |
end | |
end | |
lambda_return_test_two(lam) | |
# => returns from lambda and continues in method | |
x = 1 | |
y = 1 | |
loop {|x| | |
x = 10 | |
y = 10 | |
break} | |
p x #=> 1 | |
p y #=> 10 | |
x = 10 | |
prc = Proc.new {puts x+5} | |
lam = lambda {puts x+5} | |
prc.call | |
# => 15 | |
lam.call | |
# => 15 | |
p x | |
# => 10 | |
prc = Proc.new {puts x+=5} | |
lam = lambda {puts x+=5} | |
prc.call | |
# => 15 | |
lam.call | |
# => 20 | |
p x | |
# => 20 | |
prc = Proc.new {|x| puts x+=5} | |
lam = lambda {|x| puts x+=5} | |
prc.call(x) | |
# => 25 | |
lam.call(x) | |
# => 25 | |
p x | |
# => 20 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment