-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deep duplicate calls when making a copy of the call stack
Some prawn methods mutate the arguments passed in to them, so to combot that we need to deep duplicate the arguments whenever we duplicate the call stacks. This fixes the reported problem in #49.
- Loading branch information
Roger Nesbitt
committed
May 2, 2016
1 parent
9930fae
commit ee8622d
Showing
3 changed files
with
42 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# | ||
# Unfortunately, prawn mutates arguments passed in to it. | ||
# When we make a copy of one of the call stacks, we need to make a deep | ||
# duplicate of it so that the first time prawn mutates the arguments, it | ||
# won't affect the subsequent calls. | ||
# | ||
module Prawn::SVG::Elements::CallDuplicator | ||
private | ||
|
||
def duplicate_calls(calls) | ||
calls.map { |call| duplicate_call(call) } | ||
end | ||
|
||
def duplicate_call(call) | ||
[call[0], duplicate_array(call[1]), duplicate_calls(call[2])] | ||
end | ||
|
||
def duplicate_array(array) | ||
array.map do |value| | ||
case value | ||
when Array then duplicate_array(value) | ||
when Hash then duplicate_hash(value) | ||
else value | ||
end | ||
end | ||
end | ||
|
||
def duplicate_hash(hash) | ||
hash.each.with_object({}) do |(key, value), result| | ||
result[key] = case value | ||
when Array then duplicate_array(value) | ||
when Hash then duplicate_hash(value) | ||
else value | ||
end | ||
end | ||
end | ||
end |