c_extensions/c_procs_no_parens.rb
tests/_examples/c_extensions/c_procs_no_parens.rb in the metorex repository.
# A C extension making a Proc around a C block function, asking a Proc its
# arity, and calling Procs with arguments, keywords and a block.
require "tmpdir"
require_relative "build_helper"
directory = Dir.mktmpdir
require build_extension("c_procs.c", "c_procs", directory)
procs = CProcs.new
made = procs.make :data
p made.call(1, 2)
p made.call([1, 2])
p(made.call { :given })
p made[]
p [made.arity, made.lambda?, made.source_location]
p made.inspect.match?(/\A#<Proc:0x\h+>\z/)
p made == procs.make(:data)
reader = procs.make_block_reader
action = -> { :acted }
p reader.call(&action).equal?(action)
p reader.call
p [procs.arity(proc { |a, b| }), procs.arity(->(a, *b) {}), procs.arity(made)]
p [procs.is_proc(made), procs.is_proc(-> {}), procs.is_proc(Class.new(Proc).new {}), procs.is_proc(:sym), procs.is_proc(nil)]
p procs.call(proc { |a, b| a * b }, [6, 7])
report { procs.call proc {}, 5 }
taking = proc { |*rest, **keywords| [rest, keywords] }
p procs.call_keywords(taking, [{}])
p procs.call_keywords(taking, [{ b: 2 }, { a: 1 }])
p procs.call_keywords(taking, [])
report { procs.call_keywords taking, [1, 2] }
doubling = proc { |a, b, &block| block ? block.call(a * b) : a * b }
p procs.call_block(doubling, [6, 7], proc { |n| n * 2 })
p procs.call_block(doubling, [6, 7], nil)
with_block = proc { |*rest, **keywords, &block| [rest, keywords, block&.call] }
p procs.call_block_keywords(with_block, [{ a: 1 }], proc { 42 })
p procs.call_block_keywords(with_block, [{}], nil)
FileUtils.rm_rf directory
Output:
[1, :data, 2, [1, 2], false]
[[1, 2], :data, 1, [[1, 2]], false]
[nil, :data, 0, [], false]
[nil, :data, 0, [], false]
[-1, false, nil]
true
false
true
nil
[2, -2, -1]
[true, true, true, false, false]
42
TypeError: wrong argument type Integer (expected Array)
[[], {}]
[[{b: 2}], {a: 1}]
[[], {}]
TypeError: no implicit conversion of Integer into Hash
84
42
[[], {a: 1}, 42]
[[], {}, nil]