Project

General

Profile

Bug #11954 » snafu.rb

schnittchen (Thomas Stratmann), 01/05/2016 08:28 PM

 
module ThreadSafe
class NonConcurrentCacheBackend
def []=(key, value)
end
end

class MriCacheBackend < NonConcurrentCacheBackend
WRITE_LOCK = Mutex.new

def []=(key, value)
WRITE_LOCK.synchronize { super }
end
end
end

module ActionView
module CompiledTemplates
end

Finalizer = proc do |mod|
proc do
mod.module_eval do
end
end
end

class Template
def self.compile!
new.compile!
end

def compile!
ObjectSpace.define_finalizer(self, Finalizer[ActionView::CompiledTemplates])
end
end

class PathResolver
def find_all
ThreadSafe::MriCacheBackend.new[""] = nil

Dir["*"]
find_templates
end

def find_templates
[nil].map { |template|
Template.new
}
end
end
end

# Calling module_eval from the block inside the Finalizer proc should either raise an exception because
# wrong number of arguments, or call the block with source = identifier = line = nil.
# Instead,
# snafu.rb:11:in `block in []=': self has wrong type to call super in this context: ThreadSafe::MriCacheBackend (expected #<Class:ActionView::CompiledTemplates>) (TypeError)
# Also note that the behaviour is only triggered when much of the code is present, including
# the Dir["*"]
# The behaviour is present in Ruby 2.3.0, not in 2.2.3

ActionView::CompiledTemplates.singleton_class.send :define_method, :module_eval do |source, identifier, line| # bug does not occur when |*|
# DO NOTHING
end

2200.times do
ActionView::PathResolver.new.find_all
ActionView::Template.compile!
end
(1-1/2)