class_loader 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rake_ext'
2
2
 
3
3
  project(
4
4
  name: "class_loader",
5
- version: "0.4.2",
5
+ version: "0.4.3",
6
6
  summary: "Automatically finds, loads and reloads Classes",
7
7
 
8
8
  author: "Alexey Petrushin",
data/lib/class_loader.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  raise 'ruby 1.9.2 or higher required!' if RUBY_VERSION < '1.9.2'
2
2
 
3
+ module ClassLoader
4
+ end
5
+
3
6
  %w(
4
7
  support
5
8
  file_system_adapter/camel_case_translator
@@ -1,44 +1,42 @@
1
- module ClassLoader
2
- class ChainedAdapter
3
- attr_accessor :adapters
1
+ class ClassLoader::ChainedAdapter
2
+ attr_accessor :adapters
4
3
 
5
- def initialize
6
- @adapters = []
7
- end
8
-
9
- %w(
10
- exist?
11
- read
12
- to_file_path
13
- to_class_name
14
- ).each do |method|
15
- define_method method do |*args|
16
- catch :found do
17
- adapters.each do |a|
18
- value = a.send method, *args
19
- throw :found, value if value
20
- end
21
- nil
4
+ def initialize
5
+ @adapters = []
6
+ end
7
+
8
+ %w(
9
+ exist?
10
+ read
11
+ to_file_path
12
+ to_class_name
13
+ ).each do |method|
14
+ define_method method do |*args|
15
+ catch :found do
16
+ adapters.each do |a|
17
+ value = a.send method, *args
18
+ throw :found, value if value
22
19
  end
20
+ nil
23
21
  end
24
22
  end
25
-
26
- def each_changed_class &block
27
- adapters.each{|a| a.each_changed_class &block}
28
- end
29
-
30
- def each_class &block
31
- adapters.each{|a| a.each_class &block}
32
- end
33
-
34
- def clear
35
- adapters.each{|a| a.clear}
36
- end
37
-
38
- def add_path *args
39
- adapters.each do |a|
40
- a.add_path *args if a.respond_to? :add_path
41
- end
23
+ end
24
+
25
+ def each_changed_class &block
26
+ adapters.each{|a| a.each_changed_class &block}
27
+ end
28
+
29
+ def each_class &block
30
+ adapters.each{|a| a.each_class &block}
31
+ end
32
+
33
+ def clear
34
+ adapters.each{|a| a.clear}
35
+ end
36
+
37
+ def add_path *args
38
+ adapters.each do |a|
39
+ a.add_path *args if a.respond_to? :add_path
42
40
  end
43
41
  end
44
42
  end
@@ -1,13 +1,15 @@
1
1
  require 'monitor'
2
2
 
3
+ warn 'ClassLoader: working in slow, debug mode with explicit tmp file generation!' if defined?(CLASS_LOADER_GENERATE_TMP_FILES)
4
+
3
5
  module ClassLoader
4
6
  @observers = []
5
7
  SYNC = Monitor.new
6
8
 
7
9
  class << self
8
- def loaded_classes; @loaded_classes ||= {} end
10
+ def loaded_classes; @loaded_classes ||= {} end
9
11
 
10
- def load_class namespace, const, reload = false
12
+ def load_class namespace, const, reload = false
11
13
  SYNC.synchronize do
12
14
  original_namespace = namespace
13
15
  namespace = nil if namespace == Object or namespace == Module
@@ -52,16 +54,16 @@ module ClassLoader
52
54
  end
53
55
  end
54
56
 
55
- def reload_class class_name
57
+ def reload_class class_name
56
58
  SYNC.synchronize do
57
59
  class_name = class_name.sub(/^::/, "")
58
60
  namespace = Module.namespace_for(class_name)
59
61
  name = class_name.sub(/^#{namespace}::/, "")
60
-
62
+
61
63
  # removing old class
62
64
  # class_container = (namespace || Object)
63
65
  # class_container.send :remove_const, name if class_container.const_defined? name
64
-
66
+
65
67
  return load_class namespace, name, true
66
68
  end
67
69
  end
@@ -131,6 +133,9 @@ module ClassLoader
131
133
  #
132
134
  attr_accessor :watch_interval
133
135
  def start_watching!
136
+ # reloading doesn works in debug mode, because we by ourself are generating tmp source files
137
+ return if defined?(CLASS_LOADER_GENERATE_TMP_FILES)
138
+
134
139
  unless @watching_thread
135
140
  @watching_thread = Thread.new do
136
141
  while true
@@ -169,8 +174,25 @@ module ClassLoader
169
174
  def load class_name, const
170
175
  script = adapter.read class_name
171
176
  script = wrap_inside_namespace Module.namespace_for(class_name), script
172
- file_path = adapter.to_file_path(class_name)
173
- eval script, TOPLEVEL_BINDING, file_path
177
+ file_path = adapter.to_file_path(class_name)
178
+
179
+ # sometimes we need to generate file explicitly
180
+ # for example evaluated code will not be shown in Ruby coverage tool
181
+ unless defined?(CLASS_LOADER_GENERATE_TMP_FILES)
182
+ eval script, TOPLEVEL_BINDING, file_path
183
+ else
184
+ if file_path =~ /\.rb$/
185
+ tmp_file_path = file_path.sub /\.rb$/, '.cltmp.rb'
186
+ begin
187
+ File.open(tmp_file_path, "w"){|f| f.write(script)}
188
+ Kernel.load tmp_file_path
189
+ ensure
190
+ File.delete tmp_file_path if defined?(CLASS_LOADER_CLEAN) and ::File.exist?(tmp_file_path)
191
+ end
192
+ else
193
+ eval script, TOPLEVEL_BINDING, file_path
194
+ end
195
+ end
174
196
  end
175
197
 
176
198
  def raise_without_self exception, message
@@ -1,141 +1,139 @@
1
- module ClassLoader
2
- class FileSystemAdapter
3
- attr_reader :translator
4
-
5
- def initialize class_name_translator
6
- @translator = class_name_translator
7
- @paths, @watched_paths, @file_name_cache = [], [], {}
8
- @watched_files, @first_check = {}, true
9
- end
10
-
11
- def exist? class_name
12
- !!to_file_path(class_name)
13
- end
14
- alias_method :exists?, :exist?
15
-
16
- def read class_name
17
- file_path = to_file_path class_name
18
- return nil unless file_path
19
-
20
- if file_path =~ /\.rb$/
21
- File.open(file_path){|f| f.read}
22
- else
23
- "module #{class_name}; end;"
24
- end
25
- end
1
+ class ClassLoader::FileSystemAdapter
2
+ attr_reader :translator
3
+
4
+ def initialize class_name_translator
5
+ @translator = class_name_translator
6
+ @paths, @watched_paths, @file_name_cache = [], [], {}
7
+ @watched_files, @first_check = {}, true
8
+ end
9
+
10
+ def exist? class_name
11
+ !!to_file_path(class_name)
12
+ end
13
+ alias_method :exists?, :exist?
14
+
15
+ def read class_name
16
+ file_path = to_file_path class_name
17
+ return nil unless file_path
26
18
 
27
- def to_file_path class_name
28
- file_path, exist = @file_name_cache[class_name] || []
29
- unless exist
30
- normalized_name = translator.to_file_path class_name
31
- file_path = catch :found do
32
- # files
33
- paths.each do |base|
34
- try = "#{base}/#{normalized_name}.rb"
35
- if File.exist? try
36
- throw :found, try
37
- end
38
- end
39
-
40
- # dirs
41
- paths.each do |base|
42
- try = "#{base}/#{normalized_name}"
43
- if File.exist? try
44
- throw :found, try
45
- end
19
+ if file_path =~ /\.rb$/
20
+ File.open(file_path){|f| f.read}
21
+ else
22
+ "module #{class_name}; end;"
23
+ end
24
+ end
25
+
26
+ def to_file_path class_name
27
+ file_path, exist = @file_name_cache[class_name] || []
28
+ unless exist
29
+ normalized_name = translator.to_file_path class_name
30
+ file_path = catch :found do
31
+ # files
32
+ paths.each do |base|
33
+ try = "#{base}/#{normalized_name}.rb"
34
+ if File.exist? try
35
+ throw :found, try
46
36
  end
47
-
48
- nil
49
37
  end
50
- @file_name_cache[class_name] = [file_path, true]
51
- end
52
- file_path
53
- end
54
-
55
- def to_class_name normalized_path
56
- raise "Internal error, file_name should be absolute path (#{normalized_path})!" unless normalized_path =~ /^\//
57
- raise "Internal error, file_name should be without .rb suffix (#{normalized_path})!" if normalized_path =~ /\.rb$/
58
-
59
- paths.each do |base_path|
60
- if normalized_path.start_with? base_path
61
- normalized_name = normalized_path.sub(base_path + '/', '')
62
- if translator.is_it_class? normalized_name
63
- return translator.to_class_name(normalized_name)
38
+
39
+ # dirs
40
+ paths.each do |base|
41
+ try = "#{base}/#{normalized_name}"
42
+ if File.exist? try
43
+ throw :found, try
64
44
  end
65
45
  end
46
+
47
+ nil
66
48
  end
67
- nil
49
+ @file_name_cache[class_name] = [file_path, true]
68
50
  end
51
+ file_path
52
+ end
53
+
54
+ def to_class_name normalized_path
55
+ raise "Internal error, file_name should be absolute path (#{normalized_path})!" unless normalized_path =~ /^\//
56
+ raise "Internal error, file_name should be without .rb suffix (#{normalized_path})!" if normalized_path =~ /\.rb$/
69
57
 
70
- def add_path base_path, watch = false
71
- base_path = File.expand_path(base_path)
72
- # raise "#{base_path} already added!" if paths.include? base_path
73
- unless paths.include? base_path
74
- paths << base_path
75
- watched_paths << base_path if watch
58
+ paths.each do |base_path|
59
+ if normalized_path.start_with? base_path
60
+ normalized_name = normalized_path.sub(base_path + '/', '')
61
+ if translator.is_it_class? normalized_name
62
+ return translator.to_class_name(normalized_name)
63
+ end
76
64
  end
77
65
  end
78
-
79
- def clear
80
- @paths, @watched_paths, @file_name_cache = [], [], {}
81
- @watched_files, @first_check = {}, true
82
- end
83
-
84
- def each_changed_class &block
85
- unless @first_check == @watched_paths
86
- @first_check = @watched_paths.clone
87
- each_watched_file{|file_path, file_name| remember_file file_path}
88
- else
89
- each_watched_file do |file_path, file_name|
90
- if file_changed? file_path
91
- remember_file file_path
92
-
93
- normalized_name = file_name.sub(/\.rb$/, "")
94
- block.call translator.to_class_name(normalized_name)
95
- end
96
- end
97
- end
66
+ nil
67
+ end
68
+
69
+ def add_path base_path, watch = false
70
+ base_path = File.expand_path(base_path)
71
+ # raise "#{base_path} already added!" if paths.include? base_path
72
+ unless paths.include? base_path
73
+ paths << base_path
74
+ watched_paths << base_path if watch
98
75
  end
99
-
100
- def each_class &block
101
- @paths.each do |base_path|
102
- Dir.glob("#{base_path}/**/*.rb").each do |file_path|
103
- normalized_path = file_path.sub(/\.rb$/, "")
76
+ end
77
+
78
+ def clear
79
+ @paths, @watched_paths, @file_name_cache = [], [], {}
80
+ @watched_files, @first_check = {}, true
81
+ end
82
+
83
+ def each_changed_class &block
84
+ unless @first_check == @watched_paths
85
+ @first_check = @watched_paths.clone
86
+ each_watched_file{|file_path, file_name| remember_file file_path}
87
+ else
88
+ each_watched_file do |file_path, file_name|
89
+ if file_changed? file_path
90
+ remember_file file_path
104
91
 
105
- normalized_name = normalized_path.sub(base_path + "/", '')
106
- class_name = translator.to_class_name(normalized_name)
107
- block.call class_name
92
+ normalized_name = file_name.sub(/\.rb$/, "")
93
+ block.call translator.to_class_name(normalized_name)
108
94
  end
95
+ end
96
+ end
97
+ end
98
+
99
+ def each_class &block
100
+ @paths.each do |base_path|
101
+ Dir.glob("#{base_path}/**/*.rb").each do |file_path|
102
+ normalized_path = file_path.sub(/\.rb$/, "")
103
+
104
+ normalized_name = normalized_path.sub(base_path + "/", '')
105
+ class_name = translator.to_class_name(normalized_name)
106
+ block.call class_name
109
107
  end
110
108
  end
111
-
112
- def each_watched_file &block
113
- @watched_paths.each do |base_path|
114
- Dir.glob("#{base_path}/**/*.rb").each do |file_path|
115
- file_name = file_path.sub(base_path + '/', '')
109
+ end
110
+
111
+ def each_watched_file &block
112
+ @watched_paths.each do |base_path|
113
+ Dir.glob("#{base_path}/**/*.rb").each do |file_path|
114
+ file_name = file_path.sub(base_path + '/', '')
116
115
 
117
- if translator.is_it_class? file_name
118
- block.call file_path, file_name
119
- end
116
+ if translator.is_it_class? file_name
117
+ block.call file_path, file_name
120
118
  end
121
119
  end
122
120
  end
121
+ end
122
+
123
+ def inspect
124
+ "FileSystemAdapter (#{@paths.join(', ')})"
125
+ end
126
+
127
+ protected
128
+ attr_reader :paths, :watched_paths, :watcher, :watched_files
123
129
 
124
- def inspect
125
- "FileSystemAdapter (#{@paths.join(', ')})"
126
- end
127
-
128
- protected
129
- attr_reader :paths, :watched_paths, :watcher, :watched_files
130
-
131
- def file_changed? file_path
132
- old_time = watched_files[file_path]
133
- old_time == nil or old_time != File.mtime(file_path)
134
- end
130
+ def file_changed? file_path
131
+ old_time = watched_files[file_path]
132
+ old_time == nil or old_time != File.mtime(file_path)
133
+ end
135
134
 
136
- def remember_file file_path
137
- watched_files[file_path] = File.mtime(file_path)
138
- end
139
-
140
- end
135
+ def remember_file file_path
136
+ watched_files[file_path] = File.mtime(file_path)
137
+ end
138
+
141
139
  end
@@ -1,18 +1,16 @@
1
- module ClassLoader
2
- class CamelCaseTranslator
3
- def self.to_class_name normalized_file_name
4
- raise "internall error, invalid format for #{normalized_file_name}!" if normalized_file_name =~ /^\//
5
- normalized_file_name.gsub('/', '::')
6
- end
7
-
8
- def self.to_file_path class_name
9
- raise "internall error, invalid format for #{class_name}!" if class_name =~ /^::/
10
- class_name.gsub('::', '/')
11
- end
12
-
13
- def self.is_it_class? normalized_file_name
14
- raise "internall error, invalid format for #{normalized_file_name}!" if normalized_file_name =~ /^\//
15
- normalized_file_name[0..0] =~ /[A-Z]/
16
- end
1
+ class ClassLoader::CamelCaseTranslator
2
+ def self.to_class_name normalized_file_name
3
+ raise "internall error, invalid format for #{normalized_file_name}!" if normalized_file_name =~ /^\//
4
+ normalized_file_name.gsub('/', '::')
5
+ end
6
+
7
+ def self.to_file_path class_name
8
+ raise "internall error, invalid format for #{class_name}!" if class_name =~ /^::/
9
+ class_name.gsub('::', '/')
10
+ end
11
+
12
+ def self.is_it_class? normalized_file_name
13
+ raise "internall error, invalid format for #{normalized_file_name}!" if normalized_file_name =~ /^\//
14
+ normalized_file_name[0..0] =~ /[A-Z]/
17
15
  end
18
16
  end
@@ -1,18 +1,16 @@
1
- module ClassLoader
2
- class UnderscoredTranslator
3
- def self.to_class_name normalized_file_name
4
- raise "internall error, invalid format for #{normalized_file_name}!" if normalized_file_name =~ /^\//
5
- normalized_file_name.camelize
6
- end
7
-
8
- def self.to_file_path class_name
9
- raise "internall error, invalid format for #{class_name}!" if class_name =~ /^::/
10
- class_name.underscore
11
- end
12
-
13
- def self.is_it_class? normalized_file_name
14
- raise "internall error, invalid format for #{normalized_file_name}!" if normalized_file_name =~ /^\//
15
- normalized_file_name[0..0] =~ /[a-z]/
16
- end
1
+ module ClassLoader::UnderscoredTranslator
2
+ def self.to_class_name normalized_file_name
3
+ raise "internall error, invalid format for #{normalized_file_name}!" if normalized_file_name =~ /^\//
4
+ normalized_file_name.camelize
5
+ end
6
+
7
+ def self.to_file_path class_name
8
+ raise "internall error, invalid format for #{class_name}!" if class_name =~ /^::/
9
+ class_name.underscore
10
+ end
11
+
12
+ def self.is_it_class? normalized_file_name
13
+ raise "internall error, invalid format for #{normalized_file_name}!" if normalized_file_name =~ /^\//
14
+ normalized_file_name[0..0] =~ /[a-z]/
17
15
  end
18
16
  end
@@ -0,0 +1,8 @@
1
+ desc "Cleans tmp files generated by ClassLoader in debug mode"
2
+ namespace :class_loader do
3
+ task :clean do
4
+ Dir['../**/*.cltmp.rb'].each do |path|
5
+ File.delete path
6
+ end
7
+ end
8
+ end
data/readme.md CHANGED
@@ -42,4 +42,4 @@ There's currently a known bug in Ruby 1.8.x - class loading isn't thread safe, s
42
42
 
43
43
  ## Please let me know about bugs and your proposals, there's the 'Issues' tab at the top, feel free to submit.
44
44
 
45
- Copyright (c) 2011 Alexey Petrushin http://4ire.net, released under the MIT license.
45
+ Copyright (c) Alexey Petrushin http://4ire.net, released under the MIT license.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class_loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-05-19 00:00:00.000000000 +04:00
12
+ date: 2011-07-02 00:00:00.000000000 +04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
  description:
@@ -26,6 +26,7 @@ files:
26
26
  - lib/class_loader/file_system_adapter/underscored_translator.rb
27
27
  - lib/class_loader/file_system_adapter.rb
28
28
  - lib/class_loader/support.rb
29
+ - lib/class_loader/tasks.rb
29
30
  - lib/class_loader.rb
30
31
  - spec/class_loader_spec/anonymous_class/AnonymousSpec/ClassInsideOfAnonymousClass.rb
31
32
  - spec/class_loader_spec/another_namespace/AnotherNamespace/NamespaceA.rb