holywarez-holywarez-mpt 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,4 @@
1
+ v0.1.3 Wrap helpers support added
2
+ v0.1.2 Instance eval with arguments is now supported for any object
3
+ v0.1.1 Sample sources updated
4
+ v0.1.0 First version of MPT gem
data/LICENSE ADDED
File without changes
data/Manifest ADDED
@@ -0,0 +1,18 @@
1
+ CHANGELOG
2
+ install_gem.bat
3
+ lib/event.rb
4
+ lib/mpt.rb
5
+ lib/system.rb
6
+ lib/wrap.rb
7
+ LICENSE
8
+ Manifest
9
+ mpt.gemspec
10
+ Rakefile
11
+ README
12
+ run_samples.bat
13
+ samples/call_experiment.rb
14
+ samples/declarations.rb
15
+ samples/ordered_subscribers.rb
16
+ samples/run_experiments.rb
17
+ samples/unordered_subscribers.rb
18
+ samples/wrap_method_experiment.rb
data/README ADDED
@@ -0,0 +1,2 @@
1
+ = Russian =
2
+ Примеры использования либы можно посмотреть в директории 'samples'
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "echoe"
2
+ Echoe.new( "holywarez-mpt" ) do |p|
3
+ p.author = "Anatoly Lapshin"
4
+ p.summary = "Monkey Patching Toolkit"
5
+ p.runtime_dependencies = ['activesupport']
6
+ p.development_dependencies = []
7
+ p.need_tar_gz = false
8
+ p.retain_gemspec = true
9
+ p.gemspec_name = 'mpt.gemspec'
10
+ p.clean_pattern.push 'lib/*-*'
11
+ end
data/install_gem.bat ADDED
@@ -0,0 +1,5 @@
1
+ call rake manifest
2
+ call rake install
3
+ cd pkg
4
+ call gem install holywarez-mpt-0.1.3.gem
5
+ cd ..
data/lib/event.rb ADDED
@@ -0,0 +1,69 @@
1
+
2
+ module MPT
3
+ class EventContainer
4
+ attr_accessor :event_object
5
+
6
+ def initialize( val = nil )
7
+ self.event_object = val.dup unless val.nil?
8
+ end
9
+
10
+ end
11
+
12
+ class FilterChain < Array
13
+ def reorganize
14
+ index = 0
15
+ while index < self.size
16
+ filter = self[index]
17
+ filter_opts = filter[:options]
18
+ unless filter_opts[:after].nil?
19
+ for i in index..self.size-1
20
+ fo = self[i][:options]
21
+ unless fo[:as].nil?
22
+ if fo[:as] == filter_opts[:after]
23
+ new_chain = []
24
+ new_chain += self[0..index-1] if index > 0
25
+ new_chain += [self[i]]
26
+ new_chain += self[index..i-1]
27
+ new_chain += self[i+1..self.size-1]
28
+ self.replace new_chain
29
+ index = 0
30
+ break
31
+ end # if :as matched with :after
32
+ end # unless :as is nil
33
+ end # for next items
34
+ end # unless :after is nil
35
+ index += 1
36
+ end # while index < list size
37
+ end # def reorganize
38
+ end # filter chain class
39
+
40
+ class Event
41
+ @@mpt_subscribers = {}
42
+
43
+ class << self
44
+ def subscribe(event_name, options = {}, &block)
45
+ channel = @@mpt_subscribers[event_name] ||= MPT::FilterChain.new
46
+ channel << { :options => options, :proc => block }
47
+ channel.reorganize
48
+ end
49
+
50
+ def trigger_with_object(event_name, object, *args)
51
+ container = MPT::EventContainer.new(object)
52
+ channel = @@mpt_subscribers[event_name]
53
+ if channel.size > 0
54
+
55
+ channel.each do |subscriber|
56
+ container.instance_eval_with_args( subscriber[:proc], *args )
57
+ end
58
+ end
59
+
60
+ container.event_object
61
+ end
62
+
63
+ def trigger(event_name, *args)
64
+ trigger_with_object(event_name, nil, *args)
65
+ end
66
+ end # end of static section
67
+ end # end of class Event
68
+
69
+ end
data/lib/mpt.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "rubygems"
2
+
3
+ gem "activesupport"
4
+ require "activesupport"
5
+
6
+ gem "uuid"
7
+ require "uuid"
8
+
9
+ require "system.rb"
10
+ require "wrap.rb"
11
+ require "event.rb"
data/lib/system.rb ADDED
@@ -0,0 +1,10 @@
1
+
2
+ class Object
3
+ def instance_eval_with_args(proc, *args, &block)
4
+ mod = @mpt_injection_module ||= Module.new
5
+ self.extend mod
6
+ mod.send :define_method, :mpt_instance_with_args_handler, proc
7
+ self.mpt_instance_with_args_handler( *args, &block )
8
+ mod.send :undef_method, :mpt_instance_with_args_handler
9
+ end
10
+ end
data/lib/wrap.rb ADDED
@@ -0,0 +1,140 @@
1
+
2
+ module MPT
3
+ class Wrap
4
+ @@wrap_variables = {}
5
+ @@registry = {}
6
+ class << self
7
+ def with(var ={}, &block)
8
+ thread_id = Thread.current.object_id
9
+ @@wrap_variables[thread_id]||={}
10
+ temp = @@wrap_variables[thread_id].dup
11
+ @@wrap_variables[thread_id].merge!(var)
12
+ yield
13
+ @@wrap_variables[thread_id] = temp
14
+ end
15
+
16
+ def get(wrap_name, default = nil)
17
+ temp = @@wrap_variables[Thread.current.object_id]
18
+ res = nil
19
+
20
+
21
+ if !temp.blank?
22
+ res = temp[wrap_name] unless temp[wrap_name].blank?
23
+ end
24
+
25
+ if res.nil? && !default.nil?
26
+ res = default
27
+ if default.instance_of?( Proc )
28
+ res = default.call
29
+ end
30
+ end
31
+
32
+ res
33
+ end
34
+
35
+ def register(value)
36
+ @@uuid_generator ||= UUID.new
37
+ key = @@uuid_generator.generate(:urn).to_s
38
+ @@registry[key] = value
39
+ key
40
+ end
41
+
42
+ def get_from_registry(key)
43
+ @@registry[key]
44
+ end
45
+ end
46
+
47
+ class Blank
48
+ def self.run(*args)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ class Class
55
+ def wrap_it(target, options = { :using => :run, :scope => :before }, &block)
56
+ return if options[:by].nil? && block.nil?
57
+
58
+ targets = target
59
+ targets = [target] unless target.instance_of?( Array )
60
+ targets.each do |tgt|
61
+ wrap_it_single(tgt, options, &block)
62
+ end
63
+ end
64
+
65
+ def wrap_with(target, options = {})
66
+ return if options.blank?
67
+
68
+ targets = target
69
+ targets = [target] unless target.instance_of?( Array )
70
+ targets.each do |tgt|
71
+ wrap_with_single(tgt, options)
72
+ end
73
+ end
74
+
75
+ private
76
+ def wrap_it_single(target, options, &block)
77
+ by_name = options[:by]
78
+ old_method_name = "#{target.to_s}_without_wrap_it"
79
+
80
+ instance_to_call_code = "self"
81
+ unless by_name == :self
82
+ instance_to_call_code = "MPT::Wrap.get( #{by_name.inspect}, MPT::Wrap::Blank )"
83
+ end
84
+
85
+ if by_name.nil? && !block.nil?
86
+ block_key = MPT::Wrap.register(block)
87
+ instance_to_call_code = "self.instance_eval( &MPT::Wrap.get_from_registry(#{block_key.inspect}) )"
88
+ end
89
+
90
+ scope_call_code = "target_instance.#{options[:using]}(*args, &block); #{old_method_name}(*args, &block)"
91
+
92
+ if options[:scope] == :after
93
+ scope_call_code = "#{old_method_name}(*args, &block); target_instance.#{options[:using]}(*args, &block)"
94
+ end
95
+
96
+ if options[:scope] == :around
97
+ scope_call_code = "target_instance.#{options[:using]}(*args) { #{old_method_name}(*args, &block) }"
98
+ end
99
+
100
+ code_to_eval = <<-EOC
101
+ def #{target.to_s}_with_wrap_it(*args, &block)
102
+ target_instance = #{instance_to_call_code}
103
+ #{scope_call_code}
104
+ end
105
+
106
+ alias_method_chain #{target.to_sym.inspect}, :wrap_it
107
+ EOC
108
+
109
+ self.class_eval(code_to_eval, __FILE__, __LINE__)
110
+ end
111
+
112
+ def wrap_with_single(target, options)
113
+ key = MPT::Wrap.register(options.dup)
114
+ code = <<-EOC
115
+ def #{target.to_s}_with_wrap_options(*args)
116
+ MPT::Wrap.with MPT::Wrap.get_from_registry(#{key.inspect}) do
117
+ #{target.to_s}_without_wrap_options(*args)
118
+ end
119
+ end
120
+
121
+ alias_method_chain #{target.to_sym.inspect}, :wrap_options
122
+ EOC
123
+
124
+ self.class_eval(code, __FILE__, __LINE__)
125
+ end
126
+ end
127
+
128
+ class Class
129
+ def wrappable(accessor_name, wrap_name)
130
+ code = <<-EOS
131
+ def #{accessor_name.to_s}_with_wrap_support
132
+ MPT::Wrap.get("#{wrap_name}", Proc.new { self.send :"#{accessor_name.to_s}_without_wrap_support" })
133
+ end
134
+
135
+ alias_method_chain :#{accessor_name.to_s}, :wrap_support
136
+ EOS
137
+
138
+ class_eval(code, __FILE__, __LINE__)
139
+ end
140
+ end
data/mpt.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{holywarez-mpt}
5
+ s.version = "0.1.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Anatoly Lapshin"]
9
+ s.date = %q{2009-07-01}
10
+ s.description = %q{Monkey Patching Toolkit}
11
+ s.email = %q{}
12
+ s.extra_rdoc_files = ["CHANGELOG", "lib/event.rb", "lib/mpt.rb", "lib/system.rb", "lib/wrap.rb", "LICENSE", "README"]
13
+ s.files = ["CHANGELOG", "install_gem.bat", "lib/event.rb", "lib/mpt.rb", "lib/system.rb", "lib/wrap.rb", "LICENSE", "Manifest", "mpt.gemspec", "Rakefile", "README", "run_samples.bat", "samples/call_experiment.rb", "samples/declarations.rb", "samples/ordered_subscribers.rb", "samples/run_experiments.rb", "samples/unordered_subscribers.rb", "samples/wrap_method_experiment.rb"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Holywarez-mpt", "--main", "README"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{holywarez-mpt}
19
+ s.rubygems_version = %q{1.3.2}
20
+ s.summary = %q{Monkey Patching Toolkit}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
28
+ else
29
+ s.add_dependency(%q<activesupport>, [">= 0"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<activesupport>, [">= 0"])
33
+ end
34
+ end
data/run_samples.bat ADDED
@@ -0,0 +1,3 @@
1
+ cd samples
2
+ call ruby run_experiments.rb
3
+ cd ..
@@ -0,0 +1,15 @@
1
+ module CallExperiment
2
+ include ::MPT
3
+ experiment "Call experiment" do
4
+ controller = Controller.new
5
+ controller.logic # must be 4
6
+
7
+ Wrap.with '/system/services/logic-service' => CustomService.new do
8
+ controller.logic # must be 96
9
+ Wrap.with '/system/services/logic-service' => CustomService.new(999) do
10
+ controller.logic # must be 1998
11
+ end
12
+ controller.logic # must be 96 again
13
+ end
14
+ end # end of experiment
15
+ end
@@ -0,0 +1,41 @@
1
+ module Kernel
2
+
3
+ def experiment(title)
4
+ en = @@experiment_number ||= 1
5
+ puts "Experiment ##{en}. #{title}\n\n"
6
+
7
+ yield
8
+
9
+ puts "\nExperiment ##{en} FINISHED!\n\n\n\n"
10
+ @@experiment_number += 1
11
+ end
12
+
13
+ end
14
+
15
+ class GeneralService
16
+ def calculate(input)
17
+ input * input
18
+ end
19
+ end
20
+
21
+ class CustomService < GeneralService
22
+ def initialize(rate = 48)
23
+ @rate = rate
24
+ end
25
+
26
+ def calculate(input)
27
+ input * @rate
28
+ end
29
+ end
30
+
31
+ class Controller
32
+ def service
33
+ @service ||= GeneralService.new
34
+ end
35
+
36
+ def logic
37
+ puts "Logic result is: #{service.calculate(2)}"
38
+ end
39
+
40
+ wrappable :service, '/system/services/logic-service'
41
+ end
@@ -0,0 +1,34 @@
1
+ module OrderedSubscribersExperiment
2
+ include ::MPT
3
+
4
+ experiment "Ordered filter chain with event object" do
5
+ input_object = { :content => "This scintillating new production of Shakespeare's romantic comedy is one of the most accomplished Shakespeare in the Park productions in some time." }
6
+
7
+ Event.subscribe '/filters/count-words', :as => :remove_unimportant_characters do
8
+ event_object[:content].gsub!( /[\!\.\,\?\:\=\-]|('s)/, '' )
9
+ end
10
+
11
+ Event.subscribe '/filters/count-words' do
12
+ # empty filter handler
13
+ end
14
+
15
+ Event.subscribe '/filters/count-words', :as => :word_counter, :after => :normalizer do
16
+ word_counts = {}
17
+ words = event_object[:content].split
18
+ words.each do |word|
19
+ word_counts[word] ||= 0
20
+ word_counts[word] += 1
21
+ end
22
+
23
+ event_object[:counts] = word_counts
24
+ end
25
+
26
+ Event.subscribe '/filters/count-words', :as => :normalizer, :after => :remove_unimportant_characters do
27
+ event_object[:content].downcase!
28
+ end
29
+
30
+ result_object = Event.trigger_with_object '/filters/count-words', input_object
31
+
32
+ puts "Result is:\n#{result_object[:counts].inspect}"
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ require "rubygems"
2
+
3
+ gem "holywarez-mpt"
4
+ require "mpt"
5
+
6
+
7
+ require "declarations.rb"
8
+ require "call_experiment.rb"
9
+ require "unordered_subscribers.rb"
10
+ require "ordered_subscribers.rb"
11
+ require "wrap_method_experiment.rb"
@@ -0,0 +1,16 @@
1
+ module UnorderedSubscribersExperiment
2
+ include ::MPT
3
+
4
+ experiment "Unordered subscribers with void event object" do
5
+ Event.subscribe '/system/special-channel' do |parameter|
6
+ self.event_object = parameter
7
+ end
8
+
9
+ Event.subscribe '/system/special-channel' do |parameter|
10
+ self.event_object = "#{event_object} AND same shit"
11
+ end
12
+
13
+ result = Event.trigger '/system/special-channel', "XXX"
14
+ puts "Result is: #{result}"
15
+ end
16
+ end
@@ -0,0 +1,78 @@
1
+
2
+ module WrapMethodsExperiment
3
+ include ::MPT
4
+
5
+ class TargetORM
6
+ def initialize(name = 'default')
7
+ @name = 'default'
8
+ end
9
+
10
+ def execute(sql)
11
+ puts "#{@name} execute '#{sql}'"
12
+ end
13
+
14
+ def query(sql)
15
+ puts "#{@name} query '#{sql}'"
16
+ end
17
+
18
+ def transaction
19
+ puts "TRANSACTION BEGIN"
20
+ yield
21
+ puts "TRANSACTION COMMIT"
22
+ end
23
+ end
24
+
25
+ class TargetController
26
+ attr_reader :orm
27
+ wrappable :orm, '/system/orm'
28
+
29
+ def initialize(system_orm)
30
+ @orm = system_orm
31
+ end
32
+
33
+ def process
34
+ orm.execute( "ControllerSQL" )
35
+ end
36
+ end
37
+
38
+ class TargetDispatcher
39
+ def initialize
40
+ @orm = TargetORM.new
41
+ end
42
+
43
+ def process
44
+ @orm.query("dispatcher-sql")
45
+
46
+ controller = TargetController.new(@orm)
47
+ controller.process
48
+ end
49
+ end
50
+
51
+ class MonkeyPatch
52
+ def run(sql)
53
+ puts "Patcher run: '#{sql}'"
54
+ end
55
+ end
56
+
57
+ experiment "Wrap methods experiment" do
58
+ TargetORM.wrap_it [:execute, :query], :by => '/patches/monkey-patch', :using => :run, :scope => :before
59
+
60
+ orm = TargetORM.new
61
+ orm.execute "First SQL"
62
+
63
+ patch = MonkeyPatch.new
64
+ Wrap.with '/patches/monkey-patch' => patch do
65
+ orm.execute "Second SQL"
66
+ end
67
+
68
+ end
69
+
70
+ experiment "Wrap by around methods" do
71
+ TargetDispatcher.wrap_it( :process, :using => :transaction, :scope => :around ) { @orm }
72
+ TargetController.wrap_with :process, '/system/orm' => TargetORM.new('custom')
73
+
74
+ dispatcher = TargetDispatcher.new
75
+ dispatcher.process
76
+ end
77
+
78
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: holywarez-holywarez-mpt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Anatoly Lapshin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-01 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Monkey Patching Toolkit
26
+ email: ""
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - CHANGELOG
33
+ - lib/event.rb
34
+ - lib/mpt.rb
35
+ - lib/system.rb
36
+ - lib/wrap.rb
37
+ - LICENSE
38
+ - README
39
+ files:
40
+ - CHANGELOG
41
+ - install_gem.bat
42
+ - lib/event.rb
43
+ - lib/mpt.rb
44
+ - lib/system.rb
45
+ - lib/wrap.rb
46
+ - LICENSE
47
+ - Manifest
48
+ - mpt.gemspec
49
+ - Rakefile
50
+ - README
51
+ - run_samples.bat
52
+ - samples/call_experiment.rb
53
+ - samples/declarations.rb
54
+ - samples/ordered_subscribers.rb
55
+ - samples/run_experiments.rb
56
+ - samples/unordered_subscribers.rb
57
+ - samples/wrap_method_experiment.rb
58
+ has_rdoc: true
59
+ homepage: ""
60
+ post_install_message:
61
+ rdoc_options:
62
+ - --line-numbers
63
+ - --inline-source
64
+ - --title
65
+ - Holywarez-mpt
66
+ - --main
67
+ - README
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "1.2"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project: holywarez-mpt
85
+ rubygems_version: 1.2.0
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Monkey Patching Toolkit
89
+ test_files: []
90
+