switch to proactive autoloading. less harmfull, no load order issues.

pull/6827/head
Konstantin Haase 14 years ago
parent 3e916cfa4a
commit c8adf39118
  1. 71
      lib/proactive_autoloader.rb
  2. 9
      lib/report.rb
  3. 4
      lib/report/filter.rb
  4. 5
      lib/report/group_by.rb
  5. 4
      lib/report/inherited_attribute.rb
  6. 5
      lib/report/query_utils.rb
  7. 6
      lib/report/result.rb
  8. 6
      lib/report/validation.rb

@ -0,0 +1,71 @@
##
# From Urban Dictionary:
# proactive (91 up, 9 down)
#
# Originally a psychological term indicating an empowered, self-reliant
# individual, this has evolved through misuse into a neo-antonym of 'reactive',
# and is used as such to emphasise the preferability of one attitude or course
# of action over another. It connotes alertness, awareness and preparedness, and
# seeks to dispel any conceivable impression of incompetence.
#
# 'Proactive' is interesting in that it is perhaps the classic example of the
# unnecessary neologism. It serves as an antonym to 'reactive', yet 'reactive'
# is itself the antonym of 'active'.
#
# Arguably, since 'proactive' is now perhaps more widely used than 'active' for
# the specific purpose covered by the newer word, 'proactive' must be recognised
# as a legitimate word. The cult of hatred that has understandably grown up
# around the word can only help it endure further.
#
# One is 'active' as opposed to being 'passive' or 'reactive'. One is
# 'proactive' as opposed to 'speaking English'.
module ProactiveAutoloader
extend self
##
# Improved Module#autoload:
# * if path is not given, generate path according to ruby common sense
# * allow passing multiple constant names as symbols
#
# Example:
# autoload :Foo, :Bar, :Blah
def autoload(*list)
return super if list.size == 2 and String === list.last
list.each do |const|
super const, "#{name.underscore}/#{const.to_s.underscore}"
end
end
##
# Sets up autoload hooks in +klass+ for all Ruby files in +dir+, following
# common naming conventions. Subdirectories are *not* scanned.
def setup_autoloaders(klass, dir)
Dir.glob File.expand_path('*.rb', dir) do |file|
klass.autoload File.basename(file, '.rb').camelize, file
end
end
##
# If subclassed, say in foo/bar.rb and there is a directory foo/bar,
# set up autoload hooks in subclass for all ruby files in foo/bar
# (see setup_autoloaders).
def inherited(klass)
auto_setup_autoloaders(klass)
super
end
##
# If extending a class, say in foo/bar.rb and there is a directory foo/bar,
# set up autoload hooks in subclass for all ruby files in foo/bar
# (see setup_autoloaders).
def self.extended(klass)
auto_setup_autoloaders(klass) if klass.respond_to? :autoload
super
end
private
def auto_setup_autoloaders(klass)
setup_autoloaders klass, caller[1][/^((?!\.[^\.]+:\d+).)+/]
end
end

@ -1,14 +1,11 @@
require 'forwardable'
require 'proactive_autoloader'
class Report < ActiveRecord::Base
InheritedNamespace.activate unless defined? Rails && Rails.version =~ /^3./
extend ProactiveAutoloader
extend Forwardable
include Enumerable
#belongs_to :user
#belongs_to :project
#attr_protected :user_id, :project_id, :created_at, :updated_at
self.abstract_class = true #lets have subclasses have their own SQL tables
self.abstract_class = true # lets have subclasses have their own SQL tables
def self.accepted_properties
@@accepted_properties ||= []

@ -1,6 +1,10 @@
require "set"
class Report::Filter
extend ProactiveAutoloader
autoload :Base, 'report/filter/base'
autoload :NoFilter, 'report/filter/no_filter'
def self.all
@all ||= Set[]
end

@ -1,7 +1,12 @@
require "set"
class Report::GroupBy
extend ProactiveAutoloader
include Report::QueryUtils
autoload :Base, 'report/group_by/base'
autoload :RubyAggregation, 'report/group_by/ruby_aggregation'
autoload :SingletonValue, 'report/group_by/singleton_value.rb'
autoload :SqlAggregation, 'report/group_by/sql_aggregation'
def self.all
Set[engine::GroupBy::SingletonValue]

@ -1,6 +1,8 @@
require 'set'
module Report::InheritedAttribute
include Report::QueryUtils
def inherited_attribute(*attributes)
options = attributes.extract_options!
list = options[:list]
@ -25,8 +27,6 @@ module Report::InheritedAttribute
end
end
alias singleton_class metaclass unless respond_to? :singleton_class
def define_singleton_method(name, &block)
singleton_class.send :attr_writer, name
singleton_class.class_eval { define_method(name, &block) }

@ -1,5 +1,8 @@
module Report::QueryUtils
alias singleton_class metaclass unless respond_to? :singleton_class
delegate :quoted_false, :quoted_true, :to => "ActiveRecord::Base.connection"
attr_writer :engine
##
# Subclass of Report to be used for constant lookup and such.
@ -8,7 +11,7 @@ module Report::QueryUtils
# @return [Class] subclass
def engine
return self.class.engine unless is_a? Module
Object.const_get(name[/^[^:]+/] || :Report)
@engine ||= Object.const_get(name[/^[^:]+/] || :Report)
end
##

@ -1,4 +1,6 @@
class Report::Result
include Report::QueryUtils
class Base
attr_accessor :parent, :type, :important_fields
attr_accessor :key
@ -243,8 +245,8 @@ class Report::Result
def self.new(value, fields = {}, type = nil, important_fields = [])
result = begin
case value
when Array then WrappedResult.new value.map { |e| new e, {}, nil, important_fields }
when Hash then DirectResult.new value.with_indifferent_access
when Array then engine::Result::WrappedResult.new value.map { |e| new e, {}, nil, important_fields }
when Hash then engine::Result::DirectResult.new value.with_indifferent_access
when Base then value
else raise ArgumentError, "Cannot create Result from #{value.inspect}"
end

@ -1,4 +1,10 @@
module Report::Validation
extend ProactiveAutoloader
include Report::QueryUtils
autoload :Dates, 'report/validation/dates'
autoload :Integers, 'report/validation/integers'
autoload :Sql, 'report/validation/sql'
def register_validations(*validation_methods)
validation_methods.flatten.each do |val_method|
register_validation(val_method)

Loading…
Cancel
Save