From f80aa5994603e684e3fecd3f53bfbf242c73a107 Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 00:46:12 -0500 Subject: Decrease string allocations on AR#respond_to? When a symbol is passed in, we call `to_s` on it which allocates a string. The two hardcoded symbols that are used internally are `:to_partial_path` and `:to_model`. This change buys us 71,136 bytes of memory and 1,777 fewer objects per request. --- activerecord/lib/active_record/attribute_methods.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb index abe1d465a5..7fb899c242 100644 --- a/activerecord/lib/active_record/attribute_methods.rb +++ b/activerecord/lib/active_record/attribute_methods.rb @@ -230,7 +230,15 @@ module ActiveRecord # person.respond_to(:nothing) # => false def respond_to?(name, include_private = false) return false unless super - name = name.to_s + + case name + when :to_partial_path + name = "to_partial_path".freeze + when :to_model + name = "to_model".freeze + else + name = name.to_s + end # If the result is true then check for the select case. # For queries selecting a subset of columns, return false for unselected columns. -- cgit v1.2.3 From 1bf50badd943e684a56a03392ef0ddafefca0ad7 Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 22:25:41 -0500 Subject: Decrease string allocations in apply_inflections In `apply_inflections` a string is down cased and some whitespace stripped in the front (which allocate strings). This would normally be fine, however `uncountables` is a fairly small array (10 elements out of the box) and this method gets called a TON. Instead we can keep an array of valid regexes for each uncountable so we don't have to allocate new strings. This change buys us 325,106 bytes of memory and 3,251 fewer objects per request. --- .../lib/active_support/inflector/inflections.rb | 37 ++++++++++++++++++++-- .../lib/active_support/inflector/methods.rb | 4 +-- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb index 486838bd15..8ac1820776 100644 --- a/activesupport/lib/active_support/inflector/inflections.rb +++ b/activesupport/lib/active_support/inflector/inflections.rb @@ -27,6 +27,37 @@ module ActiveSupport class Inflections @__instance__ = ThreadSafe::Cache.new + class Uncountables < Array + def initialize + @regex_array = [] + super + end + + def delete(entry) + super entry + @regex_array.delete(to_regex(entry)) + end + + def <<(*word) + add(word) + end + + def add(words) + self.concat(words.flatten.map(&:downcase)) + @regex_array += self.map {|word| to_regex(word) } + self + end + + def uncountable?(str) + @regex_array.detect {|regex| regex.match(str) } + end + + private + def to_regex(string) + /\b#{::Regexp.escape(string)}\Z/i + end + end + def self.instance(locale = :en) @__instance__[locale] ||= new end @@ -34,7 +65,7 @@ module ActiveSupport attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex def initialize - @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/ + @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], Uncountables.new, [], {}, /(?=a)b/ end # Private, for the test suite. @@ -160,7 +191,7 @@ module ActiveSupport # uncountable 'money', 'information' # uncountable %w( money information rice ) def uncountable(*words) - @uncountables += words.flatten.map(&:downcase) + @uncountables.add(words) end # Specifies a humanized form of a string by a regular expression rule or @@ -185,7 +216,7 @@ module ActiveSupport def clear(scope = :all) case scope when :all - @plurals, @singulars, @uncountables, @humans = [], [], [], [] + @plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, [] else instance_variable_set "@#{scope}", [] end diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 60ef249e37..899ba70af6 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -354,7 +354,7 @@ module ActiveSupport # const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?" # const_regexp("::") # => "::" def const_regexp(camel_cased_word) #:nodoc: - parts = camel_cased_word.split("::") + parts = camel_cased_word.split("::".freeze) return Regexp.escape(camel_cased_word) if parts.blank? @@ -372,7 +372,7 @@ module ActiveSupport def apply_inflections(word, rules) result = word.to_s.dup - if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/]) + if word.empty? || inflections.uncountables.uncountable?(result) result else rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) } -- cgit v1.2.3 From 83ee043c6834914607849ae9cd3b9eab6b41702c Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 22:32:01 -0500 Subject: Decrease string allocations in url_options The request.script_name is dup-d which allocates an extra string. It is most commonly an empty string "". We can save a ton of string allocations by checking first if the string is empty, if so we can use a frozen empty string instead of duplicating an empty string. This change buys us 35,714 bytes of memory and 893 fewer objects per request. --- actionpack/lib/action_controller/metal/url_for.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 5a0e5c62e4..dbf7241a14 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -41,7 +41,11 @@ module ActionController if original_script_name options[:original_script_name] = original_script_name else - options[:script_name] = same_origin ? request.script_name.dup : script_name + if same_origin + options[:script_name] = request.script_name.empty? ? "".freeze : request.script_name.dup + else + options[:script_name] = script_name + end end options.freeze else -- cgit v1.2.3 From 9b8258814e695fe7fbb728456498fd0fd8709f5c Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 22:38:34 -0500 Subject: Speed up journey extract_parameterized_parts Micro optimization: `reverse.drop_while` is slower than `reverse_each.drop_while`. This doesn't save any object allocations. Second, `keys_to_keep` is typically a very small array. The operation `parameterized_parts.keys - keys_to_keep` actually allocates two arrays. It is quicker (I benchmarked) to iterate over each and check inclusion in array manually. This change buys us 1774 fewer objects per request --- actionpack/lib/action_dispatch/journey/formatter.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb index c0566c6fc9..545b67422d 100644 --- a/actionpack/lib/action_dispatch/journey/formatter.rb +++ b/actionpack/lib/action_dispatch/journey/formatter.rb @@ -54,11 +54,12 @@ module ActionDispatch def extract_parameterized_parts(route, options, recall, parameterize = nil) parameterized_parts = recall.merge(options) - keys_to_keep = route.parts.reverse.drop_while { |part| + keys_to_keep = route.parts.reverse_each.drop_while { |part| !options.key?(part) || (options[part] || recall[part]).nil? } | route.required_parts - (parameterized_parts.keys - keys_to_keep).each do |bad_key| + parameterized_parts.each do |bad_key, _| + next if keys_to_keep.include?(bad_key) parameterized_parts.delete(bad_key) end -- cgit v1.2.3 From 097ec6fb7c7e1854cdd96113213b555ae7415953 Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 22:47:34 -0500 Subject: Speed up journey missing_keys Most routes have a `route.path.requirements[key]` of `/[-_.a-zA-Z0-9]+\/[-_.a-zA-Z0-9]+/` yet every time this method is called a new regex is generated on the fly with `/\A#{DEFAULT_INPUT}\Z/`. OBJECT ALLOCATIONS BLERG! This change uses a special module that implements `===` so it can be used in a case statement to pull out the default input. When this happens, we use a pre-generated regex. This change buys us 1,643,465 bytes of memory and 7,990 fewer objects per request. --- actionpack/lib/action_dispatch/journey/formatter.rb | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb index 545b67422d..985cf8b947 100644 --- a/actionpack/lib/action_dispatch/journey/formatter.rb +++ b/actionpack/lib/action_dispatch/journey/formatter.rb @@ -111,15 +111,27 @@ module ActionDispatch routes end + module RegexCaseComparator + DEFAULT_INPUT = /[-_.a-zA-Z0-9]+\/[-_.a-zA-Z0-9]+/ + DEFAULT_REGEX = /\A#{DEFAULT_INPUT}\Z/ + + def self.===(regex) + DEFAULT_INPUT == regex + end + end + # Returns an array populated with missing keys if any are present. def missing_keys(route, parts) missing_keys = [] tests = route.path.requirements route.required_parts.each { |key| - if tests.key?(key) - missing_keys << key unless /\A#{tests[key]}\Z/ === parts[key] - else + case tests[key] + when nil missing_keys << key unless parts[key] + when RegexCaseComparator + missing_keys << key unless RegexCaseComparator::DEFAULT_REGEX === parts[key] + else + missing_keys << key unless /\A#{tests[key]}\Z/ === parts[key] end } missing_keys -- cgit v1.2.3 From 0cbec58ae48279ae5e9fdf6bbdbceb32183215dd Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 23:19:15 -0500 Subject: Decrease route_set allocations In handle_positional_args `Array#-=` is used which allocates a new array. Instead we can iterate through and delete elements, modifying the array in place. Also `Array#take` allocates a new array. We can build the same by iterating over the other element. This change buys us 106,470 bytes of memory and 2,663 fewer objects per request. --- actionpack/lib/action_dispatch/routing/route_set.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 42512cad91..43e35366a9 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -267,9 +267,13 @@ module ActionDispatch path_params -= controller_options.keys path_params -= result.keys end - path_params -= inner_options.keys - path_params.take(args.size).each do |param| - result[param] = args.shift + inner_options.each do |key, _| + path_params.delete(key) + end + + args.each_with_index do |arg, index| + param = path_params[index] + result[param] = arg if param end end -- cgit v1.2.3 From 1a14074fb525cde4a439a1fb7515fe417c37ff96 Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 23:27:35 -0500 Subject: Reduce hash allocations in route_set When generating a url with `url_for` the hash of arguments passed in, is dup-d and merged a TON. I wish I could clean this up better, and might be able to do it in the future. This change removes one dup, since it's literally right after we just dup-d the hash to pass into this constructor. This may be a breaking, change but the tests pass...so :shipit: we can revert if it causes problems This change buys us 205,933 bytes of memory and 887 fewer objects per request. --- actionpack/lib/action_dispatch/routing/route_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 43e35366a9..d93989a449 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -598,7 +598,7 @@ module ActionDispatch def initialize(named_route, options, recall, set) @named_route = named_route - @options = options.dup + @options = options @recall = recall.dup @set = set -- cgit v1.2.3 From 2a4d4301d405dbc4a6bce85b4632a78099c8d1c6 Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 23:35:18 -0500 Subject: Decrease string allocation in content_tag_string When an unknonwn key is passed to the hash in `PRE_CONTENT_STRINGS` it returns nil, when you call "#{nil}" it allocates a new empty string. We can get around this allocation by using a default value `Hash.new { "".freeze }`. We can avoid the `to_sym` call by pre-populating the hash with a symbol key in addition to a string key. We can freeze some strings when using Array#* to reduce allocations. Array#join can take frozen strings. This change buys us 86,600 bytes of memory and 1,857 fewer objects per request. --- actionview/lib/action_view/helpers/tag_helper.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb index a87c223a71..a821bd9543 100644 --- a/actionview/lib/action_view/helpers/tag_helper.rb +++ b/actionview/lib/action_view/helpers/tag_helper.rb @@ -22,9 +22,10 @@ module ActionView TAG_PREFIXES = ['aria', 'data', :aria, :data].to_set - PRE_CONTENT_STRINGS = { - :textarea => "\n" - } + PRE_CONTENT_STRINGS = Hash.new { "".freeze } + PRE_CONTENT_STRINGS[:textarea] = "\n" + PRE_CONTENT_STRINGS["textarea"] = "\n" + # Returns an empty HTML tag of type +name+ which by default is XHTML # compliant. Set +open+ to true to create an open tag compatible @@ -143,7 +144,7 @@ module ActionView def content_tag_string(name, content, options, escape = true) tag_options = tag_options(options, escape) if options content = ERB::Util.unwrapped_html_escape(content) if escape - "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}".html_safe + "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name]}#{content}".html_safe end def tag_options(options, escape = true) @@ -160,7 +161,7 @@ module ActionView attrs << tag_option(key, value, escape) end end - " #{attrs * ' '}" unless attrs.empty? + " ".freeze + attrs * ' '.freeze unless attrs.empty? end def prefix_tag_option(prefix, key, value, escape) @@ -177,7 +178,7 @@ module ActionView def tag_option(key, value, escape) if value.is_a?(Array) - value = escape ? safe_join(value, " ") : value.join(" ") + value = escape ? safe_join(value, " ".freeze) : value.join(" ".freeze) else value = escape ? ERB::Util.unwrapped_html_escape(value) : value end -- cgit v1.2.3 From 2e95d2ef90a32a7ed6fbb14f4e0a6764fc9e017b Mon Sep 17 00:00:00 2001 From: schneems Date: Fri, 24 Jul 2015 23:41:25 -0500 Subject: Optimize hash key No idea why on earth this hash key isn't already optimized by MRI, but it isn't. :shit: This change buys us 74,077 bytes of memory and 1,852 fewer objects per request. --- actionview/lib/action_view/helpers/url_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 7d92651183..5eb1377d38 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -184,7 +184,7 @@ module ActionView html_options = convert_options_to_data_attributes(options, html_options) url = url_for(options) - html_options['href'] ||= url + html_options["href".freeze] ||= url content_tag(:a, name || url, html_options, &block) end -- cgit v1.2.3 From 9b189a31696b6572ffb8164f1f3041d57e8eeebe Mon Sep 17 00:00:00 2001 From: schneems Date: Sat, 25 Jul 2015 00:08:47 -0500 Subject: Cut string ActionView template allocations The instrument method creates new strings, the most common action to instrument is "!render_template` so we can detect when that action is occurring and use a frozen string instead. This change buys us 113,714 bytes of memory and 1,790 fewer objects per request. --- actionview/lib/action_view/template.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 1ce9f94b13..e232808dcb 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -154,7 +154,7 @@ module ActionView # we use a bang in this instrumentation because you don't want to # consume this in production. This is only slow if it's being listened to. def render(view, locals, buffer=nil, &block) - instrument("!render_template") do + instrument("!render_template".freeze) do compile!(view) view.send(method_name, locals, buffer, &block) end @@ -348,7 +348,12 @@ module ActionView def instrument(action, &block) payload = { virtual_path: @virtual_path, identifier: @identifier } - ActiveSupport::Notifications.instrument("#{action}.action_view", payload, &block) + case action + when "!render_template".freeze + ActiveSupport::Notifications.instrument("!render_template.action_view".freeze, payload, &block) + else + ActiveSupport::Notifications.instrument("#{action}.action_view".freeze, payload, &block) + end end EXPLICIT_COLLECTION = /# Template Collection: (?\w+)/ -- cgit v1.2.3 From e76a84350595ca6772d3c00f456b35e411fba6c1 Mon Sep 17 00:00:00 2001 From: schneems Date: Sat, 25 Jul 2015 00:18:13 -0500 Subject: Cut string allocations in content_tag_string content_tag's first argument is will generate a string with an html tag so `:a` will generate: ``. When this happens, the symbol is implicitly `to_s`-d so a new string is allocated. We can get around that by using a frozen string instead which This change buys us 74,236 bytes of memory and 1,855 fewer objects per request. --- actionview/lib/action_view/helpers/asset_tag_helper.rb | 2 +- actionview/lib/action_view/helpers/date_helper.rb | 12 ++++++------ actionview/lib/action_view/helpers/form_options_helper.rb | 8 ++++---- actionview/lib/action_view/helpers/form_tag_helper.rb | 8 ++++---- actionview/lib/action_view/helpers/javascript_helper.rb | 6 +++--- actionview/lib/action_view/helpers/url_helper.rb | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb index 3041ad3ef7..e506c782d6 100644 --- a/actionview/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb @@ -60,7 +60,7 @@ module ActionView tag_options = { "src" => path_to_javascript(source, path_options) }.merge!(options) - content_tag(:script, "", tag_options) + content_tag("script".freeze, "", tag_options) }.join("\n").html_safe end diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index fbd7261477..94fbaa2dca 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -681,7 +681,7 @@ module ActionView content = args.first || I18n.l(date_or_time, :format => format) datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.iso8601 - content_tag(:time, content, options.reverse_merge(:datetime => datetime), &block) + content_tag("time".freeze, content, options.reverse_merge(:datetime => datetime), &block) end end @@ -809,7 +809,7 @@ module ActionView 1.upto(12) do |month_number| options = { :value => month_number } options[:selected] = "selected" if month == month_number - month_options << content_tag(:option, month_name(month_number), options) + "\n" + month_options << content_tag("option".freeze, month_name(month_number), options) + "\n" end build_select(:month, month_options.join) end @@ -971,7 +971,7 @@ module ActionView tag_options[:selected] = "selected" if selected == i text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value text = options[:ampm] ? AMPM_TRANSLATION[i] : text - select_options << content_tag(:option, text, tag_options) + select_options << content_tag("option".freeze, text, tag_options) end (select_options.join("\n") + "\n").html_safe @@ -991,11 +991,11 @@ module ActionView select_options[:class] = [select_options[:class], type].compact.join(' ') if @options[:with_css_classes] select_html = "\n" - select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank] + select_html << content_tag("option".freeze, '', :value => '') + "\n" if @options[:include_blank] select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt] select_html << select_options_as_html - (content_tag(:select, select_html.html_safe, select_options) + "\n").html_safe + (content_tag("select".freeze, select_html.html_safe, select_options) + "\n").html_safe end # Builds a prompt option tag with supplied options or from default options. @@ -1012,7 +1012,7 @@ module ActionView I18n.translate(:"datetime.prompts.#{type}", :locale => @options[:locale]) end - prompt ? content_tag(:option, prompt, :value => '') : '' + prompt ? content_tag("option".freeze, prompt, :value => '') : '' end # Builds hidden input tag for date part and value. diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb index 8e729b3c39..728e633bbf 100644 --- a/actionview/lib/action_view/helpers/form_options_helper.rb +++ b/actionview/lib/action_view/helpers/form_options_helper.rb @@ -456,7 +456,7 @@ module ActionView option_tags = options_from_collection_for_select( group.send(group_method), option_key_method, option_value_method, selected_key) - content_tag(:optgroup, option_tags, label: group.send(group_label_method)) + content_tag("optgroup".freeze, option_tags, label: group.send(group_label_method)) end.join.html_safe end @@ -528,7 +528,7 @@ module ActionView body = "".html_safe if prompt - body.safe_concat content_tag(:option, prompt_text(prompt), value: "") + body.safe_concat content_tag("option".freeze, prompt_text(prompt), value: "") end grouped_options.each do |container| @@ -541,7 +541,7 @@ module ActionView end html_attributes = { label: label }.merge!(html_attributes) - body.safe_concat content_tag(:optgroup, options_for_select(container, selected_key), html_attributes) + body.safe_concat content_tag("optgroup".freeze, options_for_select(container, selected_key), html_attributes) end body @@ -577,7 +577,7 @@ module ActionView end zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected) - zone_options.safe_concat content_tag(:option, '-------------', value: '', disabled: true) + zone_options.safe_concat content_tag("option".freeze, '-------------', value: '', disabled: true) zone_options.safe_concat "\n" zones = zones - priority_zones diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb index 896020bc15..d36701955a 100644 --- a/actionview/lib/action_view/helpers/form_tag_helper.rb +++ b/actionview/lib/action_view/helpers/form_tag_helper.rb @@ -140,15 +140,15 @@ module ActionView end if include_blank - option_tags = content_tag(:option, include_blank, value: '').safe_concat(option_tags) + option_tags = content_tag("option".freeze, include_blank, value: '').safe_concat(option_tags) end end if prompt = options.delete(:prompt) - option_tags = content_tag(:option, prompt, value: '').safe_concat(option_tags) + option_tags = content_tag("option".freeze, prompt, value: '').safe_concat(option_tags) end - content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys) + content_tag "select".freeze, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys) end # Creates a standard text field; use these text fields to input smaller chunks of text like a username @@ -568,7 +568,7 @@ module ActionView # # =>

def field_set_tag(legend = nil, options = nil, &block) output = tag(:fieldset, options, true) - output.safe_concat(content_tag(:legend, legend)) unless legend.blank? + output.safe_concat(content_tag("legend".freeze, legend)) unless legend.blank? output.concat(capture(&block)) if block_given? output.safe_concat("") end diff --git a/actionview/lib/action_view/helpers/javascript_helper.rb b/actionview/lib/action_view/helpers/javascript_helper.rb index e237a32cb7..ed7e882c94 100644 --- a/actionview/lib/action_view/helpers/javascript_helper.rb +++ b/actionview/lib/action_view/helpers/javascript_helper.rb @@ -47,8 +47,8 @@ module ActionView # tag. # # javascript_tag "alert('All is good')", defer: 'defer' - # - # Returns: + # + # Returns: #