User Tools

Site Tools


inf:ruby:procs

Table of Contents

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 <main>': 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 `<main>'
  • return w Procu będzie wykonany w kontekscie definicji Proca:
    #!/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 <main>': 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 `<main>'
    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
inf/ruby/procs.txt · Last modified: 2021/02/16 09:56 (external edit)