wrap_in_module 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.rvmrc +48 -0
- data/Gemfile +4 -0
- data/LICENSE +2 -0
- data/README.md +138 -0
- data/Rakefile +2 -0
- data/lib/wrap_in_module/version.rb +3 -0
- data/lib/wrap_in_module.rb +137 -0
- data/wrap_in_module.gemspec +17 -0
- metadata +56 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
7
|
+
# Only full ruby name is supported here, for short names use:
|
8
|
+
# echo "rvm use 1.9.3" > .rvmrc
|
9
|
+
environment_id="ruby-1.9.3-p194@wrap_in_module"
|
10
|
+
|
11
|
+
# Uncomment the following lines if you want to verify rvm version per project
|
12
|
+
# rvmrc_rvm_version="1.14.7 (master)" # 1.10.1 seams as a safe start
|
13
|
+
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
14
|
+
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
15
|
+
# return 1
|
16
|
+
# }
|
17
|
+
|
18
|
+
# First we attempt to load the desired environment directly from the environment
|
19
|
+
# file. This is very fast and efficient compared to running through the entire
|
20
|
+
# CLI and selector. If you want feedback on which environment was used then
|
21
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
22
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
23
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
24
|
+
then
|
25
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
26
|
+
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
|
27
|
+
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
|
28
|
+
else
|
29
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
30
|
+
rvm --create "$environment_id" || {
|
31
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
32
|
+
return 1
|
33
|
+
}
|
34
|
+
fi
|
35
|
+
|
36
|
+
# If you use bundler, this might be useful to you:
|
37
|
+
# if [[ -s Gemfile ]] && {
|
38
|
+
# ! builtin command -v bundle >/dev/null ||
|
39
|
+
# builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null
|
40
|
+
# }
|
41
|
+
# then
|
42
|
+
# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
|
43
|
+
# gem install bundler
|
44
|
+
# fi
|
45
|
+
# if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
|
46
|
+
# then
|
47
|
+
# bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete'
|
48
|
+
# fi
|
data/Gemfile
ADDED
data/LICENSE
ADDED
data/README.md
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
# WrapInModule
|
2
|
+
|
3
|
+
This is a Ruby gem I created to house the functionality to be able to wrap
|
4
|
+
various things inside modules. The primary focus of it was to be able to load a
|
5
|
+
ruby file in using a module as namespace for all the top level Constants,
|
6
|
+
Methods, Classes, Modules, etc. This does the same for any sub ruby scripts
|
7
|
+
that are required as well.
|
8
|
+
|
9
|
+
I found this functionality in a ruby script, supprisingly called script.rb
|
10
|
+
written by Joel VanderWerf released under the Ruby license in 2004. I have
|
11
|
+
simply wrapped his script inside a gem so that this functionality can be easily
|
12
|
+
accessed. The following is the description provided with Joel's script with my
|
13
|
+
gem namespacing.
|
14
|
+
|
15
|
+
`WrapInModule::Script` is a subclass of Module. A module which is an instance
|
16
|
+
of the `WrapInModule::Script` class encapsulates in its scope the top-level
|
17
|
+
methods, top-level constants, and instance variables defined in a ruby script
|
18
|
+
file (and its dependent files) loaded by a ruby program. This allows use of
|
19
|
+
script files to define objects that can be loaded into a program in much the
|
20
|
+
same way that objects can be loaded from YAML or Marshal files.
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
gem 'wrap_in_module'
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
$ bundle
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install wrap_in_module
|
35
|
+
|
36
|
+
## Synopsis
|
37
|
+
|
38
|
+
**program.rb:**
|
39
|
+
|
40
|
+
require 'wrap_in_module'
|
41
|
+
my_script = WrapInModule::Script.load("my-script.rb")
|
42
|
+
p my_script::VALUE
|
43
|
+
my_script.run
|
44
|
+
|
45
|
+
**my-script.rb:**
|
46
|
+
|
47
|
+
VALUE = [1,2,3]
|
48
|
+
def run
|
49
|
+
puts "#{self} running."
|
50
|
+
end
|
51
|
+
|
52
|
+
**output:**
|
53
|
+
|
54
|
+
$ ruby program.rb
|
55
|
+
[1, 2, 3]
|
56
|
+
#<Script:/tmp/my-script.rb> running.
|
57
|
+
|
58
|
+
## Usage
|
59
|
+
|
60
|
+
`WrapInModule::Script` modules are instantiated with
|
61
|
+
<tt>WrapInModule::Script.new(main_file)</tt> or the alias
|
62
|
+
<tt>WrapInModule::Script.load(main_file)</tt>. All the top-level constants and
|
63
|
+
top-level methods that are defined in the +main_file+ and its dependent local
|
64
|
+
files (see below) are scoped in the same Script module, and are thereby
|
65
|
+
available to the calling program.
|
66
|
+
|
67
|
+
The +main_file+ can load or require other files with +load+ and +require+, as
|
68
|
+
usual. These methods, in the `WrapInModule::Script` context, add some behavior
|
69
|
+
to the +Kernel+ +load+ and +require+ methods:
|
70
|
+
<tt>WrapInModule::Script#load</tt> and <tt>WrapInModule::Script#require</tt>
|
71
|
+
first search for files relative to the +main_file+'s dir. Files loaded in this
|
72
|
+
way ("dependent local files") are treated like the script file itself:
|
73
|
+
top-level definitions are added to the script module that is returned by +load+
|
74
|
+
or +require+.
|
75
|
+
|
76
|
+
Both <tt>WrapInModule::Script#load</tt> and
|
77
|
+
<tt>WrapInModule::Script#require</tt> fall back to the Kernel versions if the
|
78
|
+
file is not found locally. Hence, other ruby libraries can be loaded and
|
79
|
+
required as usual, assuming their names do not conflict with local file names.
|
80
|
+
Definitions from those files go into the usual scope (typically global). The
|
81
|
+
normal ruby +load+ and +require+ behavior can be forced by calling
|
82
|
+
<tt>Kernel.load</tt> and <tt>Kernel.require</tt>.
|
83
|
+
|
84
|
+
A `WrapInModule::Script` immitates the way the top-level ruby context works, so
|
85
|
+
a ruby file that was originally intended to be run from the top level, defining
|
86
|
+
top-level constants and top-level methods, can also be run as a
|
87
|
+
`WrapInModule::Script`, and its top-level constants and top-level methods are
|
88
|
+
wrapped in the script's scope. The difference between this behavior and simply
|
89
|
+
wrapping the loaded definitions in an _anonymous_ module using
|
90
|
+
<tt>Kernel.load(main_file, true)</tt> is that the top-level methods and
|
91
|
+
top-level constants defined in the script are accessible using the
|
92
|
+
`WrapInModule::Script` instance.
|
93
|
+
|
94
|
+
The top-level definitions of a `WrapInModule::Script` can be accessed after it
|
95
|
+
has been loaded, as follows:
|
96
|
+
|
97
|
+
<tt>script.meth</tt>
|
98
|
+
|
99
|
+
- Call a method defined using <tt>def meth</tt> or <tt>def self.meth</tt> in
|
100
|
+
the script file.
|
101
|
+
|
102
|
+
<tt>script::K</tt>
|
103
|
+
|
104
|
+
- Access a class, module, or constant defined using <tt>K = val</tt> in the
|
105
|
+
script file.
|
106
|
+
|
107
|
+
An "input" can be passed to the script before loading. Simply call
|
108
|
+
`WrapInModule::Script.new` (or `WrapInModule::Script.load`) with a block. The
|
109
|
+
block is passed a single argument, the `WrapInModule::Script` module, and
|
110
|
+
executed before the files are loaded into the Script's scope. Setting a
|
111
|
+
constant in this block makes the constant available to the script during
|
112
|
+
loading. For example:
|
113
|
+
|
114
|
+
script = Script.load("my-script.rb") { |script| script::INPUT = 3 }
|
115
|
+
|
116
|
+
Note that all methods defined in the script file are both instance methods of
|
117
|
+
the module and methods of the module instance (the effect of
|
118
|
+
<tt>Module#module_function</tt>). So <tt>include</tt>-ing a Script module in a
|
119
|
+
class will give instances of the class all the methods and constants defined in
|
120
|
+
the script, and they will reference the instance's instance variables,
|
121
|
+
rather than the Script module's instance variables.
|
122
|
+
|
123
|
+
The Script class was inspired by Nobu Nokada's suggestion in
|
124
|
+
http://ruby-talk.org/62727, in a thread (started in http://ruby-talk.org/62660)
|
125
|
+
about how to use ruby script files as specifications of objects.
|
126
|
+
|
127
|
+
## Legal and Contact Information
|
128
|
+
|
129
|
+
Usable under the Ruby license. Copyright (C)2004 Joel VanderWerf. Questions to
|
130
|
+
mailto:vjoel@users.sourceforge.net.
|
131
|
+
|
132
|
+
## Contributing
|
133
|
+
|
134
|
+
1. Fork it
|
135
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
136
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
137
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
138
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require "wrap_in_module/version"
|
2
|
+
|
3
|
+
module WrapInModule
|
4
|
+
# NOTE: The following is coppied out of script.rb v0.3
|
5
|
+
# For more information please refer to http://redshift.sourceforge.net where
|
6
|
+
# I acquired the script-0.3.tar
|
7
|
+
|
8
|
+
# A module which is an instance of the Script class encapsulates in its scope
|
9
|
+
# the top-level methods, top-level constants, and instance variables defined in
|
10
|
+
# a ruby script file (and its subfiles) loaded by a ruby program. This allows
|
11
|
+
# use of script files to define objects that can be loaded into a program in
|
12
|
+
# much the same way that objects can be loaded from YAML or Marshal files.
|
13
|
+
#
|
14
|
+
# See intro.txt[link:files/intro_txt.html] for an overview.
|
15
|
+
|
16
|
+
class Script < Module
|
17
|
+
# The file with which the Script was instantiated.
|
18
|
+
attr_reader :__main_file
|
19
|
+
|
20
|
+
# The directory in which main_file is located, and relative to which
|
21
|
+
# #load searches for files before falling back to Kernel#load.
|
22
|
+
attr_reader :__dir
|
23
|
+
|
24
|
+
# A hash that maps <tt>filename=>true</tt> for each file that has been
|
25
|
+
# required locally by the script. This has the same semantics as <tt>$"</tt>,
|
26
|
+
# alias <tt>$LOADED_FEATURES</tt>, except that it is local to this script.
|
27
|
+
attr_reader :__loaded_features
|
28
|
+
|
29
|
+
class << self
|
30
|
+
alias load new
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates new Script, and loads _main_file_ in the scope of the Script. If a
|
34
|
+
# block is given, the script is passed to it before loading from the file, and
|
35
|
+
# constants can be defined as inputs to the script.
|
36
|
+
|
37
|
+
def initialize(main_file) # :yields: self
|
38
|
+
extend ScriptModuleMethods
|
39
|
+
@__main_file = File.expand_path(main_file)
|
40
|
+
@__dir = File.dirname(@__main_file)
|
41
|
+
@__loaded_features = {}
|
42
|
+
|
43
|
+
yield self if block_given?
|
44
|
+
load_in_module(main_file)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Loads _file_ into this Script. Searches relative to the local dir, that is,
|
48
|
+
# the dir of the file given in the original call to
|
49
|
+
# <tt>Script.load(file)</tt>, loads the file, if found, into this Script's
|
50
|
+
# scope, and returns true. If the file is not found, falls back to
|
51
|
+
# <tt>Kernel.load</tt>, which searches on <tt>$LOAD_PATH</tt>, loads the file,
|
52
|
+
# if found, into global scope, and returns true. Otherwise, raises
|
53
|
+
# <tt>LoadError</tt>.
|
54
|
+
#
|
55
|
+
# The _wrap_ argument is passed to <tt>Kernel.load</tt> in the fallback case,
|
56
|
+
# when the file is not found locally.
|
57
|
+
#
|
58
|
+
# Typically called from within the main file to load additional sub files, or
|
59
|
+
# from those sub files.
|
60
|
+
|
61
|
+
def load(file, wrap = false)
|
62
|
+
load_in_module(File.join(@__dir, file))
|
63
|
+
true
|
64
|
+
rescue MissingFile
|
65
|
+
super
|
66
|
+
end
|
67
|
+
|
68
|
+
# Analogous to <tt>Kernel#require</tt>. First tries the local dir, then falls
|
69
|
+
# back to <tt>Kernel#require</tt>. Will load a given _feature_ only once.
|
70
|
+
#
|
71
|
+
# Note that extensions (*.so, *.dll) can be required in the global scope, as
|
72
|
+
# usual, but not in the local scope. (This is not much of a limitation in
|
73
|
+
# practice--you wouldn't want to load an extension more than once.) This
|
74
|
+
# implementation falls back to <tt>Kernel#require</tt> when the argument is an
|
75
|
+
# extension or is not found locally.
|
76
|
+
|
77
|
+
def require(feature)
|
78
|
+
unless @__loaded_features[feature]
|
79
|
+
@__loaded_features[feature] = true
|
80
|
+
file = File.join(@__dir, feature)
|
81
|
+
file += ".rb" unless /\.rb$/ =~ file
|
82
|
+
load_in_module(file)
|
83
|
+
end
|
84
|
+
rescue MissingFile
|
85
|
+
@__loaded_features[feature] = false
|
86
|
+
super
|
87
|
+
end
|
88
|
+
|
89
|
+
# Raised by #load_in_module, caught by #load and #require.
|
90
|
+
class MissingFile < LoadError; end
|
91
|
+
|
92
|
+
# Loads _file_ in this module's context. Note that <tt>\_\_FILE\_\_</tt> and
|
93
|
+
# <tt>\_\_LINE\_\_</tt> work correctly in _file_.
|
94
|
+
# Called by #load and #require; not normally called directly.
|
95
|
+
|
96
|
+
def load_in_module(__file__)
|
97
|
+
module_eval("@__script_scope ||= binding\n" + IO.read(__file__),
|
98
|
+
File.expand_path(__file__), 0)
|
99
|
+
# start numbering at 0 because of the extra line.
|
100
|
+
# The extra line does nothing in sub-script files.
|
101
|
+
rescue Errno::ENOENT
|
102
|
+
if /#{__file__}$/ =~ $!.message # No extra locals in this scope.
|
103
|
+
raise MissingFile, $!.message
|
104
|
+
else
|
105
|
+
raise
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_s # :nodoc:
|
110
|
+
"#<#{self.class}:#{File.join(__dir, File.basename(__main_file))}>"
|
111
|
+
end
|
112
|
+
|
113
|
+
module ScriptModuleMethods
|
114
|
+
# This is so that <tt>def meth...</tt> behaves like in Ruby's top-level
|
115
|
+
# context. The implementation simply calls
|
116
|
+
# <tt>Module#module_function(name)</tt>.
|
117
|
+
def method_added(name) # :nodoc:
|
118
|
+
module_function(name)
|
119
|
+
end
|
120
|
+
|
121
|
+
attr_reader :__script_scope
|
122
|
+
|
123
|
+
# Gets list of local vars in the script. Does not see local vars in files
|
124
|
+
# loaded or required by that script.
|
125
|
+
def __local_variables
|
126
|
+
eval("local_variables", __script_scope)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Gets value of local var in the script. Does not see local vars in files
|
130
|
+
# loaded or required by that script.
|
131
|
+
def __local_variable_get(name)
|
132
|
+
eval(name.to_s, __script_scope)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/wrap_in_module/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Andrew De Ponte"]
|
6
|
+
gem.email = ["cyphactor@gmail.com"]
|
7
|
+
gem.description = %q{Ruby gem that allows you to load a ruby file into a module. Think scoping bunch of code inside a module.}
|
8
|
+
gem.summary = %q{Ruby gem that allows you to load a ruby file into a module. Think scoping bunch of code inside a module.}
|
9
|
+
gem.homepage = "http://github.com/realpractice/wrap_in_module"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "wrap_in_module"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = WrapInModule::VERSION
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wrap_in_module
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Andrew De Ponte
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-22 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Ruby gem that allows you to load a ruby file into a module. Think scoping
|
15
|
+
bunch of code inside a module.
|
16
|
+
email:
|
17
|
+
- cyphactor@gmail.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- .rvmrc
|
24
|
+
- Gemfile
|
25
|
+
- LICENSE
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- lib/wrap_in_module.rb
|
29
|
+
- lib/wrap_in_module/version.rb
|
30
|
+
- wrap_in_module.gemspec
|
31
|
+
homepage: http://github.com/realpractice/wrap_in_module
|
32
|
+
licenses: []
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
requirements: []
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.8.24
|
52
|
+
signing_key:
|
53
|
+
specification_version: 3
|
54
|
+
summary: Ruby gem that allows you to load a ruby file into a module. Think scoping
|
55
|
+
bunch of code inside a module.
|
56
|
+
test_files: []
|