@@ -288,46 +288,62 @@ def disable_enforce_available_locales
288288 end
289289 end
290290
291- if Faker ::Config . lazy_loading?
292- def self . load_path ( *constants )
293- constants . map do |class_name |
294- class_name
295- . to_s
296- . gsub ( '::' , '/' )
297- . gsub ( /([A-Z]+)([A-Z][a-z])/ , '\1_\2' )
298- . gsub ( /([a-z\d ])([A-Z])/ , '\1_\2' )
299- . tr ( '-' , '_' )
300- . downcase
301- end . join ( '/' )
291+ def self . load_path ( *constants )
292+ constants . map do |class_name |
293+ class_name
294+ . to_s
295+ . gsub ( '::' , '/' )
296+ . gsub ( /([A-Z]+)([A-Z][a-z])/ , '\1_\2' )
297+ . gsub ( /([a-z\d ])([A-Z])/ , '\1_\2' )
298+ . tr ( '-' , '_' )
299+ . downcase
300+ end . join ( '/' )
301+ end
302+
303+ # TODO: refactor this
304+
305+ def self . resolve_const ( context_name , class_name )
306+ load_path = case class_name
307+ when :DnD
308+ load_path ( 'faker/games/dnd' )
309+ else
310+ load_path ( context_name , class_name )
311+ end
312+
313+ begin
314+ require ( load_path )
315+ rescue LoadError
316+ require ( load_path . gsub ( 'faker/' , 'faker/default/' ) )
302317 end
318+ end
303319
304- def self . lazy_load ( klass )
305- def klass . const_missing ( class_name )
306- load_path = case class_name
307- when :DnD
308- Faker . load_path ( 'faker/games/dnd' )
309- else
310- Faker . load_path ( name , class_name )
311- end
312-
313- begin
314- require ( load_path )
315- rescue LoadError
316- require ( load_path . gsub ( 'faker/' , 'faker/default/' ) )
317- end
320+ private_class_method :resolve_const
318321
319- const_get ( class_name )
322+ EAGER_LOAD_MUTEX = Mutex . new
323+ private_constant :EAGER_LOAD_MUTEX
324+
325+ # initial usage determines lazy loading or eager loading
326+ # TODO: this can be a bit surprising and error-prone
327+ def self . const_missing ( class_name )
328+ EAGER_LOAD_MUTEX . synchronize do
329+ if Config . lazy_loading?
330+ resolve_const ( name , class_name )
331+ elsif !@eager_load
332+ @eager_load = true
333+ Dir . glob ( [ "#{ __dir__ } /faker/*.rb" , "#{ __dir__ } /faker/**/*.rb" ] ) . each { |f | require f }
320334 end
321335 end
322336
323- lazy_load ( self )
337+ const_get ( class_name )
324338 end
325- end
326339
327- unless Faker ::Config . lazy_loading?
328- rb_files = [ ]
329- rb_files << File . join ( mydir , 'faker' , '*.rb' )
330- rb_files << File . join ( mydir , 'faker' , '/**/*.rb' )
340+ def self . lazy_load ( klass )
341+ mutex = Mutex . new
342+
343+ klass . define_singleton_method ( :const_missing ) do |class_name |
344+ mutex . synchronize { Faker . resolve_const ( name , class_name ) }
331345
332- Dir . glob ( rb_files ) . each { |file | require file }
346+ const_get ( class_name )
347+ end
348+ end
333349end
0 commit comments