qualitysmith_extensions 0.0.49 → 0.0.60
Sign up to get free protection for your applications and to get access to all the features.
- 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
|