Skip to content

Commit

Permalink
Allow for custom < Hash classes to override #to_s (#1896)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianks authored Jan 16, 2025
1 parent 4b65a28 commit 74af735
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.6
3.4.1
46 changes: 28 additions & 18 deletions lib/liquid/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,34 +90,38 @@ def self.to_liquid_value(obj)
obj
end

if RUBY_VERSION >= '3.4'
def self.to_s(obj, seen = {})
case obj
when Hash
def self.to_s(obj, seen = {})
case obj
when Hash
# If the custom hash implementation overrides `#to_s`, use their
# custom implementation. Otherwise we use Liquid's default
# implementation.
if obj.class.instance_method(:to_s) == HASH_TO_S_METHOD
hash_inspect(obj, seen)
when Array
array_inspect(obj, seen)
else
obj.to_s
end
when Array
array_inspect(obj, seen)
else
obj.to_s
end
end

def self.inspect(obj, seen = {})
case obj
when Hash
def self.inspect(obj, seen = {})
case obj
when Hash
# If the custom hash implementation overrides `#inspect`, use their
# custom implementation. Otherwise we use Liquid's default
# implementation.
if obj.class.instance_method(:inspect) == HASH_INSPECT_METHOD
hash_inspect(obj, seen)
when Array
array_inspect(obj, seen)
else
obj.inspect
end
end
else
def self.to_s(obj, seen = nil)
obj.to_s
end

def self.inspect(obj, seen = nil)
when Array
array_inspect(obj, seen)
else
obj.inspect
end
end
Expand Down Expand Up @@ -175,5 +179,11 @@ def self.hash_inspect(hash, seen = {})
ensure
seen.delete(hash.object_id)
end

HASH_TO_S_METHOD = Hash.instance_method(:to_s)
private_constant :HASH_TO_S_METHOD

HASH_INSPECT_METHOD = Hash.instance_method(:inspect)
private_constant :HASH_INSPECT_METHOD
end
end
17 changes: 17 additions & 0 deletions test/integration/hash_rendering_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,21 @@ def test_render_hash_with_array_values_hash
def test_render_hash_with_hash_key
assert_template_result("{{\"foo\"=>\"bar\"}=>42}", "{{ my_hash }}", { "my_hash" => { Hash["foo" => "bar"] => 42 } })
end

def test_rendering_hash_with_custom_to_s_method_uses_custom_to_s
my_hash = Class.new(Hash) do
def to_s
"kewl"
end
end.new

assert_template_result("kewl", "{{ my_hash }}", { "my_hash" => my_hash })
end

def test_rendering_hash_without_custom_to_s_uses_default_inspect
my_hash = Class.new(Hash).new
my_hash[:foo] = :bar

assert_template_result("{:foo=>:bar}", "{{ my_hash }}", { "my_hash" => my_hash })
end
end

0 comments on commit 74af735

Please sign in to comment.