dao 7.0.0 → 8.0.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.
- checksums.yaml +5 -5
- data/Rakefile +4 -5
- data/coerce-0.0.8/README +28 -0
- data/coerce-0.0.8/Rakefile +392 -0
- data/coerce-0.0.8/coerce.gemspec +31 -0
- data/coerce-0.0.8/lib/coerce.rb +210 -0
- data/dao.gemspec +25 -19
- data/lib/dao.rb +8 -15
- data/lib/dao/_lib.rb +6 -10
- data/lib/dao/active_record.rb +2 -2
- data/lib/dao/api/call.rb +6 -2
- data/lib/dao/coerce.rb +211 -0
- data/lib/dao/conducer.rb +6 -10
- data/lib/dao/errors2html.rb +1 -1
- data/lib/dao/support.rb +6 -17
- data/lib/dao/wrap.rb +259 -0
- data/test/conducer_test.rb +4 -4
- data/test/form_test.rb +2 -2
- data/test/validations_test.rb +2 -2
- data/wrap-1.5.2/README +57 -0
- data/wrap-1.5.2/Rakefile +394 -0
- data/wrap-1.5.2/lib/wrap.rb +295 -0
- data/wrap-1.5.2/test/testing.rb +195 -0
- data/wrap-1.5.2/test/wrap_test.rb +397 -0
- data/wrap-1.5.2/wrap.gemspec +38 -0
- metadata +26 -72
- data/notes/ara.txt +0 -15
data/wrap-1.5.2/Rakefile
ADDED
@@ -0,0 +1,394 @@
|
|
1
|
+
This.rubyforge_project = 'codeforpeople'
|
2
|
+
This.author = "Ara T. Howard"
|
3
|
+
This.email = "ara.t.howard@gmail.com"
|
4
|
+
This.homepage = "https://github.com/ahoward/#{ This.lib }"
|
5
|
+
|
6
|
+
task :license do
|
7
|
+
open('LICENSE', 'w'){|fd| fd.puts "same as ruby's"}
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default do
|
11
|
+
puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
|
12
|
+
end
|
13
|
+
|
14
|
+
task :test do
|
15
|
+
run_tests!
|
16
|
+
end
|
17
|
+
|
18
|
+
namespace :test do
|
19
|
+
task(:unit){ run_tests!(:unit) }
|
20
|
+
task(:functional){ run_tests!(:functional) }
|
21
|
+
task(:integration){ run_tests!(:integration) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_tests!(which = nil)
|
25
|
+
which ||= '**'
|
26
|
+
test_dir = File.join(This.dir, "test")
|
27
|
+
test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
|
28
|
+
test_rbs = Dir.glob(test_glob).sort
|
29
|
+
|
30
|
+
div = ('=' * 119)
|
31
|
+
line = ('-' * 119)
|
32
|
+
|
33
|
+
test_rbs.each_with_index do |test_rb, index|
|
34
|
+
testno = index + 1
|
35
|
+
command = "#{ This.ruby } -w -I ./lib -I ./test/lib #{ test_rb }"
|
36
|
+
|
37
|
+
puts
|
38
|
+
say(div, :color => :cyan, :bold => true)
|
39
|
+
say("@#{ testno } => ", :bold => true, :method => :print)
|
40
|
+
say(command, :color => :cyan, :bold => true)
|
41
|
+
say(line, :color => :cyan, :bold => true)
|
42
|
+
|
43
|
+
system(command)
|
44
|
+
|
45
|
+
say(line, :color => :cyan, :bold => true)
|
46
|
+
|
47
|
+
status = $?.exitstatus
|
48
|
+
|
49
|
+
if status.zero?
|
50
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
51
|
+
say("SUCCESS", :color => :green, :bold => true)
|
52
|
+
else
|
53
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
54
|
+
say("FAILURE", :color => :red, :bold => true)
|
55
|
+
end
|
56
|
+
say(line, :color => :cyan, :bold => true)
|
57
|
+
|
58
|
+
exit(status) unless status.zero?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
task :gemspec do
|
64
|
+
ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
|
65
|
+
ignore_directories = ['pkg']
|
66
|
+
ignore_files = ['test/log']
|
67
|
+
|
68
|
+
shiteless =
|
69
|
+
lambda do |list|
|
70
|
+
list.delete_if do |entry|
|
71
|
+
next unless test(?e, entry)
|
72
|
+
extension = File.basename(entry).split(%r/[.]/).last
|
73
|
+
ignore_extensions.any?{|ext| ext === extension}
|
74
|
+
end
|
75
|
+
list.delete_if do |entry|
|
76
|
+
next unless test(?d, entry)
|
77
|
+
dirname = File.expand_path(entry)
|
78
|
+
ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
|
79
|
+
end
|
80
|
+
list.delete_if do |entry|
|
81
|
+
next unless test(?f, entry)
|
82
|
+
filename = File.expand_path(entry)
|
83
|
+
ignore_files.any?{|file| File.expand_path(file) == filename}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
lib = This.lib
|
88
|
+
object = This.object
|
89
|
+
version = This.version
|
90
|
+
files = shiteless[Dir::glob("**/**")]
|
91
|
+
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
|
92
|
+
#has_rdoc = true #File.exist?('doc')
|
93
|
+
test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
|
94
|
+
summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
|
95
|
+
description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
|
96
|
+
license = object.respond_to?(:license) ? object.license : "same as ruby's"
|
97
|
+
|
98
|
+
if This.extensions.nil?
|
99
|
+
This.extensions = []
|
100
|
+
extensions = This.extensions
|
101
|
+
%w( Makefile configure extconf.rb ).each do |ext|
|
102
|
+
extensions << ext if File.exists?(ext)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
extensions = [extensions].flatten.compact
|
106
|
+
|
107
|
+
if This.dependencies.nil?
|
108
|
+
dependencies = []
|
109
|
+
else
|
110
|
+
case This.dependencies
|
111
|
+
when Hash
|
112
|
+
dependencies = This.dependencies.values
|
113
|
+
when Array
|
114
|
+
dependencies = This.dependencies
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
template =
|
119
|
+
if test(?e, 'gemspec.erb')
|
120
|
+
Template{ IO.read('gemspec.erb') }
|
121
|
+
else
|
122
|
+
Template {
|
123
|
+
<<-__
|
124
|
+
## <%= lib %>.gemspec
|
125
|
+
#
|
126
|
+
|
127
|
+
Gem::Specification::new do |spec|
|
128
|
+
spec.name = <%= lib.inspect %>
|
129
|
+
spec.version = <%= version.inspect %>
|
130
|
+
spec.platform = Gem::Platform::RUBY
|
131
|
+
spec.summary = <%= lib.inspect %>
|
132
|
+
spec.description = <%= description.inspect %>
|
133
|
+
spec.license = <%= license.inspect %>
|
134
|
+
|
135
|
+
spec.files =\n<%= files.sort.pretty_inspect %>
|
136
|
+
spec.executables = <%= executables.inspect %>
|
137
|
+
|
138
|
+
spec.require_path = "lib"
|
139
|
+
|
140
|
+
spec.test_files = <%= test_files.inspect %>
|
141
|
+
|
142
|
+
<% dependencies.each do |lib_version| %>
|
143
|
+
spec.add_dependency(*<%= Array(lib_version).flatten.inspect %>)
|
144
|
+
<% end %>
|
145
|
+
|
146
|
+
spec.extensions.push(*<%= extensions.inspect %>)
|
147
|
+
|
148
|
+
spec.rubyforge_project = <%= This.rubyforge_project.inspect %>
|
149
|
+
spec.author = <%= This.author.inspect %>
|
150
|
+
spec.email = <%= This.email.inspect %>
|
151
|
+
spec.homepage = <%= This.homepage.inspect %>
|
152
|
+
end
|
153
|
+
__
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
Fu.mkdir_p(This.pkgdir)
|
158
|
+
gemspec = "#{ lib }.gemspec"
|
159
|
+
open(gemspec, "w"){|fd| fd.puts(template)}
|
160
|
+
This.gemspec = gemspec
|
161
|
+
end
|
162
|
+
|
163
|
+
task :gem => [:clean, :gemspec] do
|
164
|
+
Fu.mkdir_p(This.pkgdir)
|
165
|
+
before = Dir['*.gem']
|
166
|
+
cmd = "gem build #{ This.gemspec }"
|
167
|
+
`#{ cmd }`
|
168
|
+
after = Dir['*.gem']
|
169
|
+
gem = ((after - before).first || after.first) or abort('no gem!')
|
170
|
+
Fu.mv(gem, This.pkgdir)
|
171
|
+
This.gem = File.join(This.pkgdir, File.basename(gem))
|
172
|
+
end
|
173
|
+
|
174
|
+
task :readme do
|
175
|
+
samples = ''
|
176
|
+
prompt = '~ > '
|
177
|
+
lib = This.lib
|
178
|
+
version = This.version
|
179
|
+
|
180
|
+
Dir['sample*/*'].sort.each do |sample|
|
181
|
+
samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
|
182
|
+
|
183
|
+
cmd = "cat #{ sample }"
|
184
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
185
|
+
samples << Util.indent(`#{ cmd }`, 4) << "\n"
|
186
|
+
|
187
|
+
cmd = "ruby #{ sample }"
|
188
|
+
samples << Util.indent(prompt + cmd, 2) << "\n\n"
|
189
|
+
|
190
|
+
cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
|
191
|
+
samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
|
192
|
+
end
|
193
|
+
|
194
|
+
template =
|
195
|
+
if test(?e, 'README.erb')
|
196
|
+
Template{ IO.read('README.erb') }
|
197
|
+
else
|
198
|
+
Template {
|
199
|
+
<<-__
|
200
|
+
NAME
|
201
|
+
#{ lib }
|
202
|
+
|
203
|
+
DESCRIPTION
|
204
|
+
|
205
|
+
INSTALL
|
206
|
+
gem install #{ lib }
|
207
|
+
|
208
|
+
SAMPLES
|
209
|
+
#{ samples }
|
210
|
+
__
|
211
|
+
}
|
212
|
+
end
|
213
|
+
|
214
|
+
open("README", "w"){|fd| fd.puts template}
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
task :clean do
|
219
|
+
Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
task :release => [:clean, :gemspec, :gem] do
|
224
|
+
gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
|
225
|
+
raise "which one? : #{ gems.inspect }" if gems.size > 1
|
226
|
+
raise "no gems?" if gems.size < 1
|
227
|
+
|
228
|
+
cmd = "gem push #{ This.gem }"
|
229
|
+
puts cmd
|
230
|
+
puts
|
231
|
+
system(cmd)
|
232
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
233
|
+
|
234
|
+
cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
|
235
|
+
puts cmd
|
236
|
+
puts
|
237
|
+
system(cmd)
|
238
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
|
244
|
+
|
245
|
+
BEGIN {
|
246
|
+
# support for this rakefile
|
247
|
+
#
|
248
|
+
$VERBOSE = nil
|
249
|
+
|
250
|
+
require 'ostruct'
|
251
|
+
require 'erb'
|
252
|
+
require 'fileutils'
|
253
|
+
require 'rbconfig'
|
254
|
+
require 'pp'
|
255
|
+
|
256
|
+
# fu shortcut
|
257
|
+
#
|
258
|
+
Fu = FileUtils
|
259
|
+
|
260
|
+
# cache a bunch of stuff about this rakefile/environment
|
261
|
+
#
|
262
|
+
This = OpenStruct.new
|
263
|
+
|
264
|
+
This.file = File.expand_path(__FILE__)
|
265
|
+
This.dir = File.dirname(This.file)
|
266
|
+
This.pkgdir = File.join(This.dir, 'pkg')
|
267
|
+
|
268
|
+
# grok lib
|
269
|
+
#
|
270
|
+
lib = ENV['LIB']
|
271
|
+
unless lib
|
272
|
+
lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
|
273
|
+
end
|
274
|
+
This.lib = lib
|
275
|
+
|
276
|
+
# grok version
|
277
|
+
#
|
278
|
+
version = ENV['VERSION']
|
279
|
+
unless version
|
280
|
+
require "./lib/#{ This.lib }"
|
281
|
+
This.name = lib.capitalize
|
282
|
+
This.object = eval(This.name)
|
283
|
+
version = This.object.send(:version)
|
284
|
+
end
|
285
|
+
This.version = version
|
286
|
+
|
287
|
+
# see if dependencies are export by the module
|
288
|
+
#
|
289
|
+
if This.object.respond_to?(:dependencies)
|
290
|
+
This.dependencies = This.object.dependencies
|
291
|
+
end
|
292
|
+
|
293
|
+
# we need to know the name of the lib an it's version
|
294
|
+
#
|
295
|
+
abort('no lib') unless This.lib
|
296
|
+
abort('no version') unless This.version
|
297
|
+
|
298
|
+
# discover full path to this ruby executable
|
299
|
+
#
|
300
|
+
c = Config::CONFIG
|
301
|
+
bindir = c["bindir"] || c['BINDIR']
|
302
|
+
ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
|
303
|
+
ruby_ext = c['EXEEXT'] || ''
|
304
|
+
ruby = File.join(bindir, (ruby_install_name + ruby_ext))
|
305
|
+
This.ruby = ruby
|
306
|
+
|
307
|
+
# some utils
|
308
|
+
#
|
309
|
+
module Util
|
310
|
+
def indent(s, n = 2)
|
311
|
+
s = unindent(s)
|
312
|
+
ws = ' ' * n
|
313
|
+
s.gsub(%r/^/, ws)
|
314
|
+
end
|
315
|
+
|
316
|
+
def unindent(s)
|
317
|
+
indent = nil
|
318
|
+
s.each_line do |line|
|
319
|
+
next if line =~ %r/^\s*$/
|
320
|
+
indent = line[%r/^\s*/] and break
|
321
|
+
end
|
322
|
+
indent ? s.gsub(%r/^#{ indent }/, "") : s
|
323
|
+
end
|
324
|
+
extend self
|
325
|
+
end
|
326
|
+
|
327
|
+
# template support
|
328
|
+
#
|
329
|
+
class Template
|
330
|
+
def initialize(&block)
|
331
|
+
@block = block
|
332
|
+
@template = block.call.to_s
|
333
|
+
end
|
334
|
+
def expand(b=nil)
|
335
|
+
ERB.new(Util.unindent(@template)).result((b||@block).binding)
|
336
|
+
end
|
337
|
+
alias_method 'to_s', 'expand'
|
338
|
+
end
|
339
|
+
def Template(*args, &block) Template.new(*args, &block) end
|
340
|
+
|
341
|
+
# colored console output support
|
342
|
+
#
|
343
|
+
This.ansi = {
|
344
|
+
:clear => "\e[0m",
|
345
|
+
:reset => "\e[0m",
|
346
|
+
:erase_line => "\e[K",
|
347
|
+
:erase_char => "\e[P",
|
348
|
+
:bold => "\e[1m",
|
349
|
+
:dark => "\e[2m",
|
350
|
+
:underline => "\e[4m",
|
351
|
+
:underscore => "\e[4m",
|
352
|
+
:blink => "\e[5m",
|
353
|
+
:reverse => "\e[7m",
|
354
|
+
:concealed => "\e[8m",
|
355
|
+
:black => "\e[30m",
|
356
|
+
:red => "\e[31m",
|
357
|
+
:green => "\e[32m",
|
358
|
+
:yellow => "\e[33m",
|
359
|
+
:blue => "\e[34m",
|
360
|
+
:magenta => "\e[35m",
|
361
|
+
:cyan => "\e[36m",
|
362
|
+
:white => "\e[37m",
|
363
|
+
:on_black => "\e[40m",
|
364
|
+
:on_red => "\e[41m",
|
365
|
+
:on_green => "\e[42m",
|
366
|
+
:on_yellow => "\e[43m",
|
367
|
+
:on_blue => "\e[44m",
|
368
|
+
:on_magenta => "\e[45m",
|
369
|
+
:on_cyan => "\e[46m",
|
370
|
+
:on_white => "\e[47m"
|
371
|
+
}
|
372
|
+
def say(phrase, *args)
|
373
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
374
|
+
options[:color] = args.shift.to_s.to_sym unless args.empty?
|
375
|
+
keys = options.keys
|
376
|
+
keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
|
377
|
+
|
378
|
+
color = options[:color]
|
379
|
+
bold = options.has_key?(:bold)
|
380
|
+
|
381
|
+
parts = [phrase]
|
382
|
+
parts.unshift(This.ansi[color]) if color
|
383
|
+
parts.unshift(This.ansi[:bold]) if bold
|
384
|
+
parts.push(This.ansi[:clear]) if parts.size > 1
|
385
|
+
|
386
|
+
method = options[:method] || :puts
|
387
|
+
|
388
|
+
Kernel.send(method, parts.join)
|
389
|
+
end
|
390
|
+
|
391
|
+
# always run out of the project dir
|
392
|
+
#
|
393
|
+
Dir.chdir(This.dir)
|
394
|
+
}
|
@@ -0,0 +1,295 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
module Wrap; end
|
4
|
+
|
5
|
+
##
|
6
|
+
#
|
7
|
+
class << Wrap
|
8
|
+
Wrap::Version = '1.5.2' unless defined?(Wrap::Version)
|
9
|
+
|
10
|
+
def version
|
11
|
+
Wrap::Version
|
12
|
+
end
|
13
|
+
|
14
|
+
def dependencies
|
15
|
+
{
|
16
|
+
'map' => [ 'map' , ' >= 4.7.1' ]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def description
|
21
|
+
'non-sucking :before and :after filters for any ruby class'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
#
|
27
|
+
begin
|
28
|
+
require 'rubygems'
|
29
|
+
Wrap.dependencies.each{|name, dependency| gem(*dependency)}
|
30
|
+
rescue LoadError
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
#
|
36
|
+
require 'map'
|
37
|
+
|
38
|
+
##
|
39
|
+
#
|
40
|
+
module Wrap
|
41
|
+
def Wrap.included(other)
|
42
|
+
super
|
43
|
+
ensure
|
44
|
+
other.send(:instance_eval, &ClassMethods)
|
45
|
+
other.send(:class_eval, &InstanceMethods)
|
46
|
+
end
|
47
|
+
|
48
|
+
def Wrap.code_for(method)
|
49
|
+
name = method.name.to_s
|
50
|
+
arity = method.arity
|
51
|
+
|
52
|
+
case
|
53
|
+
when arity == 0
|
54
|
+
signature = <<-__.strip
|
55
|
+
def #{ name }(&block)
|
56
|
+
args = []
|
57
|
+
__
|
58
|
+
|
59
|
+
when arity < 0
|
60
|
+
argv = Array.new(arity.abs - 1){|i| "arg#{ i }"}
|
61
|
+
argv.push('*args')
|
62
|
+
argv = argv.join(', ')
|
63
|
+
|
64
|
+
signature = <<-__.strip
|
65
|
+
def #{ name }(#{ argv }, &block)
|
66
|
+
args = [#{ argv }]
|
67
|
+
__
|
68
|
+
|
69
|
+
when arity > 0
|
70
|
+
argv = Array.new(arity){|i| "arg#{ i }"}
|
71
|
+
argv = argv.join(', ')
|
72
|
+
|
73
|
+
signature = <<-__.strip
|
74
|
+
def #{ name }(#{ argv }, &block)
|
75
|
+
args = [#{ argv }]
|
76
|
+
__
|
77
|
+
end
|
78
|
+
|
79
|
+
code =
|
80
|
+
<<-__
|
81
|
+
#{ signature.strip }
|
82
|
+
|
83
|
+
if running_callbacks?(#{ name.inspect })
|
84
|
+
return wrapped_#{ name }(*args, &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
running_callbacks(#{ name.inspect }) do
|
88
|
+
catch(:halt) do
|
89
|
+
return false if run_callbacks(:before, #{ name.inspect }, args)==false
|
90
|
+
|
91
|
+
begin
|
92
|
+
result = wrapped_#{ name }(*args, &block)
|
93
|
+
ensure
|
94
|
+
run_callbacks(:after, #{ name.inspect }, [result]) unless $!
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
__
|
100
|
+
end
|
101
|
+
|
102
|
+
ClassMethods = proc do
|
103
|
+
def method_added(name)
|
104
|
+
return super if wrapping?
|
105
|
+
begin
|
106
|
+
super
|
107
|
+
ensure
|
108
|
+
wrap!(name) if wrapped?(name)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def include(other)
|
113
|
+
super
|
114
|
+
ensure
|
115
|
+
other.instance_methods.each do |name|
|
116
|
+
if wrapped?(name)
|
117
|
+
begin
|
118
|
+
remove_method(name)
|
119
|
+
rescue NameError
|
120
|
+
nil
|
121
|
+
end
|
122
|
+
wrap!(name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def wrap(name, *args, &block)
|
128
|
+
wrapped!(name)
|
129
|
+
|
130
|
+
wrap!(name) if
|
131
|
+
begin
|
132
|
+
instance_method(name)
|
133
|
+
true
|
134
|
+
rescue NameError
|
135
|
+
false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def wrapped!(name)
|
140
|
+
name = name.to_s
|
141
|
+
wrapped.push(name) unless wrapped.include?(name)
|
142
|
+
name
|
143
|
+
end
|
144
|
+
|
145
|
+
def wrapped
|
146
|
+
@wrapped ||= []
|
147
|
+
end
|
148
|
+
|
149
|
+
def wrapped?(name)
|
150
|
+
ancestors.any?{|ancestor| ancestor.respond_to?(:wrapped) and ancestor.wrapped.include?(name.to_s)}
|
151
|
+
end
|
152
|
+
|
153
|
+
def wrap!(name)
|
154
|
+
name = name.to_s
|
155
|
+
method = instance_method(name)
|
156
|
+
arity = method.arity
|
157
|
+
|
158
|
+
wrapping! name do
|
159
|
+
name = name.to_s
|
160
|
+
wrapped_name = "wrapped_#{ name }"
|
161
|
+
|
162
|
+
begin
|
163
|
+
remove_method(wrapped_name)
|
164
|
+
rescue NameError
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
|
168
|
+
alias_method(wrapped_name, name)
|
169
|
+
|
170
|
+
module_eval(Wrap.code_for(method))
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def wrapping!(name, &block)
|
175
|
+
name = name.to_s
|
176
|
+
@wrapping ||= []
|
177
|
+
|
178
|
+
return if @wrapping.last == name
|
179
|
+
|
180
|
+
@wrapping.push(name)
|
181
|
+
|
182
|
+
begin
|
183
|
+
block.call
|
184
|
+
ensure
|
185
|
+
@wrapping.pop
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def wrapping?(*name)
|
190
|
+
@wrapping ||= []
|
191
|
+
|
192
|
+
if name.empty?
|
193
|
+
!@wrapping.empty?
|
194
|
+
else
|
195
|
+
@wrapping.last == name.last.to_s
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def callbacks
|
200
|
+
@callbacks ||= Map.new
|
201
|
+
end
|
202
|
+
|
203
|
+
def initialize_callbacks!(name)
|
204
|
+
callbacks[name] ||= Map[ :before, [], :after, [] ]
|
205
|
+
callbacks[name]
|
206
|
+
end
|
207
|
+
|
208
|
+
def before(name, *args, &block)
|
209
|
+
wrap(name) unless wrapped?(name)
|
210
|
+
name = wrap_expand_aliases(name)
|
211
|
+
cb = initialize_callbacks!(name)
|
212
|
+
cb.before.push(args.shift || block)
|
213
|
+
end
|
214
|
+
|
215
|
+
def after(name, *args, &block)
|
216
|
+
wrap(name) unless wrapped?(name)
|
217
|
+
name = wrap_expand_aliases(name)
|
218
|
+
cb = initialize_callbacks!(name)
|
219
|
+
cb.after.push(args.shift || block)
|
220
|
+
end
|
221
|
+
|
222
|
+
def wrap_aliases
|
223
|
+
@@wrap_aliases ||= Hash.new
|
224
|
+
end
|
225
|
+
|
226
|
+
def wrap_alias(dst, src)
|
227
|
+
wrap_aliases[dst.to_s] = src.to_s
|
228
|
+
end
|
229
|
+
|
230
|
+
def wrap_expand_aliases(name)
|
231
|
+
name = name.to_s
|
232
|
+
loop do
|
233
|
+
break unless wrap_aliases.has_key?(name)
|
234
|
+
name = wrap_aliases[name]
|
235
|
+
end
|
236
|
+
name
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
InstanceMethods = proc do
|
241
|
+
def running_callbacks(name, &block)
|
242
|
+
name = name.to_s
|
243
|
+
@running_callbacks ||= []
|
244
|
+
return block.call() if @running_callbacks.last == name
|
245
|
+
|
246
|
+
@running_callbacks.push(name)
|
247
|
+
|
248
|
+
begin
|
249
|
+
block.call()
|
250
|
+
ensure
|
251
|
+
@running_callbacks.pop
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def running_callbacks?(*name)
|
256
|
+
@running_callbacks ||= []
|
257
|
+
|
258
|
+
if name.empty?
|
259
|
+
@running_callbacks.last
|
260
|
+
else
|
261
|
+
@running_callbacks.last == name.last.to_s
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def run_callbacks(which, name, argv)
|
266
|
+
which = which.to_s.to_sym
|
267
|
+
name = name.to_s
|
268
|
+
list = []
|
269
|
+
|
270
|
+
self.class.ancestors.each do |ancestor|
|
271
|
+
next unless ancestor.respond_to?(:callbacks)
|
272
|
+
|
273
|
+
if ancestor.callbacks.is_a?(Map) and ancestor.callbacks[name].is_a?(Map)
|
274
|
+
callbacks = ancestor.callbacks[name][which]
|
275
|
+
accumulate = (which == :before ? :unshift : :push)
|
276
|
+
list.send(accumulate, *callbacks) if callbacks.is_a?(Array)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
list.each do |callback|
|
281
|
+
block = callback.respond_to?(:call) ? callback : proc{ send(callback.to_s.to_sym) }
|
282
|
+
args = argv.slice(0 .. (block.arity > 0 ? block.arity : -1))
|
283
|
+
result = instance_exec(*args, &block)
|
284
|
+
return false if result == false
|
285
|
+
end
|
286
|
+
|
287
|
+
true
|
288
|
+
end
|
289
|
+
|
290
|
+
def halt!(*args)
|
291
|
+
value = args.size == 0 ? false : args.shift
|
292
|
+
throw(:halt, value)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|