c_extensions/c_iteration.rb
tests/_examples/c_extensions/c_iteration.rb in the metorex repository.
# A C extension handing a block to the method its walk calls, calling the
# method it overrides with keywords, and reaching the module, encoding and
# IO functions Ruby's C API has for them.
require "tmpdir"
require "stringio"
require_relative "build_helper"
directory = Dir.mktmpdir
built = build_extension("c_iteration.c", "c_iteration", directory)
require(built)
p(CIteration.each_of([3, 5, 8]))
p(CIteration.pairs({ "rate" => 2 }))
class Ledger
def total(*amounts, scale: 1)
amounts.sum * scale
end
end
class Account < Ledger
end
CIteration.define_super(Account, "total")
p(Account.new.total(2, 3, { scale: 10 }))
options = Object.new
def options.to_hash
{ scale: 100 }
end
p(Account.new.total(1, options))
module Audited
def total(*amounts, **options)
[:audited, super]
end
end
CIteration.prepend(Ledger, Audited)
p(Ledger.new.total(4))
p(Ledger.ancestors.first(2))
module Rates
OLD_RATE = 1
end
CIteration.deprecate(Rates, "OLD_RATE")
$stderr = StringIO.new
Warning[:deprecated] = true
Rates::OLD_RATE
p($stderr.string.include?("constant Rates::OLD_RATE is deprecated"))
$stderr = STDERR
p(CIteration.dummy?(Encoding::UTF_7))
p(CIteration.dummy?(Encoding::UTF_8))
p(CIteration.get_io($stdout) == $stdout)
p(CIteration.positive_pow(3, 40))
p(CIteration.timeout_error)
# With nothing above it, the call reaches `method_missing`, and the C
# method's block is passed on.
class Fallback
def method_missing(name, *arguments, **options)
[name, arguments, options]
end
end
class Statement < Fallback
end
CIteration.define_super(Statement, "lookup")
p(Statement.new.lookup(1, { rate: 2 }))
class Runner
def run(*, **)
yield
end
end
class Job < Runner
end
CIteration.define_super(Job, "run")
p(Job.new.run({}) { :given })
begin
Job.new.run(nil) { :given }
rescue TypeError => problem
p(problem.message)
end
name = File.join(directory, "rates.txt")
File.open(name, "w") { |io| p(CIteration.opening(io)) }
File.open(name, "a") { |io| p(CIteration.opening(io)) }
File.open(name, "r") { |io| p(CIteration.opening(io)) }
FileUtils.rm_rf(directory)
Output:
[3, 5, 8]
[["rate", 2]]
50
100
[:audited, 4]
[Audited, Ledger]
true
true
false
true
12157665459056928801
IO::TimeoutError
[:lookup, [1], {rate: 2}]
:given
[:create, :trunc]
[:append, :create]
[]