contextify 0.1.0
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/History.txt +4 -0
- data/Manifest.txt +15 -0
- data/README.txt +71 -0
- data/Rakefile +14 -0
- data/lib/contextify.rb +2 -0
- data/lib/contextify/contextify.rb +187 -0
- data/lib/contextify/exceptions/context_not_found.rb +4 -0
- data/lib/contextify/exceptions/unknown_context.rb +4 -0
- data/lib/contextify/extensions/meta.rb +1 -0
- data/lib/contextify/extensions/meta/object.rb +24 -0
- data/lib/contextify/pending_context.rb +27 -0
- data/lib/contextify/version.rb +3 -0
- data/spec/contextify_spec.rb +72 -0
- data/spec/spec_helper.rb +5 -0
- data/tasks/spec.rb +9 -0
- metadata +80 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/contextify.rb
|
6
|
+
lib/contextify/exceptions/context_not_found.rb
|
7
|
+
lib/contextify/exceptions/unknown_context.rb
|
8
|
+
lib/contextify/extensions/meta/object.rb
|
9
|
+
lib/contextify/extensions/meta.rb
|
10
|
+
lib/contextify/pending_context.rb
|
11
|
+
lib/contextify/contextify.rb
|
12
|
+
lib/contextify/version.rb
|
13
|
+
spec/contextify_spec.rb
|
14
|
+
spec/spec_helper.rb
|
15
|
+
tasks/spec.rb
|
data/README.txt
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
= contextify
|
2
|
+
|
3
|
+
* http://contextify.rubyforge.org/
|
4
|
+
* http://github.com/postmodern/contextify/
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
Load objects from Ruby files without having to use YAML or define
|
9
|
+
classes named like the file.
|
10
|
+
|
11
|
+
== EXAMPLES:
|
12
|
+
|
13
|
+
# file: controller.rb
|
14
|
+
class Controller
|
15
|
+
|
16
|
+
include Contextify
|
17
|
+
|
18
|
+
contextify :controller
|
19
|
+
|
20
|
+
...
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
# file: my_controller.rb
|
25
|
+
controller do
|
26
|
+
|
27
|
+
def test1
|
28
|
+
'This is the first test'
|
29
|
+
end
|
30
|
+
|
31
|
+
def test2(mesg)
|
32
|
+
"Hello #{mesg}"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
controller = Controller.load_context('my_controller.rb')
|
38
|
+
# => #<Controller: ...>
|
39
|
+
controller.test1
|
40
|
+
# => "This is the first test"
|
41
|
+
controller.test2('one two three')
|
42
|
+
# => "Hello one two three"
|
43
|
+
|
44
|
+
== INSTALL:
|
45
|
+
|
46
|
+
$ sudo gem install contextify
|
47
|
+
|
48
|
+
== LICENSE:
|
49
|
+
|
50
|
+
The MIT License
|
51
|
+
|
52
|
+
Copyright (c) 2008 Hal Brodigan
|
53
|
+
|
54
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
55
|
+
a copy of this software and associated documentation files (the
|
56
|
+
'Software'), to deal in the Software without restriction, including
|
57
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
58
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
59
|
+
permit persons to whom the Software is furnished to do so, subject to
|
60
|
+
the following conditions:
|
61
|
+
|
62
|
+
The above copyright notice and this permission notice shall be
|
63
|
+
included in all copies or substantial portions of the Software.
|
64
|
+
|
65
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
66
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
67
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
68
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
69
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
70
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
71
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './tasks/spec.rb'
|
6
|
+
require './lib/contextify/version.rb'
|
7
|
+
|
8
|
+
Hoe.new('contextify', Contextify::VERSION) do |p|
|
9
|
+
p.rubyforge_name = 'contextify'
|
10
|
+
p.developer('Postmodern', 'postmodern.mod3@gmail.com')
|
11
|
+
p.remote_rdoc_dir = ''
|
12
|
+
end
|
13
|
+
|
14
|
+
# vim: syntax=Ruby
|
data/lib/contextify.rb
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'contextify/exceptions/unknown_context'
|
2
|
+
require 'contextify/exceptions/context_not_found'
|
3
|
+
require 'contextify/pending_context'
|
4
|
+
require 'contextify/extensions/meta'
|
5
|
+
|
6
|
+
module Contextify
|
7
|
+
def self.included(base)
|
8
|
+
base.module_eval do
|
9
|
+
def self.contextify(name)
|
10
|
+
name = name.to_s
|
11
|
+
|
12
|
+
Contextify.contexts[name] = self
|
13
|
+
|
14
|
+
meta_def(:context_name) { name }
|
15
|
+
|
16
|
+
meta_def(:load_context) do |path,*args|
|
17
|
+
Contextify.load_context(self.context_name,path,*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
# define the top-level context wrappers
|
21
|
+
Kernel.module_eval %{
|
22
|
+
def #{name}(*args,&block)
|
23
|
+
if (args.empty? && ::Contextify.is_pending?)
|
24
|
+
::Contextify.pending.blocks[#{name.dump}] = block
|
25
|
+
return nil
|
26
|
+
else
|
27
|
+
new_context = #{self}.new(*args)
|
28
|
+
new_context.instance_eval(&block) if block
|
29
|
+
return new_context
|
30
|
+
end
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Returns a Hash of all defined contexts.
|
38
|
+
#
|
39
|
+
def Contextify.contexts
|
40
|
+
@@contextify_contexts ||= {}
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Returns +true+ if there is a context defined with the specified
|
45
|
+
# _name_, returns +false+ otherwise.
|
46
|
+
#
|
47
|
+
def Contextify.is_context?(name)
|
48
|
+
Contextify.contexts.has_key?(name.to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Returns the Array of contexts which are waiting to be loaded.
|
53
|
+
#
|
54
|
+
def Contextify.waiting
|
55
|
+
@@contextify_waiting_contexts ||= []
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Returns the pending context being loaded.
|
60
|
+
#
|
61
|
+
def Contextify.pending
|
62
|
+
Contextify.waiting.first
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Returns +true+ if there is a pending context present, returns
|
67
|
+
# +false+ otherwise.
|
68
|
+
#
|
69
|
+
def Contextify.is_pending?
|
70
|
+
!(Contextify.waiting.empty?)
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Returns the first pending context with the specified _path_.
|
75
|
+
#
|
76
|
+
def Contextify.loading(path)
|
77
|
+
Contextify.waiting.each do |pending|
|
78
|
+
if pending.path == path
|
79
|
+
return pending
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
return nil
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# Returns +true+ if the pending context with the specified _path_
|
88
|
+
# is present, returns +false+ otherwise.
|
89
|
+
#
|
90
|
+
def Contextify.is_loading?(path)
|
91
|
+
!(Contextify.loading(path).nil?)
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Loads all context blocks from the specified _path_, returning a
|
96
|
+
# PendingContext object containing the context blocks.
|
97
|
+
#
|
98
|
+
def Contextify.load_blocks(path,&block)
|
99
|
+
path = File.expand_path(path)
|
100
|
+
|
101
|
+
unless File.file?(path)
|
102
|
+
raise(ContextNotFound,"context #{path.dump} doest not exist",caller)
|
103
|
+
end
|
104
|
+
|
105
|
+
# prevent circular loading of contexts
|
106
|
+
unless Contextify.is_pending?
|
107
|
+
# push on the new pending context
|
108
|
+
Contextify.waiting.unshift(PendingContext.new(path))
|
109
|
+
|
110
|
+
load(path)
|
111
|
+
end
|
112
|
+
|
113
|
+
# pop off and return the pending context
|
114
|
+
pending_context = Contextify.waiting.shift
|
115
|
+
|
116
|
+
block.call(pending_context) if block
|
117
|
+
return pending_context
|
118
|
+
end
|
119
|
+
|
120
|
+
#
|
121
|
+
# Loads the context block of the specified _name_ from the specified
|
122
|
+
# _path_, returning the context block. If a _block_ is given it will
|
123
|
+
# be passed the loaded context block.
|
124
|
+
#
|
125
|
+
# Contextify.load_block(:exploit,'/path/to/my_exploit.rb') # => Proc
|
126
|
+
#
|
127
|
+
# Contextify.load_block(:shellcode,'/path/to/my_shellcode.rb')
|
128
|
+
# do |block|
|
129
|
+
# ...
|
130
|
+
# end
|
131
|
+
#
|
132
|
+
def Contextify.load_block(name,path,&block)
|
133
|
+
context_block = Contextify.load_blocks(path).blocks[name.to_s]
|
134
|
+
|
135
|
+
block.call(context_block) if block
|
136
|
+
return context_block
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Loads the context of the specified _name_ and from the specified
|
141
|
+
# _path_ with the given _args_. If no contexts were defined with the
|
142
|
+
# specified _name_, an UnknownContext exception will be raised.
|
143
|
+
#
|
144
|
+
# Contextify.load_context(:note,'/path/to/my_notes.rb') # => Note
|
145
|
+
#
|
146
|
+
def Contextify.load_context(name,path,*args)
|
147
|
+
name = name.to_s
|
148
|
+
|
149
|
+
unless Contextify.is_context?(name)
|
150
|
+
raise(UnknownContext,"unknown context #{name.dump}",caller)
|
151
|
+
end
|
152
|
+
|
153
|
+
new_context = Contextify.contexts[name].new(*args)
|
154
|
+
|
155
|
+
Contextify.load_block(name,path) do |context_block|
|
156
|
+
new_context.instance_eval(&context_block) if context_block
|
157
|
+
end
|
158
|
+
|
159
|
+
return new_context
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# Loads all contexts from the specified _path_ returning an +Array+
|
164
|
+
# of loaded contexts. If a _block_ is given, it will be passed
|
165
|
+
# each loaded context.
|
166
|
+
#
|
167
|
+
# Contextify.load_contexts('/path/to/misc_contexts.rb') # => [...]
|
168
|
+
#
|
169
|
+
def Contextify.load_contexts(path,&block)
|
170
|
+
new_objs = []
|
171
|
+
|
172
|
+
Contextify.load_blocks(path) do |pending|
|
173
|
+
pending.each_block do |name,context_block|
|
174
|
+
if Contextify.is_context?(name)
|
175
|
+
new_obj = Contextify.contexts[name].new
|
176
|
+
new_obj.instance_eval(&context_block)
|
177
|
+
|
178
|
+
block.call(new_obj) if block
|
179
|
+
new_objs << new_obj
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
return new_objs
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'contextify/extensions/meta/object'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# metaprogramming assistant -- metaid.rb
|
2
|
+
class Object # :nodoc:
|
3
|
+
# The hidden singleton lurks behind everyone
|
4
|
+
def metaclass; class << self; self; end; end
|
5
|
+
def meta_eval(&blk); metaclass.instance_eval(&blk); end
|
6
|
+
|
7
|
+
# A class_eval version of meta_eval
|
8
|
+
def metaclass_eval(&blk); metaclass.class_eval(&blk); end
|
9
|
+
|
10
|
+
# A class_def version of meta_def
|
11
|
+
def metaclass_def(name, &blk)
|
12
|
+
metaclass_eval { define_method(name, &blk) }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Adds methods to a metaclass
|
16
|
+
def meta_def(name, &blk)
|
17
|
+
meta_eval { define_method(name, &blk) }
|
18
|
+
end
|
19
|
+
|
20
|
+
# Defines an instance method within a class
|
21
|
+
def class_def(name, &blk)
|
22
|
+
class_eval { define_method(name, &blk) }
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Contextify
|
2
|
+
class PendingContext
|
3
|
+
|
4
|
+
# The path being loaded
|
5
|
+
attr_reader :path
|
6
|
+
|
7
|
+
# The blocks to be loaded
|
8
|
+
attr_accessor :blocks
|
9
|
+
|
10
|
+
#
|
11
|
+
# Creates a new PendingContext object with the specified _path_.
|
12
|
+
#
|
13
|
+
def initialize(path)
|
14
|
+
@path = File.expand_path(path)
|
15
|
+
@blocks = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Iterates over each block in the pending context, passing their name
|
20
|
+
# and value to the given _block_.
|
21
|
+
#
|
22
|
+
def each_block(&block)
|
23
|
+
@blocks.each(&block)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'contextify'
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Contextify do
|
6
|
+
before(:all) do
|
7
|
+
require 'helpers/book_context'
|
8
|
+
require 'helpers/book_review_context'
|
9
|
+
|
10
|
+
@contexts_dir = File.expand_path(File.join(File.dirname(__FILE__),'helpers','contexts'))
|
11
|
+
@snow_crash_path = File.join(@contexts_dir,'snow_crash.rb')
|
12
|
+
@neuromancer_path = File.join(@contexts_dir,'neuromancer_review.rb')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should contain defined contexts" do
|
16
|
+
Contextify.is_context?('book').should == true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should create a class-level context name" do
|
20
|
+
Book.context_name.should == 'book'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should raise an UnknownContext exception when loading unknwon-contexts" do
|
24
|
+
lambda {
|
25
|
+
Contextify.load_context(:nothing, 'some_path.rb')
|
26
|
+
}.should raise_error(Contextify::UnknownContext)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should raise a ContextNotFound exception when loading from non-existant files" do
|
30
|
+
lambda {
|
31
|
+
Contextify.load_context(:book, 'not_here.rb')
|
32
|
+
}.should raise_error(Contextify::ContextNotFound)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should load contexts by context-name from a file" do
|
36
|
+
@book = Contextify.load_context(:book, @snow_crash_path)
|
37
|
+
@book.should_not be_nil
|
38
|
+
@book.class.should == Book
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should load a specific context from a file with multiple contexts" do
|
42
|
+
@book = Contextify.load_context(:book, @neuromancer_path)
|
43
|
+
@book.should_not be_nil
|
44
|
+
@book.class.should == Book
|
45
|
+
|
46
|
+
@review = Contextify.load_context(:book_review, @neuromancer_path)
|
47
|
+
@review.should_not be_nil
|
48
|
+
@review.class.should == BookReview
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should provide class-level methods for loading a context" do
|
52
|
+
@book = Book.load_context(@snow_crash_path)
|
53
|
+
@book.should_not be_nil
|
54
|
+
@book.class.should == Book
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "loaded contexts" do
|
58
|
+
before(:all) do
|
59
|
+
@book = Book.load_context(@snow_crash_path)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have attributes" do
|
63
|
+
@book.title.should == 'Snow Crash'
|
64
|
+
@book.author.should == 'Neal Stephenson'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have instance methods" do
|
68
|
+
@book.methods.include?('rating').should == true
|
69
|
+
@book.rating.should == 10
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/tasks/spec.rb
ADDED
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: contextify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Postmodern
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-29 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.2
|
24
|
+
version:
|
25
|
+
description: Load objects from Ruby files without having to use YAML or define classes named like the file.
|
26
|
+
email:
|
27
|
+
- postmodern.mod3@gmail.com
|
28
|
+
executables: []
|
29
|
+
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files:
|
33
|
+
- History.txt
|
34
|
+
- Manifest.txt
|
35
|
+
- README.txt
|
36
|
+
files:
|
37
|
+
- History.txt
|
38
|
+
- Manifest.txt
|
39
|
+
- README.txt
|
40
|
+
- Rakefile
|
41
|
+
- lib/contextify.rb
|
42
|
+
- lib/contextify/exceptions/context_not_found.rb
|
43
|
+
- lib/contextify/exceptions/unknown_context.rb
|
44
|
+
- lib/contextify/extensions/meta/object.rb
|
45
|
+
- lib/contextify/extensions/meta.rb
|
46
|
+
- lib/contextify/pending_context.rb
|
47
|
+
- lib/contextify/contextify.rb
|
48
|
+
- lib/contextify/version.rb
|
49
|
+
- spec/contextify_spec.rb
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
- tasks/spec.rb
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: http://contextify.rubyforge.org/
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --main
|
57
|
+
- README.txt
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: "0"
|
71
|
+
version:
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project: contextify
|
75
|
+
rubygems_version: 1.3.1
|
76
|
+
signing_key:
|
77
|
+
specification_version: 2
|
78
|
+
summary: Load objects from Ruby files without having to use YAML or define classes named like the file.
|
79
|
+
test_files: []
|
80
|
+
|