Skip to content

Instantly share code, notes, and snippets.

@cassj
Created November 19, 2010 15:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cassj/706651 to your computer and use it in GitHub Desktop.
Save cassj/706651 to your computer and use it in GitHub Desktop.
Trying to understand Proc objects, Proc.new, proc, lambda etc.
# 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