quality_extensions 0.1.1
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 +54 -0
- data/lib/qualitysmith_extensions/all.rb +4 -0
- data/lib/qualitysmith_extensions/array/all.rb +2 -0
- data/lib/qualitysmith_extensions/array/average.rb +44 -0
- data/lib/qualitysmith_extensions/array/classify.rb +97 -0
- data/lib/qualitysmith_extensions/array/expand_ranges.rb +52 -0
- data/lib/qualitysmith_extensions/array/group_by.rb +134 -0
- data/lib/qualitysmith_extensions/array/sequence.rb +66 -0
- data/lib/qualitysmith_extensions/array/shell_escape.rb +36 -0
- data/lib/qualitysmith_extensions/array/to_a_recursive.rb +41 -0
- data/lib/qualitysmith_extensions/array/to_query_string.rb +96 -0
- data/lib/qualitysmith_extensions/collection_extensions_for_cgi.rb +2 -0
- data/lib/qualitysmith_extensions/colored/toggleability.rb +62 -0
- data/lib/qualitysmith_extensions/console/command.facets.1.8.51.rb +749 -0
- data/lib/qualitysmith_extensions/console/command.facets.1.8.54.rb +748 -0
- data/lib/qualitysmith_extensions/console/command.rb +944 -0
- data/lib/qualitysmith_extensions/date/all.rb +2 -0
- data/lib/qualitysmith_extensions/date/deprecated.rb +40 -0
- data/lib/qualitysmith_extensions/date/iso8601.rb +31 -0
- data/lib/qualitysmith_extensions/date/month_ranges.rb +122 -0
- data/lib/qualitysmith_extensions/dir/each_child.rb +58 -0
- data/lib/qualitysmith_extensions/enumerable/enum.rb +69 -0
- data/lib/qualitysmith_extensions/enumerable/select_until.rb +4 -0
- data/lib/qualitysmith_extensions/enumerable/select_while.rb +109 -0
- data/lib/qualitysmith_extensions/exception/inspect_with_backtrace.rb +65 -0
- data/lib/qualitysmith_extensions/file/exact_match_regexp.rb +34 -0
- data/lib/qualitysmith_extensions/file_test/binary_file.rb +110 -0
- data/lib/qualitysmith_extensions/find/select.rb +68 -0
- data/lib/qualitysmith_extensions/global_variable_set.rb +153 -0
- data/lib/qualitysmith_extensions/hash/all.rb +2 -0
- data/lib/qualitysmith_extensions/hash/to_date.rb +34 -0
- data/lib/qualitysmith_extensions/hash/to_query_string.rb +121 -0
- data/lib/qualitysmith_extensions/kernel/all.rb +2 -0
- data/lib/qualitysmith_extensions/kernel/autoreload.rb +128 -0
- data/lib/qualitysmith_extensions/kernel/backtrace.rb +71 -0
- data/lib/qualitysmith_extensions/kernel/capture_output.rb +115 -0
- data/lib/qualitysmith_extensions/kernel/die.rb +49 -0
- data/lib/qualitysmith_extensions/kernel/example_printer.rb +81 -0
- data/lib/qualitysmith_extensions/kernel/filter_output.rb +108 -0
- data/lib/qualitysmith_extensions/kernel/remove_const.rb +178 -0
- data/lib/qualitysmith_extensions/kernel/remove_module.rb +127 -0
- data/lib/qualitysmith_extensions/kernel/require_all.rb +186 -0
- data/lib/qualitysmith_extensions/kernel/require_local_all.rb +4 -0
- data/lib/qualitysmith_extensions/kernel/require_once.rb +18 -0
- data/lib/qualitysmith_extensions/kernel/simulate_input.rb +52 -0
- data/lib/qualitysmith_extensions/kernel/trap_chain.rb +61 -0
- data/lib/qualitysmith_extensions/kernel/windows_platform.rb +46 -0
- data/lib/qualitysmith_extensions/module/alias_method.rb +6 -0
- data/lib/qualitysmith_extensions/module/alias_method_chain.rb +165 -0
- data/lib/qualitysmith_extensions/module/ancestry_of_instance_method.rb +43 -0
- data/lib/qualitysmith_extensions/module/attribute_accessors.rb +49 -0
- data/lib/qualitysmith_extensions/module/basename.rb +76 -0
- data/lib/qualitysmith_extensions/module/bool_attr_accessor.rb +497 -0
- data/lib/qualitysmith_extensions/module/class_methods.rb +87 -0
- data/lib/qualitysmith_extensions/module/create.rb +315 -0
- data/lib/qualitysmith_extensions/module/create_setter.rb +9 -0
- data/lib/qualitysmith_extensions/module/dirname.rb +4 -0
- data/lib/qualitysmith_extensions/module/guard_method.rb +312 -0
- data/lib/qualitysmith_extensions/module/includable_once.rb +10 -0
- data/lib/qualitysmith_extensions/module/join.rb +66 -0
- data/lib/qualitysmith_extensions/module/malias_method_chain.rb +92 -0
- data/lib/qualitysmith_extensions/module/module_methods.rb +4 -0
- data/lib/qualitysmith_extensions/module/namespace.rb +112 -0
- data/lib/qualitysmith_extensions/module/parents.rb +61 -0
- data/lib/qualitysmith_extensions/module/remove_const.rb +117 -0
- data/lib/qualitysmith_extensions/module/split.rb +55 -0
- data/lib/qualitysmith_extensions/month.rb +66 -0
- data/lib/qualitysmith_extensions/mutex/if_available.rb +75 -0
- data/lib/qualitysmith_extensions/object/ancestry_of_method.rb +257 -0
- data/lib/qualitysmith_extensions/object/default.rb +69 -0
- data/lib/qualitysmith_extensions/object/if_else.rb +157 -0
- data/lib/qualitysmith_extensions/object/ignore_access.rb +84 -0
- data/lib/qualitysmith_extensions/object/mcall.rb +92 -0
- data/lib/qualitysmith_extensions/object/methods.rb +63 -0
- data/lib/qualitysmith_extensions/object/send_if.rb +151 -0
- data/lib/qualitysmith_extensions/object/send_if_not_nil.rb +35 -0
- data/lib/qualitysmith_extensions/object/singleton_send.rb +129 -0
- data/lib/qualitysmith_extensions/regexp/join.rb +111 -0
- data/lib/qualitysmith_extensions/string/all.rb +2 -0
- data/lib/qualitysmith_extensions/string/constantize.rb +4 -0
- data/lib/qualitysmith_extensions/string/digits_only.rb +27 -0
- data/lib/qualitysmith_extensions/string/each_char_with_index.rb +41 -0
- data/lib/qualitysmith_extensions/string/md5.rb +29 -0
- data/lib/qualitysmith_extensions/string/shell_escape.rb +43 -0
- data/lib/qualitysmith_extensions/string/to_underscored_label.rb +37 -0
- data/lib/qualitysmith_extensions/string/with_knowledge_of_color.rb +64 -0
- data/lib/qualitysmith_extensions/symbol/constantize.rb +69 -0
- data/lib/qualitysmith_extensions/symbol/match.rb +157 -0
- data/lib/qualitysmith_extensions/template.rb +33 -0
- data/lib/qualitysmith_extensions/test/all.rb +2 -0
- data/lib/qualitysmith_extensions/test/assert_anything.rb +93 -0
- data/lib/qualitysmith_extensions/test/assert_changed.rb +66 -0
- data/lib/qualitysmith_extensions/test/assert_exception.rb +66 -0
- data/lib/qualitysmith_extensions/test/assert_includes.rb +36 -0
- data/lib/qualitysmith_extensions/test/assert_user_error.rb +37 -0
- data/lib/qualitysmith_extensions/test/difference_highlighting.rb +323 -0
- data/lib/qualitysmith_extensions/time/all.rb +2 -0
- data/lib/qualitysmith_extensions/time/deprecated.rb +31 -0
- data/test/all.rb +16 -0
- metadata +148 -0
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
# * Can anyone think of a better name than put_statement?
|
|
8
|
+
# * Something more like xmp? sp? stp? xm? putst? -- Too cryptic?
|
|
9
|
+
# * verbose? -- too ambiguous (that could be the name for xmp, for example)
|
|
10
|
+
# * xmp: Do the set_trace_func trick that irb_xmp/of_caller both use... so that the user doesn't have to pass in the local binding manually...
|
|
11
|
+
# * Add class method for ExamplePrinter to set a template for use by xmp? So if you don't like the default ("=> #{result}"), you can specify your own...
|
|
12
|
+
#++
|
|
13
|
+
|
|
14
|
+
require 'rubygems'
|
|
15
|
+
#require 'facets/core/binding/self/of_caller'
|
|
16
|
+
|
|
17
|
+
# This was written because the irb/xmp that was already available seemed to be
|
|
18
|
+
# needlessly complex and needlessly dependent upon "irb" stuff. This
|
|
19
|
+
# alternative is dirt simple, and it still works.
|
|
20
|
+
module ExamplePrinter
|
|
21
|
+
# Prints the given statement (+code+ -- a string) before evaluating it.
|
|
22
|
+
# Same as xmp only it doesn't print the return value.
|
|
23
|
+
#
|
|
24
|
+
# o = nil
|
|
25
|
+
# xmp 'o = C.new', binding
|
|
26
|
+
# # => o = C.new
|
|
27
|
+
def put_statement(code, binding = nil, file = __FILE__, line = __LINE__)
|
|
28
|
+
# # This didn't work. Still got this error: undefined local variable or method `x' for #<TheTest:0xb7dbc358> (NameError)
|
|
29
|
+
# Binding.of_caller do |caller_binding|
|
|
30
|
+
# #puts caller_binding
|
|
31
|
+
# puts code
|
|
32
|
+
# eval code, caller_binding
|
|
33
|
+
# end
|
|
34
|
+
puts code
|
|
35
|
+
eval code, binding, file, line
|
|
36
|
+
end
|
|
37
|
+
alias_method :stp, :put_statement
|
|
38
|
+
|
|
39
|
+
# Prints the given statement (+code+ -- a string) before evaluating it. Then prints its return value.
|
|
40
|
+
# Pretty much compatible with irb/xmp. But you have currently have to pass
|
|
41
|
+
# in the binding manually if you have any local variables/methods that xmp
|
|
42
|
+
# should have access to.
|
|
43
|
+
def xmp(code, binding = nil)
|
|
44
|
+
result = put_statement(code, binding)
|
|
45
|
+
puts "=> #{result}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
include ExamplePrinter
|
|
50
|
+
|
|
51
|
+
# _____ _
|
|
52
|
+
# |_ _|__ ___| |_
|
|
53
|
+
# | |/ _ \/ __| __|
|
|
54
|
+
# | | __/\__ \ |_
|
|
55
|
+
# |_|\___||___/\__|
|
|
56
|
+
#
|
|
57
|
+
=begin test
|
|
58
|
+
require 'test/unit'
|
|
59
|
+
require 'rubygems'
|
|
60
|
+
gem 'qualitysmith_extensions'
|
|
61
|
+
require 'qualitysmith_extensions/kernel/capture_output'
|
|
62
|
+
require 'facets/core/string/margin'
|
|
63
|
+
|
|
64
|
+
class TheTest < Test::Unit::TestCase
|
|
65
|
+
def test_puts_statement
|
|
66
|
+
result = nil
|
|
67
|
+
x = 1
|
|
68
|
+
output = capture_output { result = put_statement("3 + x", binding) }
|
|
69
|
+
assert_equal 4, result
|
|
70
|
+
assert_equal "3 + x", output.chomp
|
|
71
|
+
end
|
|
72
|
+
def test_xmp
|
|
73
|
+
x = 1
|
|
74
|
+
output = capture_output { xmp("3 + x", binding) }
|
|
75
|
+
assert_equal <<-End.margin, output.chomp
|
|
76
|
+
|3 + x
|
|
77
|
+
|=> 4
|
|
78
|
+
End
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
=end
|
|
@@ -0,0 +1,108 @@
|
|
|
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
|
+
#++
|
|
8
|
+
|
|
9
|
+
require 'stringio'
|
|
10
|
+
|
|
11
|
+
# Applies +filter+ to any $stderr output that +block+ tries to generate.
|
|
12
|
+
#
|
|
13
|
+
# +filter+ should be a Proc that accepts +attempted_output+ as its parameter and returns the string that should _actually_ be output.
|
|
14
|
+
#
|
|
15
|
+
# filter_stderr(lambda{''}) do
|
|
16
|
+
# noisy_command
|
|
17
|
+
# end
|
|
18
|
+
def filter_stderr(filter, &block)
|
|
19
|
+
old_stderr = $stderr
|
|
20
|
+
$stderr = StringIO.new
|
|
21
|
+
begin
|
|
22
|
+
yield
|
|
23
|
+
ensure
|
|
24
|
+
what_they_tried_to_output = $stderr.string
|
|
25
|
+
$stderr = old_stderr
|
|
26
|
+
$stderr.print filter.call(what_they_tried_to_output)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
def filter_stdout(filter, &block)
|
|
30
|
+
old_stderr = $stdout
|
|
31
|
+
$stdout = StringIO.new
|
|
32
|
+
begin
|
|
33
|
+
yield
|
|
34
|
+
ensure
|
|
35
|
+
what_they_tried_to_output = $stdout.string
|
|
36
|
+
$stdout = old_stderr
|
|
37
|
+
$stdout.print filter.call(what_they_tried_to_output)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# _____ _
|
|
42
|
+
# |_ _|__ ___| |_
|
|
43
|
+
# | |/ _ \/ __| __|
|
|
44
|
+
# | | __/\__ \ |_
|
|
45
|
+
# |_|\___||___/\__|
|
|
46
|
+
#
|
|
47
|
+
=begin test
|
|
48
|
+
require 'test/unit'
|
|
49
|
+
|
|
50
|
+
# Not sure whether it's better to duplicate for increased readability here or metaprogram for decreased duplication...
|
|
51
|
+
|
|
52
|
+
# Duplicate for increased readability:
|
|
53
|
+
def noisy_command
|
|
54
|
+
$stderr.puts "Some annoying error message"
|
|
55
|
+
$stderr.puts "Some error message that we actually care to see"
|
|
56
|
+
end
|
|
57
|
+
class TheTest < Test::Unit::TestCase
|
|
58
|
+
def setup
|
|
59
|
+
$stderr = StringIO.new
|
|
60
|
+
end
|
|
61
|
+
def test_simple_filter
|
|
62
|
+
filter_stderr(lambda{|input| ''}) do
|
|
63
|
+
noisy_command
|
|
64
|
+
end
|
|
65
|
+
assert_equal '', $stderr.string
|
|
66
|
+
end
|
|
67
|
+
def test_sub_filter
|
|
68
|
+
filter_stderr(Proc.new { |attempted_output|
|
|
69
|
+
attempted_output.sub(/^Some annoying error message\n/, '')
|
|
70
|
+
}
|
|
71
|
+
) do
|
|
72
|
+
noisy_command
|
|
73
|
+
end
|
|
74
|
+
assert_equal "Some error message that we actually care to see\n", $stderr.string
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Metaprogram for decreased duplication...
|
|
79
|
+
['stdout', 'stderr'].each do |stream_name|
|
|
80
|
+
eval <<-End, binding, __FILE__, __LINE__+1
|
|
81
|
+
def noisy_command_#{stream_name}
|
|
82
|
+
$#{stream_name}.puts "Some annoying error message"
|
|
83
|
+
$#{stream_name}.puts "Some error message that we actually care to see"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
class TheTest#{stream_name} < Test::Unit::TestCase
|
|
87
|
+
def setup
|
|
88
|
+
$#{stream_name} = StringIO.new
|
|
89
|
+
end
|
|
90
|
+
def test_simple_filter
|
|
91
|
+
filter_#{stream_name}(lambda{|input| ''}) do
|
|
92
|
+
noisy_command_#{stream_name}
|
|
93
|
+
end
|
|
94
|
+
assert_equal '', $#{stream_name}.string
|
|
95
|
+
end
|
|
96
|
+
def test_sub_filter
|
|
97
|
+
filter_#{stream_name}(Proc.new { |attempted_output|
|
|
98
|
+
attempted_output.sub(/^Some annoying error message\n/, '')
|
|
99
|
+
}
|
|
100
|
+
) do
|
|
101
|
+
noisy_command_#{stream_name}
|
|
102
|
+
end
|
|
103
|
+
assert_equal "Some error message that we actually care to see\n", $#{stream_name}.string
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
End
|
|
107
|
+
end
|
|
108
|
+
=end
|
|
@@ -0,0 +1,178 @@
|
|
|
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
|
+
#++
|
|
8
|
+
|
|
9
|
+
require 'rubygems'
|
|
10
|
+
require 'qualitysmith_extensions/object/ignore_access'
|
|
11
|
+
require 'qualitysmith_extensions/module/split'
|
|
12
|
+
require 'facets/core/module/by_name'
|
|
13
|
+
require 'facets/core/module/modspace'
|
|
14
|
+
|
|
15
|
+
class Module
|
|
16
|
+
alias_method :remove_const_before_was_added_to_Kernel, :remove_const
|
|
17
|
+
end
|
|
18
|
+
module Kernel
|
|
19
|
+
# This is similar to the built-in <tt>Module#remove_const</tt>, but it is accessible from all "levels" (because it is defined
|
|
20
|
+
# in +Kernel+) and can handle hierarchy.
|
|
21
|
+
#
|
|
22
|
+
# Makes it possible to write simply:
|
|
23
|
+
# remove_const(A::B::C.name)
|
|
24
|
+
# rather than having to think about which module the constant is actually defined in and calling +remove_const+ on that module.
|
|
25
|
+
#
|
|
26
|
+
# This is how you would otherwise have to do it:
|
|
27
|
+
# A::B.send(:remove_const, :C)
|
|
28
|
+
#
|
|
29
|
+
# +const_name+ must be an object that responds to +to_s+.
|
|
30
|
+
#
|
|
31
|
+
# +const_name+ must be a <i>fully qualified name</i>. For example, this will not work as expected:
|
|
32
|
+
#
|
|
33
|
+
# module Mod
|
|
34
|
+
# Foo = 'foo'
|
|
35
|
+
# remove_const(:Foo)
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# because it will try to remove ::Foo instead of Mod::Foo. Fortunately, however, this will work as expected:
|
|
39
|
+
#
|
|
40
|
+
# module Mod
|
|
41
|
+
# Foo = 'foo'
|
|
42
|
+
# remove_const(Foo.name)
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# This method is partially inspired by Facets' Kernel#constant method, which provided a more user-friendly alternative to const_get.
|
|
46
|
+
#
|
|
47
|
+
def remove_const(const_name)
|
|
48
|
+
#require 'pp'
|
|
49
|
+
#puts "remove_const(#{const_name})"
|
|
50
|
+
raise ArgumentError unless const_name.respond_to?(:to_s)
|
|
51
|
+
nesting = const_name.to_s.split(/::/).map(&:to_sym)
|
|
52
|
+
if nesting.size > 1
|
|
53
|
+
parent_module = constant(nesting[0..-2].join('::')) # For example, would be A::B for A::B::C
|
|
54
|
+
const_to_remove = nesting[-1] # For example, would be :C for A::B::C
|
|
55
|
+
parent_module.ignore_access.remove_const_before_was_added_to_Kernel(const_to_remove)
|
|
56
|
+
else
|
|
57
|
+
ignore_access.remove_const_before_was_added_to_Kernel(const_name)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#p Module.private_instance_methods.grep(/remove_const/) # Lists it
|
|
63
|
+
Module.send(:remove_method, :remove_const)
|
|
64
|
+
#p Module.instance_methods.grep(/remove_const/) # Does list it, because inherits *public* remove_const from Kernel
|
|
65
|
+
#p Module.private_instance_methods.grep(/remove_const/) # Does not list it, because it's no longer private
|
|
66
|
+
Module.send(:define_method, :remove_const, Kernel.method(:remove_const))
|
|
67
|
+
#p Module.private_instance_methods.grep(/remove_const/) # Lists it
|
|
68
|
+
|
|
69
|
+
# _____ _
|
|
70
|
+
# |_ _|__ ___| |_
|
|
71
|
+
# | |/ _ \/ __| __|
|
|
72
|
+
# | | __/\__ \ |_
|
|
73
|
+
# |_|\___||___/\__|
|
|
74
|
+
#
|
|
75
|
+
=begin test
|
|
76
|
+
require 'test/unit'
|
|
77
|
+
|
|
78
|
+
# Important regression test. This was failing at one point.
|
|
79
|
+
module A
|
|
80
|
+
B = nil
|
|
81
|
+
remove_const :B
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# How it would be done *without* this extension:
|
|
85
|
+
module TestRemoveABC_TheOldWay
|
|
86
|
+
module A
|
|
87
|
+
module B
|
|
88
|
+
C = 'foo'
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class TheTest < Test::Unit::TestCase
|
|
93
|
+
def test_1
|
|
94
|
+
assert_nothing_raised { A::B::C }
|
|
95
|
+
A::B.send(:remove_const, :C)
|
|
96
|
+
assert_raise(NameError) { A::B::C }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# How it would be done *with* this extension (all tests that follow):
|
|
102
|
+
|
|
103
|
+
module TestRemoveABC_CIsString
|
|
104
|
+
module A
|
|
105
|
+
module B
|
|
106
|
+
C = 'foo'
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
class TheTest < Test::Unit::TestCase
|
|
111
|
+
def test_1
|
|
112
|
+
assert_nothing_raised { A::B::C }
|
|
113
|
+
assert_raise(NoMethodError) { remove_const(A::B::C.name) } # Because C is a *string*, not a *module*
|
|
114
|
+
assert_nothing_raised { remove_const A::B.name + '::C' }
|
|
115
|
+
assert_raise(NameError) { A::B::C }
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
module TestRemoveAB_UsingName
|
|
121
|
+
module A
|
|
122
|
+
module B
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class TheTest < Test::Unit::TestCase
|
|
127
|
+
def test_1
|
|
128
|
+
assert_nothing_raised { A::B }
|
|
129
|
+
remove_const(A::B.name)
|
|
130
|
+
assert_raise(NameError) { A::B }
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
module TestRemoveAB_Symbol
|
|
136
|
+
module A
|
|
137
|
+
module B
|
|
138
|
+
Foo = :Foo
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
remove_const(:'A::B::Foo') # This tests that Module#remove_const was overriden as well.
|
|
143
|
+
# If we hadn't also overriden Module#remove_const, then this would have caused this error:
|
|
144
|
+
# in `remove_const': `A::B::Foo' is not allowed as a constant name (NameError)
|
|
145
|
+
|
|
146
|
+
class TheTest < Test::Unit::TestCase
|
|
147
|
+
def test_1
|
|
148
|
+
assert_nothing_raised { A::B }
|
|
149
|
+
|
|
150
|
+
assert_equal 'TestRemoveAB_Symbol::A', A.name
|
|
151
|
+
assert_raise(NameError) { remove_const(:'A::B') } # This doesn't work because A, when evaluated in this context,
|
|
152
|
+
# is TestRemoveAB_Symbol::TheTest::A, which is *not* defined.
|
|
153
|
+
|
|
154
|
+
remove_const(:'TestRemoveAB_Symbol::A::B')
|
|
155
|
+
assert_raise(NameError) { A::B }
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
module TestRemoveAB_Symbol2
|
|
161
|
+
class TheTest < Test::Unit::TestCase
|
|
162
|
+
module A
|
|
163
|
+
module B
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
def test_1
|
|
167
|
+
assert_nothing_raised { A::B }
|
|
168
|
+
|
|
169
|
+
assert_equal 'TestRemoveAB_Symbol2::TheTest::A', A.name
|
|
170
|
+
remove_const(:'A::B') # Does work, because A is defined *within* TheTest this time.
|
|
171
|
+
assert_raise(NameError) { A::B }
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
=end
|
|
177
|
+
|
|
178
|
+
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Author:: Tyler Rick
|
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
|
4
|
+
# License:: Ruby License
|
|
5
|
+
# Submit to Facets?:: No.
|
|
6
|
+
# Developer notes::
|
|
7
|
+
# * Deprecated by qualitysmith_extensions/module/remove.rb
|
|
8
|
+
#++
|
|
9
|
+
|
|
10
|
+
require 'rubygems'
|
|
11
|
+
require 'qualitysmith_extensions/object/ignore_access'
|
|
12
|
+
require 'qualitysmith_extensions/module/split'
|
|
13
|
+
require 'facets/core/module/by_name'
|
|
14
|
+
require 'facets/core/module/modspace'
|
|
15
|
+
|
|
16
|
+
module Kernel
|
|
17
|
+
# This is similar to +remove_const+, but it _only_ works for modules/classes.
|
|
18
|
+
#
|
|
19
|
+
# This is similar to the built-in <tt>Module#remove_module</tt>, but it is accessible from all "levels" (because it is defined
|
|
20
|
+
# in +Kernel+) and can handle hierarchy.
|
|
21
|
+
#
|
|
22
|
+
# Makes it possible to write simply:
|
|
23
|
+
# remove_module(A::B::C)
|
|
24
|
+
# rather than having to think about which module the constant is actually defined in and calling +remove_const+ on that module.
|
|
25
|
+
# This is how you would have to otherwise do it:
|
|
26
|
+
# A::B.send(:remove_const, :C)
|
|
27
|
+
#
|
|
28
|
+
# You can pass in either a constant or a symbol. Passing in a constant is preferred
|
|
29
|
+
#
|
|
30
|
+
# This method is partially inspired by Facets' Kernel#constant method, which provided a more user-friendly alternative to const_get.
|
|
31
|
+
#
|
|
32
|
+
def remove_module(const)
|
|
33
|
+
const = Module.by_name(const.to_s) if const.is_a?(Symbol)
|
|
34
|
+
if const.split.size > 1
|
|
35
|
+
parent_module = const.modspace # For example, would be A::B for A::B::C
|
|
36
|
+
const_to_remove = const.split.last # For example, would be :C for A::B::C
|
|
37
|
+
parent_module.ignore_access.remove_const(const_to_remove)
|
|
38
|
+
else
|
|
39
|
+
Object.ignore_access.remove_const(const.name)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# _____ _
|
|
45
|
+
# |_ _|__ ___| |_
|
|
46
|
+
# | |/ _ \/ __| __|
|
|
47
|
+
# | | __/\__ \ |_
|
|
48
|
+
# |_|\___||___/\__|
|
|
49
|
+
#
|
|
50
|
+
=begin test
|
|
51
|
+
require 'test/unit'
|
|
52
|
+
require 'qualitysmith_extensions/kernel/remove_const' # Test for compatibility. Just in case the remove_const_before_was_added_to_Kernel alias might have thrown something off.
|
|
53
|
+
|
|
54
|
+
# How it would be done *without* this extension:
|
|
55
|
+
module TestRemoveABC_TheOldWay
|
|
56
|
+
module A
|
|
57
|
+
module B
|
|
58
|
+
class C
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class TheTest < Test::Unit::TestCase
|
|
64
|
+
def test_1
|
|
65
|
+
assert_nothing_raised { A::B::C }
|
|
66
|
+
A::B.send(:remove_const, :C)
|
|
67
|
+
assert_raise(NameError) { A::B::C }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# How it would be done *with* this extension:
|
|
73
|
+
module TestRemoveABC
|
|
74
|
+
module A
|
|
75
|
+
module B
|
|
76
|
+
class C
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class TheTest < Test::Unit::TestCase
|
|
82
|
+
def test_1
|
|
83
|
+
assert_nothing_raised { A::B::C }
|
|
84
|
+
remove_module(A::B::C)
|
|
85
|
+
assert_raise(NameError) { A::B::C }
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
module TestRemoveAB
|
|
91
|
+
module A
|
|
92
|
+
module B
|
|
93
|
+
module C
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class TheTest < Test::Unit::TestCase
|
|
99
|
+
def test_1
|
|
100
|
+
assert_nothing_raised { A::B }
|
|
101
|
+
remove_module(A::B)
|
|
102
|
+
assert_raise(NameError) { A::B }
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
module TestRemoveAB_Symbol
|
|
108
|
+
module A
|
|
109
|
+
module B
|
|
110
|
+
module C
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class TheTest < Test::Unit::TestCase
|
|
116
|
+
def test_1
|
|
117
|
+
assert_nothing_raised { A::B }
|
|
118
|
+
assert_raise(NameError) { remove_module(:'A::B') } # This is why passing in the module itself is preferred.
|
|
119
|
+
remove_module(:'TestRemoveAB_Symbol::A::B')
|
|
120
|
+
assert_raise(NameError) { A::B }
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
=end
|
|
126
|
+
|
|
127
|
+
|