mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
Don't redirect $stdout in :ruby filter.
Redirecting $stdout isn't thread safe. Provide `haml_io`, an IO object that writes to the buffer.
This commit is contained in:
parent
ba8b4c1694
commit
4d3d0b27a7
3 changed files with 36 additions and 9 deletions
|
@ -5,8 +5,9 @@
|
|||
* The Haml exectutable now accepts an `--autoclose` option. You can now
|
||||
specify a list of tags that should be autoclosed
|
||||
|
||||
* The `:ruby` filter now runs the generated code with a exclusive lock, to
|
||||
prevent issues with sharing `$stdout` across threads.
|
||||
* The `:ruby` filter no longer redirects $stdout to the Haml document, as this
|
||||
is not thread safe. Instead it provides a `haml_io` local variable, which is
|
||||
an IO object that writes to the document.
|
||||
|
||||
* HTML5 is now the default output format rather than XHTML. This was already
|
||||
the default on Rails 3+, so many users will notice no difference.
|
||||
|
|
|
@ -258,9 +258,13 @@ RUBY
|
|||
end
|
||||
end
|
||||
|
||||
# Parses the filtered text with the normal Ruby interpreter. All output sent
|
||||
# to `$stdout`, such as with `puts`, is output into the Haml document. Not
|
||||
# available if the {file:REFERENCE.md#suppress_eval-option `:suppress_eval`}
|
||||
# Parses the filtered text with the normal Ruby interpreter. Creates an IO
|
||||
# object named `haml_io`, anything written to it is output into the Haml
|
||||
# document. In previous version this filter redirected any output to `$stdout`
|
||||
# to the Haml document, this was not threadsafe and has been removed, you
|
||||
# should use `haml_io` instead.
|
||||
#
|
||||
# Not available if the {file:REFERENCE.md#suppress_eval-option `:suppress_eval`}
|
||||
# option is set to true. The Ruby code is evaluated in the same context as
|
||||
# the Haml template.
|
||||
module Ruby
|
||||
|
@ -272,11 +276,13 @@ RUBY
|
|||
return if compiler.options[:suppress_eval]
|
||||
compiler.instance_eval do
|
||||
push_silent <<-FIRST.gsub("\n", ';') + text + <<-LAST.gsub("\n", ';')
|
||||
_haml_old_stdout = $stdout
|
||||
$stdout = StringIO.new(_hamlout.buffer, 'a')
|
||||
begin
|
||||
haml_io = StringIO.new(_hamlout.buffer, 'a')
|
||||
FIRST
|
||||
_haml_old_stdout, $stdout = $stdout, _haml_old_stdout
|
||||
_haml_old_stdout.close
|
||||
ensure
|
||||
haml_io.close
|
||||
haml_io = nil
|
||||
end
|
||||
LAST
|
||||
end
|
||||
end
|
||||
|
|
|
@ -235,4 +235,24 @@ class EscapedFilterTest < MiniTest::Unit::TestCase
|
|||
haml = ":escaped\n &"
|
||||
assert_equal(html, render(haml))
|
||||
end
|
||||
end
|
||||
|
||||
class RubyFilterTest < MiniTest::Unit::TestCase
|
||||
test "can write to haml_io" do
|
||||
haml = ":ruby\n haml_io.puts 'hello'\n"
|
||||
html = "hello\n"
|
||||
assert_equal(html, render(haml))
|
||||
end
|
||||
|
||||
test "haml_io appends to output" do
|
||||
haml = "hello\n:ruby\n haml_io.puts 'hello'\n"
|
||||
html = "hello\nhello\n"
|
||||
assert_equal(html, render(haml))
|
||||
end
|
||||
|
||||
test "can create local variables" do
|
||||
haml = ":ruby\n a = 7\n=a"
|
||||
html = "7\n"
|
||||
assert_equal(html, render(haml))
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue