class Benry::Recorder

record method calls, or define fake methods.

ex. record method calls

## target class
class Calc
  def average(*nums)   # average() calls total()
    return total(*nums) / nums.length
  end
  def total(*nums)
    t = 0; nums.each {|n| t += n }
    return t   # or: return nums.sum
  end
end
## record method calls
rec = Benry::Recorder.new
calc = Calc.new
rec.record(calc, :total, :average)
## call methods
calc.average(10, 20, 30, 40)
## details of method calls
p rec.length               #=> 2
puts rec.inspect
      #=> 0: #<Calc:0x001234abcd>.average(10, 20, 30, 40) #=> 25
      #   1: #<Calc:0x001234abcd>.total(10, 20, 30, 40) #=> 100
#
p rec[0].obj               #=> #<Calc:0x001234abcd>
p rec[0].obj.equal?(calc)  #=> true
p rec[0].name              #=> :average
p rec[0].args              #=> [10, 20, 30, 40]
p rec[0].ret               #=> 25
#
p rec[1].obj               #=> #<Calc:0x001234abcd>
p rec[1].obj.equal?(calc)  #=> true
p rec[1].name              #=> :total
p rec[1].args              #=> [10, 20, 30, 40]
p rec[1].ret               #=> 100
#
p rec[0].to_a              #=> [obj, :average, [10, 20, 30, 40], 25]
p rec[1].to_a              #=> [obj, :total, [10, 20, 30, 40], 100]

ex. fake method

rec = Benry::Recorder.new
calc = Calc.new
## before
p calc.total(10, 20, 30, 40)     #=> 100
p calc.average(10, 20, 30, 40)   #=>  25
## after
rec.fake_method(calc, :total=>123, :average=>34)
p calc.total(10, 20, 30, 40)     #=> 123
p calc.average(10, 20, 30, 40)   #=>  34

ex. fake object

rec = Benry::Recorder.new
obj = rec.fake_object(:foo=>10, :bar=>20)
p obj.foo()                #=> 10
p obj.bar()                #=> 20
p obj.bar(3, 4, 'a'=>5)    # accepts any arguments

Public Class Methods

new() click to toggle source
# File lib/benry/recorder.rb, line 103
def initialize()
  @called = []
end

Public Instance Methods

[](index) click to toggle source
# File lib/benry/recorder.rb, line 113
def [](index)
  return @called[index]
end
fake(obj, **name_and_values)
Alias for: fake_method
fake_method(obj, **name_and_values) click to toggle source
# File lib/benry/recorder.rb, line 147
def fake_method(obj, **name_and_values)
  #; [!g112x] defines fake methods.
  called_list = @called
  proc_obj = proc do |obj, name, val|
    (class << obj; self; end).class_eval do
      #; [!kgvm1] defined methods can can take any arguments.
      define_method(name) do |*args|
        called_list << Recorder::Called.new(obj, name, args, val)
        val
      end
    end
  end
  name_and_values.each do |name, val|
    proc_obj.call(obj, name, val)
  end
  #; [!2p1b0] returns self.
  self
end
Also aliased as: fake
fake_object(**name_and_values) click to toggle source
# File lib/benry/recorder.rb, line 167
def fake_object(**name_and_values)
  #; [!hympr] creates fake object.
  obj = Object.new
  fake_method(obj, **name_and_values)
  return obj
end
inspect() click to toggle source
# File lib/benry/recorder.rb, line 117
def inspect()
  #; [!k85bz] represents internal data.
  buf = []
  @called.each_with_index {|called, i| buf << "#{i}: #{called.inspect}\n" }
  return buf.join()
end
length() click to toggle source
# File lib/benry/recorder.rb, line 107
def length()
  @called.length
end
Also aliased as: size
record(obj, *method_names)
Alias for: record_method
record_method(obj, *method_names) click to toggle source
# File lib/benry/recorder.rb, line 124
def record_method(obj, *method_names)
  #; [!61z3j] records method calls.
  called_list = @called
  proc_obj = proc do |obj, name, orig_method|
    (class << obj; self; end).class_eval do
      alias_method orig_method, name
      define_method(name) do |*args|
        called = Recorder::Called.new(obj, name.to_s.intern, args, nil)
        called_list << called
        #; [!9kh1f] calls original method.
        ret = obj.__send__(orig_method, *args)
        called.ret = ret
        ret
      end
    end
  end
  method_names.each do |name|
    proc_obj.call(obj, name, "__#{name}_orig".intern)
  end
  self
end
Also aliased as: record
size()
Alias for: length