Class: Ambition::Processors::Select

Inherits:
Base show all
Defined in:
lib/ambition/processors/select.rb

Instance Method Summary collapse

Methods inherited from Base

#key, #process, #process_array, #process_dasgn_curr, #process_dvar, #process_false, #process_gvar, #process_ivar, #process_lit, #process_lvar, #process_nil, #process_proc, #process_str, #process_true, #process_vcall, #rubify, #to_s, #translator, translator, #value

Constructor Details

#initialize(context, block) ⇒ Select

Returns a new instance of Select.



4
5
6
7
# File 'lib/ambition/processors/select.rb', line 4

def initialize(context, block)
  @context  = context
  @block    = block
end

Instance Method Details

#joined_expressions(exp, with = nil) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'lib/ambition/processors/select.rb', line 71

def joined_expressions(exp, with = nil)
  expressions = []

  while expression = exp.shift
    expressions << process(expression)
  end

  translator.send(with, *expressions)
end

#negateObject



97
98
99
100
101
102
# File 'lib/ambition/processors/select.rb', line 97

def negate
  @negated = translator.negated = true
  yield
ensure
  @negated = translator.negated = false
end

#negate_operator(operator) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/ambition/processors/select.rb', line 89

def negate_operator(operator)
  case operator
  when :== then :not_equal
  when :=~ then :not_regexp
  else raise "Missing negated operator definition: #{operator}"
  end
end

#process_and(exp) ⇒ Object



63
64
65
# File 'lib/ambition/processors/select.rb', line 63

def process_and(exp)
  joined_expressions exp, :both
end

#process_call(args) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/ambition/processors/select.rb', line 9

def process_call(args)
  # Operation (m.name == 'chris')
  #   [[:call, [:dvar, :m], :name], :==, [:array, [:str, "chris"]]]
  if args.size == 3
    left, operator, right = args

    # params are passed as an array, even when only one element:
    #  abc(1)
    #  => [:fcall, :abc, [:array, [:lit, 1]]
    #  abc([1])
    #  => [:fcall, :abc, [:array, [:array, [:lit, 1]]]]
    if right.first == :array 
      right = process(right)
      right = right.is_a?(Array) ? right.first : right
    else
      right = process(right)
    end

    translator.send(process_operator(operator), process(left), right)

  # Property of passed arg:
  #   [[:dvar, :m], :name]
  elsif args.first.last == @receiver
    translator.call(*args[1..-1])

  # Method call: 
  #   [[:call, [:dvar, :m], :name], :upcase]
  elsif args.first.first == :call && args.first[1].last == @receiver
    receiver, method = args
    translator.chained_call(receiver.last, method)

  # Deep, chained call:
  #   [[:call, [:call, [:call, [:dvar, :m], :created_at], :something], :else], :perhaps]
  elsif args.flatten.include? @receiver
    calls = []

    until args.empty?
      args = args.last if args.last.is_a?(Array)
      break if args.last == @receiver
      calls << args.pop
    end

    translator.chained_call(*calls.reverse)

  else
    raise args.inspect
  end
end

#process_match3(exp) ⇒ Object



58
59
60
61
# File 'lib/ambition/processors/select.rb', line 58

def process_match3(exp)
  right, left = exp
  process_call [ left, :=~, right ]
end

#process_not(args) ⇒ Object



81
82
83
# File 'lib/ambition/processors/select.rb', line 81

def process_not(args)
  negate { process(args.first) }
end

#process_operator(operator) ⇒ Object



85
86
87
# File 'lib/ambition/processors/select.rb', line 85

def process_operator(operator)
  @negated ? negate_operator(operator) : operator
end

#process_or(exp) ⇒ Object



67
68
69
# File 'lib/ambition/processors/select.rb', line 67

def process_or(exp)
  joined_expressions exp, :either
end