extensions 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +12 -0
- data/HISTORY +59 -59
- data/InstalledFiles +50 -0
- data/README +19 -8
- data/README.1st +11 -11
- data/Rakefile +6 -0
- data/VERSION +1 -1
- data/bin/rbxtm +13 -13
- data/etc/website/index.html +10 -10
- data/install.rb +1098 -1098
- data/install.sh +3 -3
- data/lib/extensions/_base.rb +153 -153
- data/lib/extensions/_template.rb +36 -36
- data/lib/extensions/all.rb +19 -17
- data/lib/extensions/array.rb +24 -24
- data/lib/extensions/binding.rb +224 -0
- data/lib/extensions/class.rb +50 -50
- data/lib/extensions/continuation.rb +71 -0
- data/lib/extensions/hash.rb +23 -23
- data/lib/extensions/io.rb +58 -58
- data/lib/extensions/numeric.rb +204 -204
- data/lib/extensions/object.rb +164 -164
- data/lib/extensions/string.rb +316 -316
- data/lib/extensions/symbol.rb +28 -28
- data/test/tc_binding.rb +87 -0
- data/test/tc_continuation.rb +38 -0
- metadata +11 -11
data/install.sh
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
ruby install.rb config
|
2
|
-
ruby install.rb setup
|
3
|
-
ruby install.rb install
|
1
|
+
ruby install.rb config
|
2
|
+
ruby install.rb setup
|
3
|
+
ruby install.rb install
|
data/lib/extensions/_base.rb
CHANGED
@@ -1,153 +1,153 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# This file is 'required' by all files that implement standard class
|
4
|
-
# extensions as part of the "Ruby/Extensions" project.
|
5
|
-
#
|
6
|
-
# The "Extensions" project requires 1.8.0 or greater to run, as it is too
|
7
|
-
# much hassle at the moment to consider supporting older versions. That may
|
8
|
-
# one day be implemented if demand is there. One option would be to require
|
9
|
-
# "shim", so that we can assume all 1.8 library methods are implemented.
|
10
|
-
#
|
11
|
-
# This file is only of interest to developers of the package, so no detailed
|
12
|
-
# documentation is included here. However, by way of introduction, this is what
|
13
|
-
# it's all about. Each method that is implemented as part of this package is
|
14
|
-
# done so through a framework implemented in this file. Take the following
|
15
|
-
# simple example:
|
16
|
-
#
|
17
|
-
# ExtensionsProject.implement(Integer, :even?, :instance) do
|
18
|
-
# class Integer
|
19
|
-
# #
|
20
|
-
# # RDoc comments.
|
21
|
-
# #
|
22
|
-
# def even?
|
23
|
-
# self % 2 == 0
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# This purposes of this are as follows:
|
29
|
-
# - if the intended method (in this case IO.write) is already defined,
|
30
|
-
# we don't want to overwrite it (we issue a warning and move on)
|
31
|
-
# - if the intended method is _not_ implemented as a result of the block,
|
32
|
-
# we have not done as we said, and an error is raised
|
33
|
-
# - the ExtensionsProject class gathers information on which methods have
|
34
|
-
# been implemented, making for a very handy command-line reference (+rbxtm+)
|
35
|
-
#
|
36
|
-
# The <tt>ExtensionsProject.implement</tt> method is responsible for ensuring
|
37
|
-
# these are so. It gives us documentation, and some assurance that the
|
38
|
-
# extensions are doing what we say they are doing.
|
39
|
-
#
|
40
|
-
|
41
|
-
# :enddoc:
|
42
|
-
|
43
|
-
#
|
44
|
-
# For what reason does Ruby define Module#methods, Module#instance_methods,
|
45
|
-
# and Module#method_defined?, but not Module#instance_method_defined? ?
|
46
|
-
#
|
47
|
-
# No matter, extending standard classes is the name of the game here.
|
48
|
-
#
|
49
|
-
class Module
|
50
|
-
if Module.method_defined?(:instance_method_defined?)
|
51
|
-
STDERR.puts "Warning: Module#instance_method_defined? already defined; not overwriting"
|
52
|
-
else
|
53
|
-
def instance_method_defined?(_method)
|
54
|
-
instance_methods(true).find { |m| m == _method.to_s }
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
if Module.method_defined?(:module_method_defined?)
|
59
|
-
STDERR.puts "Warning: Module#module_method_defined? already defined; not overwriting"
|
60
|
-
else
|
61
|
-
def module_method_defined?(_method)
|
62
|
-
singleton_methods(true).find { |m| m == _method.to_s }
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
|
68
|
-
class ExtensionsProject
|
69
|
-
|
70
|
-
class << ExtensionsProject
|
71
|
-
@@extension_methods = []
|
72
|
-
|
73
|
-
#
|
74
|
-
# The list of methods implemented in this project.
|
75
|
-
#
|
76
|
-
def extension_methods
|
77
|
-
@@extension_methods
|
78
|
-
end
|
79
|
-
|
80
|
-
#
|
81
|
-
# Return the name of the project. To be used in error messages, etc., for
|
82
|
-
# consistency.
|
83
|
-
#
|
84
|
-
def project_name
|
85
|
-
"Ruby/Extensions"
|
86
|
-
end
|
87
|
-
|
88
|
-
#
|
89
|
-
# Wraps around the implementation of a method, emitting a warning if the
|
90
|
-
# method is already defined. Returns true to indicate - false to indicate
|
91
|
-
# failure (i.e. method is already defined). Raises an error if the
|
92
|
-
# specified method is not actually implemented by the block.
|
93
|
-
#
|
94
|
-
def implement(_module, _method, _type=:instance)
|
95
|
-
raise "Internal error: #{__FILE__}:#{__LINE__}" unless
|
96
|
-
_module.is_a? Module and
|
97
|
-
_method.is_a? Symbol and
|
98
|
-
_type == :instance or _type == :class or _type == :module
|
99
|
-
|
100
|
-
fullname = _module.to_s + string_rep(_type) + _method.to_s
|
101
|
-
|
102
|
-
if _defined?(_module, _method, _type)
|
103
|
-
STDERR.puts "#{project_name}: #{fullname} is already defined; not overwriting"
|
104
|
-
return false
|
105
|
-
else
|
106
|
-
yield # Perform the block; presumably a method implementation.
|
107
|
-
if _method == :initialize and _type == :instance
|
108
|
-
# Special case; we can't verify this.
|
109
|
-
@@extension_methods<< "#{_module}::new"
|
110
|
-
else
|
111
|
-
unless _defined?(_module, _method, _type)
|
112
|
-
raise "#{project_name}: internal error: was supposed to implement " +
|
113
|
-
"#{fullname}, but it didn't!"
|
114
|
-
end
|
115
|
-
@@extension_methods << fullname
|
116
|
-
end
|
117
|
-
return true
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
|
122
|
-
# See whether the given module implements the given method, taking account
|
123
|
-
# of the type (class/instance) required.
|
124
|
-
def _defined?(_module, _method, _type)
|
125
|
-
case _type
|
126
|
-
when :instance
|
127
|
-
_module.instance_method_defined?(_method) # See definition above.
|
128
|
-
when :class, :module
|
129
|
-
_module.module_method_defined?(_method) # See definition above.
|
130
|
-
end
|
131
|
-
end
|
132
|
-
private :_defined?
|
133
|
-
|
134
|
-
|
135
|
-
# Return the string representation of the given method type.
|
136
|
-
def string_rep(method_type)
|
137
|
-
case method_type
|
138
|
-
when :instance then "#"
|
139
|
-
when :class then "."
|
140
|
-
when :module then "."
|
141
|
-
else
|
142
|
-
nil
|
143
|
-
end
|
144
|
-
end
|
145
|
-
private :string_rep
|
146
|
-
end
|
147
|
-
end # class ExtensionsProject
|
148
|
-
|
149
|
-
|
150
|
-
if VERSION < "1.8.0"
|
151
|
-
raise "#{ExtensionsProject.project_name} requires Ruby 1.8.0 at least (for now)"
|
152
|
-
end
|
153
|
-
|
1
|
+
|
2
|
+
#
|
3
|
+
# This file is 'required' by all files that implement standard class
|
4
|
+
# extensions as part of the "Ruby/Extensions" project.
|
5
|
+
#
|
6
|
+
# The "Extensions" project requires 1.8.0 or greater to run, as it is too
|
7
|
+
# much hassle at the moment to consider supporting older versions. That may
|
8
|
+
# one day be implemented if demand is there. One option would be to require
|
9
|
+
# "shim", so that we can assume all 1.8 library methods are implemented.
|
10
|
+
#
|
11
|
+
# This file is only of interest to developers of the package, so no detailed
|
12
|
+
# documentation is included here. However, by way of introduction, this is what
|
13
|
+
# it's all about. Each method that is implemented as part of this package is
|
14
|
+
# done so through a framework implemented in this file. Take the following
|
15
|
+
# simple example:
|
16
|
+
#
|
17
|
+
# ExtensionsProject.implement(Integer, :even?, :instance) do
|
18
|
+
# class Integer
|
19
|
+
# #
|
20
|
+
# # RDoc comments.
|
21
|
+
# #
|
22
|
+
# def even?
|
23
|
+
# self % 2 == 0
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# This purposes of this are as follows:
|
29
|
+
# - if the intended method (in this case IO.write) is already defined,
|
30
|
+
# we don't want to overwrite it (we issue a warning and move on)
|
31
|
+
# - if the intended method is _not_ implemented as a result of the block,
|
32
|
+
# we have not done as we said, and an error is raised
|
33
|
+
# - the ExtensionsProject class gathers information on which methods have
|
34
|
+
# been implemented, making for a very handy command-line reference (+rbxtm+)
|
35
|
+
#
|
36
|
+
# The <tt>ExtensionsProject.implement</tt> method is responsible for ensuring
|
37
|
+
# these are so. It gives us documentation, and some assurance that the
|
38
|
+
# extensions are doing what we say they are doing.
|
39
|
+
#
|
40
|
+
|
41
|
+
# :enddoc:
|
42
|
+
|
43
|
+
#
|
44
|
+
# For what reason does Ruby define Module#methods, Module#instance_methods,
|
45
|
+
# and Module#method_defined?, but not Module#instance_method_defined? ?
|
46
|
+
#
|
47
|
+
# No matter, extending standard classes is the name of the game here.
|
48
|
+
#
|
49
|
+
class Module
|
50
|
+
if Module.method_defined?(:instance_method_defined?)
|
51
|
+
STDERR.puts "Warning: Module#instance_method_defined? already defined; not overwriting"
|
52
|
+
else
|
53
|
+
def instance_method_defined?(_method)
|
54
|
+
instance_methods(true).find { |m| m == _method.to_s }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if Module.method_defined?(:module_method_defined?)
|
59
|
+
STDERR.puts "Warning: Module#module_method_defined? already defined; not overwriting"
|
60
|
+
else
|
61
|
+
def module_method_defined?(_method)
|
62
|
+
singleton_methods(true).find { |m| m == _method.to_s }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
class ExtensionsProject
|
69
|
+
|
70
|
+
class << ExtensionsProject
|
71
|
+
@@extension_methods = []
|
72
|
+
|
73
|
+
#
|
74
|
+
# The list of methods implemented in this project.
|
75
|
+
#
|
76
|
+
def extension_methods
|
77
|
+
@@extension_methods
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Return the name of the project. To be used in error messages, etc., for
|
82
|
+
# consistency.
|
83
|
+
#
|
84
|
+
def project_name
|
85
|
+
"Ruby/Extensions"
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Wraps around the implementation of a method, emitting a warning if the
|
90
|
+
# method is already defined. Returns true to indicate - false to indicate
|
91
|
+
# failure (i.e. method is already defined). Raises an error if the
|
92
|
+
# specified method is not actually implemented by the block.
|
93
|
+
#
|
94
|
+
def implement(_module, _method, _type=:instance)
|
95
|
+
raise "Internal error: #{__FILE__}:#{__LINE__}" unless
|
96
|
+
_module.is_a? Module and
|
97
|
+
_method.is_a? Symbol and
|
98
|
+
_type == :instance or _type == :class or _type == :module
|
99
|
+
|
100
|
+
fullname = _module.to_s + string_rep(_type) + _method.to_s
|
101
|
+
|
102
|
+
if _defined?(_module, _method, _type)
|
103
|
+
STDERR.puts "#{project_name}: #{fullname} is already defined; not overwriting"
|
104
|
+
return false
|
105
|
+
else
|
106
|
+
yield # Perform the block; presumably a method implementation.
|
107
|
+
if _method == :initialize and _type == :instance
|
108
|
+
# Special case; we can't verify this.
|
109
|
+
@@extension_methods<< "#{_module}::new"
|
110
|
+
else
|
111
|
+
unless _defined?(_module, _method, _type)
|
112
|
+
raise "#{project_name}: internal error: was supposed to implement " +
|
113
|
+
"#{fullname}, but it didn't!"
|
114
|
+
end
|
115
|
+
@@extension_methods << fullname
|
116
|
+
end
|
117
|
+
return true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
# See whether the given module implements the given method, taking account
|
123
|
+
# of the type (class/instance) required.
|
124
|
+
def _defined?(_module, _method, _type)
|
125
|
+
case _type
|
126
|
+
when :instance
|
127
|
+
_module.instance_method_defined?(_method) # See definition above.
|
128
|
+
when :class, :module
|
129
|
+
_module.module_method_defined?(_method) # See definition above.
|
130
|
+
end
|
131
|
+
end
|
132
|
+
private :_defined?
|
133
|
+
|
134
|
+
|
135
|
+
# Return the string representation of the given method type.
|
136
|
+
def string_rep(method_type)
|
137
|
+
case method_type
|
138
|
+
when :instance then "#"
|
139
|
+
when :class then "."
|
140
|
+
when :module then "."
|
141
|
+
else
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
private :string_rep
|
146
|
+
end
|
147
|
+
end # class ExtensionsProject
|
148
|
+
|
149
|
+
|
150
|
+
if VERSION < "1.8.0"
|
151
|
+
raise "#{ExtensionsProject.project_name} requires Ruby 1.8.0 at least (for now)"
|
152
|
+
end
|
153
|
+
|
data/lib/extensions/_template.rb
CHANGED
@@ -1,36 +1,36 @@
|
|
1
|
-
#!/usr/local/bin/ruby -w
|
2
|
-
# A template for new files in the project; of no interest to end users. An
|
3
|
-
# error will be raised if you +require+ it.
|
4
|
-
#--
|
5
|
-
# :enddoc:
|
6
|
-
#
|
7
|
-
# == extensions/XXX.rb
|
8
|
-
#
|
9
|
-
# Adds methods to the builtin XXX class.
|
10
|
-
#
|
11
|
-
|
12
|
-
raise "Do not load this file!"
|
13
|
-
|
14
|
-
require "extensions/_base"
|
15
|
-
|
16
|
-
#
|
17
|
-
# * Enumerable#build_hash
|
18
|
-
#
|
19
|
-
ExtensionsProject.implement(Enumerable, :build_hash) do
|
20
|
-
module Enumerable
|
21
|
-
#
|
22
|
-
# Like #map/#collect, but it generates a Hash.
|
23
|
-
#
|
24
|
-
# [1,5,11].build_hash { |x| [x, x**2] }
|
25
|
-
# => { 1 => 2, 5 => 25, 11 => 121 }
|
26
|
-
#
|
27
|
-
def build_hash
|
28
|
-
result = {}
|
29
|
-
self.each do |elt|
|
30
|
-
key, value = yield elt
|
31
|
-
result[key] = value
|
32
|
-
end
|
33
|
-
result
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
# A template for new files in the project; of no interest to end users. An
|
3
|
+
# error will be raised if you +require+ it.
|
4
|
+
#--
|
5
|
+
# :enddoc:
|
6
|
+
#
|
7
|
+
# == extensions/XXX.rb
|
8
|
+
#
|
9
|
+
# Adds methods to the builtin XXX class.
|
10
|
+
#
|
11
|
+
|
12
|
+
raise "Do not load this file!"
|
13
|
+
|
14
|
+
require "extensions/_base"
|
15
|
+
|
16
|
+
#
|
17
|
+
# * Enumerable#build_hash
|
18
|
+
#
|
19
|
+
ExtensionsProject.implement(Enumerable, :build_hash) do
|
20
|
+
module Enumerable
|
21
|
+
#
|
22
|
+
# Like #map/#collect, but it generates a Hash.
|
23
|
+
#
|
24
|
+
# [1,5,11].build_hash { |x| [x, x**2] }
|
25
|
+
# => { 1 => 2, 5 => 25, 11 => 121 }
|
26
|
+
#
|
27
|
+
def build_hash
|
28
|
+
result = {}
|
29
|
+
self.each do |elt|
|
30
|
+
key, value = yield elt
|
31
|
+
result[key] = value
|
32
|
+
end
|
33
|
+
result
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/extensions/all.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
-
#
|
2
|
-
# == extensions/all.rb
|
3
|
-
#
|
4
|
-
# Require this file in order to access all of the standard class extensions
|
5
|
-
# available, or require individual extension files to narrow the selection.
|
6
|
-
#
|
7
|
-
|
8
|
-
require 'extensions/array.rb'
|
9
|
-
require 'extensions/
|
10
|
-
require 'extensions/
|
11
|
-
require 'extensions/
|
12
|
-
require 'extensions/
|
13
|
-
require 'extensions/
|
14
|
-
require 'extensions/
|
15
|
-
require 'extensions/
|
16
|
-
require 'extensions/
|
17
|
-
require 'extensions/
|
1
|
+
#
|
2
|
+
# == extensions/all.rb
|
3
|
+
#
|
4
|
+
# Require this file in order to access all of the standard class extensions
|
5
|
+
# available, or require individual extension files to narrow the selection.
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'extensions/array.rb'
|
9
|
+
require 'extensions/binding.rb'
|
10
|
+
require 'extensions/class.rb'
|
11
|
+
require 'extensions/continuation.rb'
|
12
|
+
require 'extensions/enumerable.rb'
|
13
|
+
require 'extensions/hash.rb'
|
14
|
+
require 'extensions/io.rb'
|
15
|
+
require 'extensions/numeric.rb'
|
16
|
+
require 'extensions/object.rb'
|
17
|
+
require 'extensions/ostruct.rb'
|
18
|
+
require 'extensions/string.rb'
|
19
|
+
require 'extensions/symbol.rb'
|
data/lib/extensions/array.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
#!/usr/local/bin/ruby -w
|
2
|
-
#
|
3
|
-
# == extensions/array.rb
|
4
|
-
#
|
5
|
-
# Adds methods to the builtin Array class.
|
6
|
-
#
|
7
|
-
|
8
|
-
require "extensions/_base"
|
9
|
-
|
10
|
-
#
|
11
|
-
# * Array#select!
|
12
|
-
#
|
13
|
-
ExtensionsProject.implement(Array, :select!) do
|
14
|
-
class Array
|
15
|
-
#
|
16
|
-
# In-place version of Array#select. (Counterpart to, and opposite of, the
|
17
|
-
# built-in #reject!)
|
18
|
-
#
|
19
|
-
def select!
|
20
|
-
reject! { |e| not yield(e) }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
#
|
3
|
+
# == extensions/array.rb
|
4
|
+
#
|
5
|
+
# Adds methods to the builtin Array class.
|
6
|
+
#
|
7
|
+
|
8
|
+
require "extensions/_base"
|
9
|
+
|
10
|
+
#
|
11
|
+
# * Array#select!
|
12
|
+
#
|
13
|
+
ExtensionsProject.implement(Array, :select!) do
|
14
|
+
class Array
|
15
|
+
#
|
16
|
+
# In-place version of Array#select. (Counterpart to, and opposite of, the
|
17
|
+
# built-in #reject!)
|
18
|
+
#
|
19
|
+
def select!
|
20
|
+
reject! { |e| not yield(e) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|