Class: Proc
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
-
.new(*args) ⇒ Object
Creates a new
Proc
object, bound to the current context.
Instance Method Summary collapse
-
#===(*args) ⇒ Object
Invokes the block, setting the block’s parameters to the values in params using something close to method calling semantics.
-
#[](*args) ⇒ Object
Invokes the block, setting the block’s parameters to the values in params using something close to method calling semantics.
-
#arity ⇒ Fixnum
Returns the number of mandatory arguments.
-
#binding ⇒ Binding
Returns the binding associated with prc.
-
#call(*args) ⇒ Object
Invokes the block, setting the block’s parameters to the values in params using something close to method calling semantics.
-
#clone ⇒ Object
:nodoc:.
-
#curry(*args) ⇒ Object
Returns a curried proc.
-
#dup ⇒ Object
:nodoc:.
-
#hash ⇒ Integer
Returns a hash value corresponding to proc body.
-
#lambda? ⇒ Boolean
Returns
true
for a Proc object for which argument handling is rigid. -
#parameters ⇒ Array
Returns the parameter information of this proc.
-
#source_location ⇒ Array, 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). -
#to_proc ⇒ Proc
Part of the protocol for converting objects to
Proc
objects. -
#to_s ⇒ String
(also: #inspect)
Returns the unique identifier for this proc, along with an indication of where the proc was defined.
-
#yield(*args) ⇒ Object
Invokes the block, setting the block’s parameters to the values in params using something close to method calling semantics.
Class Method Details
.new {|...| ... } ⇒ Proc .new ⇒ 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"
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>'
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>'
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;
}
|
#arity ⇒ Fixnum
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
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);
}
|
#binding ⇒ Binding
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
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>'
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;
}
|
#clone ⇒ Object
: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;
}
|
#curry ⇒ Proc #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
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);
}
|
#dup ⇒ Object
: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;
}
|
#hash ⇒ Integer
Returns a hash value corresponding to proc body.
See also Object#hash.
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.
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;
}
|
#parameters ⇒ Array
Returns the parameter information of this proc.
prc = lambda{|x, y=42, *other|}
prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]]
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_location ⇒ Array, 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)
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_proc ⇒ Proc
Part of the protocol for converting objects to Proc
objects. Instances of class Proc
simply return themselves.
1079 1080 1081 1082 1083 |
# File 'proc.c', line 1079
static VALUE
proc_to_proc(VALUE self)
{
return self;
}
|
#to_s ⇒ String Also known as: inspect
Returns the unique identifier for this proc, along with an indication of where the proc was defined.
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>'
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;
}
|