qualitysmith_extensions 0.0.13 → 0.0.17
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 +5 -5
- data/lib/qualitysmith_extensions/exception/inspect_with_backtrace.rb +61 -0
- data/lib/qualitysmith_extensions/kernel/example_printer.rb +2 -2
- data/lib/qualitysmith_extensions/kernel/filter_output.rb +2 -2
- data/lib/qualitysmith_extensions/module/attr_tester.rb +2 -0
- data/lib/qualitysmith_extensions/module/attribute_accessors.rb +2 -2
- data/lib/qualitysmith_extensions/module/guard_method.rb +112 -0
- data/lib/qualitysmith_extensions/module/mattr_tester.rb +120 -0
- data/lib/qualitysmith_extensions/object/mcall.rb +92 -0
- data/lib/qualitysmith_extensions/object/send_if.rb +87 -0
- data/lib/qualitysmith_extensions/object/singleton_send.rb +10 -7
- data/lib/qualitysmith_extensions/template.rb +32 -0
- data/lib/qualitysmith_extensions/test/assert_exception.rb +1 -0
- metadata +9 -2
data/Readme
CHANGED
@@ -22,8 +22,8 @@ Like Facets, this library contains:
|
|
22
22
|
|
23
23
|
== Usage
|
24
24
|
|
25
|
-
require
|
26
|
-
gem
|
25
|
+
require 'rubygems'
|
26
|
+
gem 'qualitysmith_extensions'
|
27
27
|
|
28
28
|
And then <b>include as much or as little as you want</b>.
|
29
29
|
|
@@ -31,15 +31,15 @@ Use the handy <tt>all.rb</tt> files to load everything in a particular directory
|
|
31
31
|
|
32
32
|
To load everything:
|
33
33
|
|
34
|
-
require
|
34
|
+
require 'qualitysmith_extensions/all'
|
35
35
|
|
36
36
|
To load everything just for one class:
|
37
37
|
|
38
|
-
require
|
38
|
+
require 'qualitysmith_extensions/string/all'
|
39
39
|
|
40
40
|
To load just an individual method:
|
41
41
|
|
42
|
-
require
|
42
|
+
require 'qualitysmith_extensions/array/average'
|
43
43
|
|
44
44
|
|
45
45
|
== Running tests
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Yes
|
6
|
+
# Developer notes::
|
7
|
+
# * Add depth argument to inspect()?
|
8
|
+
#++
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
require 'facets/core/module/alias_method_chain'
|
12
|
+
|
13
|
+
class Exception
|
14
|
+
# Use this if you want to output an exception with all the details that you'd *normally* see if the exception went unrescued
|
15
|
+
# (since exception.inspect/p exception doesn't provide a backtrace!)
|
16
|
+
# This is mostly useful if you rescue an exception, want to print or log it and then re-raise it...
|
17
|
+
def inspect_with_backtrace
|
18
|
+
exception.class.name + ": " + exception.message + "\n" +
|
19
|
+
exception.backtrace.map {|v| ' ' + v}.join( "\n" )
|
20
|
+
end
|
21
|
+
alias_method_chain :inspect, :backtrace
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# _____ _
|
26
|
+
# |_ _|__ ___| |_
|
27
|
+
# | |/ _ \/ __| __|
|
28
|
+
# | | __/\__ \ |_
|
29
|
+
# |_|\___||___/\__|
|
30
|
+
#
|
31
|
+
=begin test
|
32
|
+
require 'rubygems'
|
33
|
+
require 'facets/core/string/lines'
|
34
|
+
|
35
|
+
class TheTest < Test::Unit::TestCase
|
36
|
+
def raise_an_error(arg = nil)
|
37
|
+
raise ArgumentError, "You passed in the wrong argument!"
|
38
|
+
end
|
39
|
+
def test_1
|
40
|
+
begin
|
41
|
+
raise_an_error
|
42
|
+
rescue ArgumentError => exception
|
43
|
+
#puts exception.inspect
|
44
|
+
assert_equal 'ArgumentError: You passed in the wrong argument!', exception.inspect.lines[0]
|
45
|
+
assert_match /[^:]+:\d+:in `raise_an_error'/, exception.inspect.lines[1]
|
46
|
+
assert exception.inspect.lines.size > 3
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
=end
|
52
|
+
|
53
|
+
|
54
|
+
=begin
|
55
|
+
Sightings of other exception -> string formatters
|
56
|
+
|
57
|
+
log4r/formatter/formatter.rb
|
58
|
+
return "Caught #{obj.class}: #{obj.message}\n\t" +\
|
59
|
+
obj.backtrace[0...@depth].join("\n\t")
|
60
|
+
|
61
|
+
=end
|
@@ -19,7 +19,7 @@ require 'rubygems'
|
|
19
19
|
# alternative is dirt simple, and it still works.
|
20
20
|
module ExamplePrinter
|
21
21
|
# Prints the given statement (+code+ -- a string) before evaluating it.
|
22
|
-
def put_statement(code, binding = nil)
|
22
|
+
def put_statement(code, binding = nil, file = __FILE__, line = __LINE__)
|
23
23
|
# This didn't work. Still got this error: undefined local variable or method `x' for #<TheTest:0xb7dbc358> (NameError)
|
24
24
|
# Binding.of_caller do |caller_binding|
|
25
25
|
# puts caller_binding
|
@@ -27,7 +27,7 @@ module ExamplePrinter
|
|
27
27
|
# eval code, caller_binding
|
28
28
|
# end
|
29
29
|
puts code
|
30
|
-
eval code, binding
|
30
|
+
eval code, binding, file, line
|
31
31
|
end
|
32
32
|
alias_method :stp, :put_statement
|
33
33
|
|
@@ -77,7 +77,7 @@ require 'test/unit'
|
|
77
77
|
|
78
78
|
# Metaprogram for decreased duplication...
|
79
79
|
['stdout', 'stderr'].each do |stream_name|
|
80
|
-
eval
|
80
|
+
eval <<-End, binding, __FILE__, __LINE__+1
|
81
81
|
def noisy_command_#{stream_name}
|
82
82
|
$#{stream_name}.puts "Some annoying error message"
|
83
83
|
$#{stream_name}.puts "Some error message that we actually care to see"
|
@@ -103,6 +103,6 @@ require 'test/unit'
|
|
103
103
|
assert_equal "Some error message that we actually care to see\n", $#{stream_name}.string
|
104
104
|
end
|
105
105
|
end
|
106
|
-
|
106
|
+
End
|
107
107
|
end
|
108
108
|
=end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
class Module # :nodoc:
|
6
6
|
def mattr_reader(*syms)
|
7
7
|
syms.each do |sym|
|
8
|
-
class_eval(<<-EOS, __FILE__, __LINE__)
|
8
|
+
class_eval(<<-EOS, __FILE__, __LINE__+1)
|
9
9
|
unless defined? @@#{sym}
|
10
10
|
@@#{sym} = nil
|
11
11
|
end
|
@@ -23,7 +23,7 @@ class Module # :nodoc:
|
|
23
23
|
|
24
24
|
def mattr_writer(*syms)
|
25
25
|
syms.each do |sym|
|
26
|
-
class_eval(<<-EOS, __FILE__, __LINE__)
|
26
|
+
class_eval(<<-EOS, __FILE__, __LINE__+1)
|
27
27
|
unless defined? @@#{sym}
|
28
28
|
@@#{sym} = nil
|
29
29
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Yes!
|
6
|
+
# Developer notes::
|
7
|
+
# * Is it thread-safe?? Probably not, as it stands...
|
8
|
+
# But the whole thing that prompted me to create a guard method in the first place was to try to avoid a deadlock that was caused by recursively calling a method with a synchronize in it. So I'm not even sure if it's possible to make it thread-safe?
|
9
|
+
#++
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'qualitysmith_extensions/module/attribute_accessors'
|
13
|
+
require 'qualitysmith_extensions/module/mattr_tester'
|
14
|
+
require 'qualitysmith_extensions/module/attr_tester'
|
15
|
+
require 'qualitysmith_extensions/symbol/match'
|
16
|
+
|
17
|
+
|
18
|
+
class Module
|
19
|
+
def guard_method(method_name, guard_variable)
|
20
|
+
raise ArgumentError.new("Expected an instance variable name but got #{guard_variable}") if guard_variable !~ /^@([\w_]+)$/
|
21
|
+
guard_variable.to_s =~ /^@([\w_]+)$/ # Why didn't the regexp above set $1 ??
|
22
|
+
class_eval do
|
23
|
+
attr_tester $1.to_sym
|
24
|
+
end
|
25
|
+
module_eval <<-End, __FILE__, __LINE__+1
|
26
|
+
def #{method_name}(&block)
|
27
|
+
old_guard_state, #{guard_variable} = #{guard_variable}, true
|
28
|
+
yield
|
29
|
+
#{guard_variable} = old_guard_state
|
30
|
+
end
|
31
|
+
End
|
32
|
+
end
|
33
|
+
|
34
|
+
def mguard_method(method_name, guard_variable)
|
35
|
+
raise ArgumentError.new("Expected a class variable name but got #{guard_variable}") if guard_variable !~ /^@@[\w_]+$/
|
36
|
+
guard_variable.to_s =~ /^@@([\w_]+)$/
|
37
|
+
class_eval do
|
38
|
+
mattr_tester $1.to_sym
|
39
|
+
end
|
40
|
+
module_eval <<-End, __FILE__, __LINE__+1
|
41
|
+
class << self
|
42
|
+
def #{method_name}(&block)
|
43
|
+
old_guard_state, #{guard_variable} = #{guard_variable}, true
|
44
|
+
yield
|
45
|
+
#{guard_variable} = old_guard_state
|
46
|
+
end
|
47
|
+
end
|
48
|
+
End
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# _____ _
|
54
|
+
# |_ _|__ ___| |_
|
55
|
+
# | |/ _ \/ __| __|
|
56
|
+
# | | __/\__ \ |_
|
57
|
+
# |_|\___||___/\__|
|
58
|
+
#
|
59
|
+
=begin test
|
60
|
+
require 'test/unit'
|
61
|
+
|
62
|
+
class GuardMethodTest < Test::Unit::TestCase
|
63
|
+
class A
|
64
|
+
guard_method :guard_the_fruit!, :@guarding_the_fruit
|
65
|
+
end
|
66
|
+
def test_guard_method
|
67
|
+
a = A.new
|
68
|
+
assert_equal nil, a.guarding_the_fruit?
|
69
|
+
a.guard_the_fruit! do
|
70
|
+
# Call it recursively!
|
71
|
+
a.guard_the_fruit! do
|
72
|
+
assert_equal true, a.guarding_the_fruit?
|
73
|
+
end
|
74
|
+
assert_equal true, a.guarding_the_fruit? # This is the reason why we have to save the 'old_guard_state'. So that we don't stupidly set it back to false if we still haven't exited from the outermost call to the guard black.
|
75
|
+
end
|
76
|
+
assert_equal nil, a.guarding_the_fruit?
|
77
|
+
end
|
78
|
+
def test_guard_method_error
|
79
|
+
assert_raise(ArgumentError) do
|
80
|
+
self.class.class_eval do
|
81
|
+
guard_method :guard_the_fruit!, :@@guarding_the_fruit
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class MGuardMethodTest < Test::Unit::TestCase
|
88
|
+
class B
|
89
|
+
mguard_method :guard_the_fruit!, :@@guarding_the_fruit
|
90
|
+
end
|
91
|
+
def test_mguard_method
|
92
|
+
assert_equal nil, B.guarding_the_fruit?
|
93
|
+
B.guard_the_fruit! do
|
94
|
+
# Call it recursively!
|
95
|
+
B.guard_the_fruit! do
|
96
|
+
assert_equal true, B.guarding_the_fruit?
|
97
|
+
end
|
98
|
+
assert_equal true, B.guarding_the_fruit? # This is the reason why we have to save the 'old_guard_state'. So that we don't stupidly set it back to false if we still haven't exited from the outermost call to the guard black.
|
99
|
+
end
|
100
|
+
assert_equal nil, B.guarding_the_fruit?
|
101
|
+
end
|
102
|
+
def test_mguard_method_error
|
103
|
+
assert_raise(ArgumentError) do
|
104
|
+
self.class.class_eval do
|
105
|
+
mguard_method :guard_the_fruit!, :@guarding_the_fruit
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
=end
|
112
|
+
|
@@ -0,0 +1,120 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Yes
|
6
|
+
# Developer notes::
|
7
|
+
# * Based on /usr/lib/ruby/gems/1.8/gems/facets-1.8.54/lib/facets/core/module/attr_tester.rb
|
8
|
+
# * Hey Thomas, don't you think Module#attr_tester should only create the read-only a? method and have another method that creates the writer (like there how we have attr_reader, _writer, and _accessor?) ? "tester" does not imply "setter" in my mind...
|
9
|
+
#++
|
10
|
+
|
11
|
+
class Module
|
12
|
+
# This creates two methods for each given variable name. One is used to test
|
13
|
+
# the attribute and the other is used to set or toggle it.
|
14
|
+
#
|
15
|
+
# attr_tester :a
|
16
|
+
#
|
17
|
+
# is equivalent to
|
18
|
+
#
|
19
|
+
# def self.a?
|
20
|
+
# @@a ? true : @@a
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# def self.a!(switch=Exception)
|
24
|
+
# if switch == Exception
|
25
|
+
# @@a = !@@a
|
26
|
+
# else
|
27
|
+
# @@a = switch ? true : @@a
|
28
|
+
# self
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# Works for both classes and modules.
|
33
|
+
#
|
34
|
+
def mattr_tester(*args)
|
35
|
+
|
36
|
+
make = {}
|
37
|
+
args.each { |a|
|
38
|
+
# Initialize it first so that we won't have any NameErrors.
|
39
|
+
module_eval %{ @@#{a} = nil if !defined?(@@#{a}) }, __FILE__, __LINE__
|
40
|
+
|
41
|
+
make["#{a}?".to_sym] = %{
|
42
|
+
def self.#{a}?(true_value=true)
|
43
|
+
@@#{a} ? true_value : @@#{a}
|
44
|
+
end
|
45
|
+
}
|
46
|
+
make["#{a}!".to_sym] = %{
|
47
|
+
def self.#{a}!(switch=Exception)
|
48
|
+
if switch == Exception
|
49
|
+
@@#{a} = !@@#{a}
|
50
|
+
else
|
51
|
+
@@#{a} = switch ? true : @@#{a}
|
52
|
+
self
|
53
|
+
end
|
54
|
+
end
|
55
|
+
}
|
56
|
+
}
|
57
|
+
module_eval make.values.join("\n"), __FILE__, __LINE__
|
58
|
+
|
59
|
+
return make.keys
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
# _____ _
|
70
|
+
# |_ _|__ ___| |_
|
71
|
+
# | |/ _ \/ __| __|
|
72
|
+
# | | __/\__ \ |_
|
73
|
+
# |_|\___||___/\__|
|
74
|
+
#
|
75
|
+
=begin test
|
76
|
+
require 'test/unit'
|
77
|
+
require 'rubygems'
|
78
|
+
require 'qualitysmith_extensions/object/ignore_access'
|
79
|
+
|
80
|
+
|
81
|
+
class TheTest < Test::Unit::TestCase
|
82
|
+
class C
|
83
|
+
mattr_tester :a
|
84
|
+
end
|
85
|
+
module M
|
86
|
+
mattr_tester :a
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_cattr_tester_exclamation
|
90
|
+
C.access.class_variable_set(:@@a, false)
|
91
|
+
assert_equal(false, C.a?) # otherwise would have been nil
|
92
|
+
C.a!
|
93
|
+
assert_equal(true, C.a?)
|
94
|
+
C.a!
|
95
|
+
assert_equal(false, C.a?)
|
96
|
+
end
|
97
|
+
def test_cattr_tester_return
|
98
|
+
C.a!
|
99
|
+
assert_equal(true, C.a?)
|
100
|
+
C.a!("whatever")
|
101
|
+
assert_equal(true, C.a?) # Still returns a boolean even though we set it to a string.
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_mattr_tester_exclamation
|
105
|
+
assert_equal(nil, M.a?)
|
106
|
+
M.a!
|
107
|
+
assert_equal(true, M.a?)
|
108
|
+
M.a!
|
109
|
+
assert_equal(false, M.a?)
|
110
|
+
end
|
111
|
+
def test_mattr_tester_return
|
112
|
+
M.a!
|
113
|
+
assert_equal(true, M.a?)
|
114
|
+
M.a!("whatever")
|
115
|
+
assert_equal(true, M.a?) # Still returns a boolean even though we set it to a string.
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
=end
|
120
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Maybe.
|
6
|
+
# Developer notes::
|
7
|
+
#++
|
8
|
+
|
9
|
+
class Object
|
10
|
+
# Calls the method implementation from the module of your choice (+moduule+) on the object of your choice (+self+).
|
11
|
+
#
|
12
|
+
# The only (huge) catch is that +self+ must either be an instance of +moduule+ or have +moduule+ as an ancestor... which severely limits its usefullness. (Compare with singleton_send.)
|
13
|
+
#
|
14
|
+
# It is still useful, though, if you want to call some "original" implementation provided by Kernel (or some other base module) and the people that overrode it didn't play nice and use +alias_method_chain+.
|
15
|
+
#
|
16
|
+
# No matter! If the class of the object you are calling this on has Kernel as an ancestor, then you can call any method from Kernel on this object!
|
17
|
+
#
|
18
|
+
# This implementation is gratefully owed to the folks who wrote PP (/usr/lib/ruby/1.8/pp.rb)
|
19
|
+
def mcall(moduule, message, *args, &block)
|
20
|
+
moduule.instance_method(message).bind(self).call(*args, &block)
|
21
|
+
end
|
22
|
+
alias_method :msend, :mcall
|
23
|
+
end
|
24
|
+
|
25
|
+
# _____ _
|
26
|
+
# |_ _|__ ___| |_
|
27
|
+
# | |/ _ \/ __| __|
|
28
|
+
# | | __/\__ \ |_
|
29
|
+
# |_|\___||___/\__|
|
30
|
+
#
|
31
|
+
=begin test
|
32
|
+
require 'test/unit'
|
33
|
+
require 'rubygems'
|
34
|
+
require 'qualitysmith_extensions/test/assert_exception'
|
35
|
+
require 'qualitysmith_extensions/test/assert_includes'
|
36
|
+
require 'facets/core/module/alias_method_chain'
|
37
|
+
|
38
|
+
|
39
|
+
module MyColorizer
|
40
|
+
def colorize(color = nil)
|
41
|
+
self + " (colorized in #{color})"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
class String
|
45
|
+
def class()
|
46
|
+
'classy'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class TheTest < Test::Unit::TestCase
|
51
|
+
def test_doesnt_work_like_singleton_send
|
52
|
+
# This doesn't quite work the same as singleton_send ...
|
53
|
+
assert_exception(TypeError, lambda { |exception|
|
54
|
+
assert_equal 'bind argument must be an instance of MyColorizer', exception.message
|
55
|
+
}) do
|
56
|
+
"whatever".mcall(MyColorizer, :colorize, :blue)
|
57
|
+
end
|
58
|
+
# self actually has to *be* a MyColorizer for this to work... which severely limits the usefulness of mcall...
|
59
|
+
# Since the whole reason we want this is because we don't want to simply mix in MyColorizer into the base class...
|
60
|
+
end
|
61
|
+
|
62
|
+
module ClassSystem
|
63
|
+
def self.included(base)
|
64
|
+
base.class_eval do
|
65
|
+
alias_method_chain :class, :class_system
|
66
|
+
end
|
67
|
+
end
|
68
|
+
def class_with_class_system()
|
69
|
+
1<2 ? 'lower' : 'middle'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_1
|
74
|
+
assert_equal "classy", "me".class
|
75
|
+
# The main use for this would be to call "original" implementations provided by Kernel or some other base module that you can be pretty sure is an ancestor of self...
|
76
|
+
assert_contains String.ancestors, Kernel
|
77
|
+
assert_equal String, "me".mcall(Kernel, :class)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_2_after_doing_alias_method_chain
|
81
|
+
String.class_eval do
|
82
|
+
#remove_method :to_s
|
83
|
+
include ClassSystem
|
84
|
+
end
|
85
|
+
assert_equal "lower", "me".class # Version 3
|
86
|
+
assert_equal "classy", "me".class_without_class_system # Version 2
|
87
|
+
assert_equal String, "me".mcall(Kernel, :class) # Version 1
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
=end
|
92
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Maybe
|
6
|
+
# Developer notes::
|
7
|
+
# * The name of this method probably ought to be a little more specific.
|
8
|
+
# * It should say something about the fact that it the message sending is conditional but the block execution is unconditional.
|
9
|
+
# * always_execute_block_but_only_send_message_if ? Hmm... a bit too verbose, perhaps.
|
10
|
+
# * conditional_passthrough ?
|
11
|
+
# * passthrough_unless ?
|
12
|
+
# * use_wrapper_method_if ?
|
13
|
+
#++
|
14
|
+
|
15
|
+
|
16
|
+
class Object
|
17
|
+
# Unconditionally calls +block_to_always_execute+. But only sends +message+ to +self+ if +condition+ is met.
|
18
|
+
#
|
19
|
+
# This is useful if you want to wrap a block with some method but you only want the method itself to be used some of the time.
|
20
|
+
# For example, if it's for benchmarking, you may only want to enable it during development but disable during production to save on some overhead.
|
21
|
+
#
|
22
|
+
# Note: this cannot be used to call methods that expect blocks (Ruby 1.9 maybe?)
|
23
|
+
#
|
24
|
+
def send_if(condition, message, *args, &block_to_always_execute)
|
25
|
+
if condition
|
26
|
+
self.__send__(message, *args, &block_to_always_execute)
|
27
|
+
else
|
28
|
+
block_to_always_execute.call
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Opposite of send_if
|
33
|
+
def send_unless(condition, *args, &block)
|
34
|
+
self.send_if(!condition, *args, &block)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
# _____ _
|
45
|
+
# |_ _|__ ___| |_
|
46
|
+
# | |/ _ \/ __| __|
|
47
|
+
# | | __/\__ \ |_
|
48
|
+
# |_|\___||___/\__|
|
49
|
+
#
|
50
|
+
=begin test
|
51
|
+
require 'test/unit'
|
52
|
+
|
53
|
+
class Foo
|
54
|
+
attr_reader :called_benchmark
|
55
|
+
def benchmark(&block)
|
56
|
+
@called_benchmark = true
|
57
|
+
yield
|
58
|
+
sleep 0.1 # Simulate lots of overhead, which we may want to avoid if we can help it
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class TheTest < Test::Unit::TestCase
|
63
|
+
def setup
|
64
|
+
@foo = Foo.new
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_with_true
|
68
|
+
executed_block = false
|
69
|
+
@foo.send_if(true, :benchmark) do
|
70
|
+
executed_block = true
|
71
|
+
end
|
72
|
+
assert executed_block
|
73
|
+
assert @foo.called_benchmark
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_with_false
|
77
|
+
executed_block = false
|
78
|
+
@foo.send_if(false, :benchmark) do
|
79
|
+
executed_block = true
|
80
|
+
end
|
81
|
+
assert executed_block
|
82
|
+
assert !@foo.called_benchmark
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
=end
|
87
|
+
|
@@ -58,9 +58,9 @@ class Object
|
|
58
58
|
# end
|
59
59
|
# "whatever".my_colorizer.colorize(:blue)
|
60
60
|
#
|
61
|
-
def singleton_send(moduule, message, *args)
|
61
|
+
def singleton_send(moduule, message, *args, &block)
|
62
62
|
self.extend(moduule)
|
63
|
-
self.send(message, *args)
|
63
|
+
self.send(message, *args, &block)
|
64
64
|
end
|
65
65
|
alias_method :ss, :singleton_send
|
66
66
|
|
@@ -93,6 +93,10 @@ end
|
|
93
93
|
#
|
94
94
|
=begin test
|
95
95
|
require 'test/unit'
|
96
|
+
require 'rubygems'
|
97
|
+
require 'qualitysmith_extensions/test/assert_exception'
|
98
|
+
require 'qualitysmith_extensions/test/assert_includes'
|
99
|
+
|
96
100
|
|
97
101
|
module MyColorizer
|
98
102
|
def colorize(color = nil)
|
@@ -100,7 +104,6 @@ module MyColorizer
|
|
100
104
|
end
|
101
105
|
end
|
102
106
|
|
103
|
-
|
104
107
|
#module PresentationLayer
|
105
108
|
# create_module_method :to_currency do
|
106
109
|
# #...
|
@@ -108,10 +111,10 @@ end
|
|
108
111
|
#end
|
109
112
|
|
110
113
|
|
111
|
-
class
|
112
|
-
def
|
113
|
-
assert_equal "whatever (colorized in )",
|
114
|
-
assert_equal "whatever (colorized in blue)", "whatever".
|
114
|
+
class TheTest1_UsingSingletonSend < Test::Unit::TestCase
|
115
|
+
def test_using_singleton_send
|
116
|
+
assert_equal "whatever (colorized in )", "whatever".ss(MyColorizer, :colorize)
|
117
|
+
assert_equal "whatever (colorized in blue)", "whatever".ss(MyColorizer, :colorize, :blue)
|
115
118
|
end
|
116
119
|
|
117
120
|
# def test_singleton_that_accepts_object
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?::
|
6
|
+
# Developer notes::
|
7
|
+
#++
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
# _____ _
|
18
|
+
# |_ _|__ ___| |_
|
19
|
+
# | |/ _ \/ __| __|
|
20
|
+
# | | __/\__ \ |_
|
21
|
+
# |_|\___||___/\__|
|
22
|
+
#
|
23
|
+
=begin test
|
24
|
+
require 'test/unit'
|
25
|
+
|
26
|
+
class TheTest < Test::Unit::TestCase
|
27
|
+
def test_1
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
=end
|
32
|
+
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: qualitysmith_extensions
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-04-
|
6
|
+
version: 0.0.17
|
7
|
+
date: 2007-04-17 00:00:00 -07:00
|
8
8
|
summary: A collection of reusable Ruby methods developed by QualitySmith.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -31,6 +31,7 @@ authors:
|
|
31
31
|
files:
|
32
32
|
- lib/qualitysmith_extensions/global_variable_set.rb
|
33
33
|
- lib/qualitysmith_extensions/collection_extensions_for_cgi.rb
|
34
|
+
- lib/qualitysmith_extensions/template.rb
|
34
35
|
- lib/qualitysmith_extensions/all.rb
|
35
36
|
- lib/qualitysmith_extensions/month.rb
|
36
37
|
- lib/qualitysmith_extensions/test/assert_exception.rb
|
@@ -38,6 +39,7 @@ files:
|
|
38
39
|
- lib/qualitysmith_extensions/test/assert_changed.rb
|
39
40
|
- lib/qualitysmith_extensions/test/all.rb
|
40
41
|
- lib/qualitysmith_extensions/test/assert_includes.rb
|
42
|
+
- lib/qualitysmith_extensions/exception/inspect_with_backtrace.rb
|
41
43
|
- lib/qualitysmith_extensions/file_test/binary_file.rb
|
42
44
|
- lib/qualitysmith_extensions/kernel/require_all.rb
|
43
45
|
- lib/qualitysmith_extensions/kernel/simulate_input.rb
|
@@ -51,10 +53,12 @@ files:
|
|
51
53
|
- lib/qualitysmith_extensions/kernel/trap_chain.rb
|
52
54
|
- lib/qualitysmith_extensions/dir/each_child.rb
|
53
55
|
- lib/qualitysmith_extensions/object/singleton_send.rb
|
56
|
+
- lib/qualitysmith_extensions/object/mcall.rb
|
54
57
|
- lib/qualitysmith_extensions/object/send_if_not_nil.rb
|
55
58
|
- lib/qualitysmith_extensions/object/ignore_access.rb
|
56
59
|
- lib/qualitysmith_extensions/object/methods.rb
|
57
60
|
- lib/qualitysmith_extensions/object/default.rb
|
61
|
+
- lib/qualitysmith_extensions/object/send_if.rb
|
58
62
|
- lib/qualitysmith_extensions/file/exact_match_regexp.rb
|
59
63
|
- lib/qualitysmith_extensions/date/iso8601.rb
|
60
64
|
- lib/qualitysmith_extensions/date/deprecated.rb
|
@@ -66,10 +70,13 @@ files:
|
|
66
70
|
- lib/qualitysmith_extensions/console/command.rb
|
67
71
|
- lib/qualitysmith_extensions/console/command.facets.1.8.54.rb
|
68
72
|
- lib/qualitysmith_extensions/console/command.facets.1.8.51.rb
|
73
|
+
- lib/qualitysmith_extensions/module/guard_method.rb
|
69
74
|
- lib/qualitysmith_extensions/module/alias_method.rb
|
70
75
|
- lib/qualitysmith_extensions/module/includable_once.rb
|
76
|
+
- lib/qualitysmith_extensions/module/mattr_tester.rb
|
71
77
|
- lib/qualitysmith_extensions/module/create_setter.rb
|
72
78
|
- lib/qualitysmith_extensions/module/attribute_accessors.rb
|
79
|
+
- lib/qualitysmith_extensions/module/attr_tester.rb
|
73
80
|
- lib/qualitysmith_extensions/symbol/match.rb
|
74
81
|
- lib/qualitysmith_extensions/enumerable/enum.rb
|
75
82
|
- lib/qualitysmith_extensions/hash/to_query_string.rb
|