Commit Graph

2245 Commits

Author SHA1 Message Date
John Hawthorn 4a59e131ff Remove argument from DetailsKey.view_context_class
This was cached in a single ivar so passing any different klass would
still return the same instance.
2023-03-30 13:51:04 -07:00
Petrik 2c3ae61eb5 Move Template class docs to the correct namespace [ci-skip]
Documentation of a class should be defined above the class definition,
not on the parent namespace.
This fixes the documentation of ActionView::Template::Renderable showing
up in ActionView::Template.
Most of the others are marked with `:nodoc:` anyway, so it shouldn't affect
their documentation.
2023-03-30 17:52:04 +02:00
Petrik de Heus dc0f20595d
Merge pull request #47717 from p8/docs/include-readmes
Include READMEs in main framework pages of the API documentation
2023-03-30 16:43:14 +02:00
Petrik 7c94708d24 Include READMEs in main framework pages of the API documentation
Currently when opening the main framework pages there is no introduction
to the framework. Instead we only see a whole lot of modules and the
`gem_version` and `version` methods.

By including the READMEs using the `:include:` directive each frameworks
has a nice introduction.
For markdown READMEs we need to add the :markup: directive.

[ci-skip]

Co-authored-by: zzak <zzakscott@gmail.com>
2023-03-21 21:16:28 +01:00
Nicolò Rebughini a63ae913df Do not allocate the first path character in asset helper
In asset heavy views, the asset_path helper might be called a lot of
times. When checking the first character of the source element with []
we allocate a string each time just to check it against ?/.

By using String#start_with? we can avoid this step and go a bit faster.

This is the code I used to measure the change:

```

require "bundler/inline"

ROOT_STRING = '/'
TEST_PATH = "/some/path"

gemfile(true) do
  source "https://rubygems.org"

  gem "benchmark-ips"
end

Benchmark.ips do |x|
  x.report("source[0]") do
   TEST_PATH[0] != ROOT_STRING
  end

  x.report("source.start_with?") do
   TEST_PATH.start_with?(ROOT_STRING)
  end

  x.compare!
end
```

Warming up --------------------------------------
           source[0]   905.322k i/100ms
  source.start_with?     1.541M i/100ms
Calculating -------------------------------------
           source[0]      9.012M (± 0.7%) i/s -     45.266M in   5.022969s
  source.start_with?     15.395M (± 0.4%) i/s -     77.030M in   5.003691s

Comparison:
  source.start_with?: 15394807.0 i/s
           source[0]:  9012304.9 i/s - 1.71x  slower
2023-03-20 17:32:42 +01:00
Rafael Mendonça França 8241178723
Remove deprecated support to instance variables as locals to partials 2023-03-03 00:38:39 +00:00
Rafael Mendonça França 23344d4b8c
Remove deprecated constant `ActionView::Path` 2023-03-03 00:38:37 +00:00
Nick Borromeo 92216ebb19 Create an ActionView::PathRegistry module
This is a refactor of the `Registry` module added in https://github.com/rails/rails/pull/47347. This is an attempt to
minimize the namespace conflcits that will happen when users will have a top level `Registry` module which can cause
incorrect behavior

Replace ActionView::ViewPaths::Registry with ActionView::PathRegistry
2023-02-23 16:53:57 -08:00
zzak d2af670dba
Remove Copyright years (#47467)
* Remove Copyright years

* Basecamp is now 37signals... again

Co-authored-by: David Heinemeier Hansson <dhh@hey.com>

---------

Co-authored-by: David Heinemeier Hansson <dhh@hey.com>
2023-02-23 11:38:16 +01:00
Carlos Antonio da Silva ee6a7ba6b0 Clarify paragraph pointing to MDN docs on script async/defer
Follow-up of 7f4245c336

[ci skip]
2023-02-22 21:04:21 -03:00
John Hawthorn 72abd6357d Reuse "main" reloader for ActionView expiration
Co-authored-by: Matthew Draper <matthew@trebex.net>
2023-02-16 10:29:17 -08:00
John Hawthorn 785e02a2ed Cache resolvers from {append,prepend}_view_path
When prepending or appending view paths, Rails will create an ActionView::Resolver
for each String or Pathname argument. Previously, these were not cached. If view
paths were added in a request context (which is a common thing in a multi-tenant
application), new resolvers were created on each request. This effectively
disabled template caching for the added view paths.

Further, under certain circumstances, it also created a memory leak.

This commit fixes both issues by turning dynamic view path strings into cached
resolvers.

Co-authored-by: Dominik Schöler <dominik.schoeler@makandra.de>
Co-authored-by: John Hawthorn <john@hawthorn.email>
2023-02-16 10:29:17 -08:00
John Hawthorn 28284fc186 Refactor into ViewPaths::Registry 2023-02-16 10:29:17 -08:00
Yasuo Honda f838a74212
Merge pull request #46866 from ghousemohamed/change-year-2022-to-2023 2023-02-13 13:15:43 +09:00
fatkodima f2cb36f1bc Optimize `TextHelper.highlight` for large inputs
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2023-02-10 12:47:14 +02:00
zzak 78be186970
RE: defer and async options in javascript_include_tag
Combines #46296 and #46793 PRs.

Co-authored-by: Paulo Fidalgo <paulo.fidalgo.pt@gmail.com>
Co-authored-by: OKURA Masafumi <masafumi.o1988@gmail.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
Co-authored-by: Alex Ghiculescu <alex@tanda.co>
2023-02-09 13:02:21 +09:00
Sean Doyle 812e50b00a `token_list`: Guard Stimulus' `data-action` from multiple escapes
Prior to this commit, chaining more than one `token_list` calls with a
[data-action][] attribute value would result in one too many HTML
escapes. Additional subsequent calls would compound the problem.

For example, the following calls would result in an invalid descriptor
that's escaped too many times to be parsed.

```ruby
first   = "click->controller#action1"
second  = "click->controller#action2"
third   = "click->controller#action3"
fourth  = "click->controller#action4"

value = token_list(first, token_list(second, token_list(third)))

CGI.unescape_html value.to_s
 # => "click->controller#action1 click-&gt;controller#action2 click-&amp;gt;controller#action3 click-&amp;amp;gt;controller#action4"
```

By [CGI.unescape_html][] each `String` value before passing it to
[token_list][] (which re-escapes the value), we can preserve a lossless
concatenation process while also preserving the HTML safety.

After this commit, the previous example works as expected:

```ruby
first   = "click->controller#action1"
second  = "click->controller#action2"
third   = "click->controller#action3"
fourth  = "click->controller#action4"

value = token_list(first, token_list(second, token_list(third)))

CGI.unescape_html value.to_s
 # => "click->controller#action1 click->controller#action2 click->controller#action3 click->controller#action4"
```

[unescaping]: https://ruby-doc.org/stdlib-2.5.3/libdoc/cgi/rdoc/CGI/Util.html#method-i-unescape_html
[token_list]:
https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-token_list
[data-action]: https://stimulus.hotwired.dev/reference/actions
2023-02-08 11:53:02 -05:00
Cameron Dutro 0306f74238 Merge branch 'main' into capture_use_buffer 2023-01-31 14:16:29 -08:00
Cameron Dutro c5303039f4 Modify capture helper to use the output buffer's capture functionality.
A recent change designed to avoid swapping references to the view context's
output buffer (https://github.com/rails/rails/pull/45731) added a #capture
method to the OutputBuffer class. The original CaptureHelper#capture method
however still swaps the buffer via CaptureHelper#with_output_buffer, meaning
the @output_buffer reference is still reassigned by form helpers, etc. This
change delegates capture behavior to @output_buffer so a single buffer is
used per request.
2023-01-30 15:47:32 -08:00
zzak f7c0b38dd4 Several fixes for AV::Helpers::CaptureHelper 2023-01-29 09:54:11 +09:00
eileencodes 350311dbe4
Remove deprecation from template
This PR removes the deprecation added in #47005 because it is
non-trivial for HAML and Slim to implement error highlighting for
templates. If a template engine doesn't support `translate_location`
then we can fallback to `spot` and the error will be displayed but we
won't be able to automatically underline the column.
2023-01-24 12:07:49 -05:00
Rafael Mendonça França 5c835bd669
Make explicit this config only affects controllers are views 2023-01-19 20:21:29 +00:00
Rafael Mendonça França 6d4f9a8fbd
Merge pull request #46589 from mattpolito/form_with_form_builder_id
FormBuilder#id finds id set by `form_for` & `form_with`
2023-01-18 15:49:01 -05:00
Jean Boussier aa7d78d9b1 Improve Rails' Shape friendliness (second pass)
Followup: https://github.com/rails/rails/pull/47023

```
Shape Edges Report
-----------------------------------
snip...
       238  @errors
snip...
       219  @options
snip...
       129  @_request
       128  @type
       125  @virtual_path
       124  @_assigns
       123  @_config
       123  @_controller
       123  @output_buffer
       123  @view_flow
       122  @_default_form_builder
snip...
        89  @_already_called
        75  @validation_context
snip...
        65  @_new_record_before_last_commit
snip...
        58  @_url_options
snip...
```
2023-01-17 13:55:49 +01:00
Jean Boussier fc950324bd Improve Rails' Shape friendliness
Ruby 3.2 significantly changed how instance variables are store.
It now use shapes, and in short, it's important for performance
to define instance variables in a consistent order to limit the
amount of shapes.

Otherwise, the number of shapes will increase past a point where
MRI won't be able to cache instance variable access. The impact
is even more important when YJIT is enabled.

This PR is data driven. I dump the list of Shapes from Shopify's
monolith production environment, and Rails is very present among
the top offenders:

```
Shape Edges Report
-----------------------------------
       770  @default_graphql_name
       697  @own_fields
       661  @to_non_null_type
       555  @own_interface_type_memberships
       472  @description
       389  @errors
       348  @oseid
       316  @_view_runtime
       310  @_db_runtime
       292  @visibility
       286  @shop
       271  @attribute_method_patterns_cache
       264  @namespace_for_serializer
       254  @locking_column
       254  @primary_key
       253  @validation_context
       244  @quoted_primary_key
       238  @access_controls
       234  @_trigger_destroy_callback
       226  @_trigger_update_callback
       224  @finder_needs_type_condition
       215  @_committed_already_called
       214  @api_type
       203  @mutations_before_last_save
       202  @access_controls_overrides
       201  @options
       198  @mutations_from_database
       190  @_already_called
       183  @name
       179  @_request
       176  @own_arguments
       175  @_assigns
       175  @virtual_path
       174  @context
       173  @_controller
       173  @output_buffer
       173  @view_flow
       172  @_default_form_builder
       169  @cache
       159  @_touch_record
       151  @attribute_names
       151  @default_attributes
       150  @columns_hash
       149  @attribute_types
       148  @columns
       147  @marked_for_same_origin_verification
       146  @schema_loaded
       143  @_config
       143  @type
       141  @column_names
```

All the changes are of similar nature, the goal is to preset the instance
variable to nil when objects are allocated, or when classes are created.

For classes I leverage the `inherited` hook. If the patern becomes common enough
it might make sense to add a helper for this in `ActiveSupport::Concern`.
2023-01-16 12:31:37 +01:00
eileencodes 45430ae99d
Add warning for missing translate_location
If other libraries like `haml` don't implement `translate_location` then
they won't get the error highlighting behavior that was implemented to
underline errors coming from templates.

This deprecation is to notify templating engines that this change is
necessary for them to get this highlighting.
2023-01-13 16:47:22 -05:00
eileencodes d9dd1c59d0
Implement spot and don't use `keep_script_lines` in Ruby 3.2
We want to use error highlight with eval'd code, specifically ERB
templates.

Previously we could only get the information we needed by setting
`keep_script_lines` to true. In Ruby 3.2 and error_highlight we added
the ability to get this information without setting `keep_script_lines`.

This change implements that new behavior for Rails.

I removed the script line changes to support this in 3.1 because it is
not in any released version.

Ruby change: https://github.com/ruby/ruby/pull/6593
Erorr highlight change: https://github.com/ruby/error_highlight/pull/26

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2023-01-13 16:20:09 -05:00
Hartley McGuire 978993e880
Enable Style/EvalWithLocation
Ref: ad39d6b

Ensure that all evals include file and line number to identify their
source.

Two of the evals reported by this cop were unneccesary and replaced with
non-eval alternatives: xml is set as a local variable in
Template::Handlers::Builder#call, and instance_eval isn't needed to get
the current binding.

There are additionally 27 offenses in test directories, but since it
seems less important to fix those they are currently ignored.
2023-01-11 18:46:09 -05:00
Akira Matsuda 4c23742a13
`delegate to: :class` has to be defined after the target method
in order to derive the arity from the target class method.
2023-01-11 04:32:08 +09:00
Jonathan Hefner cfe300ceb1 Format inline code [ci-skip] 2023-01-08 15:47:20 -06:00
Jonathan Hefner 3eadf057db Fix typos in API docs [ci-skip] 2023-01-08 15:47:20 -06:00
Ghouse Mohamed e0559d2c1c Change 2022 -> 2023 2023-01-03 13:22:00 +05:30
Akira Matsuda 45dd422901
Let `initialize` not create an Array as its return value 2022-12-18 12:11:34 +09:00
Akira Matsuda 6576eec6a8
Create an Array for the error message only when invalid value exists 2022-12-17 17:13:17 +09:00
Akira Matsuda d8c05043c3
Avoid creating new Array object per each comparison
Benchmark.ips do |x|
  arr = [:js]

  x.report('==') { arr == [:js] }
  x.report('length') { (arr.length == 0) && (arr[0] == :js) }
  x.report('one?') { arr.one? && (arr[0] == :js) }

  x.compare!
end

Warming up --------------------------------------
                  ==   731.426k i/100ms
              length     1.967M i/100ms
                one?     1.440M i/100ms
Calculating -------------------------------------
                  ==      7.291M (± 0.8%) i/s -     36.571M in   5.016130s
              length     19.633M (± 0.8%) i/s -     98.356M in   5.010104s
                one?     14.387M (± 0.8%) i/s -     71.998M in   5.004721s

Comparison:
              length: 19632843.5 i/s
                one?: 14386784.0 i/s - 1.36x  (± 0.00) slower
                  ==:  7291274.5 i/s - 2.69x  (± 0.00) slower
2022-12-15 11:55:03 +09:00
eileencodes bd7b6decb9
Fix typo in new docs from #46730 2022-12-14 16:17:55 -05:00
eileencodes 171fea857d
Improve docs for strict_locals! [ci-skip]
The docs didn't say much about what strict locals are or why you would
use them. This adds docs on usage and what the functionality does.
2022-12-14 15:13:40 -05:00
eileencodes 334fa122b7
Refactor compiled_source
This is a continuation of #46706 to make sure we don't need to set an
instance variable to `@original_source` for the `compile` method to use.

We can't call `strict_locals!` after encode so we need to set it to a
local variable in `complile`. We changed the `strict_locals!` method to
check `NONE` instead of lazily defining instance variables which let us
simplify `strict_locals?` to return the value of `strict_locals!`. This
simplifies and clarifies the code.

Co-authored-by: Aaron Patterson tenderlove@ruby-lang.org
2022-12-14 14:12:25 -05:00
Alex Ghiculescu 49c2e51808 Allow `f.select` to be called with a single hash containing options and HTML options
I do this a lot:

```erb
<%= select :post, :author, authors, required: true %>
```

It doesn't work; the `required` attribute is ignored! Instead, you need to do this:

```erb
<%= select :post, :author, authors, {}, required: true %>
```

It's hard to remember the right API, and it looks to me like a code smell. It looks even smellier when you end up with this:

```erb
<%= select :post, :author, authors, { include_blank: "Choose an option" }, { required: true } %>
```

Where this would be nicer, but again, the `required` attribute is ignored:

```erb
<%= select :post, :author, authors, include_blank: "Choose an option", required: true %>
```

This PR implements a special handling for `required`, `multiple`, and `size` HTML attributes so that these now do the same thing:

```erb
<%= select :post, :author, authors, include_blank: "Choose an option", required: true %>
<%= select :post, :author, authors, { include_blank: "Choose an option" }, { required: true } %>
```

ps. as proof I'm not the only person who makes this mistake, one of the tests in the Rails test suite was wrong! The test added in https://github.com/rails/rails/pull/40522 puts the `multiple` attribute in the wrong place and has the wrong assertion as as result. This PR includes a fix for the test.
2022-12-13 11:44:34 -06:00
eileencodes 5026abaeb1
Refactor compiled source code into method
Moves the part of `compile!` that compiles the template source into it's
own method. We need this for future work in improving exceptions for ERB
templates to pass to ErrorHighlight.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2022-12-12 15:31:19 -05:00
Andrey Samsonov c20b629f52 Fix inconsistent behavior in form helper date/time tags with options; issue #46677
This change makes date/time options (value, min, max) in `time_field`, `date_field`, `datetime_field`, `week_field`, `month_field` form helpers behave in a unified way.
2022-12-11 17:19:18 +01:00
Matt Polito 978a3eb4b0 FormBuilder#id finds id set by `form_for` & `form_with` 2022-12-08 15:44:48 -05:00
Hartley McGuire a07f2ace03
Fix lots of code highlighting issues
The most common is replacing back-ticks with either pluses or tt tags.
There were also a few instances of code blocks not being indented.
2022-11-29 00:51:02 -05:00
Étienne Barrié 3d6a7b2faa Initialize deprecators before configuring them
Since engine initializers run later in the process, we need to run this
initializer earlier than the default.

This ensures they're all registered before the environments are loaded.
2022-11-28 10:47:26 +01:00
Jonathan Hefner 1e68400930 Prefer deprecate_constant over constant proxy
`deprecate_constant` will warn whenever the constant is referenced
instead of when the constant is a method receiver, which increases the
likelihood that the warning will be seen.  Additionally,
`DeprecatedConstantProxy` prevents using the constant as a superclass,
such as in `class MyClass < SomeDeprecatedConstant`.
2022-11-25 11:25:03 -06:00
Rafael Mendonça França db5a6ef624
Merge PR #43019 2022-11-23 19:14:33 +00:00
Mathieu Le Tiec a625e20825 Allow hash-like record_object in FormBuilder#fields_for 2022-11-22 20:03:43 +01:00
Rafael Mendonça França a8efccc32e
Merge pull request #46531 from p8/guides/fix-capitalization-of-AJAX
Rename AJAX to Ajax for consistency [ci-skip]
2022-11-21 17:24:09 -05:00
Maciej Mensfeld 9a77b0fe28
Make sure that concurrent map usage is thread-safe
Behavior upon missing prefix partial name may cause a key to overwrite when executed in multiple threads at the same time.

ref https://github.com/ruby-concurrency/concurrent-ruby/issues/970
2022-11-20 20:50:06 +01:00
Petrik 93c51f92fd Rename AJAX to Ajax for consistency [ci-skip]
Currently we use both `AJAX` (11 times) and `Ajax` (22 times).
Wikipedia uses `Ajax`: https://en.wikipedia.org/wiki/Ajax_(programming)
Mozilla uses `Ajax`: https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX

As `Ajax` is currently used the most and it's preferred by Wikipedia and
Mozilla, we can change all it's occurences to `Ajax`.
2022-11-20 11:17:44 +01:00
Petrik 482d94c139 Use 2 spaces for identation in ActionView code examples [ci-skip]
For consistency use 2 spaces for indentation (+ 1 default space after `#`)
Some of these were formatted incorrectly in the API docs.
2022-11-16 23:08:07 +01:00
Jonathan Hefner ee8d9497dd Auto-link code references [ci-skip] 2022-11-15 13:57:15 -06:00
Jonathan Hefner 9588f780dc Format inline code [ci-skip] 2022-11-15 13:57:15 -06:00
Jonathan Hefner b5248aca16 Add ActionView.deprecator
This commit adds `ActionView.deprecator` and replaces all usages of
`ActiveSupport::Deprecation.warn` in `actionview/lib` with
`ActionView.deprecator`.  This commit also replaces a call to Ruby's
`Module#deprecate_constant` with Rails' `DeprecatedConstantProxy`, so
that its deprecation behavior can be configured using
`ActionView.deprecator`.

Additionally, this commit adds `ActionView.deprecator` to
`Rails.application.deprecators` so that it can be configured via
settings such as `config.active_support.report_deprecations`.

This commit also removes a few defunct `assert_deprecated` calls that
were not failing because they were nested in `assert_raises`, and the
raised error prevented checking the deprecation.  (One was mistakenly
kept in d52d773946 when converting
`test_render_file_with_errors` to `test_render_template_with_errors`;
the other two were added in dd9991bac5 but
not removed when the deprecation was completed in
85ecf6e4098601222b604f7c1cbdcb4e49a6d1f0.)
2022-10-30 16:01:39 -05:00
Alex Ghiculescu 4fcac154f4 Support `checked` as a keyword argument in `check_box_tag` and `radio_button_tag`
Currently if you do this:

```ruby
check_box_tag "admin", "1", checked: false
```

It is treated [as truthy](19f9922523/actionview/lib/action_view/helpers/form_tag_helper.rb (L444)), and your checkbox is checked. This can be a bit surprising, particularly because the `FormHelper` version [does support](19f9922523/actionview/lib/action_view/helpers/form_helper.rb (L1285)) a keyword argument.

```ruby
f.check_box "admin", checked: false
```

So this PR updates `check_box_tag` and `radio_button_tag` to support `checked` as a positional or keyword argument, this way you can use the same API in both cases.

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2022-10-21 12:41:29 -05:00
Jean Boussier 05919b0802 Fix Action View compatibility with jbuilder
jbuilder is doing some weird things such as instantiatign RenderedTemplate
with a `Hash` instance as a `body`.

So we can't forcibly cast to string in these places.
2022-10-21 13:15:53 +02:00
Aaron Patterson 2f36f0a2bb
Merge pull request #46171 from rails/refactor-errors
Add column information inside ERB templates
2022-10-11 15:10:40 -07:00
Jean Boussier d917896f45 Enable verbose mode in test and report warnings as errors
We recently let a few very easy to avoid warnings get merged.
The root cause is that locally the test suite doesn't run in
verbose mode unless you explictly pass `-w`.

On CI warnings are enabled, but there is no reason to look at the
build output unless something is failing. And even if one wanted
to do that, that would be particularly work intensive since warnings
may be specific to a Ruby version etc.

Because of this I believe we should:

  - Always run the test suite with warnings enabled.
  - Raise an error if a warning is unexpected.

We've been using this pattern for a long time at Shopify both in private
and public repositories.
2022-10-11 09:25:18 +02:00
Aaron Patterson 3deffa9974
Remove unused constant 2022-10-09 16:36:11 -07:00
Aaron Patterson 9f5dee3a91
move ERB monkey patches to their own file 2022-10-09 16:12:37 -07:00
Aaron Patterson 0c55a87ccf
Stop using a global for storing template info
This isn't as easy, but should eliminate any memory leaks in dev
2022-10-09 15:51:23 -07:00
Aaron Patterson aa37b787ef
Use file path as the error lookup key
We have access to the path from the backtrace location object.  If we
use the path of the ERB as the key, then anytime the ERB changes it'll
just overwrite that template instance in the error handling hash
2022-10-09 14:55:50 -07:00
Aaron Patterson cd48642561
Add tests that column information can be translated 2022-10-09 14:52:17 -07:00
Aaron Patterson 1d39573a9f
Move ERB parsing to core_ext 2022-10-09 14:52:17 -07:00
Aaron Patterson a23fef384c
Don't use pattern matching because it's causing warnings 2022-10-09 14:52:17 -07:00
Aaron Patterson f6e20abd27
rubocop 2022-10-09 14:52:17 -07:00
Aaron Patterson 650e99ac5b
Map column information in to ERB templates
This commit maps the column information returned from ErrorHighlight in
to column information within the source ERB template.  ErrorHighlight
only understands the compiled Ruby code, so this commit adds a small
translation layer that converts the values from ErrorHighlight in to the
right values for the ERB source template
2022-10-09 14:52:17 -07:00
Aaron Patterson 343dba47e0
Only deal with backtrace locations in ExceptionWrapper
We should get out of the business of parsing backtraces and only use
backtrace locations.  Backtrace locations have the file and line number
information baked in, so we don't need to parse things anymore
2022-10-09 14:52:17 -07:00
Aaron Patterson 80a698d15c
Use a SyntaxError proxy object when displaying syntax error info
This commit adds a SyntaxErrorProxy object to active support and wraps
syntax error exceptions with that proxy object.  We want to enhance
syntax errors with information about the source location where they
actually happened (normally the backtrace doesn't contain such info).
Rather than mutating the original exception's backtrace, this wraps it
with a proxy object.

Eventually we will implement backtrace_locations on the proxy object so
that the exception handling middleware can be updated to _only_ deal
with backtrace_locations and never deal with raw `backtrace`
2022-10-09 14:52:17 -07:00
pinzonjulian f4812bf690 Allow direct uploads to work within engines 2022-10-06 00:29:27 +11:00
Goulven Champenois f4f15c86a2 Allow passing a class to `dom_id`
You no longer need to call `new` when passing a class to `dom_id`.
This makes `dom_id` behave like `dom_class` in this regard.
Apart from saving a few keystrokes, it prevents Ruby from needing to
instantiate a whole new object just to generate a string.

Before:
```ruby
dom_id(Post) # NoMethodError: undefined method `to_key' for Post:Class
```

After:
```ruby
dom_id(Post) # "new_post"
```

You can still call `dom_id(Post.new)`.
2022-09-20 16:53:12 +02:00
Alexandre Ruban 3259a80a3b [ci skip] Fix form_with documentation
Remote forms are no longer the default with the `form_with` helper.
2022-09-14 12:26:55 +02:00
Aaron Gough b451ff098d Add :locals to ActionView rendering instrumentation 2022-09-08 19:44:09 -04:00
John Hawthorn f5d676cd97
Merge pull request #45957 from jhawthorn/immutable_path_set
Make ActionView::PathSet immutable
2022-09-07 11:40:53 -07:00
John Hawthorn 0371317e25 Make ActionView::PathSet immutable
Previously we would mutate the PathSet in order to implement
{append,prepend}_view_path.

This removes the mutation methods we had and instead constructs a new
PathSet whenever we are modifying it. This should allow flexibility in
the classes holding a view_path to know that their view paths isn't
modified (for example, to allow caching).
2022-09-07 09:40:52 -07:00
John Hawthorn e65d41a47a View path strict type casting 2022-09-06 19:07:53 -07:00
Jonathan Hefner 8265d68796 Improve word_wrap performance
This improves `word_wrap` performance and reduces allocations.

Benchmark:

  ```ruby
  # frozen_string_literal: true
  require "benchmark/ips"
  require "benchmark/memory"

  def before(text, line_width: 80, break_sequence: "\n")
    text.split("\n").collect! do |line|
      line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1#{break_sequence}").chomp!(break_sequence) : line
    end * break_sequence
  end

  def after(text, line_width: 80, break_sequence: "\n")
    pattern = /(.{1,#{line_width}})(?:[^\S\n]+\n?|\n*\Z|\n)|\n/
    text.gsub(pattern, "\\1#{break_sequence}").chomp!(break_sequence)
  end

  TEXT = <<~LOREM
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
    eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
    minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.
  LOREM

  Benchmark.ips do |x|
    x.report("before") { before(TEXT, line_width: 50) }
    x.report("after") { after(TEXT, line_width: 50) }
    x.compare!
  end

  Benchmark.memory do |x|
    x.report("before") { before(TEXT, line_width: 50) }
    x.report("after") { after(TEXT, line_width: 50) }
    x.compare!
  end
  ```

Results:

  ```
  Warming up --------------------------------------
                before   858.000  i/100ms
                 after     2.215k i/100ms
  Calculating -------------------------------------
                before      8.540k (± 1.3%) i/s -     42.900k in   5.024157s
                 after     22.370k (± 1.1%) i/s -    112.965k in   5.050565s

  Comparison:
                 after:    22369.8 i/s
                before:     8540.2 i/s - 2.62x  (± 0.00) slower
  ```

  ```
  Calculating -------------------------------------
                before    13.993k memsize (     0.000  retained)
                         122.000  objects (     0.000  retained)
                          34.000  strings (     0.000  retained)
                 after     5.423k memsize (     0.000  retained)
                          41.000  objects (     0.000  retained)
                          20.000  strings (     0.000  retained)

  Comparison:
                 after:       5423 allocated
                before:      13993 allocated - 2.58x more
  ```
2022-09-06 16:10:31 -05:00
Max Chernyak fe554a3daf Chomp the break_sequence in word_wrap
When word_wrap's break_sequence contains non-rstrippable
characters, word_wrap fails to strip the extra break_sequence at the
end properly. Using chomp! helps cut exactly what was specified in the
argument.
2022-09-05 15:38:23 -04:00
fatkodima 3158bbb9f6 Update `rubocop-performance` and enable more performance-related cops 2022-08-26 15:07:11 +03:00
Jean Boussier 2418939007
Merge pull request #45796 from Shopify/log-subscriber-silenced
Optimize AS::LogSubscriber
2022-08-22 10:43:49 +02:00
John Hawthorn b945dfbb69
Merge pull request #45849 from jhawthorn/reuse_strict_local_templates
Reuse strict locals templates for any locals
2022-08-19 12:26:59 -07:00
John Hawthorn 11612244c7 Avoid calling present? on @strict_locals
This will either be nil or a non-blank string. The case that it is the
empty string is handled (and replaced) at compile. I'd also argue that
it's possible that the empty string could be a valid value that's
considered to be a strict local, we just happen not to use that value
(preferring the "nokey" syntax).
2022-08-18 16:32:11 -07:00
John Hawthorn 5e13363354 Reuse strict locals templates for any locals
This commit allows template lookups and render calls which find a
"strict local" template to reuse that template even when provided with
different locals.

This also makes Template#locals return nil for strict local templates,
to avoid leaking the details of the first lookup. Almost nothing calls
this method, so this should not be a significant change.
2022-08-18 16:32:11 -07:00
HParker ba5f653878 Fix assoc_hash handling in ripper tracker
Previously ripper tracker would misidentify the method name when called with a constant and assoc_hash.

This correctly finds the method name in those cases
2022-08-18 12:27:37 -07:00
Matthew Draper cb5765a127 Merge pull request #44472 from camertron/content_injection_prevention
Add additional content injection prevention to form HTML
2022-08-15 16:39:10 +09:30
Jean Boussier bd19d1baf1 Optimize AS::LogSubscriber
The various LogSubscriber subclasses tend to subscribe to events
but then end up doing nothing if the log level is high enough.

But even if we end up not logging, we have to go through the
entire notification path, record timing etc.

By allowing subscribers to dynamically bail out early, we can
save a lot of work if all subscribers are silenced.
2022-08-12 09:58:17 +02:00
Rafael Mendonça França c8668d3f16
Merge pull request #44614 from voracious/add-renderable-to-render-error-message
Add :renderable to the list of rendering keys supported by ActionView::Renderer#render
2022-08-10 19:18:11 -03:00
Jean Boussier 8994f09dd2
Merge pull request #44616 from ghiculescu/preload-all-if-proc
Always preload if using proc with multifetch cache
2022-08-09 09:01:30 +02:00
Jean Boussier 8b0499aa1d Fix typo in ActionView::OutputBuffer
Fix: #45789

I shouldn't commit this early -_-
2022-08-08 09:53:03 +02:00
Jean Boussier aa0cb6d29a Add ActionView::OutputBuffer#concat back
Fix: https://github.com/rails/rails/issues/45777

The method is being used by HAML, it's easy to add it
back.
2022-08-08 09:04:27 +02:00
Jonathan Hefner 992ead1d57 Standardize format of "Options" subsections [ci-skip] 2022-08-05 21:36:18 -05:00
Jonathan Hefner 32c169d014 Linkify code references [ci-skip] 2022-08-05 21:36:18 -05:00
Jonathan Hefner b13107fe5e Fix typos [ci-skip] 2022-08-05 21:36:18 -05:00
John Hawthorn ee68644c28 Avoid calling to_s at end of ERB
With the recent changes to OutputBuffer, calling `to_s` is extremely
expensive if the buffer later is concatenated to (if the buffer never
changes it should be relatively inexpensive, as Ruby will share memory).
2022-08-03 16:24:12 -07:00
Jean Boussier 4b67dffc8d Refactor Action View tests to stop re-assigning @output_buffer
Followup on https://github.com/rails/rails/pull/45745

`@rendered` is a much better variable for this kind of intermediate
result as that's what is used by DOM assertions.
2022-08-03 15:00:58 +02:00
Jean Boussier 206b2b8319
Merge pull request #45731 from Shopify/action-view-buffer-slice
Add OutputBuffer#raw and #capture to reduce the need to swap the buffer
2022-08-03 14:57:34 +02:00
Jean Boussier fc0db35fb1 Add OutputBuffer#raw and #capture to reduce the need to swap the buffer
Right now many helpers have to deal with two modes of operation to
capture view output.

The main one is to swap the `@output_buffer` variable with a new buffer.
But since some view implementations such as `builder` keep a reference
on the buffer they were initialized with, this doesn't always work.

So additionally, the various capturing helpers also record the buffer
length prior to executing the block, and then `slice!` the buffer back
to its original size.

This is wasteful and make the code rather unclear.

Now that `OutputBuffer` is a delegator, I'd like to refactor all this
so that:

  - @output_buffer is no longer re-assigned
  - A single OutputBuffer instance is used for the entire response rendering
  - Instead capturing is done through `OutputBuffer#capture`

Once the above is achieved, it should allow us to enabled Erubi's
`:chain_appends` option and get some reduced template size and some
performance.

Not re-assigning `@output_buffer` will also allow template to access
the local variable instead of an instance variable, which is cheaper.

But more importantly, that should make the code easier to understand
and easier to be compatible with `StreamingBuffer`.
2022-08-03 12:56:34 +02:00
Jean Boussier 476aeda794 Avoid explictly freezing literals strings when possible
Ref: https://github.com/jeremyevans/erubi/pull/33

If the template is compiled with `frozen_string_literals: true`,
then explicitly freezing string is slightly wasteful as it will be
compiled as `opt_str_freeze` instead of a simple `putobject`.

The former has to check wether `String#freeze` was redefined every
time, which while fast is useless extra work.
2022-08-03 11:15:36 +02:00
Jonathan Hefner 3661d0d8a4
Merge pull request #45675 from hirotaka/fix_date_select_with_locale
Fixes Date Helper with locale
2022-08-02 11:14:25 -05:00
Hirotaka Mizutani 60ca482cf0 Fixes Date Helper with locale
The i18n gem (https://github.com/ruby-i18n/i18n) has been modified to `freeze`
locale setting values. This could cause the Date helper to not work correctly
under certain conditions. `dup` the configuration values fixes that problem.
2022-08-02 18:32:13 +09:00
Joel Hawksley b7908a62f9 Rename 'Explicit Locals` to `Strict Locals`
Per https://github.com/rails/rails/pull/45602#discussion_r934981516
2022-08-01 17:23:47 -06:00
Joel Hawksley bbe7d19e11 Allow templates to define which locals they accept. 2022-08-01 15:42:02 -06:00
John Hawthorn 845f19a275 Avoid dynamic constant get on SET.symbols
Dynamic constant lookups (ie. x::SOME_CONST) are uncommon and slightly
slow operations (not _that_ slow). We know that the ::SET constant won't
change (this is a private API and it is called only with our own
classes) so we can switch this to an attr_reader for fast access on the
call to delgate_to.

This also removes the unused `type_klass` attr_accessor.
2022-07-29 12:54:40 -07:00
Jean Boussier 532e39ae01 Always use an actual Action View buffer to render templates
`ActionView::TestCase` would use an `ActiveSupport::SafeBuffer`
which behaves a bit differently. This never happens in production
so it's better to use a more accurate test.
2022-07-28 12:55:58 +02:00
Jean Boussier 55756eacbd Get rid of Erubi#evaluate
It's only used by a handful of tests, but having two ways to
evaluate ERB makes it very confusing. The few tests using it can
go through ActionView::Template instead.
2022-07-28 12:16:40 +02:00
Jean Boussier 06e9fbd954
Merge pull request #45614 from Shopify/faster-output-buffer
Speedup ActionView::OutputBuffer
2022-07-19 21:08:49 +02:00
Jean Boussier 4e8e828291 Speedup ActionView::OutputBuffer
MRI has a lot of optimizations for string concatenation that
are only available when concatenating into a `String` instance.

Using a `String` subclass disable these optimizations.

The difference is even more important with YJIT.

So ideally we want the buffer not to be a String subclass.
Luckily, the Action View buffer is for internal use only, so
we can replace inheritance by composition without much work.

Benchmark:

```
ActionView::OutputBuffer:   147644.2 i/s
    optimized buffer:   228001.4 i/s - 1.54x  (± 0.00) faster
```

Source: https://gist.github.com/casperisfine/7199579a138e268fda71d6a91366af49

NB: That 50% faster figure is to be contextualized, it can radically change
from one template to the other, but is always faster.
2022-07-19 12:13:34 +02:00
fatkodima 3822172c00 Fix caching of missed translations 2022-07-15 14:49:11 -05:00
Diego Michel eeb14214fd Fixes rubydoc links
Uses gem version of documentation instead of repo version

Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
2022-07-11 12:58:12 -06:00
Wojciech Wnętrzak 2dea9aebf2
Add include_seconds option to datetime_local_field.
This allows to omit seconds part in the input field, by passing `include_seconds: false`

It's a follow up to https://github.com/rails/rails/pull/41728
2022-07-06 22:27:04 +02:00
Sean Doyle 8a0bc4aa90 Support calls to `#field_name` with nil `object_name`
It's possible for `ActionView::Helpers::FormTagHelper#field_name` calls
made by instances constructed through `fields` and `fields_for` helpers
to have an `object_name` argument that's `nil`. For example, the
following will raise an `undefined method `empty?' for nil:NilClass`
exception:

```erb
<%= fields do |f| %>
  <%= f.field_name :body %>
<% end %>
```

To guard against those calls, replace the method's call to
`String#empty?` with `Object#blank?`, since `NilClass#empty?` is not
defined.
2022-06-15 18:51:20 +01:00
Deepak Mahakale b2ed0b768d
Fix typo in documentation examples (#45272) 2022-06-06 06:01:26 -04:00
Mike Dalessio 5f8f6764d8
Strings returned from `strip_tags` are correctly tagged `html_safe?`
Because these strings contain no HTML elements and the basic entities
are escaped, they are safe to be included as-is as PCDATA in HTML
content. Tagging them as html-safe avoids double-escaping entities
when being concatenated to a SafeBuffer during rendering.

Fixes https://github.com/rails/rails-html-sanitizer/issues/124
2022-05-31 10:02:07 -04:00
John Hawthorn a5b2b6155c
Merge pull request #45169 from oneiros/allow_all_available_locales_for_template_lookup
Allow all available locales for template lookups
2022-05-30 11:49:40 -07:00
David Roetzel 12c12899df Allow all available locales for template lookups.
Following the discussion here:
https://github.com/rails/rails/pull/44174/files#r785160819

Background: The `i18n` gem is relatively lax when it comes
to naming locales. It does not enforce any standard. Thus
it is possible to have e.g. per tenant locales (think
`en_tenant1`, `en_tenant2` etc.). This also worked for
translated templates up until rails 6.1.

Rails 7 changed the template lookup and enforced a naming
scheme for locales. This poses a problem for legacy apps
that use non-standard locale names.

This commit changes the way locale names are detected in
template file names. In addition to the previously used
regexp it also allows all known locales from
`I18n.available_locales`.

This makes it backwards compatible to rails 7.0
behavior while also allowing non-standard locale names.
Thanks to jvillarejo for the great idea.

Also introduce the usage of `Regexp.union`, a wonderful
suggestion by casperisfine.
2022-05-30 09:45:28 +02:00
Gannon McGibbon 01f58d62c2
Merge pull request #45180 from gmcgibbon/deprecate_behaviour_constant
Deprecate behaviour constant
2022-05-27 09:06:54 -04:00
Gannon McGibbon 3dad2919d5 Rename behaviour to behavior in documentation 2022-05-26 17:14:18 -04:00
Lachlan Sylvester 3e2158442b remove rendered_format from LookupContext 2022-05-26 18:04:24 +10:00
Sean Doyle 980de46f54 Move `convert_to_model` call from `form_for` to `form_with`
Ensure models passed to `form_with` attempt to call `to_model`.

Now that `form_for` is implemented in terms of `form_with`, this commit
also removes the `convert_to_model` call from the `form_for` implementation.

To exercise this behavior, change existing `form_with` test coverage.

Prior to this change, a call to `form_with` made with a `model:` argument
that responds to `to_model` would not incorporate the instance's persistence
state into the form's HTTP verb. After this change, the persistence state
inferred from the `model:` argument's `to_model` call is incorporated into
the `<form>` element's `[method]` attribute.

This is a separate follow-up change proposed in [rails/rails#44328][].
The original change to restore old behavior _deliberately_ excluded
applying the same logic to `form_with`, since it would be a breaking
change from how `form_with` behaved previously.

This commit proposed making that breaking change.

[rails/rails#44328]: https://github.com/rails/rails/pull/44328#discussion_r808475585
2022-05-25 09:48:58 -04:00
Cameron Dutro 59ead5343a Add additional content exfiltration prevention to form tags 2022-05-23 17:46:37 +00:00
Shouichi Kamiya aaa9bcc62e Document that url_for can take classes
Co-authored-by: oljfte <oljfte@gmail.com>
2022-05-13 10:09:17 +09:00
Alex Ghiculescu 3f1f4c7d0c Always preload if using proc with multifetch cache
https://github.com/rails/rails/pull/31250 optimised rendering a collection with `cached: true`, but also with `cached: proc {}`. The problem is the proc may reference associations that should be preloaded to avoid n+1s in generating the cache key.

For example:

```ruby
@posts = Post.preload(:author)

@view.render partial: "test/partial", collection: @post, cached: proc { |post| [post, post.author] }
```

This will n+1 on `post.author`.

To fix this, this PR will always preload the collection if there's a proc given for `cached`. `cached: true` will still not preload unless it renders, as it did in https://github.com/rails/rails/pull/31250.
2022-05-07 22:19:39 +10:00
Jonathan Hefner fe24f5880d Escape literal dot in regular expression
Follow-up to #44669.

This ensures that e.g. sizes with commas are not erroneously matched.
2022-05-05 14:08:43 -05:00
Alvaro Martin Fraguas 649516ce0f
Fix and add protections for XSS in names.
Add the method ERB::Util.xml_name_escape to escape dangerous characters
in names of tags and names of attributes, following the specification of
XML.

Use that method in the tag helpers of ActionView::Helpers. Rename the option
:escape_attributes to :escape, to simplify by applying the option to the whole
tag.
2022-04-26 12:34:42 -07:00
Xavier Noria 2953ae5c8a Define config.enable_reloading to be !config.cache_classes
Every time I write `config.cache_classes` I have to pause for a moment to make
sure I get it right. It makes you think.

On the other hand, if you read `config.enable_reloading = true`, does the
application reload? You do not need to spend 1 cycle of brain CPU to nod.
2022-04-14 18:11:36 +02:00
Jonathan Hefner 255accb0a5 Fix button_to UJS examples formatting [ci-skip]
Because the indented code block follows an indented list item, RDoc
interprets the examples as a continuation of the list item prose,
instead of code.  To distinguish the two, this commit moves the examples
to their own subsection with an intervening subheading.

Additionally, this commit applies a few other formatting tweaks.
2022-04-11 15:35:58 -05:00
Jonathan Hefner 7ad1bc8845 Fix link_to UJS examples formatting [ci-skip]
Because the indented code block follows an indented list item, RDoc
interprets the examples as a continuation of the list item prose,
instead of code.  To distinguish the two, this commit moves the examples
to their own subsection with an intervening subheading.

Additionally, this commit applies a few other formatting tweaks.
2022-04-11 15:35:24 -05:00
Jonathan Hefner eea6f4dc81
Merge pull request #44784 from ghiculescu/data-remote-no-turbo
Document that `data-remote` and `data-method` are deprecated [ci-skip]
2022-04-11 15:27:35 -05:00
Alex Ghiculescu be746b2623 Document that `data-remote` and `data-method` are deprecated
Follow up to https://github.com/rails/rails/pull/43112 and https://github.com/rails/rails/pull/44100

- `data-remote` is deprecated on links and buttons. Turbo doesn't need it since that is the default behaviour. You use `data-turbo=false` on elements that opt out of that, but I don't think that's in scope for Rails.
- `data-method` is deprecated on links. Turbo expects [data-turbo-method](https://turbo.hotwired.dev/handbook/drive#performing-visits-with-a-different-method).

Update actionview/lib/action_view/helpers/url_helper.rb

Co-authored-by: Hartley McGuire <skipkayhil@gmail.com>

Update actionview/lib/action_view/helpers/url_helper.rb

Co-authored-by: Hartley McGuire <skipkayhil@gmail.com>
2022-04-11 13:03:14 -05:00
Ryuta Kamizono 714fd07fd9 All intermediate delegation methods should preserve kwargs flag
Since 0456826180,
`foo(*caller_args)` method call delegation no longer preserve kwargs
flag.

Fixes #44846.
2022-04-06 15:32:54 +09:00
John Bampton c38d585ef0 Fix word casing of `XHTML` and `XML Builder`
Co-authored-by: Petrik de Heus <petrik@deheus.net>
2022-03-30 04:21:59 +10:00
Rafael Mendonça França 5c1bd20f0d
Merge pull request #44693 from ghousemohamed/fix-docs-related-gem-versions
Fix `#version` method docs and some typos [ci-skip]
2022-03-15 16:28:07 -04:00
Ghouse Mohamed 6ee6cb554b Fix #version docs and some typos 2022-03-16 01:48:37 +05:30
Aaron Patterson 8961b8ece7
Merge pull request #44669 from kaiquekandykoga/extract-float
Extract float
2022-03-14 15:16:06 -07:00
Kaíque Kandy Koga 16e6d77200 Extract float numbers when using size option
for image_tag and video_tag

Delete space

format_numbers number_formats

Add tests

Change tests

Use regex in extract_dimensations
2022-03-14 14:11:07 -03:00
Aaron Patterson d28efa55fa
Merge pull request #43975 from codergeek121/bugfix-for-time-select-prompt
Fix a bug with time_select and prompts
2022-03-14 09:44:42 -07:00
Matheus Richard 414394206a Extend audio_tag and video_tag to accept Active Storage attachments.
Now it's possible to write

    audio_tag(user.audio_file)
    video_tag(user.video_file)

Instead of

    audio_tag(polymorphic_path(user.audio_file))
    video_tag(polymorphic_path(user.video_file))

image_tag already supported that, so this follows the same pattern.
2022-03-14 02:05:37 -03:00
David R. Myers 9b39d1862f
Add :renderable to the list of rendering keys supported by ActionView::Renderer#render
Also, alphabetize the output list
2022-03-04 11:38:59 -05:00
Jean Boussier 13dd6f93c8
Merge pull request #44585 from davekaro/remove_circle_void_element
Remove circle from HTML_VOID_ELEMENTS set.
2022-03-02 20:26:45 +01:00
Jean Boussier 2fd34270eb Eager load controllers `view_context_class`
These classes are relatively small, however they include lots of
modules as helpers. And if any of the included module hold constants
including it cause the global constant cache to be invalidated
which is really bad for performance.

So when eager loading is enabled we create all the possible classes
as part of the application boot.
2022-03-02 08:47:54 +01:00
Dave Kroondyk 8d51706c20 Remove circle from HTML_VOID_ELEMENTS set.
`<circle>` is in the SVG_SELF_CLOSING_ELEMENTS list and is not a void element according to
'https://html.spec.whatwg.org/multipage/syntax.html#void-elements'.
2022-03-01 09:08:23 -05:00
Dave Kroondyk 3814826885 Ensure SVG elements are closed.
Changes introduced in https://github.com/rails/rails/pull/43232 break SVGs
that have mulitple of the same descendant tag because they weren't being
closed. SVG elements must be closed accodoring to spec
https://html.spec.whatwg.org/multipage/syntax.html#elements-2.

Fixes https://github.com/rails/rails/issues/44563
2022-02-28 17:52:02 -05:00
Koichi ITO 819871cc4e Enable `Style/MapToHash` cop
Ruby 2.6 added block argument processing to `Enumerable#to_h`.
https://bugs.ruby-lang.org/issues/15143

Rails 7 requires Ruby 2.7.0 or higher, so the new feature can use it.
`Style/MapToHash` cop will detect it. And this cop in the `Style` department,
but this seems to improve performance as follows:

```ruby
# map_to_hash.rb
require 'benchmark/ips'

ARRAY = (1..100).to_a
HASH = {foo: 1, bar: 2}

Benchmark.ips do |x|
  x.report('array.map.to_h') { ARRAY.map { |v| [v, v * 2] }.to_h }
  x.report('array.to_h')     { ARRAY.to_h { |v| [v, v * 2] } }

  x.compare!
end

Benchmark.ips do |x|
  x.report('hash.map.to_h') { HASH.map { |k, v| [k.to_s, v * 2] }.to_h }
  x.report('hash.to_h')     { HASH.to_h { |k, v| [k.to_s, v * 2] } }

  x.compare!
end
```

```console
% ruby map_to_hash.rb
Warming up --------------------------------------
      array.map.to_h     9.063k i/100ms
          array.to_h     9.609k i/100ms
Calculating -------------------------------------
      array.map.to_h     89.063k (± 3.9%) i/s -    453.150k in  5.096572s
          array.to_h     96.449k (± 1.7%) i/s -    490.059k in  5.082529s

Comparison:
          array.to_h:    96448.7 i/s
      array.map.to_h:    89063.4 i/s - 1.08x  (± 0.00) slower

Warming up --------------------------------------
       hash.map.to_h   106.284k i/100ms
           hash.to_h   149.354k i/100ms
Calculating -------------------------------------
       hash.map.to_h      1.102M (± 2.2%) i/s -      5.527M in   5.019657s
           hash.to_h      1.490M (± 0.9%) i/s -      7.468M in   5.013264s

Comparison:
           hash.to_h:  1489707.0 i/s
       hash.map.to_h:  1101561.5 i/s - 1.35x  (± 0.00) slower
```

`Style/MapToHash` cop ... https://docs.rubocop.org/rubocop/1.25/cops_style.html#stylemaptohash
2022-02-26 04:31:03 +09:00
Jonathan Hefner a199aaedb8 Cross-link API docs [ci-skip]
RDoc will automatically format and link API references as long as they
are not already marked up as inline code.

This commit removes markup from various API references so that those
references will link to the relevant API docs.
2022-02-21 11:45:25 -06:00
Jonathan Hefner 9dbf7a58a2 Fix formatting of parameters doc [ci-skip] 2022-02-21 11:11:11 -06:00
Jonathan Hefner a801aa7cde Mark up inline code [ci-skip] 2022-02-21 11:11:11 -06:00
Jonathan Hefner e37adfed4e Add Oxford commas [ci-skip] 2022-02-21 11:11:11 -06:00
Jonathan Hefner 07bee949c4 Replace backticks with RDoc markup [ci-skip]
RDoc does not support backticks the way that Markdown does.  Instead,
inline code must be wrapped with `+` or `<tt>`.
2022-02-21 11:11:11 -06:00
Jonathan Hefner 0d3effc97e Replace "overwrite" with "override" [ci-skip]
"Overwrite" means "destructively replace", and is more suitable when,
for example, talking about writing data to a location.

"Override" means "supersede", and is more suitable when, for example,
talking about redifining methods in a subclass.
2022-02-21 11:11:11 -06:00
Jonathan Hefner 5fdbd217d1 Fix typos [ci-skip] 2022-02-21 11:11:11 -06:00