rextra 2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
@@ -0,0 +1,85 @@
1
+ begin
2
+ require 'simplecc'
3
+ rescue LoadError
4
+ # to satisfy rdoc
5
+ class Continuation #:nodoc:
6
+ end
7
+ def Continuation.create(*args, &block) # :nodoc:
8
+ cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
9
+ result ||= args
10
+ return *[cc, *result]
11
+ end
12
+ end
13
+
14
+ class Binding; end # for RDoc
15
+ # This method returns the binding of the method that called your
16
+ # method. It will raise an Exception when you're not inside a method.
17
+ #
18
+ # It's used like this:
19
+ # def inc_counter(amount = 1)
20
+ # Binding.of_caller do |binding|
21
+ # # Create a lambda that will increase the variable 'counter'
22
+ # # in the caller of this method when called.
23
+ # inc = eval("lambda { |arg| counter += arg }", binding)
24
+ # # We can refer to amount from inside this block safely.
25
+ # inc.call(amount)
26
+ # end
27
+ # # No other statements can go here. Put them inside the block.
28
+ # end
29
+ # counter = 0
30
+ # 2.times { inc_counter }
31
+ # counter # => 2
32
+ #
33
+ # Binding.of_caller must be the last statement in the method.
34
+ # This means that you will have to put everything you want to
35
+ # do after the call to Binding.of_caller into the block of it.
36
+ # This should be no problem however, because Ruby has closures.
37
+ # If you don't do this an Exception will be raised. Because of
38
+ # the way that Binding.of_caller is implemented it has to be
39
+ # done this way.
40
+ def Binding.of_caller(&block)
41
+ old_critical = Thread.critical
42
+ Thread.critical = true
43
+ count = 0
44
+ cc, result, error, extra_data = Continuation.create(nil, nil)
45
+ error.call if error
46
+
47
+ tracer = lambda do |*args|
48
+ type, context, extra_data = args[0], args[4], args
49
+ if type == "return"
50
+ count += 1
51
+ # First this method and then calling one will return --
52
+ # the trace event of the second event gets the context
53
+ # of the method which called the method that called this
54
+ # method.
55
+ if count == 2
56
+ # It would be nice if we could restore the trace_func
57
+ # that was set before we swapped in our own one, but
58
+ # this is impossible without overloading set_trace_func
59
+ # in current Ruby.
60
+ set_trace_func(nil)
61
+ cc.call(eval("binding", context), nil, extra_data)
62
+ end
63
+ elsif type == "line" then
64
+ nil
65
+ elsif type == "c-return" and extra_data[3] == :set_trace_func then
66
+ nil
67
+ else
68
+ set_trace_func(nil)
69
+ error_msg = "Binding.of_caller used in non-method context or " +
70
+ "trailing statements of method using it aren't in the block."
71
+ cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
72
+ end
73
+ end
74
+
75
+ unless result
76
+ set_trace_func(tracer)
77
+ return nil
78
+ else
79
+ Thread.critical = old_critical
80
+ case block.arity
81
+ when 1 then yield(result)
82
+ else yield(result, extra_data)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,233 @@
1
+ #--
2
+ # rapid/rextra.rb
3
+ # USE "rdoc rapid/rextra.rb" to build the docs for this file.
4
+ #++
5
+ #
6
+ # == Example Use
7
+ # TBD
8
+ #
9
+ # == Credits
10
+ # Michael Garriss
11
+ #
12
+ # == Licence
13
+ # TBD
14
+
15
+
16
+ #--
17
+ # TODO doc this
18
+ # TODO review this
19
+ # TODO move to seperate project
20
+ # TODO test test test
21
+ #++
22
+
23
+ require 'rextra/cutting'
24
+
25
+ def ObjectSpace.make_proc str
26
+ eval "proc {#{str}}"
27
+ end
28
+
29
+ module Kernel
30
+ def call_stack
31
+ require 'ostruct'
32
+ caller.map do |c|
33
+ # TODO rewrite this regexp
34
+ m = /^([\.a-zA-Z_0-9()\/]*):(\d*)(?::in `(\S*)')?$/.match c
35
+ OpenStruct.new(:file=>m[1],:line=>m[2],:call=>m[3]) rescue nil
36
+ end.compact
37
+ end
38
+ def caller_name deep = 1
39
+ /:in `(\S*)'$/.match( caller[deep] )[1]
40
+ end
41
+ def method_name() caller_name end
42
+ end
43
+
44
+ class Object
45
+ def this
46
+ require 'weakref'
47
+ WeakRef.new self
48
+ end
49
+ def destructor str
50
+ ObjectSpace.define_finalizer this, ObjectSpace.make_proc( str )
51
+ end
52
+ end
53
+
54
+ class Module
55
+ #def once_methods *meths
56
+ # act_on_methods *meths do |meth|
57
+ # alias_method "__rapid_#{meth}", meth if method_defined? meth
58
+ # meta_eval { (@once ||= Set.new) << meth }
59
+ # class_eval<<-HERE
60
+ # def #{meth} *args, &block
61
+ # __rapid_#{method} *args, &block
62
+ # ensure # is this right?
63
+ # undef_methods __rapid_#{meth}
64
+ # empty_methods #{meth}
65
+ # end
66
+ # HERE
67
+ # end
68
+ #end
69
+ def module () self end
70
+ def modules() [self] + modules_up end
71
+ def module_up() eval name.sub( /(::)?\w+$/, '' ) end
72
+ def modules_up result = []
73
+ (r = module_up) ? r.modules_up( result << r ) : result end
74
+ def def_advice meth, &block
75
+ prev = self.instance_method meth.
76
+ define_method( meth ) do |*args|
77
+ block.call( prev.bind(self), *args ) end end
78
+
79
+ # TODO fix #const to look in global module
80
+ class Const
81
+ def initialize mod
82
+ @mod = mod
83
+ end
84
+ def method_missing( sym, *args )
85
+ @mod.modules.each do |mod|
86
+ return mod.const_get( sym ) if mod.const_defined? sym.to_s
87
+ end
88
+ #raise NameError, "uninitialized constant #{sym}"
89
+ nil
90
+ end
91
+ end
92
+
93
+ def const
94
+ Const.new self.module
95
+ end
96
+
97
+ def consts *syms
98
+ start, inc = 0, 1
99
+ start = syms.shift if syms.first.kind_of? Integer
100
+ inc = syms.pop if syms.last.kind_of? Integer
101
+ syms.each do |sym|
102
+ class_eval "#{sym.to_s.upcase} = #{start}"
103
+ start += inc
104
+ end
105
+ end
106
+
107
+ end
108
+
109
+ def parallel_each( *args )
110
+ args.shift.zip( *args ).each do |e|
111
+ yield( *e )
112
+ end
113
+ end
114
+
115
+ module Rapid
116
+
117
+ class ThreadPool
118
+ def initialize size = 10
119
+ @count, @max = 0, size
120
+ @mutex, @cond = Mutex.new, ConditionVariable.new
121
+ end
122
+ def thread *args, &block
123
+ @mutex.synchronize do
124
+ @cond.wait @mutex unless @count < @max
125
+ @count += 1
126
+ result = Thread.new(args,Thread.current,block) do |args,th,block|
127
+ begin
128
+ block.call *args
129
+ rescue => e
130
+ th.raise e
131
+ ensure
132
+ release
133
+ end end end
134
+ end
135
+ def max=(size) @mutex.synchronize { @max = size } end
136
+ private
137
+ def release
138
+ @mutex.synchronize do
139
+ @count -= 1
140
+ @cond.signal
141
+ end
142
+ end
143
+ end
144
+
145
+ VERSION = '0.0.2'
146
+
147
+ def self.tempfile name = nil
148
+ require 'tempfile'
149
+ tf = Tempfile.new name
150
+ yield tf
151
+ ensure
152
+ tf.close true
153
+ end
154
+
155
+ def self.start_daemon *args, &block
156
+ :$VERBOSE.temporary nil do
157
+ #EndData.close if $leftovers
158
+ Process.fork do
159
+ fork and exit
160
+ trap( 'INT' ) { Thread.current.kill }
161
+ $stderr = $stdout = $stdin = NullDevice.new
162
+ Process.setsid
163
+ block.call( *args )
164
+ end
165
+ end
166
+ end
167
+
168
+ def self.term_size
169
+ require 'curses'
170
+ Curses.init_screen
171
+ x, y = Curses.cols, Curses.lines
172
+ Curses.close_screen
173
+ [x, y]
174
+ ensure
175
+ Curses.close_screen
176
+ end
177
+
178
+ def self.filename
179
+ File.basename $0
180
+ end
181
+
182
+ def self.create_key size = 16 # copied from cgi/session.rb
183
+ require 'digest/md5'
184
+ md5 = Digest::MD5::new
185
+ md5.update(String(Time::now))
186
+ md5.update(String(rand(0)))
187
+ md5.update(String($$))
188
+ md5.hexdigest[0,size]
189
+ end
190
+
191
+ module Kernel
192
+
193
+ def modules() self.class.modules end
194
+ def module() self.class.module end
195
+ def module_up() self.class.module_up end
196
+ def modules_up() self.class.modules_up end
197
+
198
+ end
199
+
200
+ def required
201
+ result = []
202
+ $".each do |file|
203
+ $:.each do |path|
204
+ if File.exists?( path + '/' + file )
205
+ result << (path + '/' + file)
206
+ next
207
+ end
208
+ end
209
+ end
210
+ result
211
+ end
212
+
213
+ def required? file
214
+ (el = required.grep( /#{file}(\.rb|\.so)?$/ ).to_el).empty? ? false : el
215
+ end
216
+
217
+ class Array
218
+ def to_el # TODO better name
219
+ size == 1 ? first : self
220
+ end
221
+ end
222
+
223
+ class Numeric
224
+ def commify
225
+ to_s.reverse.scan(/\d{3}|\d+/).join(',').reverse
226
+ end
227
+ end
228
+
229
+ class Float
230
+ def to_s_cut x = 3
231
+ to_s.scan(/\d*\.\d{0,#{x}}/)
232
+ end
233
+ end
@@ -0,0 +1,66 @@
1
+ class Object
2
+ def meta() class << self; self end end
3
+ def meta_eval(&blk) meta.instance_eval( &blk ) end
4
+ def meta_def(name, &blk) meta_eval { define_method name, &blk } end
5
+ def class_def name, &blk
6
+ self.class.class_eval { define_method name, &blk }
7
+ end
8
+ def blank?
9
+ if respond_to? :empty? then empty?
10
+ elsif respond_to? :zero? then zero?
11
+ else !self
12
+ end
13
+ end
14
+ end
15
+ # -----------------------------------------------------------------------------
16
+ class Module
17
+ def act_on_methods *meths
18
+ (meths.empty? ? instance_methods : meths).each do |meth|
19
+ yield meth unless %w{__id__ __send__}.include? meth
20
+ end
21
+ end
22
+ def undef_methods *meths
23
+ act_on_methods *meths do |meth|
24
+ undef_method meth
25
+ end
26
+ end
27
+ def empty_methods *meths
28
+ act_on_methods *meths do |meth|
29
+ class_def meth do nil end
30
+ end
31
+ end
32
+ end
33
+ class SimpleObject
34
+ undef_methods
35
+ end
36
+ # -----------------------------------------------------------------------------
37
+ module Rextra
38
+ module Enumerable
39
+ class Base < SimpleObject
40
+ def initialize( master ) @master = master end
41
+ end
42
+ class All < Base
43
+ def method_missing( sym, *args )
44
+ @master.map do |e| e.send sym, *args end
45
+ end
46
+ end
47
+ class Do < Base
48
+ def method_missing( sym, *args )
49
+ @master.map! do |e| e.send sym, *args end
50
+ self
51
+ end
52
+ def end() @master end
53
+ end
54
+ end
55
+ end
56
+ module Enumerable
57
+ def all() Rextra::Enumerable::All.new self end
58
+ def do () Rextra::Enumerable::Do.new self end
59
+ end
60
+ # -----------------------------------------------------------------------------
61
+ #module Kernel
62
+ # def caller_name deep = 1
63
+ # /:in `(\S*)'$/.match(caller[deep])[1]
64
+ # end
65
+ # def method_name() caller_name end
66
+ #end
@@ -0,0 +1,80 @@
1
+ #--
2
+ # rextra/enddata.rb -
3
+ # USE "rdoc rextra/enddata.rb" to build the docs for this file.
4
+ #++
5
+ #
6
+ # == WARNING!
7
+ # load'ing or require'ing this file will write over anything in your DATA area
8
+ #
9
+ # == Example Use
10
+ # TBD
11
+ #
12
+ # == Credits
13
+ # Michael Garriss
14
+ #
15
+ # == Licence
16
+ # TBD
17
+ #
18
+
19
+ #--
20
+ # TODO review this
21
+ #++
22
+
23
+ require 'rextra'
24
+
25
+ module Rapid
26
+
27
+ class LEFTOVERS
28
+ class << self
29
+ strip_methods
30
+ def method_missing sym, *args
31
+ $leftovers.send sym, *args
32
+ end
33
+ end
34
+ end
35
+
36
+ module EndData
37
+ def self.add_tag
38
+ file = File.new $0, 'a+'
39
+ file << "\n__END__\n"
40
+ $_DATA = file # holy hack
41
+ end
42
+ if defined? DATA
43
+ $_DATA = DATA
44
+ else
45
+ self.add_tag
46
+ end
47
+ def self.make_writable( pos = $_DATA.pos )
48
+ $_DATA.reopen $0, 'a+'
49
+ $_DATA.pos = pos
50
+ end
51
+ def self.clear( pos = $_DATA.pos )
52
+ $_DATA.truncate pos
53
+ end
54
+ def self.write str
55
+ $_DATA.write str
56
+ end
57
+ def self.method_missing sym, *args
58
+ $_DATA.send sym, *args
59
+ end
60
+ end
61
+
62
+ pos = $_DATA.pos
63
+ if (m = $_DATA.read).size > 0
64
+ $leftovers = Marshal.load( m )
65
+ else
66
+ $leftovers = {}
67
+ end
68
+ begin
69
+ EndData.make_writable pos
70
+ at_exit do
71
+ unless EndData.closed?
72
+ EndData.clear pos
73
+ EndData.write Marshal.dump( $leftovers )
74
+ end
75
+ end
76
+ #rescue
77
+ end
78
+
79
+ end
80
+
data/lib/rextra.rb ADDED
@@ -0,0 +1 @@
1
+ require 'rextra/cutting'
data/test/tc_kernel.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'test/unit'
2
+ require './lib/rextra/cutting'
3
+
4
+ class KernelTest < Test::Unit::TestCase
5
+ def foo() bar end
6
+ def bar() baz end
7
+ def baz() caller_name end
8
+
9
+ def test_caller_name
10
+ assert_equal baz, 'test_caller_name'
11
+ assert_equal bar, 'bar'
12
+ assert_equal foo, 'bar'
13
+ end
14
+
15
+ def foo2() bar end
16
+ def bar2() baz end
17
+ def baz2() method_name end
18
+
19
+ def test_method_name
20
+ name = method_name
21
+ assert_equal name, 'test_method_name'
22
+ assert_equal baz2, 'baz2'
23
+ assert_equal bar2, 'baz2'
24
+ assert_equal foo2, 'baz2'
25
+ end
26
+ end
data/test/tc_module.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+ require './lib/rextra/cutting'
3
+
4
+ class ModuleTest < Test::Unit::TestCase
5
+ def test_act_on_methods
6
+ assert true
7
+ end
8
+ end
data/test/tc_object.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'test/unit'
2
+ require './lib/rextra/cutting'
3
+
4
+ class ObjectTest < Test::Unit::TestCase
5
+ def test_blank?
6
+ assert nil.blank?
7
+ assert false.blank?
8
+ assert [].blank?
9
+ assert "".blank?
10
+ assert Hash.new.blank?
11
+ assert( !5.blank? )
12
+ assert( !true.blank? )
13
+ assert( ![1].blank? )
14
+ assert( !"1".blank? )
15
+ end
16
+
17
+ class Foo; end
18
+
19
+ def test_class_def
20
+ foo = Foo.new
21
+ assert_nothing_raised { foo.class_def(:foo) { 23 } }
22
+ assert_nothing_raised { foo.class_def(:bar) { "this" } }
23
+ assert_equal foo.foo, 23
24
+ assert_equal foo.bar, "this"
25
+ end
26
+
27
+ def test_meta
28
+ assert meta
29
+ assert_equal meta.class, Class
30
+ end
31
+
32
+ def test_meta_eval
33
+ assert_nothing_raised { meta_eval { } }
34
+ assert_equal meta_eval { @foo = 10 }, 10
35
+ assert_equal meta_eval { @foo }, 10
36
+ assert_equal( class << self; @foo end, 10 )
37
+ end
38
+
39
+ class Bar; end
40
+
41
+ def test_class_def
42
+ foo = Bar.new
43
+ assert_nothing_raised { foo.meta_def(:foo) { 23 } }
44
+ assert_nothing_raised { foo.meta_def(:bar) { "this" } }
45
+ assert_equal foo.foo, 23
46
+ assert_equal foo.bar, "this"
47
+ assert_equal meta_eval { foo.foo }, 23
48
+ end
49
+ end
data/test/ts_rextra.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'test/unit'
2
+
3
+ # cutting
4
+ require 'test/tc_object'
5
+ require 'test/tc_module'
6
+ #require 'test/tc_kernel'
7
+
8
+ # bleeding
9
+ #require 'test/bleeding/tc_kernel'
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: rextra
5
+ version: !ruby/object:Gem::Version
6
+ version: "2.0"
7
+ date: 2006-10-24 00:00:00 -06:00
8
+ summary: Ruby extras.
9
+ require_paths:
10
+ - lib
11
+ email: mgarriss@gmail.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: rextra
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Michael Garriss
31
+ files:
32
+ - test/tc_kernel.rb
33
+ - test/tc_module.rb
34
+ - test/tc_object.rb
35
+ - test/ts_rextra.rb
36
+ - lib/rextra
37
+ - lib/rextra.rb
38
+ - lib/rextra/binding_of_caller.rb
39
+ - lib/rextra/bleeding.rb
40
+ - lib/rextra/cutting.rb
41
+ - lib/rextra/enddata.rb
42
+ - README
43
+ test_files:
44
+ - test/ts_rextra.rb
45
+ rdoc_options: []
46
+
47
+ extra_rdoc_files:
48
+ - README
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ requirements: []
54
+
55
+ dependencies: []
56
+