Skip to content

Instantly share code, notes, and snippets.

@jah2488
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jah2488/8938747 to your computer and use it in GitHub Desktop.
Save jah2488/8938747 to your computer and use it in GitHub Desktop.
A simple ruby method to cleanup nested module setup for namespacing.
def ns(namespace, delim = '.', &block)
nest_mod(namespace.split(delim), block)
end
def nest_mod(mod = Kernel, module_names, block)
return mod.module_exec(&block) if module_names.empty?
find_or_create_constant_in_module(mod, constantize(module_names.first)).tap do |this|
make_module_methods_accessible(this)
this.module_exec do
nest_mod(this, module_names.drop(1), block)
end
end
end
def make_module_methods_accessible(mod)
mod.module_exec { extend self }
end
def find_or_create_constant_in_module(mod, str)
return mod.const_get(str) if mod.const_defined?(str)
return mod.const_set(str, Module.new)
end
def constantize(str)
str.split('_')
.map(&:capitalize)
.join
end
if $0 !~ /rspec/
ns 'my_app.greetings.greeter' do
def present
'hello'
end
end
ns :presenters_greetings do
def present_greeting(greeter)
greeter.present
end
end
puts Presenters::Greetings.present_greeting(MyApp::Greetings::Greeter) #=> 'hello'
else
describe 'namespace' do
context 'ns' do
it 'creates all methods in the nested namespace/module' do
ns 'my_app.dojo.util.options' do
def names
%w(john jill steve carol)
end
end
expect(MyApp::Dojo::Util::Options.names).to eq(%w(john jill steve carol))
end
it 'custom deliminators can optionally be specified' do
ns 'my_app|dojo|util|options', '|' do
def names
%w(john jill steve carol)
end
end
expect(MyApp::Dojo::Util::Options.names).to eq(%w(john jill steve carol))
end
end
context 'nest_mod' do
it 'creates a module given a string and block' do
nest_mod(['greeter'], Proc.new {
@hello = 'hello'
def greet
@hello
end
})
expect(Greeter.greet).to eq('hello')
end
it 'creates nested modules' do
nest_mod(['dojo', 'util', 'options'], Proc.new {
def names
%w(john jill steve carol)
end
})
expect(Dojo::Util::Options.names).to eq(%w(john jill steve carol))
end
end
context 'to_const' do
it 'hello_world -> HelloWorld' do
expect(to_const('hello_world')).to eq('HelloWorld')
end
end
end
end
module Presenters
module Greetings
def present_greeting(greeter)
greeter.present
end
end
end
module MyApp
module Greetings
module Greeter
def present
'hello'
end
end
end
end
#vs
ns 'presenters.greetings' do
def present_greeting(greeter)
greeter.present
end
end
ns 'my_app.greetings.greeter' do
def present
'hello'
end
end
@jah2488
Copy link
Author

jah2488 commented Feb 14, 2014

I originally made this gist private on accident, if you're curious in some of the revisions the code went through, there is some more history in the private gist. https://gist.github.com/jah2488/a9d891d4393d2e5df327

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment