/*
 * 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.
 *
 */

static VALUE
proc_lambda_p(VALUE procval)
{
    rb_proc_t *proc;
    GetProcPtr(procval, proc);

    return proc->is_lambda ? Qtrue : Qfalse;
}