mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Eliminate thread-local circular reference stack by passing it as an argument instead
This commit is contained in:
parent
4454ff1bcb
commit
e9aa975cc9
1 changed files with 8 additions and 20 deletions
|
@ -12,26 +12,14 @@ module ActiveSupport
|
|||
class CircularReferenceError < StandardError
|
||||
end
|
||||
|
||||
class << self
|
||||
REFERENCE_STACK_VARIABLE = :json_reference_stack #:nodoc:
|
||||
|
||||
# Converts a Ruby object into a JSON string.
|
||||
def encode(value, options = {})
|
||||
raise_on_circular_reference(value) do
|
||||
value.send(:to_json, options)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def raise_on_circular_reference(value) #:nodoc:
|
||||
stack = Thread.current[REFERENCE_STACK_VARIABLE] ||= []
|
||||
raise CircularReferenceError, 'object references itself' if
|
||||
stack.include? value
|
||||
stack << value
|
||||
yield
|
||||
ensure
|
||||
stack.pop
|
||||
end
|
||||
# Converts a Ruby object into a JSON string.
|
||||
def self.encode(value, options = {})
|
||||
seen = (options[:seen] ||= [])
|
||||
raise CircularReferenceError, 'object references itself' if seen.include?(value)
|
||||
seen << value
|
||||
value.send(:to_json, options)
|
||||
ensure
|
||||
seen.pop
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue