Class: Proc (Ruby 2.2.2) (original) (raw)

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

}

proc === obj → result_of_proc click to toggle source

Invokes the block with obj as the proc's parameter like #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; 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;

}

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. 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 alsoProc#yield.

a_proc = Proc.new {|a, b| b.collect {|i| ia }} a_proc.call(9, 1, 2, 3)
a_proc[9, 1, 2, 3]
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 `

'

           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 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 thatKernel#eval accepts either a Proc or aBinding object as its second parameter.

def fred(param) proc {} end

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

           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,...) → 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. 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 alsoProc#yield.

a_proc = Proc.new {|a, b| b.collect {|i| ia }} a_proc.call(9, 1, 2, 3)
a_proc[9, 1, 2, 3]
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 `

'

           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;

}

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

inspect() click to toggle source

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 bylambda.

A Proc object generated by procignores 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 lambdadoesn'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])

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

lambda {}.lambda?
proc {}.lambda?

::new is the same asproc.

Proc.new {}.lambda?

lambda, proc and ::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; 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 → [String, Fixnum] click to toggle source

Returns the Ruby source filename and line number containing this proc ornil 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 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); 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,...) → obj click to toggle source

prc[params,...] → obj

(params,...) → obj

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 alsoProc#yield.

a_proc = Proc.new {|a, b| b.collect {|i| ia }} a_proc.call(9, 1, 2, 3)
a_proc[9, 1, 2, 3]
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 `

'

           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;

}