Skip to content

Commit

Permalink
Avoid unnecessary defined? usage on Ruby 3+ when using the :ensure op…
Browse files Browse the repository at this point in the history
…tion

defined? was used previously because before Ruby 3, accessing a
undefined instance variable resulted in a verbose mode warning.
As of Ruby 3, it no longer does, so there is no reason to use
defined?.  This results in fewer VM instructions, so this will
improve performance, though the difference is unlikely to be
measurable.
  • Loading branch information
jeremyevans committed Jul 25, 2022
1 parent f8ab0e5 commit 602ab7d
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
@@ -1,3 +1,7 @@
=== master

* Avoid unnecessary defined? usage on Ruby 3+ when using the :ensure option (jeremyevans)

=== 1.10.0 (2020-11-13)

* Improve template parsing, mostly by reducing allocations (jeremyevans)
Expand Down
10 changes: 9 additions & 1 deletion lib/erubi.rb
Expand Up @@ -14,6 +14,7 @@ module Erubi

TEXT_END = RUBY_VERSION >= '2.1' ? "'.freeze;" : "';"
MATCH_METHOD = RUBY_VERSION >= '2.4' ? :match? : :match
SKIP_DEFINED_FOR_INSTANCE_VARIABLE = RUBY_VERSION > '3'
# :nocov:

begin
Expand Down Expand Up @@ -87,7 +88,14 @@ def initialize(input, properties={})

@src = src = properties[:src] || String.new
src << "# frozen_string_literal: true\n" if properties[:freeze]
src << "begin; __original_outvar = #{bufvar} if defined?(#{bufvar}); " if properties[:ensure]
if properties[:ensure]
src << "begin; __original_outvar = #{bufvar}"
if SKIP_DEFINED_FOR_INSTANCE_VARIABLE && /\A@[^@]/ =~ bufvar
src << "; "
else
src << " if defined?(#{bufvar}); "
end
end

unless @escapefunc = properties[:escapefunc]
if escape
Expand Down
49 changes: 48 additions & 1 deletion test/test.rb
Expand Up @@ -261,7 +261,7 @@ def self.quux
</table>
<%== i+1 %>
END1
begin; __original_outvar = @a if defined?(@a); @a = ::String.new; @a << '<table>
begin; __original_outvar = @a#{' if defined?(@a)' if RUBY_VERSION < '3'}; @a = ::String.new; @a << '<table>
<tbody>
'; i = 0
list.each_with_index do |item, i|
Expand Down Expand Up @@ -292,6 +292,53 @@ def self.quux
@a.must_equal 'bar'
end

it "should handle ensure option with no bufvar" do
list = list = ['&\'<>"2']
@options[:ensure] = true
check_output(<<END1, <<END2, <<END3){}
<table>
<tbody>
<% i = 0
list.each_with_index do |item, i| %>
<tr>
<td><%= i+1 %></td>
<td><%== item %></td>
</tr>
<% end %>
</tbody>
</table>
<%== i+1 %>
END1
begin; __original_outvar = _buf if defined?(_buf); _buf = ::String.new; _buf << '<table>
<tbody>
'; i = 0
list.each_with_index do |item, i|
_buf << ' <tr>
<td>'; _buf << ( i+1 ).to_s; _buf << '</td>
<td>'; _buf << ::Erubi.h(( item )); _buf << '</td>
</tr>
'; end
_buf << ' </tbody>
</table>
'; _buf << ::Erubi.h(( i+1 )); _buf << '
';
_buf.to_s
; ensure
_buf = __original_outvar
end
END2
<table>
<tbody>
<tr>
<td>1</td>
<td>&amp;&#39;&lt;&gt;&quot;2</td>
</tr>
</tbody>
</table>
1
END3
end

it "should handle trailing rspace with - modifier in <%|= and <%|" do
eval(::Erubi::CaptureEndEngine.new("<%|= '&' -%>\n<%| -%>\n").src).must_equal '&'
end
Expand Down

0 comments on commit 602ab7d

Please sign in to comment.