class Proc - Documentation for Ruby 2.3.0 (original) (raw)
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)
times5.call(5)
times3.call(times5.call(4))
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
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
proc === obj → result_of_proc click to toggle source
Invokes the block with obj
as the proc's parameter like Proc#call. It is to allow a proc object to be a target of when
clause in a case statement.
static VALUE proc_call(int argc, VALUE *argv, VALUE procval) { VALUE vret; const rb_block_t *blockptr = 0; const rb_iseq_t *iseq; rb_proc_t *proc; VALUE passed_procval; GetProcPtr(procval, proc);
iseq = proc->block.iseq;
if (RUBY_VM_IFUNC_P(iseq) || iseq->body->param.flags.has_block) {
if (rb_block_given_p()) {
rb_proc_t *passed_proc;
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);
RB_GC_GUARD(passed_procval);
return vret;
}
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| valuescalar } }
a_proc.call(9, 1, 2, 3)
a_proc[9, 1, 2, 3]
a_proc.(9, 1, 2, 3)
a_proc.yield(9, 1, 2, 3)
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)
a_proc = lambda {|a,b| [a,b] } a_proc.call(1)
See also Proc#lambda?.
static VALUE proc_call(int argc, VALUE *argv, VALUE procval) { VALUE vret; const rb_block_t *blockptr = 0; const rb_iseq_t *iseq; rb_proc_t *proc; VALUE passed_procval; GetProcPtr(procval, proc);
iseq = proc->block.iseq;
if (RUBY_VM_IFUNC_P(iseq) || iseq->body->param.flags.has_block) {
if (rb_block_given_p()) {
rb_proc_t *passed_proc;
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);
RB_GC_GUARD(passed_procval);
return vret;
}
arity → fixnum 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. 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
proc { || }.arity
proc { |a| }.arity
proc { |a, b| }.arity
proc { |a, b, c| }.arity
proc { |*a| }.arity
proc { |a, *b| }.arity
proc { |a, *b, c| }.arity
proc { |x:, y:, z:0| }.arity
proc { |*a, x:, y:0| }.arity
proc { |x=0| }.arity
lambda { |x=0| }.arity
proc { |x=0, y| }.arity
lambda { |x=0, y| }.arity
proc { |x=0, y=0| }.arity
lambda { |x=0, y=0| }.arity
proc { |x, y=0| }.arity
lambda { |x, y=0| }.arity
proc { |(x, y), z=0| }.arity
lambda { |(x, y), z=0| }.arity
proc { |a, x:0, y:0| }.arity
lambda { |a, x:0, y:0| }.arity
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. 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)
static VALUE proc_binding(VALUE self) { VALUE bindval, envval; const rb_proc_t *proc; const rb_iseq_t *iseq; rb_binding_t *bind;
GetProcPtr(self, proc);
envval = rb_vm_proc_envval(proc);
iseq = proc->block.iseq;
if (SYMBOL_P(iseq)) goto error;
if (RUBY_VM_IFUNC_P(iseq)) {
struct vm_ifunc *ifunc = (struct vm_ifunc *)iseq;
if (IS_METHOD_PROC_IFUNC(ifunc)) {
VALUE method = (VALUE)ifunc->data;
envval = env_clone(envval, method_receiver(method), method_cref(method));
iseq = rb_method_iseq(method);
}
else {
error:
rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
}
}
bindval = rb_binding_alloc(rb_cBinding);
GetBindingPtr(bindval, bind);
bind->env = envval;
if (iseq) {
rb_iseq_check(iseq);
bind->path = iseq->body->location.path;
bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
}
else {
bind->path = Qnil;
bind->first_lineno = 0;
}
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| valuescalar } }
a_proc.call(9, 1, 2, 3)
a_proc[9, 1, 2, 3]
a_proc.(9, 1, 2, 3)
a_proc.yield(9, 1, 2, 3)
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)
a_proc = lambda {|a,b| [a,b] } a_proc.call(1)
See also Proc#lambda?.
static VALUE proc_call(int argc, VALUE *argv, VALUE procval) { VALUE vret; const rb_block_t *blockptr = 0; const rb_iseq_t *iseq; rb_proc_t *proc; VALUE passed_procval; GetProcPtr(procval, proc);
iseq = proc->block.iseq;
if (RUBY_VM_IFUNC_P(iseq) || iseq->body->param.flags.has_block) {
if (rb_block_given_p()) {
rb_proc_t *passed_proc;
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);
RB_GC_GUARD(passed_procval);
return vret;
}
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]
p b.curry[1, 2][3, 4]
p b.curry(5)[1][2][3][4][5]
p b.curry(5)[1, 2][3, 4][5]
p b.curry(1)[1]
b = proc {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
p b.curry[1][2][3]
p b.curry[1, 2][3, 4]
p b.curry(5)[1][2][3][4][5]
p b.curry(5)[1, 2][3, 4][5]
p b.curry(1)[1]
b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }
p b.curry[1][2][3]
p b.curry[1, 2][3, 4]
p b.curry(5)
p b.curry(1)
b = lambda {|x, y, z, *w| (x||0) + (y||0) + (z||0) + w.inject(0, &:+) }
p b.curry[1][2][3]
p b.curry[1, 2][3, 4]
p b.curry(5)[1][2][3][4][5]
p b.curry(5)[1, 2][3, 4][5]
p b.curry(1)
b = proc { :foo } p b.curry[]
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);
}
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 LONG2FIX(hash); }
lambda? → true or false click to toggle source
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)
It provides nil
for missing arguments.
proc {|a,b| [a,b] }.call(1)
It expands a single array argument.
proc {|a,b| [a,b] }.call([1,2])
A Proc object generated by lambda
doesn't have such tricks.
lambda {|a,b| [a,b] }.call(1,2,3)
lambda {|a,b| [a,b] }.call(1)
lambda {|a,b| [a,b] }.call([1,2])
Proc#lambda? is a predicate for the tricks. It returns true
if no tricks apply.
lambda {}.lambda?
proc {}.lambda?
Proc.new is the same as proc
.
Proc.new {}.lambda?
lambda
, proc
and Proc.new preserve the tricks of a Proc object given by &
argument.
lambda(&lambda {}).lambda?
proc(&lambda {}).lambda?
Proc.new(&lambda {}).lambda?
lambda(&proc {}).lambda?
proc(&proc {}).lambda?
Proc.new(&proc {}).lambda?
A Proc object generated by &
argument has the tricks
def n(&b) b.lambda? end n {}
The &
argument preserves the tricks if a Proc object is given by &
argument.
n(&lambda {})
n(&proc {})
n(&Proc.new {})
A Proc object converted from a method has no tricks.
def m() end method(:m).to_proc.lambda?
n(&method(:m))
n(&method(:m).to_proc)
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)
C.new.method(:d).to_proc.lambda?
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)
C.new.method(:e).to_proc.lambda?
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)
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
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 unnamed_parameters(rb_proc_arity(self)); } return rb_iseq_parameters(iseq, is_proc); }
source_location → [String, Fixnum] 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) { VALUE str = 0; rb_proc_t *proc; const char *cname = rb_obj_classname(self); const 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) && rb_iseq_check(iseq)) {
int first_lineno = 0;
if (iseq->body->line_info_table) {
first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
}
str = rb_sprintf("#<%s:%p@%"PRIsVALUE":%d%s>", cname, (void *)self,
iseq->body->location.path, first_lineno, is_lambda);
}
else if (SYMBOL_P(iseq)) {
str = rb_sprintf("#<%s:%p(&%+"PRIsVALUE")%s>", cname, (void *)self,
(VALUE)iseq, 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;
}
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| valuescalar } }
a_proc.call(9, 1, 2, 3)
a_proc[9, 1, 2, 3]
a_proc.(9, 1, 2, 3)
a_proc.yield(9, 1, 2, 3)
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)
a_proc = lambda {|a,b| [a,b] } a_proc.call(1)
See also Proc#lambda?.
static VALUE proc_call(int argc, VALUE *argv, VALUE procval) { VALUE vret; const rb_block_t *blockptr = 0; const rb_iseq_t *iseq; rb_proc_t *proc; VALUE passed_procval; GetProcPtr(procval, proc);
iseq = proc->block.iseq;
if (RUBY_VM_IFUNC_P(iseq) || iseq->body->param.flags.has_block) {
if (rb_block_given_p()) {
rb_proc_t *passed_proc;
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);
RB_GC_GUARD(passed_procval);
return vret;
}