===== Proc =====
* ''Proc'' to anonimowa funkcja lub blok kodu,
* do metody można przesłać tylko jeden blok kodu, ale wiele ''Proc''ów,
* ''Proc.new'', jeśli nie poda mu się żadnych argumentów, przeszuka zakres zmiennych lokalnych danej metodzie:
#!/usr/bin/env ruby -wKU
def run_block
p = Proc.new
p.call
end
run_block do
puts "Hi, Marek!"
end
# Output
Hi, Marek!
* ''Proc'' może być wywołany na kilka sposobów:
proc = Proc.new do |adjective|
puts "Working with a Procs is #{adjective} pleasure!"
end
proc.call("great")
proc.("big") # = proc.call("big")
proc["enormous"]
proc === "all"
===== Lambda =====
* Lambdy to w zasadzie obiekty ''Proc'', zachowują się jednak nieco inaczej,
* Lamby wymuszają odpowiednią liczbę argumentów (//arity//):
welcome = proc do |a, b, c|
puts "This is a proc"
end
welcome.call # a, b i c ustawiane są jako nil
# Output
This is a proc
welcome = lambda do |a, b, c|
puts "This is a lambda"
end
welcome.call
# Output
/Users/sqbell/Workspace/ruby/others/procs.rb:10:in `block in ': wrong number of arguments (0 for 3) (ArgumentError)
from /Users/sqbell/Workspace/ruby/others/procs.rb:13:in `call'
from /Users/sqbell/Workspace/ruby/others/procs.rb:13:in `'
* ''return'' w ''Proc''u będzie wykonany w kontekscie definicji ''Proc''a:
#!/usr/bin/env ruby -wKU
def run_a_proc(p)
puts "Starting to run a proc."
p.call
puts "Finished running the proc.\n\n"
end
run_a_proc lambda { puts "I'm a lambda!"; return }
# Proc jest definiowany tutaj, czyli w głównym kontekscie
# a z głównego kontekstu nie można nic zwrócić
run_a_proc proc { puts "I'm just a proc. :-("; return }
# Output
/Users/sqbell/Workspace/ruby/others/procs.rb:10:in `block in ': unexpected return (LocalJumpError)
from /Users/sqbell/Workspace/ruby/others/procs.rb:5:in `call'
from /Users/sqbell/Workspace/ruby/others/procs.rb:5:in `run_a_proc'
from /Users/sqbell/Workspace/ruby/others/procs.rb:10:in `'
Starting to run a proc.
I'm a lambda!
Finished running the proc.
Starting to run a proc.
I'm just a proc. :-(
===== Closure =====
* Closure posiada referencje do zmiennych z kontekstu, w którym została zdefiniowana,
#!/usr/bin/env ruby -wKU
def run_proc(p)
p.call
end
name = "Marek"
print_a_name = proc { puts name }
name = "Krzysztof"
run_proc print_a_name
# Output
Krzysztof