Freeze strings in array constants and begin moving

from using global constants to frozen strings (cc @avit).

It's not pretty, but it's faster and better for understanding the code
without having to look up what the special constants represent.

From the discussion in #530:

"Things are evolving, but with Ruby 2.2 here is my current
understanding:

- I believe you are correct that the strings inside the array could
benefit from freezing, in hot spots.

- Freezing a string may now be faster than looking up a frozen string
constant.

So, it might make sense now in Ransack master and upcoming releases, to
optimize for Ruby 2.2+ and stop using frozen constants, and replace
them with frozen strings or symbols."

Closes #530.
This commit is contained in:
Jon Atack 2015-08-29 22:52:57 +02:00
parent 5686c5ce8a
commit 381a83cebe
11 changed files with 57 additions and 67 deletions

View File

@ -138,16 +138,16 @@ module Arel
"#{
o.name
}(#{
o.distinct ? Ransack::Constants::DISTINCT : Ransack::Constants::EMPTY
o.distinct ? Ransack::Constants::DISTINCT : ''.freeze
}#{
o.expressions.map { |x| visit x }.join(Ransack::Constants::COMMA_SPACE)
o.expressions.map { |x| visit x }.join(', '.freeze)
})#{
o.alias ? " AS #{visit o.alias}" : Ransack::Constants::EMPTY
o.alias ? " AS #{visit o.alias}" : ''.freeze
}"
end
def visit_Arel_Nodes_And o
o.children.map { |x| visit x }.join(Ransack::Constants::SPACED_AND)
o.children.map { |x| visit x }.join(' AND '.freeze)
end
def visit_Arel_Nodes_Not o
@ -164,7 +164,7 @@ module Arel
quote(value, attr && column_for(attr))
end
}
.join(Ransack::Constants::COMMA_SPACE)
.join(', '.freeze)
})"
end
end

View File

@ -1,19 +1,10 @@
module Ransack
module Constants
ASC = 'asc'.freeze
DESC = 'desc'.freeze
ASC_DESC = [ASC, DESC].freeze
ASC_ARROW = '▲'.freeze
DESC_ARROW = '▼'.freeze
OR = 'or'.freeze
AND = 'and'.freeze
SPACED_AND = ' AND '.freeze
SORT = 'sort'.freeze
SORT_LINK = 'sort_link'.freeze
SORT_DIRECTION = 'sort_direction'.freeze
CAP_SEARCH = 'Search'.freeze
SEARCH = 'search'.freeze
@ -23,17 +14,12 @@ module Ransack
ATTRIBUTES = 'attributes'.freeze
COMBINATOR = 'combinator'.freeze
SPACE = ' '.freeze
COMMA_SPACE = ', '.freeze
COLON_SPACE = ': '.freeze
TWO_COLONS = '::'.freeze
UNDERSCORE = '_'.freeze
LEFT_PARENTHESIS = '('.freeze
Q = 'q'.freeze
I = 'i'.freeze
NON_BREAKING_SPACE = ' '.freeze
DOT_ASTERIX = '.*'.freeze
EMPTY = ''.freeze
STRING_JOIN = 'string_join'.freeze
ASSOCIATION_JOIN = 'association_join'.freeze
@ -44,14 +30,17 @@ module Ransack
FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
BOOLEAN_VALUES = (TRUE_VALUES + FALSE_VALUES).freeze
S_SORTS = %w(s sorts).freeze
AND_OR = %w(and or).freeze
IN_NOT_IN = %w(in not_in).freeze
SUFFIXES = %w(_any _all).freeze
AREL_PREDICATES = %w(
eq not_eq matches does_not_match lt lteq gt gteq in not_in
).freeze
A_S_I = %w(a s i).freeze
AND_OR = ['and'.freeze, 'or'.freeze].freeze
IN_NOT_IN = ['in'.freeze, 'not_in'.freeze].freeze
SUFFIXES = ['_any'.freeze, '_all'.freeze].freeze
AREL_PREDICATES = [
'eq'.freeze, 'not_eq'.freeze,
'matches'.freeze, 'does_not_match'.freeze,
'lt'.freeze, 'lteq'.freeze,
'gt'.freeze, 'gteq'.freeze,
'in'.freeze, 'not_in'.freeze
].freeze
A_S_I = ['a'.freeze, 's'.freeze, 'i'.freeze].freeze
EQ = 'eq'.freeze
NOT_EQ = 'not_eq'.freeze

View File

@ -17,9 +17,12 @@ module Ransack
end
def for(object, options = {})
context = Class === object ?
for_class(object, options) :
for_object(object, options)
context =
if Class === object
for_class(object, options)
else
for_object(object, options)
end
context or raise ArgumentError,
"Don't know what context to use for #{object}"
end
@ -59,7 +62,7 @@ module Ransack
end
def traverse(str, base = @base)
str ||= Constants::EMPTY
str ||= ''.freeze
if (segments = str.split(/_/)).size > 0
remainder = []
@ -68,13 +71,12 @@ module Ransack
# Strip the _of_Model_type text from the association name, but hold
# onto it in klass, for use as the next base
assoc, klass = unpolymorphize_association(
segments.join(Constants::UNDERSCORE)
segments.join('_'.freeze)
)
if found_assoc = get_association(assoc, base)
base = traverse(
remainder.join(
Constants::UNDERSCORE), klass || found_assoc.klass
)
remainder.join('_'.freeze), klass || found_assoc.klass
)
end
remainder.unshift segments.pop
@ -88,7 +90,7 @@ module Ransack
def association_path(str, base = @base)
base = klassify(base)
str ||= Constants::EMPTY
str ||= ''.freeze
path = []
segments = str.split(/_/)
association_parts = []
@ -131,15 +133,15 @@ module Ransack
klass.ransackable_scopes(auth_object).any? { |s| s.to_s == str }
end
def searchable_attributes(str = Constants::EMPTY)
def searchable_attributes(str = ''.freeze)
traverse(str).ransackable_attributes(auth_object)
end
def sortable_attributes(str = Constants::EMPTY)
def sortable_attributes(str = ''.freeze)
traverse(str).ransortable_attributes(auth_object)
end
def searchable_associations(str = Constants::EMPTY)
def searchable_associations(str = ''.freeze)
traverse(str).ransackable_associations(auth_object)
end
end

View File

@ -15,8 +15,7 @@ end
RANSACK_FORM_BUILDER = 'RANSACK_FORM_BUILDER'.freeze
require 'simple_form' if
(ENV[RANSACK_FORM_BUILDER] || Ransack::Constants::EMPTY)
.match('SimpleForm'.freeze)
(ENV[RANSACK_FORM_BUILDER] || ''.freeze).match('SimpleForm'.freeze)
module Ransack
module Helpers
@ -47,7 +46,7 @@ module Ransack
raise ArgumentError, formbuilder_error_message(
"#{action}_select") unless object.respond_to?(:context)
options[:include_blank] = true unless options.has_key?(:include_blank)
bases = [Constants::EMPTY] + association_array(options[:associations])
bases = [''.freeze].freeze + association_array(options[:associations])
if bases.size > 1
collection = attribute_collection_for_bases(action, bases)
object.name ||= default if can_use_default?(
@ -66,13 +65,13 @@ module Ransack
def sort_direction_select(options = {}, html_options = {})
unless object.respond_to?(:context)
raise ArgumentError,
formbuilder_error_message(Constants::SORT_DIRECTION)
formbuilder_error_message('sort_direction'.freeze)
end
template_collection_select(:dir, sort_array, options, html_options)
end
def sort_select(options = {}, html_options = {})
attribute_select(options, html_options, Constants::SORT) +
attribute_select(options, html_options, 'sort'.freeze) +
sort_direction_select(options, html_options)
end
@ -135,7 +134,7 @@ module Ransack
else
only = Array.wrap(only).map(&:to_s)
keys = keys.select {
|k| only.include? k.sub(/_(any|all)$/, Constants::EMPTY)
|k| only.include? k.sub(/_(any|all)$/, ''.freeze)
}
end
end

View File

@ -93,7 +93,7 @@ module Ransack
def name
[ERB::Util.h(@label_text), order_indicator]
.compact
.join(Constants::NON_BREAKING_SPACE)
.join(' '.freeze)
.html_safe
end
@ -106,8 +106,8 @@ module Ransack
def html_options(args)
html_options = extract_options_and_mutate_args!(args)
html_options.merge(
class: [[Constants::SORT_LINK, @current_dir], html_options[:class]]
.compact.join(Constants::SPACE)
class: [['sort_link'.freeze, @current_dir], html_options[:class]]
.compact.join(' '.freeze)
)
end
@ -159,7 +159,7 @@ module Ransack
if sort_dir = existing_sort_direction(attr_name)
direction_text(sort_dir)
else
default_sort_order(attr_name) || Constants::ASC
default_sort_order(attr_name) || 'asc'.freeze
end
end
@ -179,17 +179,17 @@ module Ransack
end
def no_sort_direction_specified?(dir = @current_dir)
!Constants::ASC_DESC.include?(dir)
!['asc'.freeze, 'desc'.freeze].freeze.include?(dir)
end
def direction_arrow
return Constants::DESC_ARROW if @current_dir == Constants::DESC
return Constants::DESC_ARROW if @current_dir == 'desc'.freeze
Constants::ASC_ARROW
end
def direction_text(dir)
return Constants::ASC if dir == Constants::DESC
Constants::DESC
return 'asc'.freeze if dir == 'desc'.freeze
'desc'.freeze
end
end
end

View File

@ -224,7 +224,7 @@ module Ransack
]
.reject { |e| e[1].blank? }
.map { |v| "#{v[0]}: #{v[1]}" }
.join(Constants::COMMA_SPACE)
.join(', '.freeze)
"Condition <#{data}>"
end

View File

@ -68,7 +68,7 @@ module Ransack
def respond_to?(method_id)
super or begin
method_name = method_id.to_s
writer = method_name.sub!(/\=$/, Constants::EMPTY)
writer = method_name.sub!(/\=$/, ''.freeze)
attribute_method?(method_name) ? true : false
end
end
@ -114,7 +114,7 @@ module Ransack
def method_missing(method_id, *args)
method_name = method_id.to_s
writer = method_name.sub!(/\=$/, Constants::EMPTY)
writer = method_name.sub!(/\=$/, ''.freeze)
if attribute_method?(method_name)
if writer
write_attribute(method_name, *args)
@ -169,7 +169,7 @@ module Ransack
]
.reject { |e| e[1].blank? }
.map { |v| "#{v[0]}: #{v[1]}" }
.join(Constants::COMMA_SPACE)
.join(', '.freeze)
"Grouping <#{data}>"
end

View File

@ -38,10 +38,10 @@ module Ransack
def dir=(dir)
dir = dir.downcase if dir
@dir =
if Constants::ASC_DESC.include?(dir)
if ['asc'.freeze, 'desc'.freeze].freeze.include?(dir)
dir
else
Constants::ASC
'asc'.freeze
end
end

View File

@ -10,7 +10,7 @@ module Ransack
end
def names_by_decreasing_length
names.sort { |a,b| b.length <=> a.length }
names.sort { |a, b| b.length <=> a.length }
end
def named(name)
@ -19,7 +19,7 @@ module Ransack
def detect_and_strip_from_string!(str)
if p = detect_from_string(str)
str.sub! /_#{p}$/, Constants::EMPTY
str.sub! /_#{p}$/, ''.freeze
p
end
end

View File

@ -37,7 +37,7 @@ module Ransack
def build(params)
collapse_multiparameter_attributes!(params).each do |key, value|
if Constants::S_SORTS.include?(key)
if ['s'.freeze, 'sorts'.freeze].freeze.include?(key)
send("#{key}=", value)
elsif base.attribute_method?(key)
base.send("#{key}=", value)
@ -92,7 +92,7 @@ module Ransack
def method_missing(method_id, *args)
method_name = method_id.to_s
getter_name = method_name.sub(/=$/, Constants::EMPTY)
getter_name = method_name.sub(/=$/, ''.freeze)
if base.attribute_method?(getter_name)
base.send(method_id, *args)
elsif @context.ransackable_scope?(getter_name, @context.object)
@ -113,8 +113,8 @@ module Ransack
[:base, base.inspect]
]
.compact
.map { |d| d.join(Constants::COLON_SPACE) }
.join(Constants::COMMA_SPACE)
.map { |d| d.join(': '.freeze) }
.join(', '.freeze)
"Ransack::Search<#{details}>"
end

View File

@ -25,7 +25,7 @@ module Ransack
|x| x.respond_to?(:model_name)
}
predicate = Predicate.detect_from_string(original_name)
attributes_str = original_name.sub(/_#{predicate}$/, Constants::EMPTY)
attributes_str = original_name.sub(/_#{predicate}$/, ''.freeze)
attribute_names = attributes_str.split(/_and_|_or_/)
combinator = attributes_str.match(/_and_/) ? :and : :or
defaults = base_ancestors.map do |klass|
@ -74,7 +74,7 @@ module Ransack
def self.attribute_name(context, name, include_associations = nil)
@context, @name = context, name
@assoc_path = context.association_path(name)
@attr_name = @name.sub(/^#{@assoc_path}_/, Constants::EMPTY)
@attr_name = @name.sub(/^#{@assoc_path}_/, ''.freeze)
associated_class = @context.traverse(@assoc_path) if @assoc_path.present?
@include_associated = include_associations && associated_class