Last active
October 6, 2015 03:00
-
-
Save kwstannard/2bb68f10413c83de5ad4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=begin | |
This class allows you to condsolidate the declaration of class names into | |
the file name. It also handles namespacing based on the file path if you are | |
using Rails autoloading. | |
This works with the single exception of constant lookup via nesting, so you | |
will need to replace constants with variables and methods. | |
Examples: | |
# app/models/user.rb | |
Dryer.def_class(__FILE__) do | |
def hi | |
"hello world" | |
end | |
end | |
User.new.hi | |
=> "hello world" | |
# app/models/instruments/horn.rb | |
Dryer.def_class(__FILE__) do | |
def play | |
"toot!" | |
end | |
end | |
Instruments::Horn.new.play | |
=> "toot!" | |
# app/models/address.rb | |
Dryer.def_class(__FILE__, ActiveRecord::Base) do | |
end | |
Address.new.respond_to? :save | |
=> true | |
=end | |
class Dryer < Struct.new(:file_path, :super_class, :blk) | |
def self.def_class(file_path, super_class=Object, &blk) | |
new(file_path, super_class, blk).def_class | |
end | |
def def_class | |
constant_names.each.with_index.inject(Object) do |const, (next_const, index)| | |
if constant_names.length == index + 1 | |
# this is needed to set the class name so that activerecord | |
# works properly | |
klass = const.const_set(next_const, Class.new(super_class)) | |
# here we eval the class block to define methods and everything | |
klass.class_eval &blk | |
else | |
const.const_get(next_const) | |
end | |
end | |
end | |
def constant_names | |
get_name.split('/').map(&:camelcase) | |
end | |
def get_name | |
file_path.gsub(most_likely_path, '').gsub(".rb", '') | |
end | |
def most_likely_path | |
all_autoload_paths.map{|p| file_path[/^#{p}/] || ""}.sort.last + '/' | |
end | |
def all_autoload_paths | |
config = Rails.configuration | |
config.autoload_paths + config.eager_load_paths + config.autoload_once_paths | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment