Permalink
Browse files

Fix compatibility with Ruby 1.9.3 and 2.0.0

The named arguments syntax used for the Rails 5 `digest` method is only
valid on Ruby 2.1 or higher (or 2.0.0 if default values are supplied),
causing an error parsing the lib/rabl/digestor.rb source on these
older versions.

    SyntaxError: rabl-0.13.0/lib/rabl/digestor.rb:6: syntax error, unexpected ','
          def self.digest(name:, finder:, **options)

The support for different Rails versions has been moved into separate
files that can be loaded only when required.
1 parent 7b23258 commit 130d422a4018af7102564412d6e20a31666c772e @domcleal domcleal committed Jul 15, 2016
Showing with 55 additions and 39 deletions.
  1. +1 −1 .travis.yml
  2. +2 −1 Gemfile
  3. +3 −37 lib/rabl/digestor.rb
  4. +10 −0 lib/rabl/digestor/rails3.rb
  5. +10 −0 lib/rabl/digestor/rails41.rb
  6. +29 −0 lib/rabl/digestor/rails5.rb
View
@@ -5,7 +5,7 @@ rvm:
- 1.9.3
- 2.0.0
- 2.1
- - 2.2
+ - 2.2.5
- 2.3.1
notifications:
recipients:
View
@@ -14,9 +14,10 @@ group :test do
# RABL TEST
gem 'builder'
+ rails_version = RUBY_VERSION =~ /\A(1|2.[01])/ ? '~> 4.0' : '>= 4.0'
# FIXTURES
gem 'rack-test', :require => 'rack/test'
- gem 'activerecord', :require => 'active_record'
+ gem 'activerecord', rails_version, :require => 'active_record'
gem 'sqlite3'
gem 'sinatra', '>= 1.2.0'
gem 'hashie'
View
@@ -3,45 +3,11 @@ class Digestor < ActionView::Digestor
# Override the original digest function to ignore partial which
# rabl doesn't use the Rails conventional _ symbol.
if Gem::Version.new(Rails.version) >= Gem::Version.new('5.0.0.beta1')
- def self.digest(name:, finder:, **options)
-
- options.assert_valid_keys(:dependencies, :partial)
-
- cache_key = ([ name ].compact + Array.wrap(options[:dependencies])).join('.')
-
- # this is a correctly done double-checked locking idiom
- # (Concurrent::Map's lookups have volatile semantics)
- finder.digest_cache[cache_key] || @@digest_monitor.synchronize do
- finder.digest_cache.fetch(cache_key) do # re-check under lock
- begin
- # Prevent re-entry or else recursive templates will blow the stack.
- # There is no need to worry about other threads seeing the +false+ value,
- # as they will then have to wait for this thread to let go of the @@digest_monitor lock.
-
- pre_stored = finder.digest_cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion
-
- finder.digest_cache[cache_key] = stored_digest = Digestor.new(name, finder, options).digest
- ensure
- # something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache
- finder.digest_cache.delete_pair(cache_key, false) if pre_stored && !stored_digest
- end
- end
- end
- end
+ require 'rabl/digestor/rails5'
elsif Gem::Version.new(Rails.version) >= Gem::Version.new('4.1')
- def self.digest(options = {})
- cache_key = [options[:name]] + Array.wrap(options[:dependencies])
- @@cache[cache_key.join('.')] ||= begin
- Digestor.new({ :name => options[:name], :finder => options[:finder] }.merge!(options)).digest
- end
- end
+ require 'rabl/digestor/rails41'
else
- def self.digest(name, format, finder, options = {})
- cache_key = [name, format] + Array.wrap(options[:dependencies])
- @@cache[cache_key.join('.')] ||= begin
- Digestor.new(name, format, finder, options).digest
- end
- end
+ require 'rabl/digestor/rails3'
end
private
@@ -0,0 +1,10 @@
+module Rabl
+ class Digestor < ActionView::Digestor
+ def self.digest(name, format, finder, options = {})
+ cache_key = [name, format] + Array.wrap(options[:dependencies])
+ @@cache[cache_key.join('.')] ||= begin
+ Digestor.new(name, format, finder, options).digest
+ end
+ end
+ end
+end
@@ -0,0 +1,10 @@
+module Rabl
+ class Digestor < ActionView::Digestor
+ def self.digest(options = {})
+ cache_key = [options[:name]] + Array.wrap(options[:dependencies])
+ @@cache[cache_key.join('.')] ||= begin
+ Digestor.new({ :name => options[:name], :finder => options[:finder] }.merge!(options)).digest
+ end
+ end
+ end
+end
@@ -0,0 +1,29 @@
+module Rabl
+ class Digestor < ActionView::Digestor
+ def self.digest(name:, finder:, **options)
+
+ options.assert_valid_keys(:dependencies, :partial)
+
+ cache_key = ([ name ].compact + Array.wrap(options[:dependencies])).join('.')
+
+ # this is a correctly done double-checked locking idiom
+ # (Concurrent::Map's lookups have volatile semantics)
+ finder.digest_cache[cache_key] || @@digest_monitor.synchronize do
+ finder.digest_cache.fetch(cache_key) do # re-check under lock
+ begin
+ # Prevent re-entry or else recursive templates will blow the stack.
+ # There is no need to worry about other threads seeing the +false+ value,
+ # as they will then have to wait for this thread to let go of the @@digest_monitor lock.
+
+ pre_stored = finder.digest_cache.put_if_absent(cache_key, false).nil? # put_if_absent returns nil on insertion
+
+ finder.digest_cache[cache_key] = stored_digest = Digestor.new(name, finder, options).digest
+ ensure
+ # something went wrong or ActionView::Resolver.caching? is false, make sure not to corrupt the @@cache
+ finder.digest_cache.delete_pair(cache_key, false) if pre_stored && !stored_digest
+ end
+ end
+ end
+ end
+ end
+end

0 comments on commit 130d422

Please sign in to comment.