alib 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/a.rb CHANGED
@@ -1 +1,12 @@
1
- IO.popen('-'){|pipe| puts(pipe ? pipe.read : 42)}
1
+ module M
2
+ end
3
+ class C
4
+ end
5
+
6
+ p(M === C)
7
+
8
+ class C
9
+ include M
10
+ end
11
+ p(M === C)
12
+
File without changes
@@ -3,9 +3,7 @@
3
3
  #
4
4
  module ALib
5
5
  #--{{{
6
- VERSION = '0.4.0'
7
-
8
- def self.version() VERSION end
6
+ VERSION = '0.5.0'
9
7
 
10
8
  require 'pathname'
11
9
  require 'socket'
@@ -21,14 +19,19 @@ module ALib
21
19
  require 'fcntl'
22
20
  require 'uri'
23
21
  require 'net/http'
22
+ require 'thread'
24
23
 
25
-
26
- # TODO - bundle open4!!
24
+ class ::Object
25
+ Alib = ALib
26
+ def alib() ALib end
27
+ end
27
28
 
28
29
  LIBDIR = 'alib-%s/' % VERSION
29
30
 
30
- AUTOLOAD = {
31
+ require LIBDIR + 'classmethods'
32
+ require LIBDIR + 'stdext'
31
33
 
34
+ AUTOLOAD = {
32
35
  'Util' => 'util',
33
36
 
34
37
  'Logging' => 'logging',
@@ -54,51 +57,25 @@ module ALib
54
57
  'AbstractMain' => 'main',
55
58
  'SimpleMain' => 'main',
56
59
  'ConfigurableMain' => 'main',
57
-
58
60
  }
59
61
 
60
62
  AUTOLOAD.each{|const, basename| autoload const.to_s, LIBDIR + basename.to_s}
61
63
 
62
- METACLASS =
64
+ SINGLETON_CLASS =
63
65
  class << self
64
66
  self
65
67
  end
66
68
 
67
- AUTOLOAD.each{ |const, m| METACLASS.module_eval{ define_method(m){ ALib.send 'const_get', const}}}
68
-
69
- begin
70
- require 'open4'
71
- rescue LoadError
72
- require LIBDIR + 'open4'
73
- end
69
+ AUTOLOAD.each{ |const, m| SINGLETON_CLASS.module_eval{define_method(m){ALib.send 'const_get', const}} unless Alib.respond_to? m}
74
70
 
75
- class << self
76
- #--{{{
77
- def load basename
78
- #--{{{
79
- require LIBDIR + basename.to_s
80
- #--}}}
81
- end
82
- def simple_main &b
83
- #--{{{
84
- b ? Class::new(ALib::SimpleMain, &b) : ALib::SimpleMain
85
- #--}}}
86
- end
87
- alias_method 'main', 'simple_main'
88
- alias_method 'smain', 'simple_main'
89
- def configurable_main &b
90
- #--{{{
91
- b ? Class::new(ALib::ConfigurableMain, &b) : ALib::ConfigurableMain
92
- #--}}}
71
+ %w( open4 attributes prototype binding_of_caller ).each do |lib|
72
+ begin
73
+ require lib
74
+ rescue LoadError
75
+ require LIBDIR + lib
76
+ $LOADED_FEATURES << File.basename(lib)
93
77
  end
94
- alias_method 'cmain', 'configurable_main'
95
- #--}}}
96
78
  end
97
79
  #--}}}
98
80
  end
99
81
 
100
- Alib = ALib
101
-
102
- class Object
103
- def alib() Alib end
104
- end
@@ -0,0 +1,54 @@
1
+ module Attributes
2
+ VERSION = '3.2.0'
3
+
4
+ def version() VERSION end
5
+
6
+ def attributes *a, &b
7
+ unless a.empty?
8
+ hashes, names = a.partition{|x| Hash === x}
9
+
10
+ names_and_defaults = {}
11
+ hashes.each{|h| names_and_defaults.update h}
12
+ names.flatten.compact.each{|name| names_and_defaults.update name => nil}
13
+
14
+ names_and_defaults.each do |name, default|
15
+ init = b || lambda { default }
16
+ ivar, getter, setter, query = "@#{ name }", "#{ name }", "#{ name }=", "#{ name }?"
17
+
18
+ define_method(setter) do |value|
19
+ instance_variable_set ivar, value
20
+ end
21
+
22
+ define_method(getter) do |*value|
23
+ unless value.empty?
24
+ send setter, value.shift
25
+ else
26
+ defined = instance_eval "defined? #{ ivar }"
27
+ send setter, instance_eval(&init) unless defined
28
+ instance_variable_get ivar
29
+ end
30
+ end
31
+
32
+ alias_method query, getter
33
+
34
+ (attributes << name).uniq!
35
+ attributes
36
+ end
37
+ else
38
+ @attributes ||= []
39
+ end
40
+ end
41
+
42
+ def attribute(*a, &b) attributes *a, &b end
43
+ end
44
+
45
+ class Object
46
+ def attributes *a, &b
47
+ sc = class << self; self; end
48
+ sc.attributes *a, &b
49
+ end
50
+
51
+ def attribute(*a, &b) attributes *a, &b end
52
+ end
53
+
54
+ class Module; include Attributes; end
@@ -0,0 +1,54 @@
1
+ module Attributes
2
+ VERSION = '3.2.0'
3
+
4
+ def version() VERSION end
5
+
6
+ def attributes *a, &b
7
+ unless a.empty?
8
+ hashes, names = a.partition{|x| Hash === x}
9
+
10
+ names_and_defaults = {}
11
+ hashes.each{|h| names_and_defaults.update h}
12
+ names.flatten.compact.each{|name| names_and_defaults.update name => nil}
13
+
14
+ names_and_defaults.each do |name, default|
15
+ init = b || lambda { default }
16
+ ivar, getter, setter, query = "@#{ name }", "#{ name }", "#{ name }=", "#{ name }?"
17
+
18
+ define_method(setter) do |value|
19
+ instance_variable_set ivar, value
20
+ end
21
+
22
+ define_method(getter) do |*value|
23
+ unless value.empty?
24
+ send setter, value.shift
25
+ else
26
+ defined = instance_eval "defined? #{ ivar }"
27
+ send setter, instance_eval(&init) unless defined
28
+ instance_variable_get ivar
29
+ end
30
+ end
31
+
32
+ alias_method query, getter
33
+
34
+ (attributes << name).uniq!
35
+ attributes
36
+ end
37
+ else
38
+ @attributes ||= []
39
+ end
40
+ end
41
+
42
+ def attribute(*a, &b) attributes *a, &b end
43
+ end
44
+
45
+ class Object
46
+ def attributes *a, &b
47
+ sc = class << self; self; end
48
+ sc.attributes *a, &b
49
+ end
50
+
51
+ def attribute(*a, &b) attributes *a, &b end
52
+ end
53
+
54
+ class Module; include Attributes; end
@@ -0,0 +1,70 @@
1
+ begin
2
+ require 'simplecc'
3
+ rescue LoadError
4
+ def Continuation.create(*args, &block)
5
+ cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
6
+ result ||= args
7
+ return *[cc, *result]
8
+ end
9
+ end
10
+
11
+ # This method returns the binding of the method that called your
12
+ # method. It will raise an Exception when you're not inside a method.
13
+ #
14
+ # It's used like this:
15
+ # def inc_counter
16
+ # Binding.of_caller do |binding|
17
+ # eval("counter += 1", binding)
18
+ # end
19
+ # end
20
+ # counter = 0
21
+ # 2.times { inc_counter }
22
+ # counter # => 2
23
+ #
24
+ # You will have to put the whole rest of your method into the
25
+ # block that you pass into this method. If you don't do this
26
+ # an Exception will be raised. Because of the way that this is
27
+ # implemented it has to be done this way. If you don't do it
28
+ # like this it will raise an Exception.
29
+ def Binding.of_caller(&block)
30
+ old_critical = Thread.critical
31
+ Thread.critical = true
32
+ count = 0
33
+ cc, result, error, extra_data = Continuation.create(nil, nil)
34
+ error.call if error
35
+
36
+ tracer = lambda do |*args|
37
+ type, context, extra_data = args[0], args[4], args
38
+ if type == "return"
39
+ count += 1
40
+ # First this method and then calling one will return --
41
+ # the trace event of the second event gets the context
42
+ # of the method which called the method that called this
43
+ # method.
44
+ if count == 2
45
+ # It would be nice if we could restore the trace_func
46
+ # that was set before we swapped in our own one, but
47
+ # this is impossible without overloading set_trace_func
48
+ # in current Ruby.
49
+ set_trace_func(nil)
50
+ cc.call(eval("binding", context), nil, extra_data)
51
+ end
52
+ elsif type != "line"
53
+ set_trace_func(nil)
54
+ error_msg = "Binding.of_caller used in non-method context or " +
55
+ "trailing statements of method using it aren't in the block."
56
+ cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
57
+ end
58
+ end
59
+
60
+ unless result
61
+ set_trace_func(tracer)
62
+ return nil
63
+ else
64
+ Thread.critical = old_critical
65
+ case block.arity
66
+ when 1 then yield(result)
67
+ else yield(result, extra_data)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,39 @@
1
+ module Alib
2
+ class << self
3
+ #--{{{
4
+ def version() VERSION end
5
+ def load basename
6
+ #--{{{
7
+ require LIBDIR + basename.to_s
8
+ #--}}}
9
+ end
10
+ def simple_main &b
11
+ #--{{{
12
+ #c = b ? (Class::new(ALib::SimpleMain, &b); : ALib::SimpleMain
13
+ c = Class::new ALib::SimpleMain
14
+ c.module_eval &b if b
15
+ c
16
+ #--}}}
17
+ end
18
+ alias_method 'smain', 'simple_main'
19
+ def configurable_main &b
20
+ #--{{{
21
+ c = Class::new ALib::ConfigurableMain
22
+ c.module_eval &b if b
23
+ c
24
+ #--}}}
25
+ end
26
+ alias_method 'cmain', 'configurable_main'
27
+ def script c = ALib::SimpleMain, &b
28
+ #--{{{
29
+ c = Class::new c
30
+ c.class_eval{ include ALib::Util }
31
+ c.class_eval &b if b
32
+ c.run
33
+ #--}}}
34
+ end
35
+ alias_method 'program', 'script'
36
+ alias_method 'cli', 'script'
37
+ #--}}}
38
+ end
39
+ end
File without changes
@@ -9,12 +9,62 @@ module ALib::Logging
9
9
  # not all logging devices are put into sync mode, resulting in improper log
10
10
  # rolling. this is a hack.
11
11
  #
12
+
12
13
  module LoggerExt
13
14
  #--{{{
14
15
  attr :logdev
15
16
  def << *args
16
- args.flatten.each{|a| super a}
17
+ #--{{{
18
+ m, c = Thread.main, Thread.current
19
+ args.flatten.each do |msg|
20
+ if m == c
21
+ super msg
22
+ else
23
+ eol = msg[%r/\s*$/o]
24
+ msg[%r/\s*$/o] = ''
25
+ super "#{ msg } (t:#{ c.object_id })#{ eol }"
26
+ end
27
+ end
17
28
  self
29
+ #--}}}
30
+ end
31
+ def ___mutex
32
+ #--{{{
33
+ unless defined?(@___mutex) and @___mutex
34
+ begin
35
+ Thread.critical = true
36
+ @___mutex = Sync::new unless defined?(@___mutex) and @___mutex
37
+ ensure
38
+ Thread.critical = false
39
+ end
40
+ end
41
+ @___mutex
42
+ #--}}}
43
+ end
44
+ def ___sync which = :EX
45
+ #--{{{
46
+ ___mutex.synchronize(which){ yield }
47
+ #--}}}
48
+ end
49
+
50
+ %w[ debug info warn error fatal ].each do |meth|
51
+ module_eval <<-code
52
+ def #{ meth }(*a, &b)
53
+ m, c = Thread.main, Thread.current
54
+ ___sync{
55
+ if m == c
56
+ super *a, &b
57
+ else
58
+ super{
59
+ msg = (a.empty? ? b.call : a.join).to_s
60
+ eol = msg[%r/\s*$/o]
61
+ msg[%r/\s*$/o] = ''
62
+ "\#{ msg } (t:\#{ c.object_id })\#{ eol }"
63
+ }
64
+ end
65
+ }
66
+ end
67
+ code
18
68
  end
19
69
  #--}}}
20
70
  end # module LoggerExt
@@ -54,6 +104,7 @@ module ALib::Logging
54
104
  @logger
55
105
  #--}}}
56
106
  end
107
+ alias_method 'logger!', 'logger'
57
108
  def logger= log
58
109
  #--{{{
59
110
  __logger_sync do
@@ -64,13 +115,15 @@ module ALib::Logging
64
115
  end
65
116
  #--}}}
66
117
  end
67
- %w( debug info warn error fatal ).each do |meth|
118
+
119
+ %w[ debug info warn error fatal ].each do |meth|
68
120
  module_eval <<-code
69
121
  def #{ meth }(*a, &b)
70
- __logger_sync{ logger.#{ meth }(*a, &b) }
122
+ logger.#{ meth } *a, &b
71
123
  end
72
124
  code
73
125
  end
126
+
74
127
  def log_err e
75
128
  #--{{{
76
129
  if logger.debug?
@@ -139,14 +192,25 @@ module ALib::Logging
139
192
  #--{{{
140
193
  def append_features c
141
194
  #--{{{
142
- ret = super
143
- c.extend LogMethods
144
- c.extend LogClassMethods
195
+ return self if((LogMethods === c) or (LogClassMethods === c))
196
+ ret = super rescue(return(self))
197
+ c.module_eval{
198
+ extend LogClassMethods
199
+ include LogMethods
200
+ extend LogMethods
201
+ }
202
+ #c.extend LogMethods
203
+ #c.extend LogClassMethods
145
204
  ret
146
205
  #--}}}
147
206
  end
148
207
  #--}}}
149
208
  end
150
- include LogMethods
209
+
210
+ append_features self
211
+
212
+ # include LogMethods
213
+ # extend LogMethods
214
+ # extend LogClassMethods
151
215
  #--}}}
152
216
  end # module Logging