cond 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ here = File.dirname(__FILE__)
2
+ require here + "/common"
3
+
4
+ require 'quix/ruby'
5
+
6
+ describe "specs" do
7
+ it "should run individually" do
8
+ (Dir["#{here}/*_spec.rb"] + Dir["#{here}/../examples/*_example.rb"]).each {
9
+ |spec|
10
+ unless File.basename(spec) == File.basename(__FILE__)
11
+ `"#{Quix::Ruby::EXECUTABLE}" "#{spec}"`
12
+ $?.exitstatus.should == 0
13
+ end
14
+ }
15
+ end
16
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + "/common"
2
+
3
+ #
4
+ # Try to demonstrate symbol recycling by calling GC.start on each pass
5
+ # through a symbol-generating loop.
6
+ #
7
+ # I have not yet seen jruby call the finalizers required for symbol
8
+ # recycling.
9
+ #
10
+
11
+ def symbols_spec(&block)
12
+ if defined?(RUBY_ENGINE) and RUBY_ENGINE == "jruby"
13
+ xit "jruby failing #{File.basename(__FILE__)}", &block
14
+ else
15
+ it "should be recycled", &block
16
+ end
17
+ end
18
+
19
+ describe "generated symbols" do
20
+ symbols_spec do
21
+ histogram = Hash.new { |hash, key| hash[key] = 0 }
22
+
23
+ 300.times { |n|
24
+ obj = Cond::CondPrivate::CodeSection.new(:foo)
25
+ leave, again = obj.instance_eval { [@leave, @again] }
26
+ histogram[leave] += 1
27
+ histogram[again] += 1
28
+ GC.start
29
+ }
30
+
31
+ histogram.values.any? { |t| t > 1 }.should == true
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + "/common"
2
+
3
+ require 'ostruct'
4
+
5
+ describe "ThreadLocal" do
6
+ it "should keep independent values in separate threads" do
7
+ a = Cond::CondPrivate::ThreadLocal.new { OpenStruct.new }
8
+ a.value.x = 33
9
+ other_value = nil
10
+ Thread.new {
11
+ a.value.x = 44
12
+ other_value = a.value.x
13
+ }.join
14
+
15
+ a.value.x.should == 33
16
+ other_value.should == 44
17
+ a.clear { 99 }
18
+ a.value.should == 99
19
+ end
20
+
21
+ it "should work with included accessor_module" do
22
+ a = Class.new {
23
+ include Cond::CondPrivate::ThreadLocal.accessor_module(:x) { 33 }
24
+ }.new
25
+ a.x.should == 33
26
+ a.x = 44
27
+ a.x.should == 44
28
+ end
29
+ end
@@ -0,0 +1,93 @@
1
+ require File.dirname(__FILE__) + "/common"
2
+
3
+ include Cond
4
+
5
+ describe "singleton method defined in C" do
6
+ before :all do
7
+ @memo = []
8
+ @define_handler = lambda {
9
+ handle ArgumentError do
10
+ @memo.push :handled
11
+ end
12
+ }
13
+ end
14
+
15
+ describe "unwrapped" do
16
+ it "should unwind" do
17
+ lambda {
18
+ handling do
19
+ @define_handler.call
20
+ IO.read
21
+ end
22
+ }.should raise_error(ArgumentError)
23
+ end
24
+
25
+ it "should not call handler" do
26
+ @memo.should == []
27
+ end
28
+ end
29
+
30
+ describe "wrapped" do
31
+ before :all do
32
+ Cond.wrap_singleton_method(IO, :read)
33
+ end
34
+
35
+ it "should not unwind" do
36
+ lambda {
37
+ handling do
38
+ @define_handler.call
39
+ IO.read
40
+ end
41
+ }.should_not raise_error(ArgumentError)
42
+ end
43
+
44
+ it "should call handler" do
45
+ @memo.should == [:handled]
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "instance method defined in C" do
51
+ before :all do
52
+ @memo = []
53
+ @define_handler = lambda {
54
+ handle ZeroDivisionError do |exception|
55
+ @memo.push :handled
56
+ end
57
+ }
58
+ end
59
+
60
+ describe "unwrapped" do
61
+ it "should unwind" do
62
+ lambda {
63
+ handling do
64
+ @define_handler.call
65
+ 3/0
66
+ end
67
+ }.should raise_error(ZeroDivisionError)
68
+ end
69
+
70
+ it "should not call handler" do
71
+ @memo.should == []
72
+ end
73
+ end
74
+
75
+ describe "wrapped" do
76
+ before :all do
77
+ Cond.wrap_instance_method(Fixnum, :/)
78
+ end
79
+
80
+ it "should not unwind" do
81
+ lambda {
82
+ handling do
83
+ @define_handler.call
84
+ 3/0
85
+ end
86
+ }.should_not raise_error(ZeroDivisionError )
87
+ end
88
+
89
+ it "should call handler" do
90
+ @memo.should == [:handled]
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,51 @@
1
+
2
+ require 'rbconfig'
3
+
4
+ module Quix
5
+ module Ruby
6
+ EXECUTABLE = lambda {
7
+ name = File.join(
8
+ Config::CONFIG["bindir"],
9
+ Config::CONFIG["RUBY_INSTALL_NAME"]
10
+ )
11
+
12
+ if Config::CONFIG["host"] =~ %r!(mswin|cygwin|mingw)! and
13
+ File.basename(name) !~ %r!\.(exe|com|bat|cmd)\Z!i
14
+ name + ".exe"
15
+ else
16
+ name
17
+ end
18
+ }.call
19
+
20
+ class << self
21
+ def run(*args)
22
+ system(EXECUTABLE, *args)
23
+ end
24
+
25
+ def run_or_raise(*args)
26
+ cmd = [EXECUTABLE, *args]
27
+ unless system(*cmd)
28
+ msg = (
29
+ "failed to launch ruby: " +
30
+ "system(*#{cmd.inspect}) failed with status #{$?.exitstatus}"
31
+ )
32
+ raise msg
33
+ end
34
+ end
35
+
36
+ def with_warnings(value = true)
37
+ previous = $VERBOSE
38
+ $VERBOSE = value
39
+ begin
40
+ yield
41
+ ensure
42
+ $VERBOSE = previous
43
+ end
44
+ end
45
+
46
+ def no_warnings(&block)
47
+ with_warnings(false, &block)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,88 @@
1
+
2
+ require 'rbconfig'
3
+ require 'fileutils'
4
+ require 'find'
5
+
6
+ module Quix
7
+ class SimpleInstaller
8
+ def initialize
9
+ dest_root = Config::CONFIG["sitelibdir"]
10
+ sources = []
11
+ Find.find("./lib") { |source|
12
+ if install_file?(source)
13
+ sources << source
14
+ end
15
+ }
16
+ @spec = sources.inject(Array.new) { |acc, source|
17
+ if source == "./lib"
18
+ acc
19
+ else
20
+ dest = File.join(dest_root, source.sub(%r!\A\./lib!, ""))
21
+
22
+ install = lambda {
23
+ if File.directory?(source)
24
+ unless File.directory?(dest)
25
+ puts "mkdir #{dest}"
26
+ FileUtils.mkdir(dest)
27
+ end
28
+ else
29
+ puts "install #{source} --> #{dest}"
30
+ FileUtils.install(source, dest)
31
+ end
32
+ }
33
+
34
+ uninstall = lambda {
35
+ if File.directory?(source)
36
+ if File.directory?(dest)
37
+ puts "rmdir #{dest}"
38
+ FileUtils.rmdir(dest)
39
+ end
40
+ else
41
+ if File.file?(dest)
42
+ puts "rm #{dest}"
43
+ FileUtils.rm(dest)
44
+ end
45
+ end
46
+ }
47
+
48
+ acc << {
49
+ :source => source,
50
+ :dest => dest,
51
+ :install => install,
52
+ :uninstall => uninstall,
53
+ }
54
+ end
55
+ }
56
+ end
57
+
58
+ def install_file?(source)
59
+ !File.symlink?(source) and
60
+ (File.directory?(source) or
61
+ (File.file?(source) and File.extname(source) == ".rb"))
62
+ end
63
+
64
+ attr_accessor :spec
65
+
66
+ def install
67
+ @spec.each { |entry|
68
+ entry[:install].call
69
+ }
70
+ end
71
+
72
+ def uninstall
73
+ @spec.reverse.each { |entry|
74
+ entry[:uninstall].call
75
+ }
76
+ end
77
+
78
+ def run(args = ARGV)
79
+ if args.empty? or (args.size == 1 and args.first == "install")
80
+ install
81
+ elsif args.size == 1 and args.first == "--uninstall"
82
+ uninstall
83
+ else
84
+ raise "unrecognized arguments: #{args.inspect}"
85
+ end
86
+ end
87
+ end
88
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cond
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - James M. Lawrence
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-22 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: +Cond+ allows errors to be handled at the place where they occur. You decide whether or not the stack should be unwound, depending on the circumstance and the error.
17
+ email: quixoticsycophant@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - README
26
+ - cond.gemspec
27
+ - ./examples/bad_example.rb
28
+ - ./examples/calc_example.rb
29
+ - ./examples/readme_example.rb
30
+ - ./examples/restarts_example.rb
31
+ - ./examples/seibel_example.rb
32
+ - ./install.rb
33
+ - ./lib/cond/cond_private/defaults.rb
34
+ - ./lib/cond/cond_private/symbol_generator.rb
35
+ - ./lib/cond/cond_private/thread_local.rb
36
+ - ./lib/cond.rb
37
+ - ./readmes/restarts.rb
38
+ - ./readmes/seibel_pcl.rb
39
+ - ./spec/basic_spec.rb
40
+ - ./spec/common.rb
41
+ - ./spec/error_spec.rb
42
+ - ./spec/leave_again_spec.rb
43
+ - ./spec/matching_spec.rb
44
+ - ./spec/raise_spec.rb
45
+ - ./spec/reraise_spec.rb
46
+ - ./spec/specs_spec.rb
47
+ - ./spec/symbols_spec.rb
48
+ - ./spec/thread_local_spec.rb
49
+ - ./spec/wrapping_spec.rb
50
+ - ./support/quix/ruby.rb
51
+ - ./support/quix/simple_installer.rb
52
+ - ./Rakefile
53
+ has_rdoc: true
54
+ homepage: cond.rubyforge.org
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --main
58
+ - README
59
+ - --title
60
+ - "cond: Resolve errors without unwinding the stack."
61
+ - --exclude
62
+ - spec
63
+ - --exclude
64
+ - examples
65
+ - --exclude
66
+ - readmes
67
+ - --exclude
68
+ - support
69
+ - --exclude
70
+ - lib/cond/cond_private
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project: cond
88
+ rubygems_version: 1.3.1
89
+ signing_key:
90
+ specification_version: 2
91
+ summary: Resolve errors without unwinding the stack.
92
+ test_files: []
93
+