Class: Proc

Inherits:
Object show all
Defined in:
eval.c

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:



# File 'eval.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
proc_s_new(argc, argv, klass)
    int argc;
    VALUE *argv;
    VALUE klass;
{
    VALUE block = proc_alloc(klass, Qfalse);

    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.

Returns:

  • (Boolean)


# File 'eval.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(self, other)
    VALUE self, other;
{
    struct BLOCK *data, *data2;

    if (self == other) return Qtrue;
    if (TYPE(other) != T_DATA) return Qfalse;
    if (RDATA(other)->dmark != (RUBY_DATA_FUNC)blk_mark) return Qfalse;
    if (CLASS_OF(self) != CLASS_OF(other)) return Qfalse;
    Data_Get_Struct(self, struct BLOCK, data);
    Data_Get_Struct(other, struct BLOCK, data2);
    if (data->body != data2->body) return Qfalse;
    if (data->var != data2->var) return Qfalse;
    if (data->scope != data2->scope) return Qfalse;
    if (data->dyna_vars != data2->dyna_vars) return Qfalse;
    if (data->flags != data2->flags) return Qfalse;

    return Qtrue;
}

#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).

For procs created using Kernel.proc, generates an error if the wrong number of parameters are passed to a proc with multiple parameters. For procs created using Proc.new, 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 = Proc.new {|a,b| a}
a_proc.call(1,2,3)

produces:

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

Overloads:



# File 'eval.c'

/*
 *  call-seq:
 *     prc.call(params,...)   => obj
 *     prc[params,...]        => obj
 *  
 *  Invokes the block, setting the block's parameters to the values in
 *  <i>params</i> 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). 
 *
 *  For procs created using <code>Kernel.proc</code>, generates an 
 *  error if the wrong number of parameters
 *  are passed to a proc with multiple parameters. For procs created using
 *  <code>Proc.new</code>, extra parameters are silently discarded.
 *
 *  Returns the value of the last expression evaluated in the block. See
 *  also <code>Proc#yield</code>.
 *     
 *     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 = Proc.new {|a,b| a}
 *     a_proc.call(1,2,3)
 *     
 *  <em>produces:</em>
 *     
 *     prog.rb:5: wrong number of arguments (3 for 2) (ArgumentError)
 *      from prog.rb:4:in `call'
 *      from prog.rb:5
 */

VALUE
rb_proc_call(proc, args)
    VALUE proc, args;       /* OK */
{
    return proc_invoke(proc, args, Qundef, 0);
}

#arityFixnum

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

Returns:



# File 'eval.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
 */

static VALUE
proc_arity(proc)
    VALUE proc;
{
    struct BLOCK *data;
    NODE *var, *list;
    int n;

    Data_Get_Struct(proc, struct BLOCK, data);
    var = data->var;
    if (var == 0) {
    if (data->body && nd_type(data->body) == NODE_IFUNC &&
        data->body->nd_cfnc == bmcall) {
        return method_arity(data->body->nd_tval);
    }
    return INT2FIX(-1);
    }
    if (var == (NODE*)1) return INT2FIX(0);
    if (var == (NODE*)2) return INT2FIX(0);
    if (nd_type(var) == NODE_BLOCK_ARG) {
    var = var->nd_args;
    if (var == (NODE*)1) return INT2FIX(0);
    if (var == (NODE*)2) return INT2FIX(0);
    }
    switch (nd_type(var)) {
      default:
    return INT2FIX(1);
      case NODE_MASGN:
    list = var->nd_head;
    n = 0;
    while (list) {
        n++;
        list = list->nd_next;
    }
    if (var->nd_args) return INT2FIX(-n-1);
    return INT2FIX(n);
    }
}

#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
eval("param", b)           #=> 99

Returns:



# File 'eval.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
 *     eval("param", b)           #=> 99
 */

static VALUE
proc_binding(proc)
    VALUE proc;
{
    struct BLOCK *orig, *data;
    VALUE bind;

    Data_Get_Struct(proc, struct BLOCK, orig);
    bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data);
    MEMCPY(data, orig, struct BLOCK, 1);
    frame_dup(&data->frame);

    if (data->iter) {
    blk_copy_prev(data);
    }
    else {
    data->prev = 0;
    }

    return bind;
}

#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).

For procs created using Kernel.proc, generates an error if the wrong number of parameters are passed to a proc with multiple parameters. For procs created using Proc.new, 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 = Proc.new {|a,b| a}
a_proc.call(1,2,3)

produces:

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

Overloads:



# File 'eval.c'

/*
 *  call-seq:
 *     prc.call(params,...)   => obj
 *     prc[params,...]        => obj
 *  
 *  Invokes the block, setting the block's parameters to the values in
 *  <i>params</i> 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). 
 *
 *  For procs created using <code>Kernel.proc</code>, generates an 
 *  error if the wrong number of parameters
 *  are passed to a proc with multiple parameters. For procs created using
 *  <code>Proc.new</code>, extra parameters are silently discarded.
 *
 *  Returns the value of the last expression evaluated in the block. See
 *  also <code>Proc#yield</code>.
 *     
 *     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 = Proc.new {|a,b| a}
 *     a_proc.call(1,2,3)
 *     
 *  <em>produces:</em>
 *     
 *     prog.rb:5: wrong number of arguments (3 for 2) (ArgumentError)
 *      from prog.rb:4:in `call'
 *      from prog.rb:5
 */

VALUE
rb_proc_call(proc, args)
    VALUE proc, args;       /* OK */
{
    return proc_invoke(proc, args, Qundef, 0);
}

#cloneObject

MISSING: documentation



# File 'eval.c'

/*
 * MISSING: documentation
 */

static VALUE
proc_clone(self)
    VALUE self;
{
    struct BLOCK *orig, *data;
    VALUE bind;

    Data_Get_Struct(self, struct BLOCK, orig);
    bind = Data_Make_Struct(rb_obj_class(self),struct BLOCK,blk_mark,blk_free,data);
    CLONESETUP(bind, self);
    blk_dup(data, orig);

    return bind;
}

#dupObject

#to_procProc

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

Returns:



# File 'eval.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_self(self)
    VALUE self;
{
    return self;
}

#to_sString

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

Returns:



# File 'eval.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(self)
    VALUE self;
{
    struct BLOCK *data;
    NODE *node;
    const char *cname = rb_obj_classname(self);
    const int w = (sizeof(VALUE) * CHAR_BIT) / 4;
    long len = strlen(cname)+6+w; /* 6:tags 16:addr */
    VALUE str;

    Data_Get_Struct(self, struct BLOCK, data);
    if ((node = data->frame.node) || (node = data->body)) {
    len += strlen(node->nd_file) + 2 + (SIZEOF_LONG*CHAR_BIT-NODE_LSHIFT)/3;
    str = rb_str_new(0, len);
    snprintf(RSTRING(str)->ptr, len+1,
         "#<%s:0x%.*lx@%s:%d>", cname, w, (VALUE)data->body,
         node->nd_file, nd_line(node));
    }
    else {
    str = rb_str_new(0, len);
    snprintf(RSTRING(str)->ptr, len+1,
         "#<%s:0x%.*lx>", cname, w, (VALUE)data->body);
    }
    RSTRING(str)->len = strlen(RSTRING(str)->ptr);
    if (OBJ_TAINTED(self)) OBJ_TAINT(str);

    return str;
}