bmizerany-sinatra 0.9.0.4 → 0.9.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS CHANGED
@@ -1,7 +1,7 @@
1
1
  Sinatra was designed and developed by Blake Mizerany (bmizerany) in
2
2
  California. Continued development would not be possible without the ongoing
3
3
  financial support provided by [Heroku](http://heroku.com) and the emotional
4
- support provided by Adam Wiggins (adamwiggins), Chris Wanstrath (defunkt),
4
+ support provided by Adam Wiggins (adamwiggins) of Heroku, Chris Wanstrath (defunkt),
5
5
  PJ Hyett (pjhyett), and the rest of the GitHub crew.
6
6
 
7
7
  Special thanks to the following extraordinary individuals, who-out which
data/CHANGES CHANGED
@@ -1,3 +1,47 @@
1
+ = 0.9.1 / unreleased
2
+
3
+ * Sinatra now runs under Ruby 1.9.1 [#61]
4
+ * Route patterns (splats, :named, or Regexp captures) are now
5
+ passed as arguments to the block. [#140]
6
+ * The "helpers" method now takes a variable number of modules
7
+ along with the normal block syntax. [#133]
8
+ * New simple API for extensions/plugins to add DSL-level and
9
+ request-level methods. Use Sinatra.register(mixin) to extend
10
+ the DSL with all public methods defined in the mixin module;
11
+ use Sinatra.helpers(mixin) to make all public methods defined
12
+ in the mixin module available at the request level. [#138]
13
+ * Added "redirect back" to redirect to the referring URL.
14
+ * Added a new "clean_trace" option that causes backtraces dumped
15
+ to rack.errors and displayed on the development error page to
16
+ omit framework and core library backtrace lines. The option is
17
+ enabled by default. [#77]
18
+ * Fix :provides causing crash on any request when request has no
19
+ Accept header [#139]
20
+ * Fix that ERB templates were evaluated twice per "erb" call.
21
+
22
+ = 0.9.0.4 / 2009-01-25
23
+
24
+ * Using halt with more than 1 args causes ArgumentError [#131]
25
+ * using halt in a before filter doesn't modify response [#127]
26
+ * Add deprecated Sinatra::EventContext to unbreak plugins [#130]
27
+ * Give access to GET/POST params in filters [#129]
28
+ * Preserve non-nested params in nested params hash [#117]
29
+ * Fix backtrace dump with Rack::Lint [#116]
30
+
31
+ = 0.9.0.3 / 2009-01-21
32
+
33
+ * Fall back on mongrel then webrick when thin not found. [#75]
34
+ * Use :environment instead of :env in test helpers to
35
+ fix deprecation warnings coming from framework.
36
+ * Make sinatra/test/rspec work again [#113]
37
+ * Fix app_file detection on windows [#118]
38
+ * Fix static files with Rack::Lint in pipeline [#121]
39
+
40
+ = 0.9.0.2 / 2009-01-18
41
+
42
+ * Halting a before block should stop processing of routes [#85]
43
+ * Fix redirect/halt in before filters [#85]
44
+
1
45
  = 0.9.0 / 2009-01-18
2
46
 
3
47
  * Works with and requires Rack >= 0.9.1
data/README.rdoc CHANGED
@@ -50,6 +50,12 @@ Route patterns may include named parameters, accessible via the
50
50
  "Hello #{params[:name]}!"
51
51
  end
52
52
 
53
+ You can also access named parameters via block parameters:
54
+
55
+ get '/hello/:name' do |n|
56
+ "Hello #{n}!"
57
+ end
58
+
53
59
  Route patterns may also include splat (or wildcard) parameters, accessible
54
60
  via the <tt>params[:splat]</tt> array.
55
61
 
@@ -69,6 +75,12 @@ Route matching with Regular Expressions:
69
75
  "Hello, #{params[:captures].first}!"
70
76
  end
71
77
 
78
+ Or with a block parameter:
79
+
80
+ get %r{/hello/([\w]+)} do |c|
81
+ "Hello, #{c}!"
82
+ end
83
+
72
84
  Routes may include a variety of matching conditions, such as the user agent:
73
85
 
74
86
  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rake/clean'
2
2
  require 'rake/testtask'
3
3
  require 'fileutils'
4
4
 
5
- task :default => :test
5
+ task :default => [:test]
6
6
  task :spec => :test
7
7
 
8
8
  # SPECS ===============================================================
@@ -45,6 +45,7 @@ task :install => package('.gem') do
45
45
  end
46
46
 
47
47
  directory 'dist/'
48
+ CLOBBER.include('dist')
48
49
 
49
50
  file package('.gem') => %w[dist/ sinatra.gemspec] + spec.files do |f|
50
51
  sh "gem build sinatra.gemspec"
data/compat/app_test.rb CHANGED
@@ -8,8 +8,9 @@ context "Sinatra" do
8
8
 
9
9
  specify "should put all DSL methods on (main)" do
10
10
  object = Object.new
11
- Sinatra::Application::FORWARD_METHODS.each do |method|
12
- object.private_methods.should.include(method)
11
+ methods = %w[get put post head delete configure template helpers set]
12
+ methods.each do |method|
13
+ object.private_methods.map { |m| m.to_sym }.should.include(method.to_sym)
13
14
  end
14
15
  end
15
16
 
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ context "Compat" do
4
+ setup do
5
+ Sinatra.application = nil
6
+ @app = Sinatra.application
7
+ end
8
+
9
+ specify "makes EventContext available" do
10
+ assert_same Sinatra::Default, Sinatra::EventContext
11
+ end
12
+ end
data/lib/sinatra/base.rb CHANGED
@@ -1,18 +1,21 @@
1
+ require 'thread'
1
2
  require 'time'
2
3
  require 'uri'
3
4
  require 'rack'
4
5
  require 'rack/builder'
5
6
 
6
7
  module Sinatra
7
- VERSION = '0.9.0.2'
8
+ VERSION = '0.9.0.5'
8
9
 
10
+ # The request object. See Rack::Request for more info:
11
+ # http://rack.rubyforge.org/doc/classes/Rack/Request.html
9
12
  class Request < Rack::Request
10
13
  def user_agent
11
14
  @env['HTTP_USER_AGENT']
12
15
  end
13
16
 
14
17
  def accept
15
- @env['HTTP_ACCEPT'].split(',').map { |a| a.strip }
18
+ @env['HTTP_ACCEPT'].to_s.split(',').map { |a| a.strip }
16
19
  end
17
20
 
18
21
  # Override Rack 0.9.x's #params implementation (see #72 in lighthouse)
@@ -23,6 +26,10 @@ module Sinatra
23
26
  end
24
27
  end
25
28
 
29
+ # The response object. See Rack::Response and Rack::ResponseHelpers for
30
+ # more info:
31
+ # http://rack.rubyforge.org/doc/classes/Rack/Response.html
32
+ # http://rack.rubyforge.org/doc/classes/Rack/Response/Helpers.html
26
33
  class Response < Rack::Response
27
34
  def initialize
28
35
  @status, @body = 200, []
@@ -44,17 +51,18 @@ module Sinatra
44
51
  body = [body] if body.respond_to? :to_str
45
52
  if header["Content-Length"].nil? && body.respond_to?(:to_ary)
46
53
  header["Content-Length"] = body.to_ary.
47
- inject(0) { |len, part| len + part.length }.to_s
54
+ inject(0) { |len, part| len + part.bytesize }.to_s
48
55
  end
49
56
  [status.to_i, header.to_hash, body]
50
57
  end
51
58
  end
52
59
  end
53
60
 
54
- class NotFound < NameError # :)
61
+ class NotFound < NameError #:nodoc:
55
62
  def code ; 404 ; end
56
63
  end
57
64
 
65
+ # Methods available to routes, before filters, and views.
58
66
  module Helpers
59
67
  # Set or retrieve the response status code.
60
68
  def status(value=nil)
@@ -82,7 +90,7 @@ module Sinatra
82
90
 
83
91
  # Halt processing and return the error status provided.
84
92
  def error(code, body=nil)
85
- code, body = 500, code.to_str if code.respond_to? :to_str
93
+ code, body = 500, code.to_str if code.respond_to? :to_str
86
94
  response.body = body unless body.nil?
87
95
  halt code
88
96
  end
@@ -194,11 +202,42 @@ module Sinatra
194
202
  halt 304 if etags.include?(value) || etags.include?('*')
195
203
  end
196
204
  end
205
+
206
+ ## Sugar for redirect (example: redirect back)
207
+ def back ; request.referer ; end
208
+
197
209
  end
198
210
 
211
+ # Template rendering methods. Each method takes a the name of a template
212
+ # to render as a Symbol and returns a String with the rendered output.
199
213
  module Templates
200
- def render(engine, template, options={})
201
- data = lookup_template(engine, template, options)
214
+ def erb(template, options={})
215
+ require 'erb' unless defined? ::ERB
216
+ render :erb, template, options
217
+ end
218
+
219
+ def haml(template, options={})
220
+ require 'haml' unless defined? ::Haml
221
+ options[:options] ||= self.class.haml if self.class.respond_to? :haml
222
+ render :haml, template, options
223
+ end
224
+
225
+ def sass(template, options={}, &block)
226
+ require 'sass' unless defined? ::Sass
227
+ options[:layout] = false
228
+ render :sass, template, options
229
+ end
230
+
231
+ def builder(template=nil, options={}, &block)
232
+ require 'builder' unless defined? ::Builder
233
+ options, template = template, nil if template.is_a?(Hash)
234
+ template = lambda { block } if template.nil?
235
+ render :builder, template, options
236
+ end
237
+
238
+ private
239
+ def render(engine, template, options={}) #:nodoc:
240
+ data = lookup_template(engine, template, options)
202
241
  output = __send__("render_#{engine}", template, data, options)
203
242
  layout, data = lookup_layout(engine, options)
204
243
  if layout
@@ -229,7 +268,7 @@ module Sinatra
229
268
  return if options[:layout] == false
230
269
  options.delete(:layout) if options[:layout] == true
231
270
  template = options[:layout] || :layout
232
- data = lookup_template(engine, template, options)
271
+ data = lookup_template(engine, template, options)
233
272
  [template, data]
234
273
  rescue Errno::ENOENT
235
274
  nil
@@ -241,11 +280,6 @@ module Sinatra
241
280
  "#{views_dir}/#{template}.#{engine}"
242
281
  end
243
282
 
244
- def erb(template, options={})
245
- require 'erb' unless defined? ::ERB
246
- render :erb, template, options
247
- end
248
-
249
283
  def render_erb(template, data, options, &block)
250
284
  data = data.call if data.kind_of? Proc
251
285
  instance = ::ERB.new(data)
@@ -253,13 +287,6 @@ module Sinatra
253
287
  locals_assigns = locals.to_a.collect { |k,v| "#{k} = locals[:#{k}]" }
254
288
  src = "#{locals_assigns.join("\n")}\n#{instance.src}"
255
289
  eval src, binding, '(__ERB__)', locals_assigns.length + 1
256
- instance.result(binding)
257
- end
258
-
259
- def haml(template, options={})
260
- require 'haml' unless defined? ::Haml
261
- options[:options] ||= self.class.haml if self.class.respond_to? :haml
262
- render :haml, template, options
263
290
  end
264
291
 
265
292
  def render_haml(template, data, options, &block)
@@ -267,24 +294,11 @@ module Sinatra
267
294
  engine.render(self, options[:locals] || {}, &block)
268
295
  end
269
296
 
270
- def sass(template, options={}, &block)
271
- require 'sass' unless defined? ::Sass
272
- options[:layout] = false
273
- render :sass, template, options
274
- end
275
-
276
297
  def render_sass(template, data, options, &block)
277
298
  engine = ::Sass::Engine.new(data, options[:sass] || {})
278
299
  engine.render
279
300
  end
280
301
 
281
- def builder(template=nil, options={}, &block)
282
- require 'builder' unless defined? ::Builder
283
- options, template = template, nil if template.is_a?(Hash)
284
- template = lambda { block } if template.nil?
285
- render :builder, template, options
286
- end
287
-
288
302
  def render_builder(template, data, options, &block)
289
303
  xml = ::Builder::XmlMarkup.new(:indent => 2)
290
304
  if data.respond_to?(:to_str)
@@ -294,9 +308,9 @@ module Sinatra
294
308
  end
295
309
  xml.target!
296
310
  end
297
-
298
311
  end
299
312
 
313
+ # Base class for all Sinatra applications and middleware.
300
314
  class Base
301
315
  include Rack::Utils
302
316
  include Helpers
@@ -309,6 +323,7 @@ module Sinatra
309
323
  yield self if block_given?
310
324
  end
311
325
 
326
+ # Rack call interface.
312
327
  def call(env)
313
328
  dup.call!(env)
314
329
  end
@@ -324,19 +339,24 @@ module Sinatra
324
339
  invoke { dispatch! }
325
340
  invoke { error_block!(response.status) }
326
341
 
342
+ # never respond with a body on HEAD requests
327
343
  @response.body = [] if @env['REQUEST_METHOD'] == 'HEAD'
344
+
328
345
  @response.finish
329
346
  end
330
347
 
348
+ # Access options defined with Base.set.
331
349
  def options
332
350
  self.class
333
351
  end
334
352
 
353
+ # Exit the current block and halt the response.
335
354
  def halt(*response)
336
355
  response = response.first if response.length == 1
337
356
  throw :halt, response
338
357
  end
339
358
 
359
+ # Pass control to the next matching route.
340
360
  def pass
341
361
  throw :pass
342
362
  end
@@ -352,7 +372,7 @@ module Sinatra
352
372
  # routes
353
373
  if routes = self.class.routes[@request.request_method]
354
374
  original_params = @params
355
- path = @request.path_info
375
+ path = @request.path_info
356
376
 
357
377
  routes.each do |pattern, keys, conditions, block|
358
378
  if match = pattern.match(path)
@@ -373,6 +393,7 @@ module Sinatra
373
393
  {}
374
394
  end
375
395
  @params = original_params.merge(params)
396
+ @block_params = values
376
397
 
377
398
  catch(:pass) do
378
399
  conditions.each { |cond|
@@ -421,7 +442,7 @@ module Sinatra
421
442
  headers.each { |k, v| @response.headers[k] = v } if headers
422
443
  elsif res.length == 2
423
444
  @response.status = res.first
424
- @response.body = res.last
445
+ @response.body = res.last
425
446
  else
426
447
  raise TypeError, "#{res.inspect} not supported"
427
448
  end
@@ -441,21 +462,24 @@ module Sinatra
441
462
  def dispatch!
442
463
  route!
443
464
  rescue NotFound => boom
465
+ handle_not_found!(boom)
466
+ rescue ::Exception => boom
467
+ handle_exception!(boom)
468
+ end
469
+
470
+ def handle_not_found!(boom)
444
471
  @env['sinatra.error'] = boom
445
- @response.status = 404
446
- @response.body = ['<h1>Not Found</h1>']
472
+ @response.status = 404
473
+ @response.body = ['<h1>Not Found</h1>']
447
474
  error_block! boom.class, NotFound
475
+ end
448
476
 
449
- rescue ::Exception => boom
477
+ def handle_exception!(boom)
450
478
  @env['sinatra.error'] = boom
451
479
 
452
- if options.dump_errors?
453
- backtrace = clean_backtrace(boom.backtrace)
454
- msg = ["#{boom.class} - #{boom.message}:", *backtrace].join("\n ")
455
- @env['rack.errors'].write(msg)
456
- end
480
+ dump_errors!(boom) if options.dump_errors?
481
+ raise boom if options.raise_errors?
457
482
 
458
- raise boom if options.raise_errors?
459
483
  @response.status = 500
460
484
  error_block! boom.class, Exception
461
485
  end
@@ -472,6 +496,13 @@ module Sinatra
472
496
  nil
473
497
  end
474
498
 
499
+ def dump_errors!(boom)
500
+ backtrace = clean_backtrace(boom.backtrace)
501
+ msg = ["#{boom.class} - #{boom.message}:",
502
+ *backtrace].join("\n ")
503
+ @env['rack.errors'].write(msg)
504
+ end
505
+
475
506
  def clean_backtrace(trace)
476
507
  return trace unless options.clean_trace?
477
508
 
@@ -493,13 +524,14 @@ module Sinatra
493
524
  attr_accessor :routes, :filters, :conditions, :templates,
494
525
  :middleware, :errors
495
526
 
527
+ public
496
528
  def set(option, value=self)
497
529
  if value.kind_of?(Proc)
498
530
  metadef(option, &value)
499
531
  metadef("#{option}?") { !!__send__(option) }
500
532
  metadef("#{option}=") { |val| set(option, Proc.new{val}) }
501
533
  elsif value == self && option.respond_to?(:to_hash)
502
- option.to_hash.each(&method(:set))
534
+ option.to_hash.each { |k,v| set(k, v) }
503
535
  elsif respond_to?("#{option}=")
504
536
  __send__ "#{option}=", value
505
537
  else
@@ -537,14 +569,10 @@ module Sinatra
537
569
  end
538
570
 
539
571
  def use_in_file_templates!
540
- line = caller.detect do |s|
541
- [
542
- /lib\/sinatra.*\.rb/,
543
- /\(.*\)/,
544
- /rubygems\/custom_require\.rb/
545
- ].all? { |x| s !~ x }
546
- end
547
- file = line.sub(/:\d+.*$/, '')
572
+ ignore = [/lib\/sinatra.*\.rb/, /\(.*\)/, /rubygems\/custom_require\.rb/]
573
+ file = caller.
574
+ map { |line| line.sub(/:\d+.*$/, '') }.
575
+ find { |line| ignore.all? { |pattern| line !~ pattern } }
548
576
  if data = ::IO.read(file).split('__END__')[1]
549
577
  data.gsub!(/\r\n/, "\n")
550
578
  template = nil
@@ -573,6 +601,7 @@ module Sinatra
573
601
  @conditions << block
574
602
  end
575
603
 
604
+ private
576
605
  def host_name(pattern)
577
606
  condition { pattern === request.host }
578
607
  end
@@ -603,6 +632,7 @@ module Sinatra
603
632
  }
604
633
  end
605
634
 
635
+ public
606
636
  def get(path, opts={}, &block)
607
637
  conditions = @conditions.dup
608
638
  route('GET', path, opts, &block)
@@ -627,7 +657,12 @@ module Sinatra
627
657
 
628
658
  define_method "#{verb} #{path}", &block
629
659
  unbound_method = instance_method("#{verb} #{path}")
630
- block = lambda { unbound_method.bind(self).call }
660
+ block =
661
+ if block.arity != 0
662
+ lambda { unbound_method.bind(self).call(*@block_params) }
663
+ else
664
+ lambda { unbound_method.bind(self).call }
665
+ end
631
666
 
632
667
  (routes[verb] ||= []).
633
668
  push([pattern, keys, conditions, block]).last
@@ -659,11 +694,22 @@ module Sinatra
659
694
  end
660
695
 
661
696
  public
697
+ def helpers(*extensions, &block)
698
+ class_eval(&block) if block_given?
699
+ include *extensions
700
+ end
701
+
702
+ def register(*extensions, &block)
703
+ extensions << Module.new(&block) if block
704
+ extend *extensions
705
+ end
706
+
662
707
  def development? ; environment == :development ; end
663
708
  def test? ; environment == :test ; end
664
709
  def production? ; environment == :production ; end
665
710
 
666
711
  def configure(*envs, &block)
712
+ return if reloading?
667
713
  yield if envs.empty? || envs.include?(environment.to_sym)
668
714
  end
669
715
 
@@ -674,7 +720,7 @@ module Sinatra
674
720
 
675
721
  def run!(options={})
676
722
  set options
677
- handler = detect_rack_handler
723
+ handler = detect_rack_handler
678
724
  handler_name = handler.name.gsub(/.*::/, '')
679
725
  puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
680
726
  "on #{port} for #{environment} with backup from #{handler_name}"
@@ -690,8 +736,19 @@ module Sinatra
690
736
  end
691
737
 
692
738
  def call(env)
693
- construct_middleware if @callsite.nil?
694
- @callsite.call(env)
739
+ synchronize do
740
+ reload! if reload?
741
+ construct_middleware if @callsite.nil?
742
+ @callsite.call(env)
743
+ end
744
+ end
745
+
746
+ def reload!
747
+ @reloading = true
748
+ superclass.send :reset!, self
749
+ $LOADED_FEATURES.delete("sinatra.rb")
750
+ ::Kernel.load app_file
751
+ @reloading = false
695
752
  end
696
753
 
697
754
  private
@@ -720,17 +777,34 @@ module Sinatra
720
777
  @callsite = nil
721
778
  end
722
779
 
723
- def inherited(subclass)
724
- subclass.routes = dupe_routes
725
- subclass.templates = templates.dup
780
+ def reset!(subclass = self)
781
+ subclass.routes = dupe_routes
782
+ subclass.templates = templates.dup
726
783
  subclass.conditions = []
727
- subclass.filters = filters.dup
728
- subclass.errors = errors.dup
784
+ subclass.filters = filters.dup
785
+ subclass.errors = errors.dup
729
786
  subclass.middleware = middleware.dup
730
787
  subclass.send :reset_middleware
788
+ end
789
+
790
+ def inherited(subclass)
791
+ reset!(subclass)
731
792
  super
732
793
  end
733
794
 
795
+ def reloading?
796
+ @reloading ||= false
797
+ end
798
+
799
+ @@mutex = Mutex.new
800
+ def synchronize(&block)
801
+ if lock?
802
+ @@mutex.synchronize(&block)
803
+ else
804
+ yield
805
+ end
806
+ end
807
+
734
808
  def dupe_routes
735
809
  routes.inject({}) do |hash,(request_method,routes)|
736
810
  hash[request_method] = routes.dup
@@ -762,6 +836,8 @@ module Sinatra
762
836
  set :root, Proc.new { app_file && File.expand_path(File.dirname(app_file)) }
763
837
  set :views, Proc.new { root && File.join(root, 'views') }
764
838
  set :public, Proc.new { root && File.join(root, 'public') }
839
+ set :reload, Proc.new { app_file? && app_file !~ /\.ru$/i && development? }
840
+ set :lock, Proc.new { reload? }
765
841
 
766
842
  # static files route
767
843
  get(/.*[^\/]$/) do
@@ -838,6 +914,7 @@ module Sinatra
838
914
  end
839
915
  end
840
916
 
917
+ # Base class for classic style (top-level) applications.
841
918
  class Default < Base
842
919
  set :raise_errors, false
843
920
  set :dump_errors, true
@@ -846,61 +923,35 @@ module Sinatra
846
923
  set :methodoverride, true
847
924
  set :static, true
848
925
  set :run, false
849
- set :reload, Proc.new { app_file? && app_file !~ /\.ru$/i && development? }
850
- set :lock, Proc.new { reload? }
851
926
 
852
- def self.reloading?
853
- @reloading ||= false
854
- end
855
-
856
- def self.configure(*envs)
857
- super unless reloading?
858
- end
859
-
860
- def self.call(env)
861
- synchronize do
862
- reload! if reload?
863
- super
864
- end
865
- end
866
-
867
- def self.reload!
868
- @reloading = true
869
- superclass.send :inherited, self
870
- $LOADED_FEATURES.delete("sinatra.rb")
871
- ::Kernel.load app_file
872
- @reloading = false
873
- end
874
-
875
- private
876
- @@mutex = Mutex.new
877
- def self.synchronize(&block)
878
- if lock?
879
- @@mutex.synchronize(&block)
880
- else
881
- yield
882
- end
927
+ def self.register(*extensions, &block) #:nodoc:
928
+ added_methods = extensions.map {|m| m.public_instance_methods }.flatten
929
+ Delegator.delegate *added_methods
930
+ super(*extensions, &block)
883
931
  end
884
932
  end
885
933
 
934
+ # The top-level Application. All DSL methods executed on main are delegated
935
+ # to this class.
886
936
  class Application < Default
887
937
  end
888
938
 
889
- module Delegator
890
- METHODS = %w[
891
- get put post delete head template layout before error not_found
892
- configures configure set set_option set_options enable disable use
893
- development? test? production? use_in_file_templates!
894
- ]
895
-
896
- METHODS.each do |method_name|
897
- eval <<-RUBY, binding, '(__DELEGATE__)', 1
898
- def #{method_name}(*args, &b)
899
- ::Sinatra::Application.#{method_name}(*args, &b)
900
- end
901
- private :#{method_name}
902
- RUBY
939
+ module Delegator #:nodoc:
940
+ def self.delegate(*methods)
941
+ methods.each do |method_name|
942
+ eval <<-RUBY, binding, '(__DELEGATE__)', 1
943
+ def #{method_name}(*args, &b)
944
+ ::Sinatra::Application.#{method_name}(*args, &b)
945
+ end
946
+ private :#{method_name}
947
+ RUBY
948
+ end
903
949
  end
950
+
951
+ delegate :get, :put, :post, :delete, :head, :template, :layout, :before,
952
+ :error, :not_found, :configures, :configure, :set, :set_option,
953
+ :set_options, :enable, :disable, :use, :development?, :test?,
954
+ :production?, :use_in_file_templates!, :helpers
904
955
  end
905
956
 
906
957
  def self.new(base=Base, options={}, &block)
@@ -908,4 +959,47 @@ module Sinatra
908
959
  base.send :class_eval, &block if block_given?
909
960
  base
910
961
  end
962
+
963
+ # Extend the top-level DSL with the modules provided.
964
+ def self.register(*extensions, &block)
965
+ Default.register(*extensions, &block)
966
+ end
967
+
968
+ # Include the helper modules provided in Sinatra's request context.
969
+ def self.helpers(*extensions, &block)
970
+ Default.helpers(*extensions, &block)
971
+ end
972
+ end
973
+
974
+ class String #:nodoc:
975
+ # Define String#each under 1.9 for Rack compatibility. This should be
976
+ # removed once Rack is fully 1.9 compatible.
977
+ alias_method :each, :each_line unless ''.respond_to? :each
978
+
979
+ # Define String#bytesize as an alias to String#length for Ruby 1.8.6 and
980
+ # earlier.
981
+ alias_method :bytesize, :length unless ''.respond_to? :bytesize
982
+ end
983
+
984
+ class Rack::Builder
985
+ ## Sugar to include a classic style app in a rackup.
986
+ ##
987
+ ## This will eval the source into a Sinatra::Default class
988
+ ## Example:
989
+ ##
990
+ ## require 'sinatra/base'
991
+ ##
992
+ ## map '/foo' do
993
+ ## run Sinatra("foo.rb")
994
+ ## end
995
+ ##
996
+ ## run Sinatra("bar.rb")
997
+ ##
998
+ def Sinatra(file, base=Sinatra::Default)
999
+ Sinatra.new(base) do
1000
+ expanded = File.expand_path(file)
1001
+ self.class_eval { set :app_file, expanded }
1002
+ self.class_eval(File.read(expanded), expanded)
1003
+ end
1004
+ end
911
1005
  end