rextra 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+