Skip to content

Instantly share code, notes, and snippets.

@matthewd
Last active August 29, 2015 14:00
Show Gist options
  • Save matthewd/b74b0de5244b2a95952b to your computer and use it in GitHub Desktop.
Save matthewd/b74b0de5244b2a95952b to your computer and use it in GitHub Desktop.
gsub forwarding with $1
class X < String
def evil_call(meth, args, block, &wrap_block)
block.binding.eval(<<-END, __FILE__, __LINE__+1).call(to_str, meth, args, wrap_block)
lambda do |str, meth, args, block|
str.send(meth, *args, &block)
end
END
end
def gsub(*args, &block)
if block
X.new(evil_call(:gsub, args, block) {|*x| "<#{block.(*x).downcase}>" })
else
X.new(to_str.gsub(*args))
end
end
end
require 'minitest/autorun'
class EvilTest < Minitest::Test
def test_return_type
assert_equal X, (X.new.gsub('a', 'b')).class
assert_equal X, (X.new.gsub('a') { 'b' }).class
end
def test_normal_string
assert_equal 'XboXb', 'bob'.gsub(/(b)/) { "X#$1" }
end
def test_evil_string
assert_equal '<xb>o<xb>', X.new('bob').gsub(/(b)/) { "X#$1" }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment