Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Parse ruby .inspect string to be eval'd
def deinspect(str, level=0)
str.gsub!(/:0x0[^ ]+/, '')
matches = str.match(/<([\w:]+) (.*)>/)
return str unless matches
head = matches[1]
body = matches[2]
hash_content = nil
body.gsub!(/\{.+?\}/) do |_|
hash_content = $~[0]
""
end
level_ = level
prev = ""
body.gsub!(/<(?>[^><]+|\g<0>)*>/) do |_|
level_ += 1
prev += deinspect($~[0], level_)
"x#{level_}"
end
args = []
body.gsub("#", "").gsub(/(@?\w+)=([\w0-9]+|"[^"]*"|\{\})/i) do |_|
args << [ $~[1], $~[2] ]
end
args_new = []
after = ""
args.each do |arg|
if arg[0].include? "@"
arg1 = arg[1]
if hash_content
arg1.gsub!(/\{\}/, hash_content)
end
after += "x#{level}.instance_eval { #{arg[0]} = #{arg1} }\n"
else
args_new << ["#{arg[0]}: #{arg[1]}"]
end
end
args_new = args_new.join ", "
if args.length == 0
args_new = body.gsub("#", "")
end
if hash_content
args_new.gsub!(/\{\}/, hash_content)
end
func = "#{head}.new(#{args_new})"
if head == "URI::HTTPS"
func = "URI.parse(\"#{body}\")"
end
if head == "OAuth::Consumer"
func = "OAuth::Consumer.new('foo', 'bar')"
end
if head == "OAuth::AccessToken"
func = "OAuth::AccessToken.new('')"
end
if head == "Net::HTTPOK"
func = "nil"
end
"#{prev}x#{level} = #{func}\n#{after}"
end
print deinspect(str.split("\n").join(""))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment