define_exception 0.0.2
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/lib/define_exception.rb +139 -0
- data/test/define_exception_spec.rb +39 -0
- metadata +58 -0
@@ -0,0 +1,139 @@
|
|
1
|
+
# = Introduction
|
2
|
+
#
|
3
|
+
# Simple mixin that provides a way of defining custom exception classes
|
4
|
+
# with default messages that dries up your code.
|
5
|
+
#
|
6
|
+
# = The Problem of Laborious Exception Class Definitions
|
7
|
+
#
|
8
|
+
# Typically you would write the following in your code to define a custom exception
|
9
|
+
#
|
10
|
+
# class MyError < RuntimeError; end #nodoc
|
11
|
+
#
|
12
|
+
# This seems simple enough until you have to raise it many times throughout your code
|
13
|
+
# and have to provide an error message:
|
14
|
+
#
|
15
|
+
# raise( MyError, 'You shall not do what you just did' )
|
16
|
+
#
|
17
|
+
# It gets harder when you get tired of writing the same message to the <i>raise</i> command.
|
18
|
+
# You can define a hash constant to keep track of common error messages:
|
19
|
+
#
|
20
|
+
# ERRORS = { :myerror => 'You shall not do what you just did', ... }
|
21
|
+
#
|
22
|
+
# and then reference it
|
23
|
+
#
|
24
|
+
# raise( MyError, ERRORS[:myerror] )
|
25
|
+
#
|
26
|
+
# but this just doesn't seem very rubyish. You can also define the message when you write
|
27
|
+
# the custom exception class:
|
28
|
+
#
|
29
|
+
# class MyError < RuntimeError
|
30
|
+
# def message
|
31
|
+
# 'You shall not do what you just did' )
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# The problem is that this always uses this message even when overridden in <i>raise</i>
|
36
|
+
#
|
37
|
+
# raise( MyError, 'Use this instead' ) # <= 'You shall not do what you just did'
|
38
|
+
#
|
39
|
+
# The real solution for you class is to override the constructor:
|
40
|
+
#
|
41
|
+
# class MyError < RuntimeError
|
42
|
+
# def intialize( message = nil )
|
43
|
+
# super( message || 'Default Error Message' )
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# raise MyError # <= 'Default Error Message'
|
48
|
+
# raise MyError, 'Not the Default' # <= 'Not the Default'
|
49
|
+
#
|
50
|
+
# = A Better Way
|
51
|
+
#
|
52
|
+
# Though this accomplishes the goal it is laborious to write all this code especially
|
53
|
+
# as the number of custom exception definitions grow. A better solution would be to make
|
54
|
+
# a class method available that simply handles creating the exception for use automatically
|
55
|
+
# thus drying up our code:
|
56
|
+
#
|
57
|
+
# class TestMe
|
58
|
+
# define_exception 'MyError', 'The Default Message'
|
59
|
+
# define_exception 'AnotherError', 'Another Default Message'
|
60
|
+
# define_exception 'WorstError', 'Worst Default Message'
|
61
|
+
# ...
|
62
|
+
# def tester( args )
|
63
|
+
# raise MyError unless ...
|
64
|
+
# raise AnotherError unless ...
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# def worst( args )
|
68
|
+
# raise( WorstError, 'You really messed up' ) unless ...
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# = Usage
|
73
|
+
#
|
74
|
+
# The standard ruby practice of requiring the gem and then use <i>include DefineException</i> to
|
75
|
+
# make the class method available.
|
76
|
+
#
|
77
|
+
# = Example
|
78
|
+
#
|
79
|
+
# require 'rubygems'
|
80
|
+
# require 'define_exception'
|
81
|
+
#
|
82
|
+
# include DefineException
|
83
|
+
#
|
84
|
+
# class Test
|
85
|
+
# define_exception 'TestMe', 'this is the default message'
|
86
|
+
#
|
87
|
+
# def test
|
88
|
+
# raise TestMe
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# def test2
|
92
|
+
# raise( TestMe, 'You shall not do that again' )
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# t = Test.new
|
97
|
+
#
|
98
|
+
# begin
|
99
|
+
# t.test
|
100
|
+
# rescue Test::TestMe => e
|
101
|
+
# puts e.message
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# t.test2
|
105
|
+
#
|
106
|
+
# running the above example would correctly produce
|
107
|
+
#
|
108
|
+
# wes:~/Define-Exception> ruby test.rb
|
109
|
+
# this is the default message
|
110
|
+
# test.rb:14:in `test2': You shall not do that again (Test::TestMe)
|
111
|
+
# from test.rb:26
|
112
|
+
#
|
113
|
+
# = Information
|
114
|
+
#
|
115
|
+
# Author:: Wes Bailey, wes@verticalresponse.com
|
116
|
+
# License:: Ruby License
|
117
|
+
|
118
|
+
module DefineException
|
119
|
+
module ClassMethods
|
120
|
+
def define_exception( exception_name, default_message = 'Application Error Occurred' )
|
121
|
+
exception_name = exception_name.to_s.split( '_' ).inject( '' ) { |s,v| s << v.capitalize } if /\_/.match( exception_name.to_s )
|
122
|
+
|
123
|
+
class_eval <<-EOD
|
124
|
+
class #{exception_name} < RuntimeError
|
125
|
+
def initialize( message = nil )
|
126
|
+
super( message || "#{default_message}" )
|
127
|
+
end
|
128
|
+
end
|
129
|
+
EOD
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class << self
|
134
|
+
def included( base )
|
135
|
+
#base.extend( self )
|
136
|
+
base.extend( ClassMethods )
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
$: << File.dirname( File.join( __FILE__, '..' ) )
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'define_exception'
|
5
|
+
require 'spec/test/unit'
|
6
|
+
|
7
|
+
include DefineException
|
8
|
+
|
9
|
+
describe "Define Exception" do
|
10
|
+
it "should enable a class to define a custom exception" do
|
11
|
+
MESSAGE = 'This is the default message'
|
12
|
+
|
13
|
+
class TestDefineException
|
14
|
+
define_exception 'TestException', MESSAGE
|
15
|
+
|
16
|
+
def test
|
17
|
+
raise TestException
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
lambda {
|
22
|
+
tde = TestDefineException.new
|
23
|
+
tde.test
|
24
|
+
}.should raise_error( TestDefineException::TestException, MESSAGE )
|
25
|
+
|
26
|
+
class AnotherTest
|
27
|
+
define_exception :another_exception, MESSAGE
|
28
|
+
|
29
|
+
def test
|
30
|
+
raise AnotherException
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
lambda {
|
35
|
+
tde = AnotherTest.new
|
36
|
+
tde.test
|
37
|
+
}.should raise_error( AnotherTest::AnotherException, MESSAGE )
|
38
|
+
end
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: define_exception
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Wes Bailey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-05-24 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: wes@verticalresponse.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/define_exception.rb
|
26
|
+
has_rdoc: true
|
27
|
+
homepage: http://github.com/wbailey/define_exception
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options:
|
30
|
+
- --title
|
31
|
+
- Define Exception Mixin
|
32
|
+
- --main
|
33
|
+
- lib/define_exception.rb
|
34
|
+
- --line-numbers
|
35
|
+
- --inline-source
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: "0"
|
43
|
+
version:
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
requirements: []
|
51
|
+
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.3.1
|
54
|
+
signing_key:
|
55
|
+
specification_version: 2
|
56
|
+
summary: A simple way of defining exceptions for use in your ruby classes
|
57
|
+
test_files:
|
58
|
+
- test/define_exception_spec.rb
|