Class: RubySmart::Namespace::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_smart/namespace/base.rb

Constant Summary collapse

MODULE_DETECT_REGEX =

regexp to find a camel-cased module

/^(?:[A-Z][a-z0-9]+){2,}$/
RESOURCE_CLEAN_REGEX =

regexp to clean a module from it's concept MyUsersController

MyUsers

/^((?:[A-Z][a-z0-9]+)+?)(?:[A-Z][a-z0-9]+)?$/
CONCEPT_CLEAN_REGEX =

regexp to clean a module from it's resource MyUsersController

Controller

/^(?:[A-Z][a-z0-9]+)+([A-Z][a-z0-9]+)$/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object) ⇒ Base

Returns a new instance of Base.



324
325
326
327
328
329
# File 'lib/ruby_smart/namespace/base.rb', line 324

def initialize(object)
  klass = object.is_a?(Module) ? object : object.class
  raise "Generating a namespace from a Namespace will break the universe!" if klass <= ::RubySmart::Namespace::Base

  @klass = klass
end

Instance Attribute Details

#klassObject (readonly)

stores the calling class as instance



22
23
24
# File 'lib/ruby_smart/namespace/base.rb', line 22

def klass
  @klass
end

Class Method Details

.build(*args) ⇒ Object

builds & resolves a new module by provided module names

::RubySmart::Namespace::Base.build(:user,'cell','index')

::User::Cell::Index

Parameters:

  • args (Array<String, Symbol, Array>)
    • array of separated namespace strings

Returns:



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ruby_smart/namespace/base.rb', line 54

def build(*args)
  current = ''
  path    = path(*args)
  path.split('::').each do |mod|
    if current == '' && !Object.const_defined?(mod)
      Object.const_set(mod, Module.new)
    elsif current != '' && !current.constantize.const_defined?(mod)
      current.constantize.const_set(mod, Module.new)
    end
    current = "#{current}::#{mod}"
  end

  resolve(path)
end

.components(klass) ⇒ Array<Object>

returns all components as array

components(User::Endpoint::Index)

[User, User::Endpoint, User::Endpoint::Index]

Parameters:

Returns:



117
118
119
120
121
122
123
# File 'lib/ruby_smart/namespace/base.rb', line 117

def components(klass)
  ary = []
  modules(klass).map do |mod|
    ary << mod
    ary.join('::').constantize
  end
end

.concept(klass, match_regexp = MODULE_DETECT_REGEX) ⇒ Symbol?

returns the concept name of a provided klass. it detects the first camel-case module and returns its concept name (camelcase string, just the last one).

it's pendant is accessible through the .resource method.

concept(User::Endpoint::Index)

nil

concept(User::GamesHelper)

:helper

concept(Home::CategoriesInitializer::Users)

:initializer

concept(Admin::UsersController)

:controller

concept(MembersHelper::UserProvider)

:helper

concept(Category)

nil

Parameters:

  • klass (Object)
  • match_regexp (Regexp) (defaults to: MODULE_DETECT_REGEX)

Returns:

  • (Symbol, nil)

    concept symbol



199
200
201
202
203
204
# File 'lib/ruby_smart/namespace/base.rb', line 199

def concept(klass, match_regexp = MODULE_DETECT_REGEX)
  modules = self.modules(klass)
  res     = modules.detect { |m| m.match(match_regexp) }
  return nil unless res
  res.gsub(CONCEPT_CLEAN_REGEX, '\1').underscore.to_sym
end

.handle(klass) ⇒ Symbol

returns the handle name of a provided klass. It checks for at least three modules and returns the last module name.

handle(User::Endpoint::Index)

:index

handle(Member)

nil

Parameters:

Returns:

  • (Symbol)

    handle symbol



305
306
307
308
309
# File 'lib/ruby_smart/namespace/base.rb', line 305

def handle(klass)
  modules = self.modules(klass)
  return nil if modules.length < 3
  modules[-1].underscore.to_sym
end

.info(klass) ⇒ Object

prints a info string for each namespace method. just for debugging

Parameters:



314
315
316
317
318
319
320
321
# File 'lib/ruby_smart/namespace/base.rb', line 314

def info(klass)
  puts "-----------------------------------------------------------------------------------------------"
  puts "=> #{klass} <="
  %w(components modules sections scope concept resource service handle).each do |m|
    puts "#{m.ljust(11)}-> #{send(m, klass)}"
  end
  puts "-----------------------------------------------------------------------------------------------"
end

.modules(klass) ⇒ Array<String>

returns all modules as array

modules(User::Endpoint::Index)

['User', 'Endpoint', 'Index']

Parameters:

Returns:

  • (Array<String>)

    modules



132
133
134
# File 'lib/ruby_smart/namespace/base.rb', line 132

def modules(klass)
  klass.to_s.split('::')
end

.path(*args) ⇒ String

returns the full object name as string.

::RubySmart::Namespace::Base.path(:user, 'Models',:open_tags, 'find')

"User::Model::OpenTag::Find"

Parameters:

  • args (Array<String, Symbol, Array>)
    • array of separated namespace strings

Returns:

  • (String)

    path



43
44
45
# File 'lib/ruby_smart/namespace/base.rb', line 43

def path(*args)
  args.map(&:to_s).map(&:classify).join('::')
end

.resolve(*args) ⇒ Object

resolves a object by provided names

::RubySmart::Namespace::Base.resolve(:user,'cell','index')

::User::Cell::Index

Parameters:

  • args (Array<String, Symbol, Array>)
    • array of separated namespace strings

Returns:



32
33
34
# File 'lib/ruby_smart/namespace/base.rb', line 32

def resolve(*args)
  path(*args).constantize
end

.resource(klass, match_regexp = MODULE_DETECT_REGEX) ⇒ Symbol

returns the resource name of a provided klass. If there is less or equal than three modules it detects the first camel-cased module and returns its resource name (all camelcase token, except the last one - then singularize). For more than three modules it'll return the As last fallback it uses the first module.

resource(User::Endpoint::Index)

:user

resource(User::GamesHelper)

:game

resource(Home::CategoriesInitializer::Users)

:category

resource(Admin::UsersController)

:user

resource(MembersHelper)

:member

resource(Category)

:category

Parameters:

  • klass (Object)
  • match_regexp (Regexp) (defaults to: MODULE_DETECT_REGEX)

Returns:

  • (Symbol)

    resource symbol



232
233
234
235
236
237
238
239
240
241
242
# File 'lib/ruby_smart/namespace/base.rb', line 232

def resource(klass, match_regexp = MODULE_DETECT_REGEX)
  modules = self.modules(klass)

  res = if modules.length <= 3
          (modules.detect { |m| m.match(match_regexp) } || modules[0]).gsub(RESOURCE_CLEAN_REGEX, '\1')
        else
          modules[-3]
        end

  res.underscore.singularize.to_sym
end

.scope(klass) ⇒ Symbol?

returns the scope of a provided klass. PLEASE NOTE: There is no scope for a class with a single module

scope(User::Endpoint::Index)

:user

scope(User::Index)

:user

scope(Admin::UsersController)

:admin

scope(HomeController)

nil

scope(Member)

nil

Parameters:

Returns:

  • (Symbol, nil)

    scope symbol



167
168
169
170
171
# File 'lib/ruby_smart/namespace/base.rb', line 167

def scope(klass)
  modules = self.modules(klass)
  return nil if modules.length < 2
  modules[0].underscore.to_sym
end

.section(klass, pos = 0) ⇒ Symbol?

returns the section name of a provided klass and position (default: 0)

section(User::Cell::Index)

:user

section(User::EndpointHandler::Index, 1)

:endpoint_handler

section(Member)

:member

section(Admin::Home::Cell::Index, -2)

:cell

section(Admin::Home::Cell::Index, 1)

:home

Parameters:

  • klass (Object)
  • pos (Integer) (defaults to: 0)
    • section position

Returns:

  • (Symbol, nil)

    section symbol



290
291
292
# File 'lib/ruby_smart/namespace/base.rb', line 290

def section(klass, pos = 0)
  sections(klass)[pos]
end

.sections(klass) ⇒ Array<Symbol>

returns all sections as array

sections(User::Endpoint::Index)

[:user, :endpoint, :index]

Parameters:

Returns:

  • (Array<Symbol>)

    sections



143
144
145
# File 'lib/ruby_smart/namespace/base.rb', line 143

def sections(klass)
  modules(klass).map { |mod| mod.underscore.to_sym }
end

.service(klass) ⇒ Symbol?

returns the service name of a provided klass. It checks for at least three modules and returns the penultimate module.

service(User::Cell::Index)

:cell

service(User::EndpointHandler::Index)

:endpoint_handler

service(Member)

nil

service(Admin::Home::Cell::Index)

:cell

service(Admin::Home::Cell::Index, 1)

:home

Parameters:

Returns:

  • (Symbol, nil)

    service symbol



264
265
266
267
268
# File 'lib/ruby_smart/namespace/base.rb', line 264

def service(klass)
  modules = self.modules(klass)
  return nil if modules.length < 3
  modules[-2].underscore.to_sym
end

.transform(klass, packs, resolve = true) ⇒ Object, String

converts a provided module to a totally new one

::RubySmart::Namespace::Base.transform(User::Cell::Index, [:resource, :endpoint, :handle])

User::Endpoint::Index

::RubySmart::Namespace::Base.transform(Admin::UsersController, [:__scope, :home_controller])

Admin::HomeController

Parameters:

  • klass (Object)
  • packs (Array)
    • packs used for packing (constant symbols can be used for namespace method invocation)
  • resolve (Boolean) (defaults to: true)
    • resolve module or return path (default: true)

Options Hash (packs):

  • :__scope__ (Symbol)
    • uses scope
  • :__concept__ (Symbol)
    • uses concept
  • :__resource__ (Symbol)
    • uses resource
  • :__section__ (Symbol)
    • uses section
  • :__service__ (Symbol)
    • uses service
  • :__handle__ (Symbol)
    • uses handle

Returns:

  • (Object, String)

    module or path



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/ruby_smart/namespace/base.rb', line 87

def transform(klass, packs, resolve = true)
  s = packs.map do |pack|
    case pack
    when :__scope__
      scope(klass)
    when :__concept__
      concept(klass)
    when :__resource__
      resource(klass)
    when :__section__
      section(klass)
    when :__service__
      service(klass)
    when :__handle__
      handle(klass)
    else
      pack
    end
  end

  resolve ? self.resolve(*s) : path(*s)
end

Instance Method Details

#componentsObject

returns all components as array See ::RubySmart::Namespace::Base.components



333
334
335
# File 'lib/ruby_smart/namespace/base.rb', line 333

def components
  self.class.components(klass)
end

#conceptObject

returns the concept name of a provided klass. it detects the first camel-case module and returns its concept name (camelcase string, just the last one).

See ::RubySmart::Namespace::Base.concept



361
362
363
# File 'lib/ruby_smart/namespace/base.rb', line 361

def concept
  self.class.concept(klass)
end

#handleObject

returns the handle name of a provided klass. It checks for at least three modules and returns the last module name.

See ::RubySmart::Namespace::Base.handle



394
395
396
# File 'lib/ruby_smart/namespace/base.rb', line 394

def handle
  self.class.handle(klass)
end

#infoObject

prints a info string for each namespace method. just for debugging

See ::RubySmart::Namespace::Base.info



409
410
411
# File 'lib/ruby_smart/namespace/base.rb', line 409

def info
  self.class.info(klass)
end

#modulesObject

returns all modules as array See ::RubySmart::Namespace::Base.modules



339
340
341
# File 'lib/ruby_smart/namespace/base.rb', line 339

def modules
  self.class.modules(klass)
end

#resourceObject

returns the resource name of a provided klass. It checks for at least three modules and returns the first module name. If there is more or less than three modules it detects the first camel-cased module and returns its resource name (all camelcase token, except the last one - then singularize). As last fallback it uses the first module.

See ::RubySmart::Namespace::Base.resource



371
372
373
# File 'lib/ruby_smart/namespace/base.rb', line 371

def resource
  self.class.resource(klass)
end

#scopeObject

returns the scope of a provided klass. PLEASE NOTE: There is no scope for a class with a single module

See ::RubySmart::Namespace::Base.scope



353
354
355
# File 'lib/ruby_smart/namespace/base.rb', line 353

def scope
  self.class.scope(klass)
end

#section(pos = 0) ⇒ Object

returns the section name of a provided klass.

See ::RubySmart::Namespace::Base.section



386
387
388
# File 'lib/ruby_smart/namespace/base.rb', line 386

def section(pos = 0)
  self.class.section(klass, pos)
end

#sectionsObject

returns all sections as array See ::RubySmart::Namespace::Base.sections



345
346
347
# File 'lib/ruby_smart/namespace/base.rb', line 345

def sections
  self.class.sections(klass)
end

#serviceObject

returns the service name of a provided klass. It checks for at least three modules and returns the penultimate service.

See ::RubySmart::Namespace::Base.service



379
380
381
# File 'lib/ruby_smart/namespace/base.rb', line 379

def service
  self.class.service(klass)
end

#transform(packs, resolve = true) ⇒ Object

converts a provided module to a totally new one

See ::RubySmart::Namespace::Base.transform



401
402
403
# File 'lib/ruby_smart/namespace/base.rb', line 401

def transform(packs, resolve = true)
  self.class.transform(klass, packs, resolve)
end