Class: Proc

Inherits:
Object show all
Defined in:
proc.c

Overview

Proc objects are blocks of code that have been bound to a set of local variables. Once bound, the code may be called in different contexts and still access those variables.

def gen_times(factor)
  return Proc.new {|n| n*factor }
end

times3 = gen_times(3)
times5 = gen_times(5)

times3.call(12)               #=> 36
times5.call(5)                #=> 25
times3.call(times5.call(4))   #=> 60

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new {|...| ... } ⇒ Proc .newProc

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"

Overloads:

  • .new {|...| ... } ⇒ Proc

    Yields:

    • (...)

    Returns:

  • .newProc

    Returns:



617
618
619
620
621
622
623
624
# File 'proc.c', line 617

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;
}

Instance Method Details

#call(params, ...) ⇒ Object #[](params, ...) ⇒ Object

Invokes the block, setting the block's parameters to the values in params using something close to method calling semantics. Generates a warning if multiple values are passed to a proc that expects just one (previously this silently converted the parameters to an array). Note that prc.() invokes prc.call() with the parameters given. It's a syntax sugar to hide “call”.

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

Returns the value of the last expression evaluated in the block. See also Proc#yield.

a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
a_proc.call(9, 1, 2, 3)   #=> [9, 18, 27]
a_proc[9, 1, 2, 3]        #=> [9, 18, 27]
a_proc = lambda {|a,b| a}
a_proc.call(1,2,3)

produces:

prog.rb:4:in `block in <main>': wrong number of arguments (3 for 2) (ArgumentError)
	from prog.rb:5:in `call'
	from prog.rb:5:in `<main>'

Overloads:



711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# File 'proc.c', line 711

static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
    VALUE vret;
    rb_proc_t *proc;
    rb_block_t *blockptr = 0;
    rb_iseq_t *iseq;
    VALUE passed_procval;
    GetProcPtr(procval, proc);

    iseq = proc->block.iseq;
    if (BUILTIN_TYPE(iseq) == T_NODE || iseq->param.flags.has_block) {
	if (rb_block_given_p()) {
	    rb_proc_t *passed_proc;
	    RB_GC_GUARD(passed_procval) = rb_block_proc();
	    GetProcPtr(passed_procval, passed_proc);
	    blockptr = &passed_proc->block;
	}
    }

    vret = rb_vm_invoke_proc(GET_THREAD(), proc, argc, argv, blockptr);
    RB_GC_GUARD(procval);
    return vret;
}

#call(params, ...) ⇒ Object #[](params, ...) ⇒ Object

Invokes the block, setting the block's parameters to the values in params using something close to method calling semantics. Generates a warning if multiple values are passed to a proc that expects just one (previously this silently converted the parameters to an array). Note that prc.() invokes prc.call() with the parameters given. It's a syntax sugar to hide “call”.

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

Returns the value of the last expression evaluated in the block. See also Proc#yield.

a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
a_proc.call(9, 1, 2, 3)   #=> [9, 18, 27]
a_proc[9, 1, 2, 3]        #=> [9, 18, 27]
a_proc = lambda {|a,b| a}
a_proc.call(1,2,3)

produces:

prog.rb:4:in `block in <main>': wrong number of arguments (3 for 2) (ArgumentError)
	from prog.rb:5:in `call'
	from prog.rb:5:in `<main>'

Overloads:



711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# File 'proc.c', line 711

static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
    VALUE vret;
    rb_proc_t *proc;
    rb_block_t *blockptr = 0;
    rb_iseq_t *iseq;
    VALUE passed_procval;
    GetProcPtr(procval, proc);

    iseq = proc->block.iseq;
    if (BUILTIN_TYPE(iseq) == T_NODE || iseq->param.flags.has_block) {
	if (rb_block_given_p()) {
	    rb_proc_t *passed_proc;
	    RB_GC_GUARD(passed_procval) = rb_block_proc();
	    GetProcPtr(passed_procval, passed_proc);
	    blockptr = &passed_proc->block;
	}
    }

    vret = rb_vm_invoke_proc(GET_THREAD(), proc, argc, argv, blockptr);
    RB_GC_GUARD(procval);
    return vret;
}

#arityFixnum

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. Keywords arguments will 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   { |x=0| }.arity         #=>  0
lambda { |x=0| }.arity         #=> -1
proc   { |x=0, y| }.arity      #=>  1
lambda { |x=0, y| }.arity      #=> -2
proc   { |x=0, y=0| }.arity    #=>  0
lambda { |x=0, y=0| }.arity    #=> -1
proc   { |x, y=0| }.arity      #=>  1
lambda { |x, y=0| }.arity      #=> -2
proc   { |(x, y), z=0| }.arity #=>  1
lambda { |(x, y), z=0| }.arity #=> -2
proc   { |a, x:0, y:0| }.arity #=>  1
lambda { |a, x:0, y:0| }.arity #=> -2

Returns:



824
825
826
827
828
829
# File 'proc.c', line 824

static VALUE
proc_arity(VALUE self)
{
    int arity = rb_proc_arity(self);
    return INT2FIX(arity);
}

#bindingBinding

Returns the binding associated with prc. Note that Kernel#eval accepts either a Proc or a Binding object as its second parameter.

def fred(param)
  proc {}
end

b = fred(99)
eval("param", b.binding)   #=> 99

Returns:



2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
# File 'proc.c', line 2442

static VALUE
proc_binding(VALUE self)
{
    rb_proc_t *proc;
    VALUE bindval;
    rb_binding_t *bind;
    rb_iseq_t *iseq;

    GetProcPtr(self, proc);
    iseq = proc->block.iseq;
    if (RB_TYPE_P((VALUE)iseq, T_NODE)) {
	if (!IS_METHOD_PROC_NODE((NODE *)iseq)) {
	    rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
	}
	iseq = rb_method_get_iseq(RNODE(iseq)->u2.value);
    }

    bindval = rb_binding_alloc(rb_cBinding);
    GetBindingPtr(bindval, bind);
    bind->env = proc->envval;
    bind->blockprocval = proc->blockprocval;
    if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
	bind->path = iseq->location.path;
	bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self));
    }
    else {
	bind->path = Qnil;
	bind->first_lineno = 0;
    }
    return bindval;
}

#call(params, ...) ⇒ Object #[](params, ...) ⇒ Object

Invokes the block, setting the block's parameters to the values in params using something close to method calling semantics. Generates a warning if multiple values are passed to a proc that expects just one (previously this silently converted the parameters to an array). Note that prc.() invokes prc.call() with the parameters given. It's a syntax sugar to hide “call”.

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

Returns the value of the last expression evaluated in the block. See also Proc#yield.

a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
a_proc.call(9, 1, 2, 3)   #=> [9, 18, 27]
a_proc[9, 1, 2, 3]        #=> [9, 18, 27]
a_proc = lambda {|a,b| a}
a_proc.call(1,2,3)

produces:

prog.rb:4:in `block in <main>': wrong number of arguments (3 for 2) (ArgumentError)
	from prog.rb:5:in `call'
	from prog.rb:5:in `<main>'

Overloads:



711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# File 'proc.c', line 711

static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
    VALUE vret;
    rb_proc_t *proc;
    rb_block_t *blockptr = 0;
    rb_iseq_t *iseq;
    VALUE passed_procval;
    GetProcPtr(procval, proc);

    iseq = proc->block.iseq;
    if (BUILTIN_TYPE(iseq) == T_NODE || iseq->param.flags.has_block) {
	if (rb_block_given_p()) {
	    rb_proc_t *passed_proc;
	    RB_GC_GUARD(passed_procval) = rb_block_proc();
	    GetProcPtr(passed_procval, passed_proc);
	    blockptr = &passed_proc->block;
	}
    }

    vret = rb_vm_invoke_proc(GET_THREAD(), proc, argc, argv, blockptr);
    RB_GC_GUARD(procval);
    return vret;
}

#cloneObject

:nodoc:



109
110
111
112
113
114
115
# File 'proc.c', line 109

static VALUE
proc_clone(VALUE self)
{
    VALUE procval = proc_dup(self);
    CLONESETUP(procval, self);
    return procval;
}

#curryProc #curry(arity) ⇒ 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 (4 for 3)
p b.curry(5)                 #=> wrong number of arguments (5 for 3)
p b.curry(1)                 #=> wrong number of arguments (1 for 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 (1 for 3)

b = proc { :foo }
p b.curry[]                  #=> :foo

Overloads:



2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
# File 'proc.c', line 2558

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;

    rb_scan_args(argc, argv, "01", &arity);
    if (NIL_P(arity)) {
	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);
}

#dupObject

:nodoc:



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'proc.c', line 93

static VALUE
proc_dup(VALUE self)
{
    VALUE procval;
    rb_proc_t *src;
    rb_proc_t *dst = ALLOC(rb_proc_t);

    GetProcPtr(self, src);
    *dst = *src;
    procval = rb_proc_wrap(rb_cProc, dst);
    RB_GC_GUARD(self); /* for: body = proc_dup(body) */

    return procval;
}

#hashInteger

Returns a hash value corresponding to proc body.

See also Object#hash.

Returns:



1019
1020
1021
1022
1023
1024
1025
1026
1027
# File 'proc.c', line 1019

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 LONG2FIX(hash);
}

#lambda?Boolean

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

A Proc 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 Proc 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

Proc#lambda? is a predicate for the tricks. It returns true if no tricks apply.

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

Proc.new is the same as proc.

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

lambda, proc and Proc.new preserve the tricks of a Proc 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 Proc object generated by & argument has the tricks

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

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

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

A Proc 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 Proc 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 insures 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.

Returns:

  • (Boolean)

Returns:

  • (Boolean)


218
219
220
221
222
223
224
225
# File 'proc.c', line 218

VALUE
rb_proc_lambda_p(VALUE procval)
{
    rb_proc_t *proc;
    GetProcPtr(procval, proc);

    return proc->is_lambda ? Qtrue : Qfalse;
}

#parametersArray

Returns the parameter information of this proc.

prc = lambda{|x, y=42, *other|}
prc.parameters  #=> [[:req, :x], [:opt, :y], [:rest, :other]]

Returns:



989
990
991
992
993
994
995
996
997
998
# File 'proc.c', line 989

static VALUE
rb_proc_parameters(VALUE self)
{
    int is_proc;
    rb_iseq_t *iseq = get_proc_iseq(self, &is_proc);
    if (!iseq) {
	return unnamed_parameters(rb_proc_arity(self));
    }
    return rb_iseq_parameters(iseq, is_proc);
}

#source_locationArray, Fixnum

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

Returns ]

Returns:



954
955
956
957
958
# File 'proc.c', line 954

VALUE
rb_proc_location(VALUE self)
{
    return iseq_location(get_proc_iseq(self, 0));
}

#to_procProc

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

Returns:



1079
1080
1081
1082
1083
# File 'proc.c', line 1079

static VALUE
proc_to_proc(VALUE self)
{
    return self;
}

#to_sString Also known as: inspect

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

Returns:



1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
# File 'proc.c', line 1037

static VALUE
proc_to_s(VALUE self)
{
    VALUE str = 0;
    rb_proc_t *proc;
    const char *cname = rb_obj_classname(self);
    rb_iseq_t *iseq;
    const char *is_lambda;

    GetProcPtr(self, proc);
    iseq = proc->block.iseq;
    is_lambda = proc->is_lambda ? " (lambda)" : "";

    if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
	int first_lineno = 0;

	if (iseq->line_info_table) {
	    first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self));
	}
	str = rb_sprintf("#<%s:%p@%"PRIsVALUE":%d%s>", cname, (void *)self,
			 iseq->location.path, first_lineno, is_lambda);
    }
    else {
	str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq,
			 is_lambda);
    }

    if (OBJ_TAINTED(self)) {
	OBJ_TAINT(str);
    }
    return str;
}

#call(params, ...) ⇒ Object #[](params, ...) ⇒ Object

Invokes the block, setting the block's parameters to the values in params using something close to method calling semantics. Generates a warning if multiple values are passed to a proc that expects just one (previously this silently converted the parameters to an array). Note that prc.() invokes prc.call() with the parameters given. It's a syntax sugar to hide “call”.

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

Returns the value of the last expression evaluated in the block. See also Proc#yield.

a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
a_proc.call(9, 1, 2, 3)   #=> [9, 18, 27]
a_proc[9, 1, 2, 3]        #=> [9, 18, 27]
a_proc = lambda {|a,b| a}
a_proc.call(1,2,3)

produces:

prog.rb:4:in `block in <main>': wrong number of arguments (3 for 2) (ArgumentError)
	from prog.rb:5:in `call'
	from prog.rb:5:in `<main>'

Overloads:



711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# File 'proc.c', line 711

static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
    VALUE vret;
    rb_proc_t *proc;
    rb_block_t *blockptr = 0;
    rb_iseq_t *iseq;
    VALUE passed_procval;
    GetProcPtr(procval, proc);

    iseq = proc->block.iseq;
    if (BUILTIN_TYPE(iseq) == T_NODE || iseq->param.flags.has_block) {
	if (rb_block_given_p()) {
	    rb_proc_t *passed_proc;
	    RB_GC_GUARD(passed_procval) = rb_block_proc();
	    GetProcPtr(passed_procval, passed_proc);
	    blockptr = &passed_proc->block;
	}
    }

    vret = rb_vm_invoke_proc(GET_THREAD(), proc, argc, argv, blockptr);
    RB_GC_GUARD(procval);
    return vret;
}