roda-cj 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 00b2172bd61961f3176d6c3b058c2f01b67366c3
4
- data.tar.gz: 0892c32cefa17382cea92d15ac5520f5a0342939
3
+ metadata.gz: 2f2740123aa0c6fafe4c1665f9c83e408cef9105
4
+ data.tar.gz: 74ec8c03a23405c2ac18eb23ceea5ccb3f4813c1
5
5
  SHA512:
6
- metadata.gz: ac35c86664a528718846cfde26d78cdd33c41238b53b06cf73775fd7e86afd257a1ca36b7b6c57efa0460f53f95e0d2da49d5a0a7e5b457a5e696b6c15313ca5
7
- data.tar.gz: 1546b8958db7fb24ec76483259686d90b65908a29a321795a7717c16dccc371f172bd9c8ac9b5dc8ad88fb97758fedc0d14e95d99bc451d2679b2b3b553b95af
6
+ metadata.gz: 876514335f729d2beeea7b218bc14d7cac1772f5b568a4a985457b01321c16ef33116bb3dd605e218d3512185d34dffaca426b9e803d0e860c56619eb2838359
7
+ data.tar.gz: d046733fe6737ccabc612523c7812b1be778cea3675223a1a5bc3c202a91fad2da26e2fac842789542368fcb95e0b8d201cff9235de3410c3e1e5e414314f1f0
data/CHANGELOG CHANGED
@@ -1,5 +1,7 @@
1
1
  = HEAD
2
2
 
3
+ * Optimize matching by caching consume regexp for strings, regexp, symbol, and :extension matchers (jeremyevans)
4
+
3
5
  * Add r.root for matching root (path "/"), for easier to read version of r.is "" (jeremyevans)
4
6
 
5
7
  * Optimize r.is terminal matcher, remove :term hash matcher (jeremyevans)
@@ -22,19 +22,19 @@ class Roda
22
22
  # Or set the response body and return:
23
23
  #
24
24
  # route do |r|
25
- # r.halt("body')
25
+ # r.halt('body')
26
26
  # end
27
27
  #
28
28
  # Or set both:
29
29
  #
30
30
  # route do |r|
31
- # r.halt(403, "body')
31
+ # r.halt(403, 'body')
32
32
  # end
33
33
  #
34
34
  # Or set response status, headers, and body:
35
35
  #
36
36
  # route do |r|
37
- # r.halt(403, {'Content-Type'=>'text/csv'}, "body')
37
+ # r.halt(403, {'Content-Type'=>'text/csv'}, 'body')
38
38
  # end
39
39
  #
40
40
  # Note that there is a difference between provide status, headers, and body as separate
data/lib/roda/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Roda
2
- RodaVersion = '0.9.1'.freeze
2
+ RodaVersion = '0.9.2'.freeze
3
3
  end
data/lib/roda.rb CHANGED
@@ -14,6 +14,43 @@ class Roda
14
14
  # only contains the class methods.
15
15
  class RodaRequest < ::Rack::Request;
16
16
  @roda_class = ::Roda
17
+ @match_pattern_cache = {}
18
+
19
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE != 'ruby'
20
+ # :nocov:
21
+ @match_pattern_mutex = Mutex.new
22
+
23
+ def self.cached_matcher(obj)
24
+ unless pattern = @match_pattern_mutex.synchronize{@match_pattern_cache[obj]}
25
+ pattern = consume_pattern(yield)
26
+ @match_pattern_mutex.synchronize{@match_pattern_cache[obj] = pattern}
27
+ end
28
+ pattern
29
+ end
30
+
31
+ def self.inherited(subclass)
32
+ super
33
+ subclass.instance_variable_set(:@match_pattern_cache, {})
34
+ subclass.instance_variable_set(:@match_pattern_mutex, Mutex.new)
35
+ end
36
+ # :nocov:
37
+ else
38
+ # Return the cached pattern for the given object. If the object is
39
+ # not already cached, yield to get the basic pattern, and convert the
40
+ # basic pattern to a pattern that does not partial segments.
41
+ def self.cached_matcher(obj)
42
+ unless pattern = @match_pattern_cache[obj]
43
+ pattern = @match_pattern_cache[obj] = consume_pattern(yield)
44
+ end
45
+ pattern
46
+ end
47
+
48
+ # Initialize the match_pattern cache in the subclass.
49
+ def self.inherited(subclass)
50
+ super
51
+ subclass.instance_variable_set(:@match_pattern_cache, {})
52
+ end
53
+ end
17
54
 
18
55
  class << self
19
56
  # Reference to the Roda class related to this request class.
@@ -25,6 +62,15 @@ class Roda
25
62
  def inspect
26
63
  "#{roda_class.inspect}::RodaRequest"
27
64
  end
65
+
66
+ private
67
+
68
+ # The pattern to use for consuming, based on the given argument. The returned
69
+ # pattern requires the path starts with a string and does not match partial
70
+ # segments.
71
+ def consume_pattern(pattern)
72
+ /\A(\/(?:#{pattern}))(\/|\z)/
73
+ end
28
74
  end
29
75
  end
30
76
 
@@ -390,12 +436,49 @@ class Roda
390
436
  throw :halt, response
391
437
  end
392
438
 
439
+ # Match any of the elements in the given array. Return at the
440
+ # first match without evaluating future matches. Returns false
441
+ # if no elements in the array match.
442
+ def _match_array(matcher)
443
+ matcher.any? do |m|
444
+ if matched = match(m)
445
+ if m.is_a?(String)
446
+ captures.push(m)
447
+ end
448
+ end
449
+
450
+ matched
451
+ end
452
+ end
453
+
454
+ # Match the given regexp exactly if it matches a full segment.
455
+ def _match_regexp(re)
456
+ consume(self.class.cached_matcher(re){re})
457
+ end
458
+
459
+ # Match the given hash if all hash matchers match.
460
+ def _match_hash(hash)
461
+ hash.all?{|k,v| send("match_#{k}", v)}
462
+ end
463
+
464
+ # Match the given string to the request path. Regexp escapes the
465
+ # string so that regexp metacharacters are not matched, and recognizes
466
+ # colon tokens for placeholders.
467
+ def _match_string(str)
468
+ consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:\w+/, SEGMENT)})
469
+ end
470
+
471
+ # Match the given symbol if any segment matches.
472
+ def _match_symbol(sym)
473
+ consume(self.class.cached_matcher(sym){SEGMENT})
474
+ end
475
+
393
476
  # Attempts to match the pattern to the current path. If there is no
394
477
  # match, returns false without changes. Otherwise, modifies
395
478
  # SCRIPT_NAME to include the matched path, removes the matched
396
479
  # path from PATH_INFO, and updates captures with any regex captures.
397
480
  def consume(pattern)
398
- matchdata = env[PATH_INFO].match(/\A(\/(?:#{pattern}))(\/|\z)/)
481
+ matchdata = env[PATH_INFO].match(pattern)
399
482
 
400
483
  return false unless matchdata
401
484
 
@@ -423,17 +506,17 @@ class Roda
423
506
  def match(matcher)
424
507
  case matcher
425
508
  when String
426
- match_string(matcher)
509
+ _match_string(matcher)
427
510
  when Regexp
428
- consume(matcher)
511
+ _match_regexp(matcher)
429
512
  when Symbol
430
- consume(SEGMENT)
513
+ _match_symbol(matcher)
431
514
  when TERM
432
515
  env[PATH_INFO] == EMPTY_STRING
433
516
  when Hash
434
- matcher.all?{|k,v| send("match_#{k}", v)}
517
+ _match_hash(matcher)
435
518
  when Array
436
- match_array(matcher)
519
+ _match_array(matcher)
437
520
  when Proc
438
521
  matcher.call
439
522
  else
@@ -441,25 +524,10 @@ class Roda
441
524
  end
442
525
  end
443
526
 
444
- # Match any of the elements in the given array. Return at the
445
- # first match without evaluating future matches. Returns false
446
- # if no elements in the array match.
447
- def match_array(matcher)
448
- matcher.any? do |m|
449
- if matched = match(m)
450
- if m.is_a?(String)
451
- captures.push(m)
452
- end
453
- end
454
-
455
- matched
456
- end
457
- end
458
-
459
527
  # Match files with the given extension. Requires that the
460
528
  # request path end with the extension.
461
529
  def match_extension(ext)
462
- consume("([^\\/]+?)\.#{ext}\\z")
530
+ consume(self.class.cached_matcher(ext){"([^\\/]+?)\.#{ext}\\z"})
463
531
  end
464
532
 
465
533
  # Match by request method. This can be an array if you want
@@ -488,15 +556,6 @@ class Roda
488
556
  end
489
557
  end
490
558
 
491
- # Match the given string to the request path. Regexp escapes the
492
- # string so that regexp metacharacters are not matched, and recognizes
493
- # colon tokens for placeholders.
494
- def match_string(str)
495
- str = Regexp.escape(str)
496
- str.gsub!(/:\w+/, SEGMENT)
497
- consume(str)
498
- end
499
-
500
559
  # Yield to the given block, clearing any captures before
501
560
  # yielding and restoring the SCRIPT_NAME and PATH_INFO on exit.
502
561
  def try
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda-cj
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-10 00:00:00.000000000 Z
11
+ date: 2014-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack