/
misc.rb
232 lines (170 loc) · 3.41 KB
/
misc.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
class MatchData
#
# Return a hash of named matches
#
def to_hash
Hash[ names.zip(captures) ]
end
end
class Binding
#
# Get a variables in this binding
#
def [](key)
eval(key.to_s)
end
#
# Set a variable in this binding
#
def []=(key, val)
Thread.current[:_alter_binding_local_] = val
eval("#{key} = Thread.current[:_alter_binding_local_]")
Thread.current[:_alter_binding_local_] = nil
end
#
# Return all the local variables in the binding
#
if RUBY_VERSION["1.8"]
def local_variables
eval("local_variables").map(&:to_sym)
end
else
def local_variables
eval("local_variables")
end
end
alias_method :keys, :local_variables
end
class Proc
#
# Chain two procs together, returning a new proc. Each proc is executed one after the other,
# with the same input arguments. The return value is an array of all the procs' return values.
#
# You can use either the .join method, or the overloaded & operator.
#
# Examples:
# joined = proc1 & proc2
# joined = proc1.join proc2
# newproc = proc { 1 } & proc { 2 }
# newproc.call #=> [1, 2]
#
def join(other=nil, &block)
other ||= block
proc { |*args| [self.call(*args), other.call(*args)] }
end
alias_method :&, :join
#
# Chains two procs together, returning a new proc. The output from each proc is passed into
# the input of the next one.
#
# Example:
# chain = proc { 1 } | proc { |input| input + 1 }
# chain.call #=> 2
#
def chain(other=nil, &block)
other ||= block
proc { |*args| other.call( self.call(*args) ) }
end
alias_method :|, :chain
end
unless defined?(BasicObject)
#
# Backported BasicObject for Ruby 1.8
#
class BasicObject
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
end
end
class Object
#
# Negates a boolean, chained-method style.
#
# Example:
# >> 10.even?
# => true
# >> 10.not.even?
# => false
#
def not
NotWrapper.new(self)
end
end
class NotWrapper < BasicObject # :nodoc:
def initialize(orig)
@orig = orig
end
def inspect
"{NOT #{@orig.inspect}}"
end
def is_a?(other)
other === self
end
def method_missing(meth, *args, &block)
result = @orig.send(meth, *args, &block)
if result.is_a? ::TrueClass or result.is_a? ::FalseClass
!result
else
raise "Sorry, I don't know how to invert #{result.inspect}"
end
end
end
unless IO.respond_to? :copy_stream
class IO
#
# IO.copy_stream backport
#
def self.copy_stream(input, output)
while chunk = input.read(8192)
output.write(chunk)
end
end
end
end
class Range
#
# Pick a random number from the range.
#
def rand
Kernel.rand(self)
end
end
class Struct
#
# Transform this struct into a JSON hash
#
def to_hash
hash = {}
each_pair { |k,v| hash[k] = v }
hash
end
#
# Transform the struct into a simple JSON hash.
#
def to_json(*args)
to_hash.to_json
end
end
module URI
#
# Return a Hash of the variables in the query string
#
def params
query.to_params
end
end
class Time
#
# Which "quarter" of the year does this date fall into?
#
def quarter
(month / 3.0).ceil
end
end
#
# Give ObjectSpace Enumerable powers (select, map, etc.)
#
module ObjectSpace
include Enumerable
alias_method :each, :each_object
extend self
end