Module: Namespace
- Defined in:
- lib/namespace.rb
Overview
Namespaces for ruby.
See Namespace.open and Namespace#import for more details
Defined Under Namespace
Modules: Ext Classes: ConflictError, ImportError
Class Attribute Summary collapse
-
.cache ⇒ Object
readonly
Returns the value of attribute cache.
-
.load_path ⇒ Object
readonly
Returns the value of attribute load_path.
Class Method Summary collapse
-
.basename(namespace) ⇒ Object
Returns the top name of a namespace.
-
.included(mod) ⇒ Object
Raises a ScriptError if the module is included.
-
.normalize(namespace) ⇒ Object
Transforms a string into a normalized namespace identifier.
-
.open(namespace) ⇒ Object
Loads a file according to the
namespace
in the context of a module, and returns that object.
Instance Method Summary collapse
-
#import(namespace, options = {}) ⇒ Object
options = select the imported name.
Class Attribute Details
.cache ⇒ Object (readonly)
Returns the value of attribute cache.
8 9 10 |
# File 'lib/namespace.rb', line 8 def cache @cache end |
.load_path ⇒ Object (readonly)
Returns the value of attribute load_path.
9 10 11 |
# File 'lib/namespace.rb', line 9 def load_path @load_path end |
Class Method Details
.basename(namespace) ⇒ Object
Returns the top name of a namespace
Example: basename(“some::deep::namespace”) => “namespace”
65 66 67 |
# File 'lib/namespace.rb', line 65 def basename(namespace) normalize(namespace).gsub(/.*::/,'') end |
.included(mod) ⇒ Object
Raises a ScriptError if the module is included
70 71 72 |
# File 'lib/namespace.rb', line 70 def included(mod) raise ScriptError, "Namespace is not designed to be included, only extended. See #{mod}" end |
.normalize(namespace) ⇒ Object
Transforms a string into a normalized namespace identifier
58 59 60 |
# File 'lib/namespace.rb', line 58 def normalize(namespace) namespace.to_s.sub(/^[\/:\s]*/, '').sub(/[\/:\s]*$/, '').gsub(/[\/\\:]+/, '::') end |
.open(namespace) ⇒ Object
Loads a file according to the namespace
in the context of a module, and returns that object.
It’s not a Python import, where the namespace is available. What you get here, is a sort of Sandbox where constants defined in the file are not polluting the global namespace but available on the returned object. Since the returned object is a Module, it can be included in the current module if you’re also in the context of a “Sandbox”.
#import has been chosen because the ruby namespace is already crowded (require, load and include are already taken)
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/namespace.rb', line 22 def open(namespace) namespace = normalize(namespace) # Cache lookup ns = @cache[namespace] return ns if ns # File lookup file_path = namespace.gsub(':', File::SEPARATOR) + '.rb' file = @load_path.inject(nil) do |file, load_path| path = File.join(load_path, file_path) File.exists?(path) ? path : file end raise ImportError, "no such file to load -- #{file_path}" unless file file_content = File.read(file) # Pre-process __NAMESPACE__ keyword to act like __FILE__ # in know... it's not exactly the same... (eg "__FILE__") but it should do the trick file_content.gsub!('__NAMESPACE__', namespace.inspect) ns = Module.new ns.instance_variable_set("@__namespace__", namespace) # Allow calling methods in self, like in global namespace ns.extend(ns) # Adds the #import methods from the DSL ns.extend(Namespace, Namespace::Ext) ns.module_eval(file_content, file) # Cache @cache[namespace] = ns return ns end |
Instance Method Details
#import(namespace, options = {}) ⇒ Object
options = select the imported name
THINK: since variable is already returned, is :as necessary?
80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/namespace.rb', line 80 def import(namespace, ={}) mod = Namespace::open(namespace) name = [:as] || ['as'] || Namespace.basename(namespace) raise ConflictError, "name `#{name}` is already taken" if method_defined?(name) instance_variable_set("@#{name}", mod) attr_reader name private name mod end |