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 ⇒ Object
Creates a new
Proc
object, bound to the current context.
Instance Method Summary collapse
-
#==(other_proc) ⇒ Boolean
Return
true
if prc is the same object as other_proc, or if they are both procs with the same body. -
#===(obj) ⇒ Object
Invokes the block, with obj as the block's parameter.
-
#===(obj) ⇒ Object
Invokes the block, with obj as the block's parameter.
-
#arity ⇒ Fixnum
Returns the number of arguments that would not be ignored.
-
#binding ⇒ Binding
Returns the binding associated with prc.
-
#===(obj) ⇒ Object
Invokes the block, with obj as the block's parameter.
-
#clone ⇒ Object
:nodoc:.
-
#curry ⇒ Object
Returns a curried proc.
-
#dup ⇒ Object
:nodoc:.
-
#==(other_proc) ⇒ Boolean
Return
true
if prc is the same object as other_proc, or if they are both procs with the same body. -
#hash ⇒ Integer
Return hash value corresponding to proc body.
-
#lambda? ⇒ Boolean
Returns true for a Proc object which argument handling is rigid.
-
#parameters ⇒ Array
returns the parameter information of this proc.
-
#source_location ⇒ Array
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
Shows the unique identifier for this proc, along with an indication of where the proc was defined.
-
#===(obj) ⇒ Object
Invokes the block, with obj as the block's parameter.
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"
|
# File 'proc.c'
/*
* call-seq:
* Proc.new {|...| block } -> a_proc
* Proc.new -> a_proc
*
* Creates a new <code>Proc</code> object, bound to the current
* context. <code>Proc::new</code> may be called without a block only
* within a method with an attached block, in which case that block is
* converted to the <code>Proc</code> 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;
}
|
Instance Method Details
#==(other_proc) ⇒ Boolean
Return true
if prc is the same object as other_proc, or if they are both procs with the same body.
|
# File 'proc.c'
/*
* call-seq:
* prc == other_proc -> true or false
*
* Return <code>true</code> if <i>prc</i> is the same object as
* <i>other_proc</i>, or if they are both procs with the same body.
*/
static VALUE
proc_eq(VALUE self, VALUE other)
{
if (self == other) {
return Qtrue;
}
else {
if (rb_obj_is_proc(other)) {
rb_proc_t *p1, *p2;
GetProcPtr(self, p1);
GetProcPtr(other, p2);
if (p1->envval == p2->envval &&
p1->block.iseq->iseq_size == p2->block.iseq->iseq_size &&
p1->block.iseq->local_size == p2->block.iseq->local_size &&
MEMCMP(p1->block.iseq->iseq, p2->block.iseq->iseq, VALUE,
p1->block.iseq->iseq_size) == 0) {
return Qtrue;
}
}
}
return Qfalse;
}
|
#===(obj) ⇒ Object
Invokes the block, with obj as the block's parameter. It is to allow a proc object to be a target of when
clause in the case statement.
|
# File 'proc.c'
/*
* call-seq:
* prc === obj -> result_of_proc
*
* Invokes the block, with <i>obj</i> as the block's parameter. It is
* to allow a proc object to be a target of +when+ clause in the case statement.
*/
static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
rb_proc_t *proc;
rb_block_t *blockptr = 0;
rb_iseq_t *iseq;
GetProcPtr(procval, proc);
iseq = proc->block.iseq;
if (BUILTIN_TYPE(iseq) == T_NODE || iseq->arg_block != -1) {
if (rb_block_given_p()) {
rb_proc_t *proc;
VALUE procval;
procval = rb_block_proc();
GetProcPtr(procval, proc);
blockptr = &proc->block;
}
}
return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
argc, argv, blockptr);
}
|
#===(obj) ⇒ Object
Invokes the block, with obj as the block's parameter. It is to allow a proc object to be a target of when
clause in the case statement.
|
# File 'proc.c'
/*
* call-seq:
* prc === obj -> result_of_proc
*
* Invokes the block, with <i>obj</i> as the block's parameter. It is
* to allow a proc object to be a target of +when+ clause in the case statement.
*/
static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
rb_proc_t *proc;
rb_block_t *blockptr = 0;
rb_iseq_t *iseq;
GetProcPtr(procval, proc);
iseq = proc->block.iseq;
if (BUILTIN_TYPE(iseq) == T_NODE || iseq->arg_block != -1) {
if (rb_block_given_p()) {
rb_proc_t *proc;
VALUE procval;
procval = rb_block_proc();
GetProcPtr(procval, proc);
blockptr = &proc->block;
}
}
return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
argc, argv, blockptr);
}
|
#arity ⇒ Fixnum
Returns the number of arguments that would not be ignored. 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, return -n-1, where n is the number of mandatory arguments. A proc
with no argument declarations is the same a block declaring ||
as its arguments.
Proc.new {}.arity #=> 0
Proc.new {||}.arity #=> 0
Proc.new {|a|}.arity #=> 1
Proc.new {|a,b|}.arity #=> 2
Proc.new {|a,b,c|}.arity #=> 3
Proc.new {|*a|}.arity #=> -1
Proc.new {|a,*b|}.arity #=> -2
Proc.new {|a,*b, c|}.arity #=> -3
|
# File 'proc.c'
/*
* call-seq:
* prc.arity -> fixnum
*
* Returns the number of arguments that would not be ignored. 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, return -n-1, where n is the number of mandatory
* arguments. A <code>proc</code> with no argument declarations
* is the same a block declaring <code>||</code> as its arguments.
*
* Proc.new {}.arity #=> 0
* Proc.new {||}.arity #=> 0
* Proc.new {|a|}.arity #=> 1
* Proc.new {|a,b|}.arity #=> 2
* Proc.new {|a,b,c|}.arity #=> 3
* Proc.new {|*a|}.arity #=> -1
* Proc.new {|a,*b|}.arity #=> -2
* Proc.new {|a,*b, c|}.arity #=> -3
*/
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
|
# File 'proc.c'
/*
* call-seq:
* prc.binding -> binding
*
* Returns the binding associated with <i>prc</i>. Note that
* <code>Kernel#eval</code> accepts either a <code>Proc</code> or a
* <code>Binding</code> object as its second parameter.
*
* def fred(param)
* proc {}
* end
*
* b = fred(99)
* eval("param", b.binding) #=> 99
*/
static VALUE
proc_binding(VALUE self)
{
rb_proc_t *proc;
VALUE bindval;
rb_binding_t *bind;
GetProcPtr(self, proc);
if (TYPE(proc->block.iseq) == T_NODE) {
if (!IS_METHOD_PROC_NODE((NODE *)proc->block.iseq)) {
rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
}
}
bindval = binding_alloc(rb_cBinding);
GetBindingPtr(bindval, bind);
bind->env = proc->envval;
if (RUBY_VM_NORMAL_ISEQ_P(proc->block.iseq)) {
bind->filename = proc->block.iseq->filename;
bind->line_no = rb_iseq_first_lineno(proc->block.iseq);
}
else {
bind->filename = Qnil;
bind->line_no = 0;
}
return bindval;
}
|
#===(obj) ⇒ Object
Invokes the block, with obj as the block's parameter. It is to allow a proc object to be a target of when
clause in the case statement.
|
# File 'proc.c'
/*
* call-seq:
* prc === obj -> result_of_proc
*
* Invokes the block, with <i>obj</i> as the block's parameter. It is
* to allow a proc object to be a target of +when+ clause in the case statement.
*/
static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
rb_proc_t *proc;
rb_block_t *blockptr = 0;
rb_iseq_t *iseq;
GetProcPtr(procval, proc);
iseq = proc->block.iseq;
if (BUILTIN_TYPE(iseq) == T_NODE || iseq->arg_block != -1) {
if (rb_block_given_p()) {
rb_proc_t *proc;
VALUE procval;
procval = rb_block_proc();
GetProcPtr(procval, proc);
blockptr = &proc->block;
}
}
return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
argc, argv, blockptr);
}
|
#clone ⇒ Object
:nodoc:
|
# File 'proc.c'
/* :nodoc: */
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
|
# File 'proc.c'
/*
* call-seq:
* prc.curry -> a_proc
* prc.curry(arity) -> a_proc
*
* Returns a curried proc. If the optional <i>arity</i> 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
*/
static VALUE
proc_curry(int argc, VALUE *argv, VALUE self)
{
int sarity, marity = rb_proc_arity(self);
VALUE arity, opt = Qfalse;
if (marity < 0) {
marity = -marity - 1;
opt = Qtrue;
}
rb_scan_args(argc, argv, "01", &arity);
if (NIL_P(arity)) {
arity = INT2FIX(marity);
}
else {
sarity = FIX2INT(arity);
if (rb_proc_lambda_p(self) && (sarity < marity || (sarity > marity && !opt))) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", sarity, marity);
}
}
return make_curry_proc(self, rb_ary_new(), arity);
}
|
#dup ⇒ Object
:nodoc:
|
# File 'proc.c'
/* :nodoc: */
static VALUE
proc_dup(VALUE self)
{
VALUE procval = rb_proc_alloc(rb_cProc);
rb_proc_t *src, *dst;
GetProcPtr(self, src);
GetProcPtr(procval, dst);
dst->block = src->block;
dst->block.proc = procval;
dst->blockprocval = src->blockprocval;
dst->envval = src->envval;
dst->safe_level = src->safe_level;
dst->is_lambda = src->is_lambda;
return procval;
}
|
#==(other_proc) ⇒ Boolean
Return true
if prc is the same object as other_proc, or if they are both procs with the same body.
|
# File 'proc.c'
/*
* call-seq:
* prc == other_proc -> true or false
*
* Return <code>true</code> if <i>prc</i> is the same object as
* <i>other_proc</i>, or if they are both procs with the same body.
*/
static VALUE
proc_eq(VALUE self, VALUE other)
{
if (self == other) {
return Qtrue;
}
else {
if (rb_obj_is_proc(other)) {
rb_proc_t *p1, *p2;
GetProcPtr(self, p1);
GetProcPtr(other, p2);
if (p1->envval == p2->envval &&
p1->block.iseq->iseq_size == p2->block.iseq->iseq_size &&
p1->block.iseq->local_size == p2->block.iseq->local_size &&
MEMCMP(p1->block.iseq->iseq, p2->block.iseq->iseq, VALUE,
p1->block.iseq->iseq_size) == 0) {
return Qtrue;
}
}
}
return Qfalse;
}
|
#hash ⇒ Integer
Return hash value corresponding to proc body.
|
# File 'proc.c'
/*
* call-seq:
* prc.hash -> integer
*
* Return hash value corresponding to proc body.
*/
static VALUE
proc_hash(VALUE self)
{
st_index_t hash;
rb_proc_t *proc;
GetProcPtr(self, proc);
hash = rb_hash_start((st_index_t)proc->block.iseq);
hash = rb_hash_uint(hash, (st_index_t)proc->envval);
hash = rb_hash_uint(hash, (st_index_t)proc->block.lfp >> 16);
hash = rb_hash_end(hash);
return LONG2FIX(hash);
}
|
#lambda? ⇒ Boolean
Returns true for a Proc object which argument handling is rigid. Such procs are typically generated by lambda.
A Proc object generated by proc ignore extra arguments.
proc {|a,b| [a,b] }.call(1,2,3) #=> [1,2]
It provides nil for lacked arguments.
proc {|a,b| [a,b] }.call(1) #=> [1,nil]
It expand 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.
lambda {}.lambda? #=> true
proc {}.lambda? #=> false
Proc.new is same as proc.
Proc.new {}.lambda? #=> false
lambda, proc and Proc.new preserves 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 same as method definition. The defined method has no tricks.
class C
define_method(:d) {}
end
C.new.e(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 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 is for a wrapper of define_method. It eases defining a method defining method which defines a usual method which has no tricks.
class << C
def def2(name, &body)
define_method(name, &body)
end
end
class C
def2(:f) {}
end
C.new.f(1,2) #=> ArgumentError
The wrapper, def2, defines a method which has no tricks.
|
# File 'proc.c'
/*
* call-seq:
* prc.lambda? -> true or false
*
* Returns true for a Proc object which argument handling is rigid.
* Such procs are typically generated by lambda.
*
* A Proc object generated by proc ignore extra arguments.
*
* proc {|a,b| [a,b] }.call(1,2,3) #=> [1,2]
*
* It provides nil for lacked arguments.
*
* proc {|a,b| [a,b] }.call(1) #=> [1,nil]
*
* It expand 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.
*
* lambda {}.lambda? #=> true
* proc {}.lambda? #=> false
*
* Proc.new is same as proc.
*
* Proc.new {}.lambda? #=> false
*
* lambda, proc and Proc.new preserves 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 same as method definition.
* The defined method has no tricks.
*
* class C
* define_method(:d) {}
* end
* C.new.e(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 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 is for a wrapper of define_method.
* It eases defining a method defining method which defines a usual method which has no tricks.
*
* class << C
* def def2(name, &body)
* define_method(name, &body)
* end
* end
* class C
* 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
returns the parameter information of this proc.
prc = lambda{|x, y=42, *rest|}
prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :rest]]
|
# File 'proc.c'
/*
* call-seq:
* proc.parameters -> array
*
* returns the parameter information of this proc.
*
* prc = lambda{|x, y=42, *rest|}
* prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :rest]]
*/
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
returns the ruby source filename and line number containing this proc or nil if this proc was not defined in ruby (i.e. native)
|
# File 'proc.c'
/*
* call-seq:
* prc.source_location -> [String, 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)
*/
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.
|
# File 'proc.c'
/*
* call-seq:
* prc.to_proc -> prc
*
* Part of the protocol for converting objects to <code>Proc</code>
* objects. Instances of class <code>Proc</code> simply return
* themselves.
*/
static VALUE
proc_to_proc(VALUE self)
{
return self;
}
|
#to_s ⇒ String
Shows the unique identifier for this proc, along with an indication of where the proc was defined.
|
# File 'proc.c'
/*
* call-seq:
* prc.to_s -> string
*
* Shows 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);
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 line_no = 0;
if (iseq->insn_info_table) {
line_no = rb_iseq_first_lineno(iseq);
}
str = rb_sprintf("#<%s:%p@%s:%d%s>", cname, (void *)self,
RSTRING_PTR(iseq->filename),
line_no, 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;
}
|
#===(obj) ⇒ Object
Invokes the block, with obj as the block's parameter. It is to allow a proc object to be a target of when
clause in the case statement.
|
# File 'proc.c'
/*
* call-seq:
* prc === obj -> result_of_proc
*
* Invokes the block, with <i>obj</i> as the block's parameter. It is
* to allow a proc object to be a target of +when+ clause in the case statement.
*/
static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
rb_proc_t *proc;
rb_block_t *blockptr = 0;
rb_iseq_t *iseq;
GetProcPtr(procval, proc);
iseq = proc->block.iseq;
if (BUILTIN_TYPE(iseq) == T_NODE || iseq->arg_block != -1) {
if (rb_block_given_p()) {
rb_proc_t *proc;
VALUE procval;
procval = rb_block_proc();
GetProcPtr(procval, proc);
blockptr = &proc->block;
}
}
return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
argc, argv, blockptr);
}
|