Class: AutoReloader
- Inherits:
-
Object
- Object
- AutoReloader
- Includes:
- Singleton
- Defined in:
- lib/auto_reloader.rb,
lib/auto_reloader/version.rb
Defined Under Namespace
Modules: RequireOverride
Constant Summary collapse
- ActivatedMoreThanOnce =
Class.new RuntimeError
- InvalidUsage =
Class.new RuntimeError
- VERSION =
'0.1.2'
Instance Attribute Summary collapse
-
#default_delay ⇒ Object
readonly
Returns the value of attribute default_delay.
-
#default_onchange ⇒ Object
readonly
Returns the value of attribute default_onchange.
-
#reloadable_paths ⇒ Object
Returns the value of attribute reloadable_paths.
Class Method Summary collapse
- .activate(*args) ⇒ Object
- .reload!(delay: instance.default_delay, onchange: instance.default_onchange) ⇒ Object
- .reloadable_paths=(paths) ⇒ Object
- .unload! ⇒ Object
Instance Method Summary collapse
- #activate(reloadable_paths: [], onchange: true, delay: nil) ⇒ Object
-
#initialize ⇒ AutoReloader
constructor
A new instance of AutoReloader.
- #reload!(delay: default_delay, onchange: default_onchange) ⇒ Object
- #require(path, &block) ⇒ Object
- #require_relative(path, fullpath) ⇒ Object
- #unload! ⇒ Object
Constructor Details
#initialize ⇒ AutoReloader
Returns a new instance of AutoReloader.
28 29 30 |
# File 'lib/auto_reloader.rb', line 28 def initialize @activate_lock = Mutex.new end |
Instance Attribute Details
#default_delay ⇒ Object (readonly)
Returns the value of attribute default_delay.
11 12 13 |
# File 'lib/auto_reloader.rb', line 11 def default_delay @default_delay end |
#default_onchange ⇒ Object (readonly)
Returns the value of attribute default_onchange.
11 12 13 |
# File 'lib/auto_reloader.rb', line 11 def default_onchange @default_onchange end |
#reloadable_paths ⇒ Object
Returns the value of attribute reloadable_paths.
11 12 13 |
# File 'lib/auto_reloader.rb', line 11 def reloadable_paths @reloadable_paths end |
Class Method Details
.activate(*args) ⇒ Object
24 25 26 |
# File 'lib/auto_reloader.rb', line 24 def self.activate(*args) instance.activate *args end |
.reload!(delay: instance.default_delay, onchange: instance.default_onchange) ⇒ Object
89 90 91 92 93 94 95 |
# File 'lib/auto_reloader.rb', line 89 def self.reload!(delay: instance.default_delay, onchange: instance.default_onchange) if block_given? instance.reload!(delay: delay, onchange: onchange){ yield } else instance.reload!(delay: delay, onchange: onchange) end end |
.reloadable_paths=(paths) ⇒ Object
49 50 51 |
# File 'lib/auto_reloader.rb', line 49 def self.reloadable_paths=(paths) instance.reloadable_paths = paths end |
.unload! ⇒ Object
114 115 116 |
# File 'lib/auto_reloader.rb', line 114 def self.unload! instance.unload! end |
Instance Method Details
#activate(reloadable_paths: [], onchange: true, delay: nil) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/auto_reloader.rb', line 33 def activate(reloadable_paths: [], onchange: true, delay: nil) @activate_lock.synchronize do raise ActivatedMoreThanOnce, "Can only activate Autoreloader once" if @reloadable_paths @default_delay = delay @default_onchange = onchange self.reloadable_paths = reloadable_paths Object.include RequireOverride @require_lock = Monitor.new # monitor is like Mutex, but reentrant @reload_lock = Mutex.new @top_level_consts_stack = [] @unload_constants = Set.new @unload_files = Set.new @last_reloaded = clock_time end end |
#reload!(delay: default_delay, onchange: default_onchange) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/auto_reloader.rb', line 98 def reload!(delay: default_delay, onchange: default_onchange) if onchange && !block_given? raise InvalidUsage, 'A block must be provided to reload! when onchange is true (the default)' end unload! unless reload_ignored = ignore_reload?(delay, onchange) result = nil if block_given? result = yield find_mtime end @last_reloaded = clock_time if delay result end |
#require(path, &block) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/auto_reloader.rb', line 57 def require(path, &block) was_required = false @require_lock.synchronize do @top_level_consts_stack << Set.new old_consts = Object.constants prev_consts = new_top_level_constants = nil begin was_required = yield ensure prev_consts = @top_level_consts_stack.pop if was_required new_top_level_constants = Object.constants - old_consts - prev_consts.to_a @top_level_consts_stack.each{|c| c.merge new_top_level_constants } end end return false unless was_required # was required already, do nothing full_loaded_path = $LOADED_FEATURES.last reloadable = reloadable?(full_loaded_path, path) if reloadable @reload_lock.synchronize do @unload_constants.merge new_top_level_constants @unload_files << full_loaded_path end end end was_required end |
#require_relative(path, fullpath) ⇒ Object
85 86 87 |
# File 'lib/auto_reloader.rb', line 85 def require_relative(path, fullpath) Object.require fullpath end |
#unload! ⇒ Object
118 119 120 121 122 123 124 125 |
# File 'lib/auto_reloader.rb', line 118 def unload! @reload_lock.synchronize do @unload_files.each{|f| $LOADED_FEATURES.delete f } @unload_constants.each{|c| Object.send :remove_const, c } @unload_files = Set.new @unload_constants = Set.new end end |