glue 0.17.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,224 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
- #
3
- # == extensions/binding.rb
4
- #
5
- # Adds methods to the builtin Binding class.
6
- #
7
-
8
- require "extensions/_base"
9
- require "extensions/continuation"
10
-
11
- #
12
- # Ruby's built-in Binding class doesn't contain any methods. It is merely a "context" object
13
- # that can be used in calls to <tt>Kernel.eval</tt>, like this:
14
- #
15
- # def example(_binding)
16
- # return eval("x", _binding)
17
- # end
18
- #
19
- # x = 55
20
- # current_binding = Kernel.binding
21
- # example(current_binding) # -> 55
22
- #
23
- # The most useful method introduced to Binding by the _extensions_ package is
24
- # Binding.of_caller. It allows you to access the binding of the calling method, thus
25
- # enabling you to access local variables in that scope. The other methods are a convenient
26
- # object-oriented facade for operations that you can already do with #eval as demonstrated
27
- # above. Here is an example that showcases all of the Binding methods included in
28
- # _extensions_.
29
- #
30
- # def example
31
- # Binding.of_caller do |b|
32
- # puts "x + y = #{b.eval('x + y')}"
33
- # puts "x = #{b[:x]}"
34
- # puts "Local variables: " + b.local_variables.join(', ')
35
- # b[:y] += 1
36
- # puts "Changed value of y in calling context to #{b[:y]}"
37
- # puts "Is 'z' defined in calling context? " + (b.defined?(:z) ? 'Yes' : 'No')
38
- # end
39
- # end
40
- #
41
- # x = 5
42
- # y = 17
43
- # example
44
- # y # -> 18
45
- #
46
- # Binding.of_caller was written by Florian Gross. The other methods were written by Tom
47
- # Sawyer.
48
- #
49
- class Binding
50
- end
51
-
52
- #
53
- # * Binding.of_caller
54
- #
55
- ExtensionsProject.implement(Binding, :of_caller, :class) do
56
- class Binding
57
- #
58
- # This method returns the binding of the method that called your method, enabling you to
59
- # access its local variables. If you call it without being in a method, it will raise an
60
- # Exception.
61
- #
62
- # === Example
63
- #
64
- # def inc_counter
65
- # Binding.of_caller do |b|
66
- # eval("counter += 1", b)
67
- # end
68
- # # <--- line (A)
69
- # end
70
- # counter = 0
71
- # inc_counter
72
- # inc_counter
73
- # counter # -> 2
74
- #
75
- # === Warning
76
- #
77
- # <tt>Binding.of_caller</tt> must be the _last_ method call in the method. For example,
78
- # if you insert some code at line *A* in the example above, an Exception will be raised.
79
- # You'll get away with a simple assignment, but anything involving a method call is
80
- # trouble.
81
- #
82
- # === Explanation
83
- #
84
- # It works by installing a temporary trace_func (see Kernel.set_trace_func). This makes
85
- # available -- to the trace function -- the binding of a method after it has returned.
86
- # Using a continuation, <tt>Binding.of_caller</tt> will let _your_ method return,
87
- # retrieve the binding, and return to the <tt>of_caller</tt> call with that binding in
88
- # hand. This time it executes the block.
89
- #
90
- # Because it is actually running <tt>Binding.of_caller</tt> twice, and returning from
91
- # your method twice, any code between the <tt>of_caller</tt> call and the end of your
92
- # method will be run twice. This is obviously not desirable, so an Exception is raised
93
- # if any code is found.
94
- #
95
- # See the thread around ruby-talk:109607 for more discussion.
96
- #
97
- # === Extra Warning
98
- #
99
- # If you have a trace function in place, <tt>Binding.of_caller</tt> will destroy that.
100
- # Ruby does not allow you to access the current trace function, so it can't be restored
101
- # afterwards. XXX: will this clash with the profiler and/or debugger?
102
- #
103
- # === Credits
104
- #
105
- # <tt>Binding.of_caller</tt> was written by Florian Frank.
106
- #
107
- def Binding.of_caller(&block)
108
- old_critical = Thread.critical
109
- Thread.critical = true
110
- count = 0
111
- cc, result, error = Continuation.create(nil, nil)
112
- error.call if error
113
-
114
- tracer = lambda do |*args|
115
- type, context = args[0], args[4]
116
- if type == "return"
117
- count += 1
118
- # First this method and then calling one will return --
119
- # the trace event of the second event gets the context
120
- # of the method which called the method that called this
121
- # method.
122
- if count == 2
123
- # It would be nice if we could restore the trace_func
124
- # that was set before we swapped in our own one, but
125
- # this is impossible without overloading set_trace_func
126
- # in current Ruby.
127
- set_trace_func(nil)
128
- cc.call(eval("binding", context), nil)
129
- end
130
- elsif type != "line"
131
- set_trace_func(nil)
132
- error_msg = "Binding.of_caller used in non-method context or " +
133
- "trailing statements of method using it aren't in the block."
134
- cc.call(nil, lambda { raise(Exception, error_msg ) })
135
- end
136
- end
137
-
138
- unless result
139
- set_trace_func(tracer)
140
- return nil
141
- else
142
- Thread.critical = old_critical
143
- yield result
144
- end
145
- end
146
- end # class Binding
147
- end
148
-
149
-
150
- #
151
- # * Binding#eval
152
- #
153
- ExtensionsProject.implement(Binding, :eval, :instance) do
154
- class Binding
155
- #
156
- # Evaluates the given string in the context of this binding.
157
- #
158
- def eval(str)
159
- Kernel.eval(str, self)
160
- end
161
- end
162
- end
163
-
164
-
165
- #
166
- # * Binding#local_variables
167
- #
168
- ExtensionsProject.implement(Binding, :local_variables, :instance) do
169
- class Binding
170
- #
171
- # Returns the variables that are local to this binding.
172
- #
173
- def local_variables
174
- self.eval('local_variables')
175
- end
176
- end
177
- end
178
-
179
-
180
- #
181
- # * Binding#[]
182
- #
183
- ExtensionsProject.implement(Binding, :[], :instance) do
184
- class Binding
185
- #
186
- # Returns the value of the given variable in this binding.
187
- #
188
- def [](variable)
189
- self.eval(variable.to_s)
190
- end
191
- end
192
- end
193
-
194
-
195
- #
196
- # * Binding#[]=
197
- #
198
- ExtensionsProject.implement(Binding, :[]=, :instance) do
199
- class Binding
200
- #
201
- # Sets the given variable (in this binding) to the given value.
202
- #
203
- def []=(variable, value)
204
- self.eval("lambda { |v| #{variable} = v }").call(value)
205
- end
206
- end
207
- end
208
-
209
-
210
- #
211
- # * Binding#defined?
212
- #
213
- ExtensionsProject.implement(Binding, :defined?, :instance) do
214
- class Binding
215
- #
216
- # Evaluates <tt>defined?</tt> in this binding.
217
- #
218
- def defined?(variable)
219
- self.eval("defined?(#{variable})")
220
- end
221
- end
222
- end
223
-
224
-
@@ -1,50 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
- #
3
- # == extensions/class.rb
4
- #
5
- # Adds methods to the builtin Class class.
6
- #
7
-
8
- require "extensions/_base"
9
-
10
- ExtensionsProject.implement(Class, :autoinit) do
11
- class Class
12
- #
13
- # A shorthand for the common chore of assigning initialize's parameters to
14
- # instance variables. For example:
15
- #
16
- # class Circle
17
- #
18
- # attr_reader :radius, :location, :area
19
- #
20
- # autoinit(:radius, :location) do
21
- # @area = Math::PI * @radius ** 2
22
- # end
23
- #
24
- # end
25
- #
26
- # A TypeError is raised unless all the arguments to +autoinit+ are strings
27
- # or symbols.
28
- #
29
- #--
30
- # Taken from ruby-talk:11668, by Avi Bryant.
31
- def autoinit(*args, &block) # :yield:
32
- unless args.all? { |a| Symbol === a or String === a }
33
- raise TypeError, "All arguments must be symbols or strings"
34
- end
35
- block = proc {} if block.nil?
36
- define_method(:__init_proc) { block }
37
- params = args.join(", ")
38
- vars = args.map { |a| "@#{a}" }.join(", ")
39
-
40
- code = %{
41
- def initialize(#{params})
42
- #{vars} = #{params}
43
- instance_eval(&__init_proc)
44
- end
45
- }
46
- class_eval code
47
- end
48
- end
49
- end
50
-
@@ -1,71 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
- #
3
- # == extensions/continuation.rb
4
- #
5
- # Adds methods to the builtin Continuation class.
6
- #
7
-
8
- require "extensions/_base"
9
-
10
- #
11
- # * Continuation.create
12
- #
13
- ExtensionsProject.implement(Continuation, :create, :class) do
14
- class Continuation
15
- #
16
- # <tt>Continuation.create</tt> offers a nicer interface for creating continuations than
17
- # <tt>Kernel.callcc</tt>.
18
- #
19
- # === Example
20
- #
21
- # Count down from 10 to 0 using a continuation.
22
- #
23
- # continuation, counter = Continuation.create(10)
24
- # puts counter
25
- # continuation.call(counter - 1) if counter > 0
26
- #
27
- # Implement a workalike of <tt>Array#inject</tt> using continuations. For simplicity's
28
- # sake, this is not fully compatible with the real <tt>#inject</tt>.
29
- #
30
- # class Array
31
- # def cc_inject( value=nil )
32
- # copy = self.clone
33
- # cc, result, item = Continuation.create( value, nil )
34
- # next_item = copy.shift
35
- # if result and item
36
- # cc.call( yield(result, item), next_item )
37
- # elsif next_item
38
- # cc.call( next_item, result )
39
- # end
40
- # result
41
- # end
42
- # end
43
- #
44
- # [1,2,3,4,5].cc_inject { |acc, n| acc + n } # -> 15
45
- #
46
- # === Explanation
47
- #
48
- # I've got no idea how it works. TODO: work it out. In particular, what do the arguments
49
- # do? And what the hell is going on in #cc_inject???!?
50
- #
51
- # === See Also
52
- #
53
- # This method is included in the 'extensions' package primarily to support
54
- # Binding.of_caller.
55
- #
56
- # === Credits
57
- #
58
- # <tt>Continuation.create</tt> was written and demonstrated by Florian Gross. See
59
- # ruby-talk:94681.
60
- #
61
- def Continuation.create(*args, &block)
62
- cc = nil
63
- result = callcc { |c|
64
- cc = c
65
- block.call(cc) if block and args.empty?
66
- }
67
- result ||= args
68
- return *[cc, *result]
69
- end
70
- end
71
- end
@@ -1,250 +0,0 @@
1
- #
2
- # == extensions/enumerable.rb
3
- #
4
- # Adds methods to the builtin Enumerable module.
5
- #
6
-
7
- require "extensions/_base"
8
-
9
- #
10
- # * Enumerable#build_hash
11
- #
12
- ExtensionsProject.implement(Enumerable, :build_hash) do
13
- module Enumerable
14
- #
15
- # Like <tt>#map</tt>/<tt>#collect</tt>, but it generates a Hash. The block
16
- # is expected to return two values: the key and the value for the new hash.
17
- # numbers = (1..3)
18
- # squares = numbers.build_hash { |n| [n, n*n] } # 1=>1, 2=>4, 3=>9
19
- # sq_roots = numbers.build_hash { |n| [n*n, n] } # 1=>1, 4=>2, 9=>3
20
- #
21
- def build_hash
22
- result = {}
23
- self.each do |elt|
24
- key, value = yield elt
25
- result[key] = value
26
- end
27
- result
28
- end
29
- end
30
-
31
- # There was a bug in Hash which causes the above code to issue a warning when
32
- # used with a Hash. That was fixed on 2003-10-24.
33
- if RUBY_RELEASE_DATE < "2003-10-25"
34
- class Hash #:nodoc:
35
- def build_hash
36
- result = {}
37
- self.each_pair do |k, v|
38
- key, value = yield(k, v)
39
- result[key] = value
40
- end
41
- result
42
- end
43
- end
44
- end
45
- end
46
-
47
-
48
- #
49
- # Enumerable#mapf
50
- #
51
- ExtensionsProject.implement(Enumerable, :mapf) do
52
- module Enumerable
53
- #
54
- # "map function"
55
- # enum.mapf(:x)
56
- # is short for
57
- # enum.map { |elt| elt.x }
58
- #
59
- def mapf(message)
60
- self.map { |elt| elt.send(message) }
61
- end
62
- end
63
- end
64
-
65
-
66
- #
67
- # Enumerable#collectf
68
- #
69
- ExtensionsProject.implement(Enumerable, :collectf) do
70
- module Enumerable
71
- alias collectf mapf
72
- end
73
- end
74
-
75
-
76
- #
77
- # * Enumerable#includes?
78
- #
79
- ExtensionsProject.implement(Enumerable, :includes?) do
80
- module Enumerable
81
- alias includes? include?
82
- end
83
- end
84
-
85
-
86
- #
87
- # * Enumerable#contains?
88
- #
89
- ExtensionsProject.implement(Enumerable, :contains?) do
90
- module Enumerable
91
- alias contains? include?
92
- end
93
- end
94
-
95
-
96
- #
97
- # * Enumerable#has?
98
- #
99
- ExtensionsProject.implement(Enumerable, :has?) do
100
- module Enumerable
101
- alias has? include?
102
- end
103
- end
104
-
105
-
106
- #
107
- # * Enumerable#map_with_index
108
- #
109
- ExtensionsProject.implement(Enumerable, :map_with_index) do
110
- module Enumerable
111
- #
112
- # Same as Enumerable#map, but the index is yielded as well. See
113
- # Enumerable#each_with_index.
114
- # puts files.map_with_index { |fn, idx| "#{idx}. #{fn}" }
115
- # print "Please select a file (0-#{files.size}): "
116
- #
117
- def map_with_index
118
- result = []
119
- self.each_with_index do |elt, idx|
120
- result << yield(elt, idx)
121
- end
122
- result
123
- end
124
- end
125
- end
126
-
127
-
128
- #
129
- # * Enumerable#collect_with_index
130
- #
131
- ExtensionsProject.implement(Enumerable, :collect_with_index) do
132
- module Enumerable
133
- alias collect_with_index map_with_index
134
- end
135
- end
136
-
137
-
138
- #
139
- # * Enumerable#partition_by
140
- #
141
- ExtensionsProject.implement(Enumerable, :partition_by) do
142
- module Enumerable
143
- #
144
- # See Enumerable#partition for the background. #partition_by is best
145
- # explained by example.
146
- #
147
- # (1..5).partition_by { |n| n % 3 }
148
- # # -> { 0 => [3], 1 => [1, 4], 2 => [2,5] }
149
- #
150
- # ["I had", 1, "dollar and", 50, "cents"].partition_by { |e| e.class }
151
- # # -> { String => ["I had","dollar and","cents"], Fixnum => [1,50] }
152
- #
153
- # #partition_by is used to group items in a collection by something they
154
- # have in common. The common factor is the key in the resulting hash, the
155
- # array of like elements is the value.
156
- #
157
- def partition_by
158
- result = {}
159
- self.each do |e|
160
- value = yield e
161
- (result[value] ||= []) << e
162
- end
163
- result
164
- end
165
- end
166
- end
167
-
168
-
169
- #
170
- # * Enumerable#none?
171
- #
172
- ExtensionsProject.implement(Enumerable, :none?) do
173
- module Enumerable
174
- #
175
- # Enumerable#none? is the logical opposite of the builtin method Enumerable#any?. It
176
- # returns +true+ if and only if _none_ of the elements in the collection satisfy the
177
- # predicate.
178
- #
179
- # If no predicate is provided, Enumerable#none? returns +true+ if and only if _none_ of the
180
- # elements have a true value (i.e. not +nil+ or +false+).
181
- #
182
- # [].none? # true
183
- # [nil].none? # true
184
- # [5,8,9].none? # false
185
- # (1...10).none? { |n| n < 0 } # true
186
- # (1...10).none? { |n| n > 0 } # false
187
- #
188
- def none? # :yield: e
189
- if block_given?
190
- not self.any? { |e| yield e }
191
- else
192
- not self.any?
193
- end
194
- end
195
- end
196
- end
197
-
198
-
199
- #
200
- # * Enumerable#one?
201
- #
202
- ExtensionsProject.implement(Enumerable, :one?) do
203
- module Enumerable
204
- #
205
- # Enumerable#one? returns +true+ if and only if <em>exactly one</em> element in the
206
- # collection satisfies the given predicate.
207
- #
208
- # If no predicate is provided, Enumerable#one? returns +true+ if and only if <em>exactly
209
- # one</em> element has a true value (i.e. not +nil+ or +false+).
210
- #
211
- # [].one? # false
212
- # [nil].one? # false
213
- # [5].one? # true
214
- # [5,8,9].one? # false
215
- # (1...10).one? { |n| n == 5 } # true
216
- # (1...10).one? { |n| n < 5 } # false
217
- #
218
- def one? # :yield: e
219
- matches = 0
220
- if block_given?
221
- self.each do |e|
222
- if yield(e)
223
- matches += 1
224
- return false if matches > 1
225
- end
226
- end
227
- return (matches == 1)
228
- else
229
- one? { |e| e }
230
- end
231
- end
232
- end
233
- end
234
-
235
-
236
- #
237
- # * Object.in?
238
- # This has special treatment: it's included here and in object.rb, so we don't
239
- # want a warning if it's alredy defined.
240
- #
241
- unless Object.method_defined?(:in?)
242
- ExtensionsProject.implement(Object, :in?) do
243
- class Object
244
- def in?(enumerable) # :nodoc: It's documented in object.rb.
245
- enumerable.include?(self)
246
- end
247
- end
248
- end
249
- end
250
-