Skip to content

Commit

Permalink
Merge pull request rails#204 from trptcolin/visitor_dispatch_caching
Browse files Browse the repository at this point in the history
Cache visitor dispatch on a per-visitor basis
  • Loading branch information
tenderlove committed Sep 11, 2013
2 parents a1a46fd + d93a05e commit bd6adc8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
9 changes: 6 additions & 3 deletions lib/arel/visitors/visitor.rb
Expand Up @@ -7,12 +7,15 @@ def accept object

private

DISPATCH = Hash.new do |hash, klass|
hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
DISPATCH = Hash.new do |hash, visitor_class|
hash[visitor_class] =
Hash.new do |hash, node_class|
hash[node_class] = "visit_#{(node_class.name || '').gsub('::', '_')}"
end
end

def dispatch
DISPATCH
DISPATCH[self.class]
end

def visit object, attribute = nil
Expand Down
22 changes: 22 additions & 0 deletions test/visitors/test_dispatch_contamination.rb
@@ -0,0 +1,22 @@
require 'helper'

module Arel
module Visitors
describe 'avoiding contamination between visitor dispatch tables' do
before do
@connection = Table.engine.connection
@table = Table.new(:users)
end

it 'dispatches properly after failing upwards' do
node = Nodes::Union.new(Nodes::True.new, Nodes::False.new)
assert_equal "( TRUE UNION FALSE )", node.to_sql

node.first # from Nodes::Node's Enumerable mixin

assert_equal "( TRUE UNION FALSE )", node.to_sql
end
end
end
end

0 comments on commit bd6adc8

Please sign in to comment.