adamtanner-terror 0.3.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/.gitignore +2 -0
- data/LICENSE +20 -0
- data/README.markdown +49 -0
- data/Rakefile +13 -0
- data/VERSION +1 -0
- data/lib/terror.rb +48 -0
- data/spec/terror_spec.rb +68 -0
- metadata +61 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Adam Tanner
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
!! TERROR !!
|
2
|
+
|
3
|
+
Terror allows you to define your errors/exceptions in a pretty run-of-the-mill style DSL.
|
4
|
+
|
5
|
+
Reasons Terror exists:
|
6
|
+
|
7
|
+
* Because defining errors as subclasses of StandardError looks ugly.
|
8
|
+
* Also, because I wanted to make a pseudo-useful DSL.
|
9
|
+
|
10
|
+
How to use Terror:
|
11
|
+
|
12
|
+
For times where all you need is a pretty name to raise.
|
13
|
+
|
14
|
+
exceptions :exceptionally, "exceptional"
|
15
|
+
|
16
|
+
|
17
|
+
If you need a little more control over your exceptions you can use a block.
|
18
|
+
The methods inside the block become camel-cased exceptions where the method name
|
19
|
+
is the exception name.
|
20
|
+
|
21
|
+
exceptions do
|
22
|
+
there_is_no_exception "You did wrong. There is no exception!"
|
23
|
+
end
|
24
|
+
|
25
|
+
The argument passed to the method is the message you want to use when you raise the exception.
|
26
|
+
For the example above you would do:
|
27
|
+
|
28
|
+
raise ThereIsNoException, ThereIsNoException.message
|
29
|
+
|
30
|
+
If you need even more control over your exceptions and want to add custom functionality you can
|
31
|
+
pass the method a block and insert whatever code you want available for the exception.
|
32
|
+
|
33
|
+
exceptions do
|
34
|
+
my_exception do
|
35
|
+
def handle_my_exception()
|
36
|
+
return "Check that out, I can add my own methods!"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
And, of course, all of these can be done together in the same exceptions method if you need more,
|
42
|
+
or less, functionality for different exceptions.
|
43
|
+
|
44
|
+
Things I'd Like to Get Around to Doing:
|
45
|
+
|
46
|
+
* Making this a gem.
|
47
|
+
* Writing tests. (In progress)
|
48
|
+
|
49
|
+
That's all folks.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gem|
|
4
|
+
gem.name = "terror"
|
5
|
+
gem.summary = "Because defining exceptions as subclasses of StandardError looks ugly."
|
6
|
+
gem.description = "Because defining exceptions as subclasses of StandardError looks ugly."
|
7
|
+
gem.email = "adam@adamtanner.org"
|
8
|
+
gem.homepage = "http://github.com/adamtanner/terror"
|
9
|
+
gem.authors = ["Adam Tanner"]
|
10
|
+
end
|
11
|
+
rescue LoadError
|
12
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
13
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/lib/terror.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Terror
|
2
|
+
def self.included(base)
|
3
|
+
base.send(:include, Terror::InstanceMethods)
|
4
|
+
base.send(:extend, Terror::ClassMethods)
|
5
|
+
Terror.base_class = base
|
6
|
+
end
|
7
|
+
|
8
|
+
class ErrorBuilder
|
9
|
+
def method_missing(method, *arguments, &block)
|
10
|
+
return Terror.base_class.new.send(method, *arguments) if Terror.base_class.new.respond_to?(method)
|
11
|
+
return Terror.base_class.send(method, *arguments) if Terror.base_class.respond_to?(method)
|
12
|
+
error_class = Terror.base_class.const_set(Terror.camelize(method), Class.new(StandardError))
|
13
|
+
error_class.class_eval(&block) if block_given?
|
14
|
+
message, arguments = arguments
|
15
|
+
if message
|
16
|
+
error_class.class_eval %{ class << self; self.send(:define_method, :message) { "#{message}" }; end }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def exceptions(*exceptions, &block)
|
23
|
+
Terror::ErrorBuilder.new.instance_eval(&block) if block_given?
|
24
|
+
|
25
|
+
exceptions.each do |exception|
|
26
|
+
Terror.base_class.const_set(Terror.camelize(exception), Class.new(StandardError))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module InstanceMethods
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
# @see Lifted from the Rails Inflector.
|
37
|
+
def self.camelize(string)
|
38
|
+
string.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.base_class=(base)
|
42
|
+
@@base_class = base
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.base_class
|
46
|
+
@@base_class
|
47
|
+
end
|
48
|
+
end
|
data/spec/terror_spec.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
2
|
+
|
3
|
+
require 'terror'
|
4
|
+
|
5
|
+
describe Terror do
|
6
|
+
before(:all) do
|
7
|
+
TestClass = Class.new
|
8
|
+
TestClass.send(:include, Terror)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should take a symbol and convert it to an exception" do
|
12
|
+
TestClass.exceptions :exception_from_symbol
|
13
|
+
TestClass.constants.should include("ExceptionFromSymbol")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should take a string and convert it to an exception" do
|
17
|
+
TestClass.exceptions "ExceptionFromString"
|
18
|
+
TestClass.constants.should include("ExceptionFromString")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should convert the method in the block to an exception" do
|
22
|
+
TestClass.exceptions { exception_from_block }
|
23
|
+
TestClass.constants.should include("ExceptionFromBlock")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should assign the message from the method in the block" do
|
27
|
+
TestClass.exceptions { exception_from_block_with_message "Message from exception." }
|
28
|
+
TestClass::ExceptionFromBlockWithMessage.message.should match("Message from exception.")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should evaluate the block given to the method in the context of the exception" do
|
32
|
+
TestClass.exceptions do
|
33
|
+
exception_with_custom_code do
|
34
|
+
def custom_handle
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
TestClass::ExceptionWithCustomCode.new.should respond_to(:custom_handle)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should evaluate instance methods from the base class from within the block" do
|
42
|
+
TestClass.send(:define_method, :message_from_base_class) { return "This is a message from the base class!" }
|
43
|
+
TestClass.exceptions do
|
44
|
+
exception_with_message_from_helper message_from_base_class
|
45
|
+
end
|
46
|
+
TestClass::ExceptionWithMessageFromHelper.message.should match("This is a message from the base class!")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should evaluate singleton methods from the base class from within the block" do
|
50
|
+
TestClass.class_eval %{ def self.message_from_base_class; return "This is a message from the base class!"; end }
|
51
|
+
TestClass.exceptions do
|
52
|
+
exception_with_message_from_class_helper message_from_base_class
|
53
|
+
end
|
54
|
+
TestClass::ExceptionWithMessageFromClassHelper.message.should match("This is a message from the base class!")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should evaluate methods with arguments from the base class from within the block" do
|
58
|
+
TestClass.send(:define_method, :message_from_base_class_with_arguments) do |first, second, third|
|
59
|
+
"This is my message. I love #{first} #{second} #{third}!"
|
60
|
+
end
|
61
|
+
TestClass.exceptions do
|
62
|
+
exception_with_message_from_helper_with_arguments message_from_base_class_with_arguments("super", "long", "methods")
|
63
|
+
end
|
64
|
+
TestClass::ExceptionWithMessageFromHelperWithArguments.message.
|
65
|
+
should match("This is my message. I love super long methods!")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: adamtanner-terror
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Tanner
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-31 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Because defining exceptions as subclasses of StandardError looks ugly.
|
17
|
+
email: adam@adamtanner.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.markdown
|
25
|
+
files:
|
26
|
+
- .gitignore
|
27
|
+
- LICENSE
|
28
|
+
- README.markdown
|
29
|
+
- Rakefile
|
30
|
+
- VERSION
|
31
|
+
- lib/terror.rb
|
32
|
+
- spec/terror_spec.rb
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: http://github.com/adamtanner/terror
|
35
|
+
licenses:
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --charset=UTF-8
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
version:
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
requirements: []
|
54
|
+
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 1.3.5
|
57
|
+
signing_key:
|
58
|
+
specification_version: 2
|
59
|
+
summary: Because defining exceptions as subclasses of StandardError looks ugly.
|
60
|
+
test_files:
|
61
|
+
- spec/terror_spec.rb
|