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 ADDED
@@ -0,0 +1,4 @@
1
+ === 1.0.0 / 2008-12-29
2
+
3
+ * Initial release.
4
+
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,2 @@
1
+ require 'contextify/contextify'
2
+ require 'contextify/version'
@@ -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,4 @@
1
+ module Contextify
2
+ class ContextNotFound < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Contextify
2
+ class UnknownContext < RuntimeError
3
+ end
4
+ 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,3 @@
1
+ module Contextify
2
+ VERSION = '0.1.0'
3
+ 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
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '>=1.1.3'
3
+ require 'spec'
4
+
5
+ require 'contextify/version'
data/tasks/spec.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ desc "Run all specifications"
4
+ Spec::Rake::SpecTask.new(:spec) do |t|
5
+ t.libs += ['lib', 'spec']
6
+ t.spec_opts = ['--colour', '--format', 'specdoc']
7
+ end
8
+
9
+ task :default => :spec
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
+