Skip to content

Commit 7b368df

Browse files
authored
Fix SelfDrop equality (#2091)
1 parent 742ac3d commit 7b368df

3 files changed

Lines changed: 37 additions & 1 deletion

File tree

lib/liquid/context.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def find_variable(key, raise_on_not_found: true)
208208

209209
# `self` resolves to a SelfDrop (enabling `self['var']` lookups),
210210
# but only when it hasn't been explicitly assigned as a local variable.
211-
return SelfDrop.new(self) if key == Expression::SELF && !index
211+
return @self_drop ||= SelfDrop.new(self) if key == Expression::SELF && !index
212212

213213
variable = if index
214214
lookup_and_evaluate(@scopes[index], key, raise_on_not_found: raise_on_not_found)

lib/liquid/self_drop.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,20 @@ def to_liquid
3535
self
3636
end
3737

38+
def ==(other)
39+
other.is_a?(SelfDrop) && other.self_context.equal?(@self_context)
40+
end
41+
42+
alias_method :eql?, :==
43+
44+
def hash
45+
@self_context.object_id.hash
46+
end
47+
48+
protected
49+
50+
attr_reader :self_context
51+
3852
undef context=
3953
end
4054
end

test/integration/self_drop_context_test.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,28 @@ def test_self_drop_context_setter_is_undefined
7777
assert_template_result('42', '{{ self.x }}', { 'x' => 42 })
7878
end
7979

80+
def test_self_drop_repeated_lookups_compare_equal_for_same_context
81+
context = Context.new
82+
drop = context.find_variable("self")
83+
cached_drop = context.find_variable("self")
84+
85+
assert_same(drop, cached_drop)
86+
assert_equal(drop.object_id, cached_drop.object_id)
87+
assert_equal(drop, cached_drop)
88+
end
89+
90+
def test_assigned_self_drop_compares_equal_to_itself
91+
assert_template_result('T', '{% assign s = self %}{% if s == s %}T{% else %}F{% endif %}')
92+
end
93+
94+
def test_distinct_self_assignments_compare_equal_for_same_context
95+
assert_template_result('T', '{% assign a = self %}{% assign b = self %}{% if a == b %}T{% else %}F{% endif %}')
96+
end
97+
98+
def test_bare_self_compares_equal_to_bare_self
99+
assert_template_result('T', '{% if self == self %}T{% else %}F{% endif %}')
100+
end
101+
80102
def test_self_drop_with_strict_variables_does_not_raise_for_defined_var
81103
t = Template.parse('{{ self.x }}')
82104
result = t.render({ 'x' => 42 }, strict_variables: true)

0 commit comments

Comments
 (0)