Skip to content

Instantly share code, notes, and snippets.

@kwstannard
Last active October 18, 2015 14:38
Show Gist options
  • Save kwstannard/287a2cfe1cd2705ce192 to your computer and use it in GitHub Desktop.
Save kwstannard/287a2cfe1cd2705ce192 to your computer and use it in GitHub Desktop.
class Dryer = Struct.new(:file_path, :super_class, :blk) do
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_namespaces.split('/').map(&:camelcase)
end
def get_namespaces
# this assumes you are following ruby convention of paths corresponding to
# namespaces. If you do not, this can't work.
file_path.gsub(most_likely_relative_path, '').gsub(".rb", '')
end
def most_likely_relative_path
# sort by length selects the path closest to the original file path.
possible_relative_paths.sort_by(&:length).last + '/'
end
def possible_relative_paths
$LOAD_PATH.select{|p| file_path[/^#{p}/]}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment