In Files

    • proc.c

    Parent

    Class/Module Index [+]

    Quicksearch
    No matching classes.

    Proc

    A Proc object is an encapsulation of a block of code, which can be stored in a local variable, passed to a method or another , and can be called. is an essential concept in Ruby and a core of its functional programming features.

    square = Proc.new {|x| x**2 }
    square.call(3) #=> 9
    # shorthands:
    square.(3) #=> 9
    square[3] #=> 9
    

    objects are closures, meaning they remember and can use the entire context in which they were created.

    def gen_times(factor)
     Proc.new {|n| n*factor } # remembers the value of factor at the moment of creation
    end
    times3 = gen_times(3)
    times5 = gen_times(5)
    times3.call(12) #=> 36
    times5.call(5) #=> 25
    times3.call(times5.call(4)) #=> 60
    

    Creation

    There are several methods to create a

    • Use the class constructor:

      proc1 = Proc.new {|x| x**2 }
      
    • Use the method as a shorthand of :

      proc2 = proc {|x| x**2 }
      
    • Receiving a block of code into proc argument (note the &):

      def make_proc(&block)
       block
      end
      proc3 = make_proc {|x| x**2 }
      
    • Construct a proc with lambda semantics using the method (see below for explanations about lambdas):

      lambda1 = lambda {|x| x**2 }
      
    • Use the Lambda literal syntax (also constructs a proc with lambda semantics):

      lambda2 = ->(x) { x**2 }
      

    Lambda and non-lambda semantics

    Procs are coming in two flavors: lambda and non-lambda (regular procs). Differences are:

    • In lambdas, return means exit from this lambda;

    • In regular procs, return means exit from embracing method (and will throw LocalJumpError if invoked outside the method);

    • In lambdas, arguments are treated in the same way as in methods: strict, with ArgumentError for mismatching argument number, and no additional argument processing;

    • Regular procs accept arguments more generously: missing arguments are filled with nil, single arguments are deconstructed if the proc has multiple arguments, and there is no error raised on extra arguments.

    Examples:

    p = proc {|x, y| "x=#{x}, y=#{y}" }
    p.call(1, 2) #=> "x=1, y=2"
    p.call([1, 2]) #=> "x=1, y=2", array deconstructed
    p.call(1, 2, 8) #=> "x=1, y=2", extra argument discarded
    p.call(1) #=> "x=1, y=", nil substituted instead of error
    l = lambda {|x, y| "x=#{x}, y=#{y}" }
    l.call(1, 2) #=> "x=1, y=2"
    l.call([1, 2]) # ArgumentError: wrong number of arguments (given 1, expected 2)
    l.call(1, 2, 8) # ArgumentError: wrong number of arguments (given 3, expected 2)
    l.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
    def test_return
     -> { return 3 }.call # just returns from lambda into method body
     proc { return 4 }.call # returns from method
     return 5
    end
    test_return # => 4, return from proc
    

    Lambdas are useful as self-sufficient functions, in particular useful as arguments to higher-order functions, behaving exactly like Ruby methods.

    Procs are useful for implementing iterators:

    def test
     [[1, 2], [3, 4], [5, 6]].map {|a, b| return a if a + b > 10 }
     # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    end
    

    Inside map, the block of code is treated as a regular (non-lambda) proc, which means that the internal arrays will be deconstructed to pairs of arguments, and return will exit from the method test. That would not be possible with a stricter lambda.

    You can tell a lambda from a regular proc by using the instance method.

    Lambda semantics is typically preserved during the proc lifetime, including &-deconstruction to a block of code:

    p = proc {|x, y| x }
    l = lambda {|x, y| x }
    [[1, 2], [3, 4]].map(&p) #=> [1, 2]
    [[1, 2], [3, 4]].map(&l) # ArgumentError: wrong number of arguments (given 1, expected 2)
    

    The only exception is dynamic method definition: even if defined by passing a non-lambda proc, methods still have normal semantics of argument checking.

    class C
     define_method(:e, &proc {})
    end
    C.new.e(1,2) #=> ArgumentError
    C.new.method(:e).to_proc.lambda? #=> true
    

    This exception ensures that methods never have unusual argument passing conventions, and makes it easy to have wrappers defining methods that behave as usual.

    class C
     def self.def2(name, &body)
     define_method(name, &body)
     end
     def2(:f) {}
    end
    C.new.f(1,2) #=> ArgumentError
    

    The wrapper def2 receives body as a non-lambda proc, yet defines a method which has normal semantics.

    Conversion of other objects to procs

    Any object that implements the to_proc method can be converted into a proc by the & operator, and therefore con be consumed by iterators.

    class Greater
     def initialize(greating)
     @greating = greating
     end
     def to_proc
     proc {|name| "#{@greating}, #{name}!" }
     end
    end
    hi = Greater.new("Hi")
    hey = Greater.new("Hey")
    ["Bob", "Jane"].map(&hi) #=> ["Hi, Bob!", "Hi, Jane!"]
    ["Bob", "Jane"].map(&hey) #=> ["Hey, Bob!", "Hey, Jane!"]
    

    Of the Ruby core classes, this method is implemented by , , and .

    :to_s.to_proc.call(1) #=> "1"
    [1, 2].map(&:to_s) #=> ["1", "2"]
    method(:puts).to_proc.call(1) # prints 1
    [1, 2].each(&method(:puts)) # prints 1, 2
    {test: 1}.to_proc.call(:test) #=> 1
    %i[test many keys].map(&{test: 1}) #=> [1, nil, nil]
    

    Public Class Methods

    new {|...| block } → a_proc click to toggle source
    new → a_proc

    Creates a new Proc object, bound to the current context. Proc::new may be called without a block only within a method with an attached block, in which case that block is converted to the Proc object.

    def proc_from
     Proc.new
    end
    proc = proc_from { "hello" }
    proc.call #=> "hello"
    
     static VALUE
    rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
    {
     VALUE block = proc_new(klass, FALSE);
     rb_obj_call_init(block, argc, argv);
     return block;
    }
     

    Public Instance Methods

    prc << g → a_proc click to toggle source

    Returns a proc that is the composition of this proc and the given g. The returned proc takes a variable number of arguments, calls g with them then calls this proc with the result.

    f = proc {|x| x * x }
    g = proc {|x| x + x }
    p (f << g).call(2) #=> 16
    
     static VALUE
    proc_compose_to_left(VALUE self, VALUE g)
    {
     VALUE proc, args, procs[2];
     rb_proc_t *procp;
     int is_lambda;
     procs[0] = self;
     procs[1] = g;
     args = rb_ary_tmp_new_from_values(0, 2, procs);
     GetProcPtr(self, procp);
     is_lambda = procp->is_lambda;
     proc = rb_proc_new(compose, args);
     GetProcPtr(proc, procp);
     procp->is_lambda = is_lambda;
     return proc;
    }
     
    proc === obj → result_of_proc click to toggle source

    Invokes the block with obj as the proc's parameter like . This allows a proc object to be the target of a when clause in a case statement.

     static VALUE
    proc_call(int argc, VALUE *argv, VALUE procval)
    {
     /* removed */
    }
     
    prc >> g → a_proc click to toggle source

    Returns a proc that is the composition of this proc and the given g. The returned proc takes a variable number of arguments, calls g with them then calls this proc with the result.

    f = proc {|x| x * x }
    g = proc {|x| x + x }
    p (f >> g).call(2) #=> 8
    
     static VALUE
    proc_compose_to_right(VALUE self, VALUE g)
    {
     VALUE proc, args, procs[2];
     rb_proc_t *procp;
     int is_lambda;
     procs[0] = g;
     procs[1] = self;
     args = rb_ary_tmp_new_from_values(0, 2, procs);
     GetProcPtr(self, procp);
     is_lambda = procp->is_lambda;
     proc = rb_proc_new(compose, args);
     GetProcPtr(proc, procp);
     procp->is_lambda = is_lambda;
     return proc;
    }
     
    prc[params,...] → obj click to toggle source

    Invokes the block, setting the block's parameters to the values in params using something close to method calling semantics. Returns the value of the last expression evaluated in the block.

    a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
    a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
    a_proc[9, 1, 2, 3] #=> [9, 18, 27]
    a_proc.(9, 1, 2, 3) #=> [9, 18, 27]
    a_proc.yield(9, 1, 2, 3) #=> [9, 18, 27]
    

    Note that prc.() invokes prc.call() with the parameters given. It's syntactic sugar to hide "call".

    For procs created using lambda or ->() an error is generated if the wrong number of parameters are passed to the proc. For procs created using Proc.new or Kernel.proc, extra parameters are silently discarded and missing parameters are set to nil.

    a_proc = proc {|a,b| [a,b] }
    a_proc.call(1) #=> [1, nil]
    a_proc = lambda {|a,b| [a,b] }
    a_proc.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
    

    See also .

     static VALUE
    proc_call(int argc, VALUE *argv, VALUE procval)
    {
     /* removed */
    }
     
    arity → integer click to toggle source

    Returns the number of mandatory arguments. If the block is declared to take no arguments, returns 0. If the block is known to take exactly n arguments, returns n. If the block has optional arguments, returns -n-1, where n is the number of mandatory arguments, with the exception for blocks that are not lambdas and have only a finite number of optional arguments; in this latter case, returns n. Keyword arguments will be considered as a single additional argument, that argument being mandatory if any keyword argument is mandatory. A proc with no argument declarations is the same as a block declaring || as its arguments.

    proc {}.arity #=> 0
    proc { || }.arity #=> 0
    proc { |a| }.arity #=> 1
    proc { |a, b| }.arity #=> 2
    proc { |a, b, c| }.arity #=> 3
    proc { |*a| }.arity #=> -1
    proc { |a, *b| }.arity #=> -2
    proc { |a, *b, c| }.arity #=> -3
    proc { |x:, y:, z:0| }.arity #=> 1
    proc { |*a, x:, y:0| }.arity #=> -2
    proc { |a=0| }.arity #=> 0
    lambda { |a=0| }.arity #=> -1
    proc { |a=0, b| }.arity #=> 1
    lambda { |a=0, b| }.arity #=> -2
    proc { |a=0, b=0| }.arity #=> 0
    lambda { |a=0, b=0| }.arity #=> -1
    proc { |a, b=0| }.arity #=> 1
    lambda { |a, b=0| }.arity #=> -2
    proc { |(a, b), c=0| }.arity #=> 1
    lambda { |(a, b), c=0| }.arity #=> -2
    proc { |a, x:0, y:0| }.arity #=> 1
    lambda { |a, x:0, y:0| }.arity #=> -2
    
     static VALUE
    proc_arity(VALUE self)
    {
     int arity = rb_proc_arity(self);
     return INT2FIX(arity);
    }
     
    binding → binding click to toggle source

    Returns the binding associated with prc.

    def fred(param)
     proc {}
    end
    b = fred(99)
    eval("param", b.binding) #=> 99
    
     static VALUE
    proc_binding(VALUE self)
    {
     VALUE bindval, binding_self = Qundef;
     rb_binding_t *bind;
     const rb_proc_t *proc;
     const rb_iseq_t *iseq = NULL;
     const struct rb_block *block;
     const rb_env_t *env = NULL;
     GetProcPtr(self, proc);
     block = &proc->block;
     again:
     switch (vm_block_type(block)) {
     case block_type_iseq:
     iseq = block->as.captured.code.iseq;
     binding_self = block->as.captured.self;
     env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
     break;
     case block_type_proc:
     GetProcPtr(block->as.proc, proc);
     block = &proc->block;
     goto again;
     case block_type_symbol:
     goto error;
     case block_type_ifunc:
     {
     const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
     if (IS_METHOD_PROC_IFUNC(ifunc)) {
     VALUE method = (VALUE)ifunc->data;
     VALUE name = rb_fstring_lit("<empty_iseq>");
     rb_iseq_t *empty;
     binding_self = method_receiver(method);
     iseq = rb_method_iseq(method);
     env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
     env = env_clone(env, method_cref(method));
     /* set empty iseq */
     empty = rb_iseq_new(NULL, name, name, Qnil, 0, ISEQ_TYPE_TOP);
     RB_OBJ_WRITE(env, &env->iseq, empty);
     break;
     }
     else {
     error:
     rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
     return Qnil;
     }
     }
     }
     bindval = rb_binding_alloc(rb_cBinding);
     GetBindingPtr(bindval, bind);
     RB_OBJ_WRITE(bindval, &bind->block.as.captured.self, binding_self);
     RB_OBJ_WRITE(bindval, &bind->block.as.captured.code.iseq, env->iseq);
     rb_vm_block_ep_update(bindval, &bind->block, env->ep);
     RB_OBJ_WRITTEN(bindval, Qundef, VM_ENV_ENVVAL(env->ep));
     if (iseq) {
     rb_iseq_check(iseq);
     RB_OBJ_WRITE(bindval, &bind->pathobj, iseq->body->location.pathobj);
     bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
     }
     else {
     RB_OBJ_WRITE(bindval, &bind->pathobj,
     rb_iseq_pathobj_new(rb_fstring_lit("(binding)"), Qnil));
     bind->first_lineno = 1;
     }
     return bindval;
    }
     
    call(params,...) → obj click to toggle source

    Invokes the block, setting the block's parameters to the values in params using something close to method calling semantics. Returns the value of the last expression evaluated in the block.

    a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
    a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
    a_proc[9, 1, 2, 3] #=> [9, 18, 27]
    a_proc.(9, 1, 2, 3) #=> [9, 18, 27]
    a_proc.yield(9, 1, 2, 3) #=> [9, 18, 27]
    

    Note that prc.() invokes prc.call() with the parameters given. It's syntactic sugar to hide "call".

    For procs created using lambda or ->() an error is generated if the wrong number of parameters are passed to the proc. For procs created using Proc.new or Kernel.proc, extra parameters are silently discarded and missing parameters are set to nil.

    a_proc = proc {|a,b| [a,b] }
    a_proc.call(1) #=> [1, nil]
    a_proc = lambda {|a,b| [a,b] }
    a_proc.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
    

    See also .

     static VALUE
    proc_call(int argc, VALUE *argv, VALUE procval)
    {
     /* removed */
    }
     
    curry → a_proc click to toggle source
    curry(arity) → a_proc

    Returns a curried proc. If the optional arity argument is given, it determines the number of arguments. A curried proc receives some arguments. If a sufficient number of arguments are supplied, it passes the supplied arguments to the original proc and returns the result. Otherwise, returns another curried proc that takes the rest of arguments.

    b = proc {|x, y, z| (x||0) + (y||0) + (z||0) }
    p b.curry[1][2][3] #=> 6
    p b.curry[1, 2][3, 4] #=> 6
    p b.curry(5)[1][2][3][4][5] #=> 6
    p b.curry(5)[1, 2][3, 4][5] #=> 6
    p b.curry(1)[1] #=> 1
    b = proc {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
    p b.curry[1][2][3] #=> 6
    p b.curry[1, 2][3, 4] #=> 10
    p b.curry(5)[1][2][3][4][5] #=> 15
    p b.curry(5)[1, 2][3, 4][5] #=> 15
    p b.curry(1)[1] #=> 1
    b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }
    p b.curry[1][2][3] #=> 6
    p b.curry[1, 2][3, 4] #=> wrong number of arguments (given 4, expected 3)
    p b.curry(5) #=> wrong number of arguments (given 5, expected 3)
    p b.curry(1) #=> wrong number of arguments (given 1, expected 3)
    b = lambda {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
    p b.curry[1][2][3] #=> 6
    p b.curry[1, 2][3, 4] #=> 10
    p b.curry(5)[1][2][3][4][5] #=> 15
    p b.curry(5)[1, 2][3, 4][5] #=> 15
    p b.curry(1) #=> wrong number of arguments (given 1, expected 3)
    b = proc { :foo }
    p b.curry[] #=> :foo
    
     static VALUE
    proc_curry(int argc, const VALUE *argv, VALUE self)
    {
     int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);
     VALUE arity;
     if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(arity = argv[0])) {
     arity = INT2FIX(min_arity);
     }
     else {
     sarity = FIX2INT(arity);
     if (rb_proc_lambda_p(self)) {
     rb_check_arity(sarity, min_arity, max_arity);
     }
     }
     return make_curry_proc(self, rb_ary_new(), arity);
    }
     
    hash → integer click to toggle source

    Returns a hash value corresponding to proc body.

    See also Object#hash.

     static VALUE
    proc_hash(VALUE self)
    {
     st_index_t hash;
     hash = rb_hash_start(0);
     hash = rb_hash_proc(hash, self);
     hash = rb_hash_end(hash);
     return ST2FIX(hash);
    }
     
    inspect() click to toggle source
    Alias for:
    lambda? → true or false click to toggle source

    Returns true for a object for which argument handling is rigid. Such procs are typically generated by lambda.

    A object generated by proc ignores extra arguments.

    proc {|a,b| [a,b] }.call(1,2,3) #=> [1,2]
    

    It provides nil for missing arguments.

    proc {|a,b| [a,b] }.call(1) #=> [1,nil]
    

    It expands a single array argument.

    proc {|a,b| [a,b] }.call([1,2]) #=> [1,2]
    

    A object generated by lambda doesn't have such tricks.

    lambda {|a,b| [a,b] }.call(1,2,3) #=> ArgumentError
    lambda {|a,b| [a,b] }.call(1) #=> ArgumentError
    lambda {|a,b| [a,b] }.call([1,2]) #=> ArgumentError
    

    is a predicate for the tricks. It returns true if no tricks apply.

    lambda {}.lambda? #=> true
    proc {}.lambda? #=> false
    

    is the same as proc.

    Proc.new {}.lambda? #=> false
    

    lambda, proc and preserve the tricks of a object given by & argument.

    lambda(&lambda {}).lambda? #=> true
    proc(&lambda {}).lambda? #=> true
    Proc.new(&lambda {}).lambda? #=> true
    lambda(&proc {}).lambda? #=> false
    proc(&proc {}).lambda? #=> false
    Proc.new(&proc {}).lambda? #=> false
    

    A object generated by & argument has the tricks

    def n(&b) b.lambda? end
    n {} #=> false
    

    The & argument preserves the tricks if a object is given by & argument.

    n(&lambda {}) #=> true
    n(&proc {}) #=> false
    n(&Proc.new {}) #=> false
    

    A object converted from a method has no tricks.

    def m() end
    method(:m).to_proc.lambda? #=> true
    n(&method(:m)) #=> true
    n(&method(:m).to_proc) #=> true
    

    define_method is treated the same as method definition. The defined method has no tricks.

    class C
     define_method(:d) {}
    end
    C.new.d(1,2) #=> ArgumentError
    C.new.method(:d).to_proc.lambda? #=> true
    

    define_method always defines a method without the tricks, even if a non-lambda object is given. This is the only exception for which the tricks are not preserved.

    class C
     define_method(:e, &proc {})
    end
    C.new.e(1,2) #=> ArgumentError
    C.new.method(:e).to_proc.lambda? #=> true
    

    This exception ensures that methods never have tricks and makes it easy to have wrappers to define methods that behave as usual.

    class C
     def self.def2(name, &body)
     define_method(name, &body)
     end
     def2(:f) {}
    end
    C.new.f(1,2) #=> ArgumentError
    

    The wrapper def2 defines a method which has no tricks.

     VALUE
    rb_proc_lambda_p(VALUE procval)
    {
     rb_proc_t *proc;
     GetProcPtr(procval, proc);
     return proc->is_lambda ? Qtrue : Qfalse;
    }
     
    parameters → array click to toggle source

    Returns the parameter information of this proc.

    prc = lambda{|x, y=42, *other|}
    prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]]
    
     static VALUE
    rb_proc_parameters(VALUE self)
    {
     int is_proc;
     const rb_iseq_t *iseq = rb_proc_get_iseq(self, &is_proc);
     if (!iseq) {
     return rb_unnamed_parameters(rb_proc_arity(self));
     }
     return rb_iseq_parameters(iseq, is_proc);
    }
     
    source_location → [String, Integer] click to toggle source

    Returns the Ruby source filename and line number containing this proc or nil if this proc was not defined in Ruby (i.e. native).

     VALUE
    rb_proc_location(VALUE self)
    {
     return iseq_location(rb_proc_get_iseq(self, 0));
    }
     
    to_proc → proc click to toggle source

    Part of the protocol for converting objects to Proc objects. Instances of class Proc simply return themselves.

     static VALUE
    proc_to_proc(VALUE self)
    {
     return self;
    }
     
    to_s → string click to toggle source

    Returns the unique identifier for this proc, along with an indication of where the proc was defined.

     static VALUE
    proc_to_s(VALUE self)
    {
     const rb_proc_t *proc;
     GetProcPtr(self, proc);
     return rb_block_to_s(self, &proc->block, proc->is_lambda ? " (lambda)" : NULL);
    }
     
    Also aliased as:
    yield(params,...) → obj click to toggle source

    Invokes the block, setting the block's parameters to the values in params using something close to method calling semantics. Returns the value of the last expression evaluated in the block.

    a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } }
    a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
    a_proc[9, 1, 2, 3] #=> [9, 18, 27]
    a_proc.(9, 1, 2, 3) #=> [9, 18, 27]
    a_proc.yield(9, 1, 2, 3) #=> [9, 18, 27]
    

    Note that prc.() invokes prc.call() with the parameters given. It's syntactic sugar to hide "call".

    For procs created using lambda or ->() an error is generated if the wrong number of parameters are passed to the proc. For procs created using Proc.new or Kernel.proc, extra parameters are silently discarded and missing parameters are set to nil.

    a_proc = proc {|a,b| [a,b] }
    a_proc.call(1) #=> [1, nil]
    a_proc = lambda {|a,b| [a,b] }
    a_proc.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2)
    

    See also .

     static VALUE
    proc_call(int argc, VALUE *argv, VALUE procval)
    {
     /* removed */
    }
     

    This page was generated for Ruby

    is provided by and . .

    Generated with Ruby-doc Rdoc Generator 0.44.0.