aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Add a warning for enum elements with 'not_' prefix.Edu Depetris2019-06-303-0/+39
| | | | | | | | | | When a enum element contains the prefix 'not_'. I warns to users to be aware of this new feature. Example code: class Foo < ActiveRecord::Base enum status: [:sent, :not_sent] end
* Make `bin/setup` test pass even if the database does not existyuuji.yaginuma2019-06-301-1/+1
|
* Link to top of PR as well as other links [ci skip]yuuji.yaginuma2019-06-291-1/+1
|
* Add "SCHEMA" to the query in `configure_connection` like as other adaptersRyuta Kamizono2019-06-281-1/+1
| | | | | | | This makes to be able to ignore the query in `assert_queries` even if accidentally reconnected a connection. https://buildkite.com/rails/rails/builds/61917#4c49187a-3173-4d5c-8a8d-d65768f5bfc9/1000-1799
* warning: instance variable @serial not initialized (#36556)utilum2019-06-281-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Introduced in bba7c63a663b073034f4c73f0d59655751694e5a Before: ``` $ TESTOPTS="-n=/test_yaml_dump_and_load/" bundle exec rake test:postgresql :scisors: ... :scisors: Using postgresql Run options: -n=/test_yaml_dump_and_load/ --seed 36896 /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized /home/u/code/rails/activerecord/lib/active_record/connection_adapters/postgresql/column.rb:15: warning: instance variable @serial not initialized . Finished in 0.195325s, 5.1197 runs/s, 35.8376 assertions/s. 1 runs, 7 assertions, 0 failures, 0 errors, 0 skips ``` Co-authored-by: Ryuta Kamizono <kamipo@gmail.com>
* Merge pull request #36565 from rails/fix-url-configsEileen M. Uchitelle2019-06-273-2/+33
|\ | | | | Fix broken url configs
| * Fix broken url configseileencodes2019-06-273-2/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This PR is to fix #36559 but I also found other issues that haven't been reported. The check for `(config.size == 1 && config.values.all? { |v| v.is_a? String })` was naive. The only reason this passed was because we had tests that had single hash size configs, but that doesn't mean we don't want to create a hash config in other cases. So this now checks for `config["database"] || config["adapter"] || ENV["DATABASE_URL"]`. In the end for url configs we still get a UrlConfig but we need to pass through the HashConfig to create the right kind of UrlConfig. The UrlConfig's are really complex and I don't necessarily understand everything that's needed in order to act the same as Rails 5.2. I edited the connection handler test to demonstrate how the previous implementation was broken when checking config size. Now old and new tests pass so I think this is closer to 5.2. Fixes #36559
* | Address to "DEPRECATION WARNING: Uniqueness validator will no longer enforce ↵Ryuta Kamizono2019-06-281-1/+1
|/ | | | | | case sensitive comparison in Rails 6.1" Caused by #36210.
* Merge pull request #36560 from eileencodes/warn-if-database-yml-cant-be-readEileen M. Uchitelle2019-06-273-9/+48
|\ | | | | Warn if we can't read the yaml to create database tasks
| * Load initial database.yml once, and warn if we can't create taskseileencodes2019-06-273-9/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For multiple databases we attempt to generate the tasks by reading the database.yml before the Rails application is booted. This means that we need to strip out ERB since it could be reading Rails configs. In some cases like https://github.com/rails/rails/issues/36540 the ERB is too complex and we can't overwrite with the DummyCompilier we used in https://github.com/rails/rails/pull/35497. For the complex causes we simply issue a warning that says we couldn't infer the database tasks from the database.yml. While working on this I decided to update the code to only load the database.yml once initially so that we avoid having to issue the same warning multiple times. Note that this had no performance impact in my testing and is merely for not having to save the error off somewhere. Also this feels cleaner. Note that this will not break running tasks that exist, it will just mean that tasks for multi-db like `db:create:other_db` will not be generated. If the database.yml is actually unreadable it will blow up during normal rake task calls. Fixes #36540
* | [ci skip] Update free-programming-books link in getting started guideMasayuki Morita2019-06-261-1/+1
| | | | | | | | | | https://github.com/vhf/free-programming-books seems to have moved to https://github.com/EbookFoundation/free-programming-books
* | `length(title)` is a safe SQL string since #36448Ryuta Kamizono2019-06-261-2/+2
| |
* | Merge pull request #36555 from dineshpanda/update-initialization-guideRafael França2019-06-251-0/+4
|\ \ | | | | | | [ci skip] Refer actionmailbox and actiontext in the guide
| * | [ci skip] Refer actionmailbox and actiontext in the guidedineshpanda2019-06-261-0/+4
|/ /
* | Merge pull request #36553 from tatsuyafw/fix-robots-txt-urlRyuta Kamizono2019-06-252-2/+2
|\ \ | | | | | | Replace the www.robotstxt.org URL with https one [ci skip]
| * | Replace the www.robotstxt.org URL with https one [ci skip]Tatsuya Hoshino2019-06-252-2/+2
|/ / | | | | | | The robots.txt site is moved permanently to https URL.
* | Merge pull request #36530 from benoittgt/source_annotation_deprecation_issueRafael França2019-06-241-1/+1
|\ \ | |/ |/| Rely on Kernel require instead of self require
| * Rely on Kernel require instead of self requireBenoit Tigeot2019-06-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With this code (exctracted from derailed_benchmarks): ```ruby require "bundler/inline" gemfile(true) do source "https://rubygems.org" gem "rails", "~> 6.0.0.rc1", require: false end FILES = [ "rails/engine/configuration", "rails/source_annotation_extractor", "active_support/deprecation" ] module Kernel alias :original_require :require def require(file) Kernel.require(file) end class << self alias :original_require :require end end Kernel.define_singleton_method(:require) do |file| original_require(file) end FILES.each do |file| puts "requiring file: #{file}" require file end ``` It fails with Rails 6 and the change introduced by 32065 ``` requiring file: rails/engine/configuration requiring file: rails/source_annotation_extractor Traceback (most recent call last): 11: from repro_derailed.rb:33:in `<main>' 10: from repro_derailed.rb:33:in `each' 9: from repro_derailed.rb:35:in `block in <main>' 8: from repro_derailed.rb:21:in `require' 7: from repro_derailed.rb:30:in `block in <main>' 6: from repro_derailed.rb:30:in `require' 5: from /Users/benoit.tigeot/.rvm/gems/ruby-2.5.1/gems/railties-6.0.0.rc1/lib/rails/source_annotation_extractor.rb:8:in `<top (required)>' 4: from /Users/benoit.tigeot/.rvm/gems/ruby-2.5.1/gems/activesupport-6.0.0.rc1/lib/active_support/deprecation/proxy_wrappers.rb:10:in `new' 3: from /Users/benoit.tigeot/.rvm/gems/ruby-2.5.1/gems/activesupport-6.0.0.rc1/lib/active_support/deprecation/proxy_wrappers.rb:10:in `new' 2: from /Users/benoit.tigeot/.rvm/gems/ruby-2.5.1/gems/activesupport-6.0.0.rc1/lib/active_support/deprecation/proxy_wrappers.rb:125:in `initialize' 1: from /Users/benoit.tigeot/.rvm/gems/ruby-2.5.1/gems/activesupport-6.0.0.rc1/lib/active_support/deprecation/proxy_wrappers.rb:23:in `method_missing' /Users/benoit.tigeot/.rvm/gems/ruby-2.5.1/gems/activesupport-6.0.0.rc1/lib/active_support/deprecation/proxy_wrappers.rb:148:in `warn': private method `warn' called for nil:NilClass (NoMethodError) ``` Related: - https://github.com/schneems/derailed_benchmarks/pull/130 - https://github.com/rails/rails/pull/32065
* | Merge pull request #36210 from ↵Rafael França2019-06-244-1/+49
|\ \ | | | | | | | | | | | | vishaltelangre/raise-record-invalid-when-associations-fail-to-save-due-to-uniqueness-failure Fix: ActiveRecord::RecordInvalid is not raised when an associated record fails to #save! due to uniqueness validation failure
| * | Fix: ActiveRecord::RecordInvalid is not raised when an associated record ↵Vishal Telangre2019-05-104-1/+49
| | | | | | | | | | | | | | | | | | | | | | | | fails to #save! due to uniqueness validation failure Add tests Fix tests failing due to introduction of uniquness rule added to Book model
* | | Update link to OWASP XSS cheat sheet [ci skip]Aaron Suarez2019-06-231-1/+1
| | |
* | | Test against all sent attributesyuuji.yaginuma2019-06-231-0/+2
| |/ |/|
* | Indentation >>Akira Matsuda2019-06-221-6/+6
| |
* | Schema Cache: extract deduplication commonalityKasper Timm Hansen2019-06-211-10/+15
| |
* | Merge pull request #36529 from Shopify/schema-cache-deduplication-init-withKasper Timm Hansen2019-06-211-6/+6
|\ \ | | | | | | Also deduplicate schema cache data when using the init_with interface
| * | Also deduplicate schema cache data when using the init_with interfaceJean Boussier2019-06-211-6/+6
|/ /
* | Merge pull request #36490 from y-yagi/revise_36034Yuji Yaginuma2019-06-217-1/+79
|\ \ | | | | | | Make `ActionDispatch::Response#content_type` behavior configurable
| * | Make `ActionDispatch::Response#content_type` behavior configurableyuuji.yaginuma2019-06-217-1/+79
|/ / | | | | | | | | | | | | | | | | I changed return value of `ActionDispatch::Response#content_type` in #36034. But this change seems to an obstacle to upgrading. https://github.com/rails/rails/pull/36034#issuecomment-498795893 Therefore, I restored the behavior of `ActionDispatch::Response#content_type` to 5.2 and deprecated old behavior. Also, made it possible to control the behavior with the config.
* | Merge pull request #36526 from yahonda/test_statement_cache_with_in_clause_pgRyuta Kamizono2019-06-211-1/+1
|\ \ | | | | | | Address test_statement_cache_with_in_clause failure
| * | Address test_statement_cache_with_in_clause failure due to nondeterministic ↵Yasuo Honda2019-06-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | sort order This failure is occasional, does not always reproduce. ```ruby $ cd activerecord $ bundle exec rake test_postgresql ... snip ... ....F Failure: ActiveRecord::BindParameterTest#test_statement_cache_with_in_clause [/home/yahonda/git/rails/activerecord/test/cases/bind_parameter_test.rb:97]: Expected: [1, 3] Actual: [3, 1] rails test home/yahonda/git/rails/activerecord/test/cases/bind_parameter_test.rb:93 ```
* | | Merge pull request #36525 from ↵Rafael França2019-06-203-3/+4
|\ \ \ | |/ / |/| | | | | | | | eileencodes/revert-integer-change-to-schema-migration Revert schema dumper to use strings rather than integers
| * | Revert schema dumper to use strings rather than integerseileencodes2019-06-203-3/+4
|/ / | | | | | | | | | | | | | | | | | | | | I think we should change this, but not in 6-0-stable since that's already in RC and I was trying to only make changes that won't require any app changes. This reverts a portion of https://github.com/rails/rails/pull/36439 that made all schema migration version numbers get dumped as an integer. While it doesn't _really_ matter it did change behavior. We should bring this back in 6.1 with a deprecation.
* | Merge pull request #36520 from kamipo/test_case_for_deterministic_orderRyuta Kamizono2019-06-201-0/+6
|\ \ | | | | | | Add test cases to ensure deterministic order for ordinal methods
| * | Add test cases to ensure deterministic order for ordinal methodsRyuta Kamizono2019-06-191-0/+6
| | | | | | | | | | | | | | | | | | Before 1340498d2, `order` with no-op value (e.g. `nil`, `""`) had broken the contract of ordinal methods, which returns a result deterministic ordered.
* | | Merge pull request #36523 from ↵Yuji Yaginuma2019-06-202-0/+3
|\ \ \ | | | | | | | | | | | | | | | | y-yagi/include_bcc_in_mail_sent_from_development_page Include BCC in the mail that sent from the development page
| * | | Include BCC in the mail that sent from the development pageyuuji.yaginuma2019-06-202-0/+3
|/ / / | | | | | | | | | | | | The BCC should be included as we show input field for BCC in view. https://github.com/rails/rails/blob/bf625f7fecabbcda22b388e088ad5c29016b2385/actionmailbox/app/views/rails/conductor/action_mailbox/inbound_emails/new.html.erb#L21-L24
* | | Merge pull request #36486 from benthorner/masterYuji Yaginuma2019-06-204-6/+32
|\ \ \ | | | | | | | | Allow using env var to specify pidfile
| * | | Allow using env var to specify pidfileBen Thorner2019-06-194-6/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously it was only possible to specify the location of the pidfile for the 'rails server' command with the '-P' flag. This adds support for specifying the pidfile using a PIDFILE env var, which can still be overridden by the '-P' flag and with the default pidfile path unchanged. The motivation for this feature comes from using Docker to run multiple instances of the same rails app. When developing a rails app with Docker, it's common to bind-mount the rails root directory in the running container, so that changes to files are shared between the container and the host. However, this doesn't work so well with the pidfile and it's necessary to (remember to) add a '-P' flag to the 'rails server' command line; being able to specify this flag using an env var would make developing with Rails+Docker a bit simpler.
* | | | Merge pull request #36518 from Shopify/drop-schema-cache-column-hashKasper Timm Hansen2019-06-191-8/+5
|\ \ \ \ | | | | | | | | | | Stop serializing and parsing columns_hash in Active Record schema caches
| * | | | Stop serializing and parsing columns_hash in Active Record schema cachesJean Boussier2019-06-191-8/+5
| | |/ / | |/| |
* | | | Merge pull request #36521 from itsWill/autoloading_in_exceptionsGannon McGibbon2019-06-192-0/+5
|\ \ \ \ | | | | | | | | | | Autoload SyntaxErrorInTemplate
| * | | | Autoload SyntaxErrorInTemplateGuilherme Mansur2019-06-192-0/+5
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a SyntaxError is detected in a template we raise this exception. On a first request to the server the exception we get a NameError since the exception is not required from `active_view/template/error.rb` yet. However later on it gets required and a second request will succeed. On the first request we see the rails "Something Wen Wrong" page and not the expected syntax error in template error page with the webconsole and stacktrace. By autoloading the constant we fix this issue. Co-authored-by: Gannon McGibbon <gannon.mcgibbon@gmail.com>
* | | | Merge pull request #36279 from itsWill/better_error_messages_for_abstract_tableGannon McGibbon2019-06-194-0/+19
|\ \ \ \ | |/ / / |/| | | Better error message for calling columns_hash
| * | | Better error message for calling columns_hashGuilherme Mansur2019-06-194-0/+19
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a record does not have a table name, as in the case for a record with `self.abstract_class = true` and no `self.table_name` set the error message raises a cryptic: "ActiveRecord::StatementInvalid: Could not find table ''" this patch now raises a new `TableNotSpecified Error` Fixes: #36274 Co-Authored-By: Eugene Kenny <elkenny@gmail.com>
* | | Merge pull request #35891 from Shopify/schema-cache-deduplicationKasper Timm Hansen2019-06-1912-16/+123
|\ \ \ | | | | | | | | Deduplicate various Active Record schema cache structures
| * | | Deduplicate various Active Record schema cache structuresJean Boussier2019-06-0312-16/+123
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Real world database schemas contain a lot of duplicated data. Some column names like `id`, `created_at` etc can easily be repeated hundreds of times. Same for SqlTypeMetada, most database will contain only a limited number of possible combinations. This result in a lot of wasted memory. The idea here is to make these data sctructures immutable, use a registry to substitute similar instances with pre-existing ones.
* | | | Merge pull request #36508 from kamipo/avoid_getutcRyuta Kamizono2019-06-183-10/+10
|\ \ \ \ | | | | | | | | | | Avoid redundant `time.getutc` call if it is already utc time object
| * | | | Avoid redundant `time.getutc` call if it is already utc time objectRyuta Kamizono2019-06-183-10/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently `type.serialize` and `connection.{quote|type_cast}` for a time object always does `time.getutc` call regardless of whether it is already utc time object or not, that duplicated proccess (`connection.type_cast(type.serialize(time))`) allocates extra/useless time objects for each type casting. This avoids that redundant `time.getutc` call if it is already utc time object. In the case of a model has timestamps (`created_at` and `updated_at`), it avoids 6,000 time objects allocation for 1,000 times `model.save`. ```ruby ObjectSpace::AllocationTracer.setup(%i{path line type}) pp ObjectSpace::AllocationTracer.trace { 1_000.times { User.create } }.select { |k, _| k[0].end_with?("quoting.rb", "time_value.rb") } ``` Before (c104bfe424e6cebe9c8e85a38515327a6c88b1f8): ``` {["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 203, :T_ARRAY]=>[1004, 0, 778, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 220, :T_STRING]=>[2, 0, 2, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 209, :T_ARRAY]=>[8, 0, 8, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 57, :T_ARRAY]=>[4, 0, 4, 1, 1, 0], ["~/rails/activemodel/lib/active_model/type/helpers/time_value.rb", 17, :T_DATA]=>[4000, 0, 3096, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 120, :T_DATA]=>[2000, 0, 1548, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 126, :T_STRING]=>[4000, 0, 3096, 0, 1, 0]} ``` After (this change): ``` {["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 203, :T_ARRAY]=>[1004, 0, 823, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 220, :T_STRING]=>[2, 0, 2, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 209, :T_ARRAY]=>[8, 0, 8, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 57, :T_ARRAY]=>[4, 0, 4, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 126, :T_STRING]=>[2000, 0, 1638, 0, 1, 0]} ```
* | | | | Merge pull request #36482 from Shopify/fix-translation-helper-default-hashRafael França2019-06-172-1/+6
|\ \ \ \ \ | |/ / / / |/| | | | Fix TranslationHelper#translate handling of Hash defaults
| * | | | Fix TranslationHelper#translate handling of Hash defaultsJean Boussier2019-06-142-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It is sometimes expected of the `translate` methods to return a Hash, for instance it's the case of the `number.format` key. As such users might need to specify a Hash default, e.g. `translate(:'some.format', default: { separator: '.', delimiter: ',' })`. This works as expected with the `I18n.translate` methods, however `TranslationHelper#translate` apply `Array()` on the default value. As a result the default value end up as `[:separator, '.', :delimiter, ',']`.