contextify 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+