Module: Fruity::Baseline

Extended by:
Baseline
Included in:
Baseline
Defined in:
lib/fruity/baseline.rb

Overview

Utility module for building baseline equivalents for callables.

Constant Summary collapse

NOOPs =
Hash.new{|h, k| h[k] = {}}
PARAM_MAP =
{
  :req => "%{name}",
  :opt => "%{name} = nil",
  :rest => "*%{name}",
  :block => "&%{name}",
}

Instance Method Summary collapse

Instance Method Details

#[](exec) ⇒ Object

Returns the baseline for the given callable object The signature (number of arguments) and type (proc, …) will be copied as much as possible.



13
14
15
16
17
# File 'lib/fruity/baseline.rb', line 13

def [](exec)
  kind = callable_kind(exec)
  signature = callable_signature(exec)
  NOOPs[kind][signature] ||= build_baseline(kind, signature)
end

#arg_list(signature) ⇒ Object



51
52
53
# File 'lib/fruity/baseline.rb', line 51

def arg_list(signature)
  signature.map.with_index{|kind, i| PARAM_MAP[kind] % {:name => "p#{i}"}}.join(",")
end

#build_baseline(kind, signature) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fruity/baseline.rb', line 55

def build_baseline(kind, signature)
  args = "|#{arg_list(signature)}|"
  case kind
  when :lambda, :proc
    eval("#{kind}{#{args}}")
  when :builtin_method
    case signature
    when []
      nil.method(:nil?)
    when [:req]
      nil.method(:==)
    else
      Array.method(:[])
    end
  when :method
    @method_counter ||= 0
    @method_counter += 1
    name = "baseline_#{@method_counter}"
    eval("define_method(:#{name}){#{args}}")
    method(name)
  end
end

#callable_kind(exec) ⇒ Object



21
22
23
24
25
26
27
28
29
# File 'lib/fruity/baseline.rb', line 21

def callable_kind(exec)
  if exec.is_a?(Method)
    exec.source_location ? :method : :builtin_method
  elsif exec.lambda?
    :lambda
  else
    :proc
  end
end

#callable_signature(exec) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/fruity/baseline.rb', line 31

def callable_signature(exec)
  if exec.respond_to?(:parameters)
    exec.parameters.map(&:first)
  else
    # Ruby 1.8 didn't have parameters, so rely on arity
    opt = exec.arity < 0
    req = opt ? -1-exec.arity : exec.arity
    signature = [:req] * req
    signature << :rest if opt
    signature
  end
end