qualitysmith_extensions 0.0.49 → 0.0.60
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/qualitysmith_extensions/colored/toggleability.rb +1 -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 +4 -0
- data/lib/qualitysmith_extensions/kernel/require_all.rb +61 -11
- data/lib/qualitysmith_extensions/kernel/require_local_all.rb +4 -0
- data/lib/qualitysmith_extensions/module/alias_method_chain.rb +165 -0
- data/lib/qualitysmith_extensions/module/create.rb +7 -7
- data/lib/qualitysmith_extensions/module/malias_method_chain.rb +92 -0
- data/lib/qualitysmith_extensions/module/namespace.rb +6 -5
- metadata +7 -2
@@ -15,6 +15,7 @@ gem 'qualitysmith_extensions'
|
|
15
15
|
require 'qualitysmith_extensions/module/guard_method'
|
16
16
|
|
17
17
|
class String
|
18
|
+
@@colorize_enabled = true # Default to enabled
|
18
19
|
def colorize_with_toggleability(string, options = {})
|
19
20
|
if @@colorize_enabled
|
20
21
|
colorize_without_toggleability(string, options)
|
@@ -0,0 +1,109 @@
|
|
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
|
+
# Changes::
|
8
|
+
#++
|
9
|
+
|
10
|
+
|
11
|
+
module Enumerable
|
12
|
+
# Returns an array containing all _consecutive_ elements of +enum+ for which +block+ is not false, starting at the first element.
|
13
|
+
# So it is very much like select, only it stops searching as soon as <tt>block</tt> ceases to be true. (That means it will stop searching immediately if the first element doesn't match.)
|
14
|
+
#
|
15
|
+
# This might be preferable to +select+, for example, if:
|
16
|
+
# * you have a very large collection of elements
|
17
|
+
# * the desired elements are expected to all be consecutively occuring and are all at the beginning of the collection
|
18
|
+
# * it would be costly to continue iterating all the way to the very end
|
19
|
+
#
|
20
|
+
# This is probably only useful for collections that have some kind of predictable ordering (such as Arrays).
|
21
|
+
#
|
22
|
+
# AKA: select_top_elements_that_match
|
23
|
+
#
|
24
|
+
def select_until(inclusive = false, &block)
|
25
|
+
selected = []
|
26
|
+
inclusive ? (
|
27
|
+
each do |item|
|
28
|
+
selected << item
|
29
|
+
break if block.call(item)
|
30
|
+
end
|
31
|
+
) : (
|
32
|
+
each do |item|
|
33
|
+
break if block.call(item)
|
34
|
+
selected << item
|
35
|
+
end
|
36
|
+
)
|
37
|
+
selected
|
38
|
+
end
|
39
|
+
|
40
|
+
def select_while(&block)
|
41
|
+
selected = []
|
42
|
+
each do |item|
|
43
|
+
break if !block.call(item)
|
44
|
+
selected << item
|
45
|
+
end
|
46
|
+
selected
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
# _____ _
|
55
|
+
# |_ _|__ ___| |_
|
56
|
+
# | |/ _ \/ __| __|
|
57
|
+
# | | __/\__ \ |_
|
58
|
+
# |_|\___||___/\__|
|
59
|
+
#
|
60
|
+
=begin test
|
61
|
+
require 'test/unit'
|
62
|
+
|
63
|
+
class TheTest < Test::Unit::TestCase
|
64
|
+
def test_1
|
65
|
+
assert_equal [1, 2], (1..4).select_while {|i| i <= 2}
|
66
|
+
assert_equal [1, 2], (1..4).select_until {|i| i == 3}
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_not_same_as_select
|
70
|
+
# Ah, yes, it behaves the same as select in *this* simple case:
|
71
|
+
assert_equal [1, 2], (1..4).select {|i| i <= 2}
|
72
|
+
|
73
|
+
# But what about _this_ one... hmm?
|
74
|
+
assert_equal [1, 2], [1, 2, 3, 2, 1].select_while {|i| i <= 2}
|
75
|
+
assert_equal [1, 2, 2, 1], [1, 2, 3, 2, 1].select {|i| i <= 2} # Not the same! Keyword: _consecutive_.
|
76
|
+
|
77
|
+
# Or _this_ one...
|
78
|
+
assert_equal [1, 2, 1], [1, 2, 1, 99, 2].select_while {|i| i <= 2}
|
79
|
+
assert_equal [1, 2], [1, 2, 1, 99, 2].select {|i| i <= 2}.uniq # Even this isn't the same.
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_inclusive_option
|
83
|
+
assert_equal [
|
84
|
+
'def cabbage',
|
85
|
+
' :cabbage',
|
86
|
+
], [
|
87
|
+
'def cabbage',
|
88
|
+
' :cabbage',
|
89
|
+
'end',
|
90
|
+
].select_until {|line| line =~ /end/}
|
91
|
+
# Not far enough. We actually want to *include* that last element.
|
92
|
+
|
93
|
+
assert_equal [
|
94
|
+
'def cabbage',
|
95
|
+
' :cabbage',
|
96
|
+
'end',
|
97
|
+
], [
|
98
|
+
'def cabbage',
|
99
|
+
' :cabbage',
|
100
|
+
'end',
|
101
|
+
'def carrot',
|
102
|
+
' :carrot',
|
103
|
+
'end',
|
104
|
+
].select_until(true) {|line| line =~ /end/}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
=end
|
108
|
+
|
109
|
+
|
@@ -13,7 +13,11 @@ require 'facets/core/module/alias_method_chain'
|
|
13
13
|
class Exception
|
14
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
15
|
# (since exception.inspect/p exception doesn't provide a backtrace!)
|
16
|
+
#
|
16
17
|
# This is mostly useful if you rescue an exception, want to print or log it and then re-raise it...
|
18
|
+
#
|
19
|
+
# Use inspect_without_backtrace if you want to access the previous behavior (<tt>#<MissingSourceFile: no such file to load -- whatever></tt>).
|
20
|
+
#
|
17
21
|
def inspect_with_backtrace
|
18
22
|
exception.class.name + ": " + exception.message + "\n" +
|
19
23
|
exception.backtrace.map {|v| ' ' + v}.join( "\n" )
|
@@ -13,19 +13,30 @@ require_local '../file/exact_match_regexp'
|
|
13
13
|
|
14
14
|
module Kernel
|
15
15
|
|
16
|
-
#
|
16
|
+
# <tt>require</tt>s all Ruby files specified by <tt>what</tt>, but not matching any of the exclude filters.
|
17
|
+
# * If <tt>what</tt> is a string, recursively <tt>require</tt>s all Ruby files in the directory named <tt>what</tt> or any of its subdirectories.
|
18
|
+
# * If <tt>what</tt> is a FileList, <tt>require</tt>s all Ruby files that match the <tt>what</tt> FileList.
|
19
|
+
#
|
20
|
+
# Options:
|
17
21
|
# <tt>:exclude</tt>: An array of regular expressions or glob patterns that will be passed to FileList#exclude. If you specify this option, a file will not be included if it matches *any* of these patterns.
|
18
22
|
# <tt>:exclude_files</tt>: An array of filenames to exclude. These will be matched exactly, so if you tell it to exclude 'bar.rb', 'foobar.rb' will _not_ be excluded.
|
19
23
|
#
|
20
|
-
# Note:
|
21
|
-
#
|
22
24
|
# Examples:
|
23
25
|
# require_all 'lib/', :exclude => [/ignore/, /bogus/] # will require 'lib/a.rb', 'lib/long/path/b.rb', but not 'lib/ignore/c.rb'
|
24
26
|
# require_all File.dirname(__FILE__), :exclude_files => ['blow_up_stuff.rb']
|
25
|
-
def require_all(
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
def require_all(what, options = {})
|
28
|
+
files, exclusions = [nil]*2
|
29
|
+
|
30
|
+
case what
|
31
|
+
when String
|
32
|
+
base_dir = what
|
33
|
+
base_dir += '/' unless base_dir[-1].chr == '/'
|
34
|
+
files = FileList[base_dir + "**/*.rb"]
|
35
|
+
when FileList
|
36
|
+
files = what
|
37
|
+
else
|
38
|
+
raise ArgumentError.new("Expected a String or a FileList")
|
39
|
+
end
|
29
40
|
files = files.exclude(*exclusions) if (exclusions = options.delete(:exclude))
|
30
41
|
files = files.exclude(*exclusions.map {|a| File.exact_match_regexp(a) }) if (exclusions = options.delete(:exclude_files))
|
31
42
|
|
@@ -35,6 +46,22 @@ module Kernel
|
|
35
46
|
end
|
36
47
|
end
|
37
48
|
|
49
|
+
# <tt>require</tt>s all Ruby files in +dir+ (relative to <tt>File.dirname(__FILE__)</tt>) or any of its subdirectories.
|
50
|
+
#
|
51
|
+
# This is just a shortcut for this:
|
52
|
+
# require_all File.join(File.dirname(__FILE__), dir)
|
53
|
+
#
|
54
|
+
# All of the +options+ available for +require_all+ are still available here.
|
55
|
+
#
|
56
|
+
def require_local_all(dir = './', options = {})
|
57
|
+
raise ArgumentError.new("dir must be a String") unless dir.is_a?(String)
|
58
|
+
local_dir = File.dirname( caller[0] )
|
59
|
+
require_all(
|
60
|
+
File.join(local_dir, dir),
|
61
|
+
options
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
38
65
|
end
|
39
66
|
|
40
67
|
# _____ _
|
@@ -51,6 +78,7 @@ require 'English'
|
|
51
78
|
class TheTest < Test::Unit::TestCase
|
52
79
|
def setup
|
53
80
|
@base_dir = "#{Dir.tmpdir}/require_all_test"
|
81
|
+
@base_local_dir = File.dirname(__FILE__) # To allow testing of require_local_all. But tests should put everything in "#{@base_local_dir}/require_all_test" to avoid clutter or name conflicts with other files!
|
54
82
|
FileUtils.mkdir @base_dir
|
55
83
|
@deep_dir = "really/really/deep/subdir"
|
56
84
|
$loaded = []
|
@@ -58,6 +86,7 @@ class TheTest < Test::Unit::TestCase
|
|
58
86
|
end
|
59
87
|
def teardown
|
60
88
|
FileUtils.rm_rf @base_dir
|
89
|
+
FileUtils.rm_rf "#{@base_local_dir}/require_all_test"
|
61
90
|
end
|
62
91
|
|
63
92
|
|
@@ -99,14 +128,30 @@ class TheTest < Test::Unit::TestCase
|
|
99
128
|
assert_equal ['require_me.rb'], $loaded
|
100
129
|
end
|
101
130
|
|
131
|
+
def test_require_local_all
|
132
|
+
create_ruby_file 'require_all_test/lib/require_me.rb', @base_local_dir
|
133
|
+
create_ruby_file 'require_all_test/lib/please_ignore_me.rb', @base_local_dir
|
134
|
+
|
135
|
+
require_local_all 'require_all_test/lib', :exclude => [/ignore/]
|
136
|
+
assert_equal ['require_all_test/lib/require_me.rb'], $loaded
|
137
|
+
end
|
138
|
+
|
102
139
|
def test_exclude_pattern_with_directory
|
103
140
|
create_ruby_file 'subdir/test/assert_even.rb'
|
104
141
|
create_ruby_file 'subdir/test/assert_odd.rb'
|
105
142
|
|
106
|
-
require_all File.dirname(@base_dir), :exclude => [/
|
143
|
+
require_all File.dirname(@base_dir), :exclude => [/(^|\/)test/]
|
107
144
|
assert_equal [], $loaded
|
108
145
|
end
|
109
146
|
|
147
|
+
def test_passing_a_FileList
|
148
|
+
create_ruby_file 'subdir/junk/pretty_much_useless.rb'
|
149
|
+
create_ruby_file 'subdir/not_junk/good_stuff.rb'
|
150
|
+
|
151
|
+
require_all FileList[File.dirname(@base_dir) + "/**/*.rb"], :exclude => [/(^|\/)junk/]
|
152
|
+
assert_equal ['subdir/not_junk/good_stuff.rb'], $loaded
|
153
|
+
end
|
154
|
+
|
110
155
|
def test_exclude_filename
|
111
156
|
create_ruby_file 'yes.rb'
|
112
157
|
create_ruby_file 'all.rb'
|
@@ -125,11 +170,16 @@ class TheTest < Test::Unit::TestCase
|
|
125
170
|
assert_equal ['yes.rb'], $loaded
|
126
171
|
end
|
127
172
|
|
128
|
-
|
173
|
+
#-------------------------------------------------------------------------------------------------------------------------------
|
174
|
+
# Helpers
|
175
|
+
|
176
|
+
def create_ruby_file(file_name, base_dir = @base_dir)
|
177
|
+
# use dirname instead?
|
129
178
|
if file_name =~ /(.*)\//
|
130
|
-
FileUtils.mkdir_p
|
179
|
+
FileUtils.mkdir_p base_dir + '/' + $1
|
131
180
|
end
|
132
|
-
|
181
|
+
path = base_dir + '/' + file_name
|
182
|
+
File.open(path, "w") {|f| f.puts "$loaded << '#{file_name}'"}
|
133
183
|
end
|
134
184
|
|
135
185
|
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 the Rails people; QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Yes.
|
6
|
+
# Developer notes::
|
7
|
+
# Changes::
|
8
|
+
#++
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
gem 'facets'
|
12
|
+
#require 'facets/core/module/alias_method_chain' # Doesn't support blocks or I'd use it.
|
13
|
+
require 'facets/core/kernel/singleton_class'
|
14
|
+
|
15
|
+
|
16
|
+
# /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/module/aliasing.rb
|
17
|
+
class Module
|
18
|
+
def alias_method_chain(target, feature)
|
19
|
+
# Strip out punctuation on predicates or bang methods since
|
20
|
+
# e.g. target?_without_feature is not a valid method name.
|
21
|
+
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
22
|
+
yield(aliased_target, punctuation) if block_given?
|
23
|
+
alias_method "#{aliased_target}_without_#{feature}#{punctuation}", target
|
24
|
+
alias_method target, "#{aliased_target}_with_#{feature}#{punctuation}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
# end /usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/core_ext/module/aliasing.rb
|
28
|
+
|
29
|
+
class Module
|
30
|
+
|
31
|
+
def alias_method_chain_with_prevent_repeat_aliasing(target, feature, &block)
|
32
|
+
# Strip out punctuation on predicates or bang methods since
|
33
|
+
# e.g. target?_without_feature is not a valid method name.
|
34
|
+
|
35
|
+
aliased_target, punctuation = target.to_s.sub(/([?!])$/, ''), $1
|
36
|
+
target_without_feature = "#{aliased_target}_without_#{feature}#{punctuation}"
|
37
|
+
|
38
|
+
#puts "#{target} is #{method_defined?(target)}"
|
39
|
+
alias_method_chain_without_prevent_repeat_aliasing(target, feature, &block) unless method_defined?(target_without_feature)
|
40
|
+
end
|
41
|
+
alias_method_chain :alias_method_chain, :prevent_repeat_aliasing
|
42
|
+
|
43
|
+
# If you pass <tt>:create_target => true</tt> as one of the +options+:
|
44
|
+
# * Guarantees that <tt>alias_method_chain target, feature</tt> will work even if the target method has not been defined yet.
|
45
|
+
# If the target method doesn't exist yet, an empty (no-op) target method will be created.
|
46
|
+
# * This could come in handy for callback methods (method_added, method_missing, etc.), for instane, when you don't know if that
|
47
|
+
# particular callback method has been defined or not.
|
48
|
+
# * You want your alias_method_chain to wrap the existing method if there *is* an existing method, but to <b>not break</b> in
|
49
|
+
# the case that the method _doesn't_ exist.
|
50
|
+
def alias_method_chain_with_target_need_not_exist(target, feature, options = {}, &block)
|
51
|
+
create_target = options.delete(:create_target)
|
52
|
+
|
53
|
+
if create_target && true #!self.methods.include?(target)
|
54
|
+
self.send :define_method, target do |*args|
|
55
|
+
# Intentionally empty
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method_chain_without_target_need_not_exist(target, feature, &block)
|
60
|
+
end
|
61
|
+
alias_method_chain :alias_method_chain, :target_need_not_exist
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
=begin test
|
67
|
+
require 'test/unit'
|
68
|
+
|
69
|
+
class Test_alias_method_chain_basic < Test::Unit::TestCase
|
70
|
+
|
71
|
+
class X
|
72
|
+
def foo?
|
73
|
+
'foo?'
|
74
|
+
end
|
75
|
+
def foo_with_feature?
|
76
|
+
foo_without_feature? + '_with_feature'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_question_mark
|
81
|
+
name, punctuation = nil, nil
|
82
|
+
X.instance_eval do
|
83
|
+
alias_method_chain :foo?, :feature do |a, b|
|
84
|
+
name, punctuation = a, b
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
assert_equal 'foo?_with_feature', X.new.foo?
|
89
|
+
assert_equal 'foo', name
|
90
|
+
assert_equal '?', punctuation
|
91
|
+
end
|
92
|
+
|
93
|
+
class Y
|
94
|
+
def foo!
|
95
|
+
'foo!'
|
96
|
+
end
|
97
|
+
def foo_with_feature!
|
98
|
+
foo_without_feature! + '_with_feature'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_exclamation_mark
|
103
|
+
name, punctuation = nil, nil
|
104
|
+
Y.instance_eval do
|
105
|
+
alias_method_chain :foo!, :feature do |a, b|
|
106
|
+
name, punctuation = a, b
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
assert_equal 'foo!_with_feature', Y.new.foo!
|
111
|
+
assert_equal 'foo', name
|
112
|
+
assert_equal '!', punctuation
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
class Test_alias_method_chain_with_prevent_repeat_aliasing < Test::Unit::TestCase
|
118
|
+
|
119
|
+
class X
|
120
|
+
def foo
|
121
|
+
'foo'
|
122
|
+
end
|
123
|
+
def foo_with_feature
|
124
|
+
foo_without_feature + '_with_feature'
|
125
|
+
end
|
126
|
+
alias_method_chain :foo, :feature
|
127
|
+
alias_method_chain :foo, :feature # We want to test that this won't cause an infinite recursion (stack overflow).
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_1
|
131
|
+
assert_equal 'foo_with_feature', X.new.foo
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
class Test_alias_method_chain_with_target_need_not_exist < Test::Unit::TestCase
|
138
|
+
|
139
|
+
# Let's assume that we are *re*-opening X here, and at this point we *don't know* if it has a foo method or not.
|
140
|
+
# Also, we *don't want to care*. We just want to add to the chain if the method exists, or *create* the chain
|
141
|
+
# if it does not yet.
|
142
|
+
class X
|
143
|
+
def foo_with_feature
|
144
|
+
# *Don't* do this if you're using :create_target => true:
|
145
|
+
# foo_without_feature + '_with_feature'
|
146
|
+
# If you're using :create_target => true, then you are pretty much saying "I don't know anything about thhe target method".
|
147
|
+
# Yet the previous statement shows that you expect it to return a String. You can't do that. You can't pretend to know
|
148
|
+
# anything about it's return value. It will always be nil if alias_method_chain created an empty method for you.
|
149
|
+
# But, it may be something else if it already existed and alias_method_chain did *not* create an empty method for you.
|
150
|
+
|
151
|
+
# The safest thing to do is to just call it and pay not attention to its return value. (Or at least *consider* the
|
152
|
+
# possibility that it may be nil.)
|
153
|
+
|
154
|
+
foo_without_feature
|
155
|
+
'feature was successfully added'
|
156
|
+
end
|
157
|
+
alias_method_chain :foo, :feature, :create_target => true
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_1
|
161
|
+
assert_equal 'feature was successfully added', X.new.foo
|
162
|
+
assert_equal 'feature was successfully added', X.new.foo { 'test that it works with a block' }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
=end
|
@@ -166,13 +166,13 @@ class ModuleCreationHelperTest < Test::Unit::TestCase
|
|
166
166
|
def test_no_options_for_class
|
167
167
|
klass = Class.create(:Foo)
|
168
168
|
assert_equal Object, klass.superclass
|
169
|
-
assert_equal Object, klass.
|
169
|
+
assert_equal Object, klass.namespace_module
|
170
170
|
assert Object.const_defined?('Foo')
|
171
171
|
end
|
172
172
|
|
173
173
|
def test_no_options_for_module
|
174
174
|
mod = Module.create(:FooMod)
|
175
|
-
assert_equal Object, mod.
|
175
|
+
assert_equal Object, mod.namespace_module
|
176
176
|
assert Object.const_defined?('FooMod')
|
177
177
|
end
|
178
178
|
|
@@ -187,34 +187,34 @@ class ModuleCreationHelperTest < Test::Unit::TestCase
|
|
187
187
|
def test_superclass
|
188
188
|
klass = Class.create(:Bar, :superclass => BaseClass)
|
189
189
|
assert_equal BaseClass, klass.superclass
|
190
|
-
assert_equal Object, klass.
|
190
|
+
assert_equal Object, klass.namespace_module
|
191
191
|
assert Object.const_defined?('Bar')
|
192
192
|
end
|
193
193
|
|
194
194
|
def test_namespace_for_class
|
195
195
|
klass = Class.create(:Baz, :namespace => Namespace)
|
196
196
|
assert_equal Object, klass.superclass
|
197
|
-
assert_equal Namespace, klass.
|
197
|
+
assert_equal Namespace, klass.namespace_module
|
198
198
|
assert Namespace.const_defined?('Baz')
|
199
199
|
end
|
200
200
|
|
201
201
|
def test_namespace_for_class__namespace_as_part_of_name
|
202
202
|
klass = Class.create(:'Namespace::Baz')
|
203
203
|
assert_equal Object, klass.superclass
|
204
|
-
assert_equal Namespace, klass.
|
204
|
+
assert_equal Namespace, klass.namespace_module
|
205
205
|
assert Namespace.const_defined?('Baz')
|
206
206
|
end
|
207
207
|
|
208
208
|
def test_namespace_for_module
|
209
209
|
mod = Module.create(:BazMod, :namespace => Namespace)
|
210
|
-
assert_equal Namespace, mod.
|
210
|
+
assert_equal Namespace, mod.namespace_module
|
211
211
|
assert Namespace.const_defined?('BazMod')
|
212
212
|
end
|
213
213
|
|
214
214
|
def test_superclass_and_namespace
|
215
215
|
klass = Class.create(:Biz, :superclass => BaseClass, :namespace => Namespace)
|
216
216
|
assert_equal BaseClass, klass.superclass
|
217
|
-
assert_equal Namespace, klass.
|
217
|
+
assert_equal Namespace, klass.namespace_module
|
218
218
|
assert Namespace.const_defined?('Biz')
|
219
219
|
end
|
220
220
|
|
@@ -0,0 +1,92 @@
|
|
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
|
+
# Changes::
|
8
|
+
#++
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
gem 'facets'
|
12
|
+
require 'facets/core/kernel/singleton_class'
|
13
|
+
require 'qualitysmith_extensions/module/alias_method_chain'
|
14
|
+
|
15
|
+
class Module
|
16
|
+
|
17
|
+
# Same as <tt>Module#alias_method_chain</tt>, only it works for modules/classes
|
18
|
+
#
|
19
|
+
# class X
|
20
|
+
# def self.foo
|
21
|
+
# 'foo'
|
22
|
+
# end
|
23
|
+
# malias_method_chain :foo, :feature
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Note: You could always do the same thing with <tt>Module#alias_method_chain</tt> by simply doing this:
|
27
|
+
#
|
28
|
+
# class << self
|
29
|
+
# alias_method_chain :foo, :feature
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
def malias_method_chain(target, feature, *args)
|
33
|
+
# Strip out punctuation on predicates or bang methods since
|
34
|
+
# e.g. target?_without_feature is not a valid method name.
|
35
|
+
|
36
|
+
singleton_class.instance_eval do
|
37
|
+
alias_method_chain target, feature, *args
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# _____ _
|
45
|
+
# |_ _|__ ___| |_
|
46
|
+
# | |/ _ \/ __| __|
|
47
|
+
# | | __/\__ \ |_
|
48
|
+
# |_|\___||___/\__|
|
49
|
+
#
|
50
|
+
=begin test
|
51
|
+
require 'test/unit'
|
52
|
+
|
53
|
+
class TestHowYouWouldDoItWithPlain_alias_method_chain < Test::Unit::TestCase
|
54
|
+
|
55
|
+
class X
|
56
|
+
def self.foo
|
57
|
+
'foo'
|
58
|
+
end
|
59
|
+
def self.foo_with_feature
|
60
|
+
foo_without_feature + '_with_feature'
|
61
|
+
end
|
62
|
+
class << self
|
63
|
+
alias_method_chain :foo, :feature
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_001
|
68
|
+
assert_equal 'foo_with_feature', X.foo
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
class Test_malias_method_chain < Test::Unit::TestCase
|
74
|
+
|
75
|
+
class Y
|
76
|
+
def self.foo
|
77
|
+
'foo'
|
78
|
+
end
|
79
|
+
def self.foo_with_feature
|
80
|
+
foo_without_feature + '_with_feature'
|
81
|
+
end
|
82
|
+
malias_method_chain :foo, :feature
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_001
|
86
|
+
assert_equal 'foo_with_feature', Y.foo
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
=end
|
92
|
+
|
@@ -5,6 +5,7 @@
|
|
5
5
|
# Submit to Facets?:: Yes.
|
6
6
|
# Developer notes::
|
7
7
|
# Changes::
|
8
|
+
# * 0.0.52: Renamed namespace to namespace_module to avoid conflicting with Facets' Module#namespace and Rake's namespace
|
8
9
|
#++
|
9
10
|
|
10
11
|
|
@@ -16,7 +17,7 @@ require 'qualitysmith_extensions/module/split'
|
|
16
17
|
class Module
|
17
18
|
# Return the module which contains this one; if this is a root module, such as
|
18
19
|
# +::MyModule+, then Object is returned.
|
19
|
-
def
|
20
|
+
def namespace_module
|
20
21
|
namespace_name = name.split('::')[0..-2].join('::')
|
21
22
|
namespace_name.empty? ? Object : namespace_name.constantize
|
22
23
|
end
|
@@ -31,7 +32,7 @@ class Module
|
|
31
32
|
def self.dirname(module_or_name)
|
32
33
|
case module_or_name
|
33
34
|
when Module
|
34
|
-
module_or_name.
|
35
|
+
module_or_name.namespace_module.name
|
35
36
|
when Symbol
|
36
37
|
Module.split_name(module_or_name)[0..-2].join('::')
|
37
38
|
when String
|
@@ -66,14 +67,14 @@ module OuterModule::MiddleModule::InnerModule; end
|
|
66
67
|
class NamespaceTest < Test::Unit::TestCase
|
67
68
|
module InnerModule; end
|
68
69
|
def test_1
|
69
|
-
assert_equal Object, OuterModule.
|
70
|
+
assert_equal Object, OuterModule.namespace_module
|
70
71
|
end
|
71
72
|
def test_nesting
|
72
73
|
assert_equal OuterModule::MiddleModule,
|
73
|
-
OuterModule::MiddleModule::InnerModule.
|
74
|
+
OuterModule::MiddleModule::InnerModule.namespace_module
|
74
75
|
end
|
75
76
|
def test_nesting_2
|
76
|
-
assert_equal NamespaceTest, InnerModule.
|
77
|
+
assert_equal NamespaceTest, InnerModule.namespace_module
|
77
78
|
end
|
78
79
|
end
|
79
80
|
|
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-05
|
6
|
+
version: 0.0.60
|
7
|
+
date: 2007-06-05 00:00:00 -07:00
|
8
8
|
summary: A collection of reusable Ruby methods developed by QualitySmith.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/qualitysmith_extensions/kernel/simulate_input.rb
|
49
49
|
- lib/qualitysmith_extensions/kernel/die.rb
|
50
50
|
- lib/qualitysmith_extensions/kernel/require_once.rb
|
51
|
+
- lib/qualitysmith_extensions/kernel/require_local_all.rb
|
51
52
|
- lib/qualitysmith_extensions/kernel/example_printer.rb
|
52
53
|
- lib/qualitysmith_extensions/kernel/all.rb
|
53
54
|
- lib/qualitysmith_extensions/kernel/filter_output.rb
|
@@ -83,11 +84,13 @@ files:
|
|
83
84
|
- lib/qualitysmith_extensions/module/module_methods.rb
|
84
85
|
- lib/qualitysmith_extensions/module/alias_method.rb
|
85
86
|
- lib/qualitysmith_extensions/module/namespace.rb
|
87
|
+
- lib/qualitysmith_extensions/module/malias_method_chain.rb
|
86
88
|
- lib/qualitysmith_extensions/module/includable_once.rb
|
87
89
|
- lib/qualitysmith_extensions/module/parents.rb
|
88
90
|
- lib/qualitysmith_extensions/module/dirname.rb
|
89
91
|
- lib/qualitysmith_extensions/module/basename.rb
|
90
92
|
- lib/qualitysmith_extensions/module/create_setter.rb
|
93
|
+
- lib/qualitysmith_extensions/module/alias_method_chain.rb
|
91
94
|
- lib/qualitysmith_extensions/module/attribute_accessors.rb
|
92
95
|
- lib/qualitysmith_extensions/module/create.rb
|
93
96
|
- lib/qualitysmith_extensions/module/bool_attr_accessor.rb
|
@@ -96,6 +99,8 @@ files:
|
|
96
99
|
- lib/qualitysmith_extensions/module/class_methods.rb
|
97
100
|
- lib/qualitysmith_extensions/symbol/constantize.rb
|
98
101
|
- lib/qualitysmith_extensions/symbol/match.rb
|
102
|
+
- lib/qualitysmith_extensions/enumerable/select_while.rb
|
103
|
+
- lib/qualitysmith_extensions/enumerable/select_until.rb
|
99
104
|
- lib/qualitysmith_extensions/enumerable/enum.rb
|
100
105
|
- lib/qualitysmith_extensions/hash/to_query_string.rb
|
101
106
|
- lib/qualitysmith_extensions/hash/all.rb
|