procemon 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +8 -4
- data/VERSION +1 -1
- data/examples/fun_with_procs_and_methods.rb +37 -8
- data/examples/how_to_inject_with_extra_process_a_method.rb +12 -6
- data/lib/procemon.rb +13 -11
- data/lib/procemon/{function → extra}/str2duck.rb +2 -1
- data/lib/procemon/function/meta/inject_methods.rb +61 -29
- data/lib/procemon/function/proc_source/method.rb +14 -2
- data/lib/procemon/function/proc_source/proc.rb +7 -1
- data/lib/procemon/function/proc_source/proc_source.rb +7 -9
- data/lib/procemon/function/proc_source/proc_source_body.rb +1 -1
- data/procemon.gemspec +1 -1
- data/test/test.rb +17 -0
- metadata +3 -3
data/README.md
CHANGED
@@ -10,20 +10,24 @@ meta-programing tricks, terminal argument controls, daemonise trick,
|
|
10
10
|
tmp folder helpers, Application centralized datas, folder structure logic ,
|
11
11
|
meta data control, dynamic lib read etc
|
12
12
|
|
13
|
-
|
14
13
|
There is really lot of helper method, i mean i even lose my life love if i want to start describe all of them
|
15
14
|
you can generate rdoc if you want, i more like examples, so from now on,
|
16
15
|
i will make examples!
|
17
16
|
|
18
|
-
|
17
|
+
# Examples
|
18
|
+
|
19
|
+
The "how_to_inject_with_extra_process_a_method"
|
20
|
+
tells you how to NOT monkey patch methods in modules.
|
19
21
|
You want use a module? sure awsome !
|
20
22
|
You need to add plus functionality but dont want to follow the module updates
|
21
23
|
(in case of conflight with the monkey patch)
|
22
24
|
Than this is your tool. Tell the method to inject what method and it will , but remember
|
23
25
|
params are always have to obey to the original method!
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
+
The "fun_with_procs_and_methods"
|
28
|
+
tells you how to play with proc and method objects source code,
|
29
|
+
combine them, manipulate them, and convert back into live code
|
30
|
+
with the right bindings
|
27
31
|
|
28
32
|
## LICENSE
|
29
33
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.1
|
@@ -1,7 +1,5 @@
|
|
1
1
|
require_relative "../lib/procemon.rb"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
3
|
test= Proc.new do |*params|
|
6
4
|
|
7
5
|
puts "some awsome code here"
|
@@ -22,7 +20,6 @@ method_source= method(:hello_this).source
|
|
22
20
|
#
|
23
21
|
#}
|
24
22
|
|
25
|
-
|
26
23
|
proc_source= test.source
|
27
24
|
#Proc.new{ |*params|
|
28
25
|
#
|
@@ -31,13 +28,45 @@ proc_source= test.source
|
|
31
28
|
#}
|
32
29
|
|
33
30
|
# example for terminal run
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
puts method_source
|
32
|
+
puts method_source.body,"---------"
|
33
|
+
puts method_source.params,"---------"
|
34
|
+
puts method_source.parameters.inspect,"---------"
|
35
|
+
puts method_source.params.inspect,"---------"
|
36
|
+
|
37
|
+
puts "\n"
|
39
38
|
|
40
39
|
merged_proc= ( method_source.body + proc_source.body ).build(*(method_source.params+proc_source.params))
|
41
40
|
puts merged_proc
|
41
|
+
puts merged_proc.to_proc
|
42
|
+
puts merged_proc.to_proc.source
|
43
|
+
|
44
|
+
|
45
|
+
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
46
|
+
|
47
|
+
class A
|
48
|
+
|
49
|
+
class << self
|
50
|
+
|
51
|
+
def hello test=nil
|
52
|
+
puts "world!"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.singleton test=nil
|
58
|
+
puts "singleton"
|
59
|
+
end
|
60
|
+
|
61
|
+
def instance hello= "wolrd"
|
62
|
+
puts "instance"
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
puts A.instance_method(:instance).source
|
68
|
+
|
69
|
+
puts A.method(:singleton).source
|
42
70
|
|
43
71
|
|
72
|
+
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative "../lib/procemon.rb"
|
2
2
|
|
3
3
|
class TestT
|
4
4
|
|
@@ -18,16 +18,22 @@ TestT.inject_instance_method :test do
|
|
18
18
|
|
19
19
|
end
|
20
20
|
|
21
|
-
TestT.inject_singleton_method :test, :after do
|
21
|
+
TestT.inject_singleton_method :test, params: "after" do
|
22
22
|
|
23
23
|
puts "hello world! singleton"
|
24
24
|
|
25
25
|
end
|
26
26
|
|
27
|
+
puts "\nafter,singleton case:"
|
27
28
|
TestT.test
|
29
|
+
puts "\nbefore,instance case:"
|
28
30
|
TestT.new.test
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
|
33
|
+
#after,singleton case:
|
34
|
+
#TestT
|
35
|
+
#hello world! singleton
|
36
|
+
#
|
37
|
+
#before,instance case:
|
38
|
+
#hello world! instance
|
39
|
+
##<TestT:0x00000000d4a008>
|
data/lib/procemon.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
#encoding: UTF-8
|
2
2
|
module Procemon
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
File.join(\
|
8
|
-
File.dirname(__FILE__),\
|
9
|
-
__FILE__.to_s.split(File::Separator).last.split('.')[0],
|
10
|
-
'**',"*.{rb,ru}"\
|
11
|
-
)\
|
12
|
-
).uniq.sort.each do |one_helper_file|
|
13
|
-
load one_helper_file
|
14
|
-
end
|
4
|
+
require File.join(File.dirname(__FILE__),"procemon","function","require")
|
5
|
+
require_relative_directory File.join("procemon","function")
|
6
|
+
require_relative_directory File.join("procemon","mpatch")
|
15
7
|
|
8
|
+
# load up helpers
|
9
|
+
#Dir.glob(\
|
10
|
+
# File.join(\
|
11
|
+
# File.dirname(__FILE__),\
|
12
|
+
# __FILE__.to_s.split(File::Separator).last.split('.')[0],
|
13
|
+
# '**',"*.{rb,ru}"\
|
14
|
+
# )\
|
15
|
+
#).uniq.sort.each do |one_helper_file|
|
16
|
+
# load one_helper_file
|
17
|
+
#end
|
16
18
|
|
17
19
|
def self.init_all
|
18
20
|
|
@@ -2,64 +2,96 @@ class Class
|
|
2
2
|
|
3
3
|
# this will inject a code block to a target instance method
|
4
4
|
# by default the before or after sym is not required
|
5
|
-
#
|
5
|
+
#
|
6
|
+
# options can be:
|
7
|
+
# - params: "merged" -> if given than the block params and the original method params will be merged
|
8
|
+
# - add: 'before'/'after' add your code into method before the original part of after
|
6
9
|
#
|
7
10
|
# Test.inject_singleton_method :hello do |*args|
|
8
11
|
# puts "singleton extra, so #{args[0]}"
|
9
12
|
# end
|
10
13
|
#
|
11
|
-
def inject_singleton_method(method,options
|
14
|
+
def inject_singleton_method(method,options={},&block)
|
12
15
|
|
13
16
|
original_method= self.method(method).clone
|
14
|
-
#Singleton.methods[self.object_id]= self.method(method)
|
15
17
|
self.singleton_class.__send__ :undef_method, method
|
16
|
-
self.class_eval do
|
17
|
-
define_singleton_method method do |*arguments|
|
18
|
-
|
19
|
-
if options == :before
|
20
|
-
block.source.to_proc(self.binding?).call *arguments
|
21
|
-
end
|
22
18
|
|
23
|
-
|
19
|
+
source_code= InjectMethodHelper.generate_source(
|
20
|
+
block,original_method,options
|
21
|
+
)
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
23
|
+
self.define_singleton_method method do |*arguments|
|
24
|
+
source_code.to_proc(self.binding?).call(*arguments)
|
30
25
|
end
|
31
26
|
|
27
|
+
return nil
|
32
28
|
end
|
29
|
+
alias :extend_singleton_method :inject_singleton_method
|
33
30
|
|
34
31
|
# this will inject a code block to a target singleton method
|
35
32
|
# by default the before or after sym is not required
|
36
|
-
# default => before
|
37
33
|
#
|
38
|
-
#
|
34
|
+
# options can be:
|
35
|
+
# - params: "merged" -> if given than the block params and the original method params will be merged
|
36
|
+
# - add: 'before'/'after' add your code into method before the original part of after
|
37
|
+
#
|
38
|
+
# Test.inject_instance_method :hello, params: "merged" do |*args|
|
39
39
|
# puts "singleton on a instance method and "+args[0]
|
40
40
|
# end
|
41
41
|
#
|
42
|
-
def inject_instance_method(method,options
|
42
|
+
def inject_instance_method(method,options={},&block)
|
43
|
+
|
44
|
+
original_method= self.instance_method(method).clone
|
45
|
+
|
46
|
+
source_code= InjectMethodHelper.generate_source(
|
47
|
+
block,original_method,options
|
48
|
+
)
|
43
49
|
|
44
50
|
self.class_eval do
|
45
|
-
|
51
|
+
undef_method method
|
52
|
+
define_method(
|
53
|
+
method,
|
54
|
+
source_code.to_proc(self.binding?)
|
55
|
+
)
|
46
56
|
end
|
47
|
-
extended_process = Proc.new do |*args|
|
48
57
|
|
49
|
-
|
50
|
-
block.source.to_proc(self.binding?).call *args
|
51
|
-
end
|
58
|
+
end
|
52
59
|
|
53
|
-
|
60
|
+
alias :extend_instance_method :inject_instance_method
|
54
61
|
|
55
|
-
|
56
|
-
|
57
|
-
|
62
|
+
end
|
63
|
+
|
64
|
+
module InjectMethodHelper
|
58
65
|
|
66
|
+
def self.generate_source block,original_method,options
|
67
|
+
|
68
|
+
# source code
|
69
|
+
begin
|
70
|
+
source_code= nil
|
71
|
+
case options[:add].to_s.downcase[0]
|
72
|
+
when "a"
|
73
|
+
source_code= original_method.source.body+block.source.body
|
74
|
+
else
|
75
|
+
source_code= block.source.body+original_method.source.body
|
76
|
+
end
|
59
77
|
end
|
60
|
-
|
61
|
-
|
78
|
+
|
79
|
+
# params
|
80
|
+
begin
|
81
|
+
source_params= nil
|
82
|
+
case options[:params].to_s.downcase[0]
|
83
|
+
when "m"
|
84
|
+
begin
|
85
|
+
source_params= (block.source.params+original_method.source.params)
|
86
|
+
end
|
87
|
+
else
|
88
|
+
begin
|
89
|
+
source_params= original_method.source.params
|
90
|
+
end
|
91
|
+
end
|
62
92
|
end
|
93
|
+
|
94
|
+
return source_code.build(*source_params)
|
63
95
|
end
|
64
96
|
|
65
97
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module MethodToProcSource
|
2
2
|
|
3
3
|
# creatue a raw eval-able process source, so you can set
|
4
4
|
# the right bindings using the .to_proc call from String methods
|
@@ -22,6 +22,11 @@ class Method
|
|
22
22
|
|
23
23
|
begin
|
24
24
|
|
25
|
+
if return_string.split("\n")[0].include? '('
|
26
|
+
return_string.sub!('(',' ')
|
27
|
+
return_string.sub!(')',' ')
|
28
|
+
end
|
29
|
+
|
25
30
|
args_to_replace = return_string.split("\n")[0].match(/\s*def\s*\S*\s*(.*)/).captures[0]
|
26
31
|
|
27
32
|
if args_to_replace != String.new
|
@@ -34,7 +39,6 @@ class Method
|
|
34
39
|
return_string.sub!(/\s*\bdef\s*[\w\S]*/,'Proc.new{')
|
35
40
|
return_string.sub!(/}[^}]*$/,"}")
|
36
41
|
|
37
|
-
|
38
42
|
if !return_string.include?('Proc.new')
|
39
43
|
return_string.sub!(/^[^{]*(?!={)/,'Proc.new')
|
40
44
|
end
|
@@ -48,4 +52,12 @@ class Method
|
|
48
52
|
alias :source_string :source
|
49
53
|
alias :proc_source :source
|
50
54
|
|
55
|
+
end
|
56
|
+
|
57
|
+
class Method
|
58
|
+
include MethodToProcSource
|
59
|
+
end
|
60
|
+
|
61
|
+
class UnboundMethod
|
62
|
+
include MethodToProcSource
|
51
63
|
end
|
@@ -6,16 +6,22 @@ class Proc
|
|
6
6
|
attr_accessor :source_cache
|
7
7
|
end
|
8
8
|
Proc.source_cache= Hash.new
|
9
|
-
def source
|
9
|
+
def source(test=nil)
|
10
10
|
# defaults
|
11
11
|
begin
|
12
12
|
return_string= ProcSource.new
|
13
13
|
block= 0
|
14
14
|
end
|
15
15
|
|
16
|
+
unless test.nil?
|
17
|
+
puts Proc.source_cache.inspect
|
18
|
+
puts self.object_id
|
19
|
+
end
|
20
|
+
|
16
21
|
unless Proc.source_cache[self.object_id].nil?
|
17
22
|
return Proc.source_cache[self.object_id]
|
18
23
|
else
|
24
|
+
|
19
25
|
File.open(File.expand_path(self.source_location[0])
|
20
26
|
).each_line_from self.source_location[1] do |line|
|
21
27
|
block += line.source_formater_for_line_sub
|
@@ -18,7 +18,7 @@ class ProcSource < String
|
|
18
18
|
def to_proc(binding=nil)
|
19
19
|
begin
|
20
20
|
|
21
|
-
|
21
|
+
unless self.split("\n")[0].include?('Proc.new')
|
22
22
|
raise ArgumentError, "string obj is not a valid process source"
|
23
23
|
end
|
24
24
|
|
@@ -31,22 +31,20 @@ class ProcSource < String
|
|
31
31
|
|
32
32
|
# do cache to proc!
|
33
33
|
begin
|
34
|
-
|
35
|
-
|
36
|
-
#Proc.source_cache[return_proc.object_id]= self
|
34
|
+
Proc.source_cache[return_proc.object_id]= self
|
37
35
|
end
|
38
36
|
|
39
|
-
|
37
|
+
return return_proc
|
40
38
|
end
|
41
39
|
end
|
42
40
|
|
43
41
|
def body
|
42
|
+
|
44
43
|
body= ProcSourceBody.new(self.dup.to_s)
|
45
|
-
body.sub!(
|
46
|
-
replace2= body.split("\n")[0].scan(/^\s*{?\s*(.*)/)[0][0]
|
47
|
-
body.sub!(replace2,String.new) if replace2 != String.new
|
44
|
+
body.sub!(/^\s*Proc\.new\s*{ *[\S ]*/,String.new)
|
48
45
|
body.gsub!(/^$\n/, String.new)
|
49
|
-
body
|
46
|
+
body.sub!(/\s*}\s*$/,String.new)
|
47
|
+
|
50
48
|
return body
|
51
49
|
end
|
52
50
|
|
data/procemon.gemspec
CHANGED
@@ -20,8 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
22
|
##=======Runtime-ENV================##
|
23
|
-
### Terminal like commands
|
24
23
|
#spec.add_runtime_dependency "commander", ['~>4.1.3']
|
24
|
+
#spec.add_runtime_dependency "activesupport"
|
25
25
|
|
26
26
|
## Node.JS
|
27
27
|
#spec.add_runtime_dependency "execjs"
|
data/test/test.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Require Gemfile gems
|
2
|
+
require 'grape'
|
3
|
+
require_relative "../lib/procemon"
|
4
|
+
|
5
|
+
Grape::API.inject_singleton_method :inherited, add: "after" do |subclass|
|
6
|
+
|
7
|
+
subclass.class_eval do
|
8
|
+
|
9
|
+
before do
|
10
|
+
puts "hello world!"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
puts "hello".binding?
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: procemon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'This is a collection of my Ruby Procs in the adventure of becoming
|
15
15
|
the best! In short this provides extra tools in Application configs, argumens processing,daemonise,
|
@@ -31,6 +31,7 @@ files:
|
|
31
31
|
- examples/how_to_inject_with_extra_process_a_method.rb
|
32
32
|
- files.rb
|
33
33
|
- lib/procemon.rb
|
34
|
+
- lib/procemon/extra/str2duck.rb
|
34
35
|
- lib/procemon/function/application.rb
|
35
36
|
- lib/procemon/function/argv.rb
|
36
37
|
- lib/procemon/function/binding/binding.rb
|
@@ -50,7 +51,6 @@ files:
|
|
50
51
|
- lib/procemon/function/proc_source/string.rb
|
51
52
|
- lib/procemon/function/require.rb
|
52
53
|
- lib/procemon/function/sender.rb
|
53
|
-
- lib/procemon/function/str2duck.rb
|
54
54
|
- lib/procemon/function/systemu.rb
|
55
55
|
- lib/procemon/function/tmp_dir.rb
|
56
56
|
- lib/procemon/function/validation.rb
|