Skip to content

Instantly share code, notes, and snippets.

@yalab
Created September 23, 2016 09:37
Show Gist options
  • Save yalab/1a2b63ce4537c74c38a0b3d5fd7f6e6c to your computer and use it in GitHub Desktop.
Save yalab/1a2b63ce4537c74c38a0b3d5fd7f6e6c to your computer and use it in GitHub Desktop.
require 'erubis'
template = <<'END'
<%= Time.now %>
<%= ::Time.now %>
<%= "string gsub".gsub!(//, '') %>
## Hello <%= @user %>!
<% for item in @list %>
- <%= item %>
<% end %>
<%== self %>
<%== binding %>
<% open("/etc/hosts") do |f| %>
<%= f.read %>
<% end %>
END
SKIP_REDFINE_METHODS = [:instance_variable_set, :is_a?, :puts, :p, :instance_eval, :object_id, :__send__]
module M
Object.constants.each do |klass_name|
klass = Object.const_get(klass_name)
next unless klass.is_a?(Class)
klass.methods.each do |method|
refine klass do
next if SKIP_REDFINE_METHODS.include?(method)
module_eval <<-EOS, __FILE__, __LINE__
def #{method}(*args)
"refined #{klass}##{method}"
end
EOS
end
end
klass.singleton_methods.each do |method|
refine klass.singleton_class do
define_method(method) do
"refined #{klass}.#{method}"
end
end
end
end
refine String do
def gsub!(pat, str)
"refined string gsub!"
end
end
# refine Time.singleton_class do
# def now
# "hoge"
# end
# end
end
class EContext < Erubis::Context
Kernel.methods.each do |m|
next if SKIP_REDFINE_METHODS.include? m
module_eval <<-EOS, __FILE__, __LINE__
def #{m}(*args)
"EContext##{m}"
end
EOS
end
end
class EEscapedEruby < Erubis::EscapedEruby
using M
def evaluate(_context=EContext.new)
_context = EContext.new(_context) if _context.is_a?(Hash)
@_proc ||= eval("proc { #{@src} }", binding(), @filename || '(erubis)')
return _context.instance_eval(&@_proc)
end
end
context = EContext.new(:user=>'World', :list=>['a','b','c'])
eruby = EEscapedEruby.new(template)
eruby.src = eruby.src
print eruby.evaluate(context)
p Time.now
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment