
Ruby on Rails 3 - Final Release Notes
- Transfer
Table of contents
- Migrating to Rails 3.0
- Rails 3 Requires Ruby 1.8.7+
- Application object in Rails
script/*
replaced byscript/rails
- Dependencies and
config.gem
- Transition process
- Building an application on Rails 3.0
- Inclusion of gems
- Life is on the verge
- Architectural changes
- Cooldown Railties
- All Rails core components are now independent
- Active Model Abstraction
- Controller abstraction
- Arel Integration
- Extract Mail
- Documentation
- Internationalization
- Railties
- Action pack
- Abstract controller
- Action controller
- Action dispatch
- Action view
- Active model
- ORM abstraction and interface with Action Pack
- Validations
- Active record
- Query interface
- Enhancements
- Patches and deprecated methods
- Active resource
- Active support
- Action mailers
- About the creators
Introduction
Ruby on Rails 3.0 is released! He will cook dinner for you and fill the washing machine with linen. You will still wonder how you used to live without him. These are the best rails we have ever made!
But seriously speaking, it was a really great thing. With the arrival of the creators of Merb in the team, we implemented their best ideas, and, in addition, emphasized the agnosticism of the framework, simplifying and speeding up the code, and also added a handful of new APIs. If you upgrade to Rails 3.0 with Merb 1.x, you will likely be familiar with a lot. And you certainly will love Rails 3.0, moving from any version 2.x.
But even if you don’t care about the internal cleaning of the code, you still will not feel the taste of Rails 3.0. We have prepared a whole bunch of new features and updated APIs. It's time to become a Rails developer. Here are the main changes:
- A brand new RESTful-style router;
- New API for Action Mailer, created in the image and likeness of Action Controller (from now on without the hellish sending of messages from several parts);
- Language for creating a query chain in Active Record, built on the basis of relational algebra;
- Unobtrusive Javascript helpers with drivers for Prototype, jQuery and, in the near future, other frameworks (end to inline JS);
- Explicit dependency management with the Bundler.
These release notes cover only the main innovations, but not every bugfix or minor change is taken away. Rails 3.0 consists of about 4,000 commits from more than 1,600 authors! If you need to know everything to the smallest detail, pay attention to the list of all commits .
1. Transition to Rails 3
As usual, when upgrading to the new version, it’s best to have your code covered as much as possible with tests. And, for starters, you'd better upgrade to 2.3.5 to make sure your application is working properly even before upgrading to Rails 3.0.
1.1 Rails 3.0 Requires Ruby 1.8.7+
Rails 3.0 requires Ruby 1.8.7 or higher. Support for previous versions is officially discontinued, so we recommend that you upgrade to a new version of Ruby as soon as possible. In addition, Rails is compatible with Ruby version 1.9.2.
Keep in mind that in Ruby 1.8.7 p248 and p249 there are marshaling bugs that crash Rails 3.0. In Ruby Enterprise Edition, this has been fixed since version 1.8.7-2010.02. As for 1.9, Ruby 1.9.1 cannot be used either. in Rails 3.0, it causes segmentation errors (segfaults). Thus, if you want to use the Rails 3.0 branch of Ruby 1.9, jump immediately to 1.9.2.
1.2 Application Object
As part of its work on supporting multiple Rails applications running in the same process, Rails 3.0 introduces a new concept that involves the use of an object
Application
. This object contains everything specific to your application, configuration settings, and by its nature it is very similar to the contents of config / environment.rb from previous versions of Rails. Now each Rails application has a special object
Application
. This object is defined in the config / application.rb file. If you need to upgrade an existing application to the new version of Rails, you need to create this file manually and copy the necessary information from config / environment.rb into it.1.3 script/*
replaced byscript/rails
The new script / rails now replaces all scripts in the corresponding folder. But you do not need to access the script / rails directly - just run the command
rails
from the root of the application, which, in the context of your application, will execute the specified script. For instance:rails console # => ./script/console
rails g scaffold post title:string # => ./script/generate scaffold post title:string
The team will rails –help
kindly provide the entire list of available options.1.4 Dependencies and config.gem
The method has
config.gem
gone into oblivion in favor of bundler
'a and Gemfile
' a (see below “Enabling gems”)1.5 Transition Process
To automate and simplify the transition process, a special plugin was created - Rails Upgrade .
Just install the plugin and run it
$ rake rails:upgrade:check
to find out which of the existing parts of your program need updating (with links to information on how and what to update). Also in the plugin there is a task for generation Gemfile
, based on existing calls in config.gem
and task for generating a new file with routes based on the old one. To download the plugin, simply do the following - $ script/plugin install git://github.com/rails/rails_upgrade.git
. For an example of how this works, see the Rails Upgrade is now an Official Plugin link .
On the other hand, if you need more help, you can always contact people on the IRC channel or in the newsletterrubyonrails-talk , which probably do the same thing as you, and perhaps even face the same problems. When you finally succeed - do not forget to write on your blog to share your experience with others!
Additional Information - The Path to Rails 3: Approaching the upgrade .
2. Creating a new Rails application
The sequence at the moment looks like this:
$ gem install rails --version 3.0.0
$ rails myapp
$ cd myapp
2.1 Inclusion of gems
Rails now uses
Gemfile
to know which plugins are needed to run your application. To read and work with this file, there is a new bundler gem, which puts all the necessary gems into the directory vendor
, thereby isolating your application from system gems. Additional Information - Using bundler .
2.2 Life on the verge
Now, thanks to
bundler
-u and Gemfile
-u, in order to “freeze” your application, it is enough to execute the special command bundle
-ra - goodbye rake freeze
! .. Well, if you use the code from the master branch of the Rails repository, just pass the flag to create the application
--dev
:$ rails myapp —edge
3. Architectural changes in Rails
The Rails architecture has undergone 6 significant changes.
3.1 Reloading Railties
Railties has been updated to provide a robust API for writing plugins for any component of the framework. Generators and bindings were also completely rewritten, which gives developers the opportunity to switch to an incomparably different level of elegance in their use.
3.2 All Rails core components are now independent
Together with the merger of Merb and Rails, one of the main tasks was to get rid of the strong connection between the components of the Rails core. This goal has been achieved, and now all the key components of Rails use a single API, which you can use to develop plugins.
This means that any plug-in or replacement of any kernel component (using, for example, DataMapper or Sequel) has access to the same functionality as the kernel, with the possibility of its expansion and improvement.
More Information - The Great Decoupling
3.3 Active Model Abstraction
Part of the work on separating components was extracting all Active Record bindings from the Action Pack. Now that this is complete, any new ORM plugin needs to implement all Active Model interfaces to work correctly with the Action Pack.
Additional Information - ActiveModel: Let Any Ruby Object Feel ActiveRecord
3.4 Abstract controller
Another significant part of the work on separation of components in the kernel was the creation of a base superclass isolated from HTTP in order to render templates, etc. The creation of Abstract Controller allowed us to significantly simplify the Action Controller and Action Mailer by extracting common code for both in Abstract Controller
Additional Information - Rails Edge Architecture .
3.5 Arel Integration
Arel (or Active Relation) was taken as the foundation for Active Record and is now one of the dependencies of the Rails application. Arel introduces a special abstraction of SQL, thereby simplifying Active Record and providing the foundation for implementing relation functionality in Active Record.
Additional Information - Why I wrote Arel .
3.6 Retrieving Mail
From the day of its creation, Action Mailer was constantly hung up with dubious patches, pre-parsers and, in addition to combining with TMail, acquired agents for sending and receiving mail. In version 3.0, all email related functionality was abstracted to the Mail gem . This, again, reduced the amount of duplicate code and helped separate the Action Mailer from the email parser.
More information - New Action Mailer API in Rails 3 .
4. Documentation
The documentation for all changes to the API is in the process of being updated. In addition to this, the Rails Edge guides are also updated to meet all the changes in Rails 3.0. However, the guides at guides.rubyonrails.org will only correspond to the latest stable version (i.e. version 2.3.5, up to the final release 3.0).
Additional Information - Rails Documentation Projects .
5. Internationalization
In Rails 3, a significant amount of work has been done to support internationalization. The latest version of the i18n gem is included and carries significant speed optimization.
- I18n in every home - now, if desired, l18n can be embedded in any object by adding ActiveModel :: Translation and ActiveModel :: Validations modules to it. In addition, translation support for errors.messages has been added.
- Attributes can now set the default language.
- Form tags automatically determining the status of an object (Create or Update), tighten the correct translation language.
- The Label tag with l18n now works correctly - just pass the attribute name to it.
6. Railties
Together with the separation of the main components inside Rails, Railities have been carefully redesigned to facilitate the interaction between frameworks, engines and plugins, making it as painless and flexible as possible:
- Each application is now assigned its own namespace (for example, the application is launched as follows:)
YourAppName.boot
, which makes interaction between applications much easier. - Now you can turn to
Rails.config
where a huge variety of configuration settings for your application are available. - Everything inside is
Rails.root/app
now automatically added toload path
, so now you can, say, add a fileapp/observers/user_observer.rb
, and Rails just loads it.
-dev
, when installing the application, it Gemfile
is taken from the current Rails repository. See rails –help
for reference. A huge amount of attention has been given to generators of various Railities. In short:
- Generators have been rewritten from scratch and are no longer backward compatible.
- The template and generator APIs were connected together.
- Generators are no longer loaded from a special path (load path), but simply loaded from a boot path (Ruby load path), so the call
script/generate foo
will do the same asgenerators/foo_generator
- Now you can easily connect any new template engine, ORM or test framework to the generator.
- In the new generators, you can easily rewrite the original templates by simply putting the desired file in
RAILS_ROOT/lib/templates
. - It appeared
Rails::Generators::TestCase
thanks to which you can create and test your own generators.
- Generated views now use tags
div
insteadp
. - When generating forms using scaffold, instead of duplicating the code in the edit and new views, partial with an annotation is now used
_form
- When generating forms using scaffold it is now used
f.submit
that returns “Create ModelName” or “Update ModelName”, depending on the state in which the object came
- A task has been added
rake db:forward
, thanks to which it is now possible to twist migrations forward individually or in groups. - A task has been added
rake routes CONTROLLER=x
, which now allows you to view routes for one specific controller.
RAILS_ROOT
in favor ofRails.root
,RAILS_ENV
in favor ofRails.env
,RAILS_DEFAULT_LOGGER
in favor ofRails.logger
.
PLUGIN/rails/tasks
and PLUGIN/tasks
no longer load - all tasks should be in the directory PLUGIN/lib/tasks
. Additional information :
7. Action Pack
The Action Pack has undergone significant internal and external changes.
7.1 Abstract Controller
From
Action Controller
'a to Abstract Controller
, in the form of modules, the main parts were taken out that can now be used to render templates, partial
' s, helper
's, internationalization, logging and any other part of the request-response cycle. Thanks to this abstraction, it is ActionMailer::Base
now simply inherited from Abstract Controller
'a, being, you will be assured, a wrapper over Rails DSL in the form of a Mail gem. Removing in
Abstract Controller
everything that could be made possible a lot easier Action Controller
. However, keep in mind that programmers will not be able to directly access Abstract Controller
' y, this is not an API. Additional Information - Rails Edge Architecture .
7.2 Action Controller
- As
application_controller.rb
from now onprotect_from_forgery
by default. cookie_verifier_secret
was deprecated. Now you should refer to it insteadRails.application.config.cookie_secret
, and its implementation is now in a separate fileinitializers/cookie_verification_secret.rb
session_store
was moved toinitializers/session_store.rb
cookies.secure
now allows setting encrypted values in the cookie hash:cookie.secure[:key] => value
cookies.permanent
now allows you to set constant values in the cookie hash:cookie.permanent[:key] => value
which throws an exception if the verification is unsuccessful- Now you can send
notice => ‘Это flash-сообщение’
or:alert => ‘Что-то пошло не так’
to callformat
in the blockrespond_to
. The hashflash[]
is still in operation respond_with
was added to the controllers, thereby simplifying obsoleteformat
blocks- has been added
ActionController::Responder
with which you can flexibly generate responses
filter_parameter_logging
in favorconfig.filter_parameters << :password
7.3 Action Dispatch
Introduced in Rails 3.0, this new component is designed to greatly simplify routing.
- after strong cleaning and rewriting routing, from now on
router
it israck_mount
over Rails DLS, i.e. in fact, it is now a separate small application - Routes declared in the application are now in the namespace of the Application module. Those. now instead of:
Need to write:ActionController::Routing::Routes.draw do
map.resources :posts
endAppName::Application.routes do
resources :posts
end - a method has been added
match
, so now you can hang a Rack application on a suitable (matched) route - added method
constraints
, allowing you to protect your routes with conditions - A method has been added
scope
with which you can put routes into namespaces (for example, for different languages or special actions). For example, the following code:
will call a methodscope ‘es’ do
resources :projects, :path_names => { :edit => ‘cambiar’ }, :as => ‘projeto’
endedit
at/es/projeto/1/cambiar
- added method
root
as shortcut tomatch ‘/’, :to => path
- an
match
optional segment can be transmitted. So, inmatch “/:controller(/:action(/:id))(.:format)”
, any parenthesized text is optional - routes can be expressed as blocks, i.e. Now for example, you can write
:home { match ‘/:action’ }
map
are still in operation, but with the advent of 3.1 they will disappear completely. Recognized obsolete:
- hosted non-REST application
/:controller/:action/:id
route ( ) has been commented out :path_prefix
removed for routes, and:name_prefix
now automatically adds "_" at the end of the passed value
7.4 Action View
7.4.1 Unobtrusive JavaScript
The helpers in Action View have undergone significant revisions: hooks for Unobtrusive JavaScript (UJS) have been introduced, and the old inline AJAX teams have sunk into oblivion. Thus, in Rails, you can now use any UJS driver to implement UJS hooks in helpers.
This means that all previously existing helpers
remote_
have been removed from the rails and are now in the special Prototype Legacy Helper helper . Now, to access UJS hooks, just pass :remote => true
. So, for example:will return:form_for @post, :remote => true
form action="http://host.com" id="create-post" method="post" data-remote="true"
7.4.2 Block Helpers
Helpers such as
form_for
or div_for
that insert content from a block now use <%=
:<%= form_for @post do |f| %>
...
<% end %>
Your own helpers of this type will return a string, and will not append it manually to the output buffer.
Helpers for other purposes, such as
cache
and content_for
, remain intact.7.4.3 Other changes
- You no longer need to call
h(String)
HTML for filtering - now all views are generated with default filtering. In order to pass an unfiltered string, you need to callraw(string)
. - Helpers now return HTML5 markup.
- The helper
label
now retrieves data from I18n with one parameter, i.e.f.label :name
will immediately return the translated:name
. select
for I18n is now called as:en.helpers.select
instead:en.support.select
.- You no longer need to put a minus sign in the closing tag of the ERb-template in order to avoid translation deadlines.
- Helper added to ActionView
grouped_collection_select
. - Added method
content_for?
to check before rendering whether content exists. - By
:value => nil
submitting the form for helpers, you thereby set the value of the field tonil
instead of using the standard value. - Submitting
:id => nil
for helpers forms an attributeid
will not be generated. - By passing
:alt => nil
image_tag to the helper, you set the field value tonil
instead of using the standard value.
8 Active Model
Active Model is a new component of Rails 3.0. Now any ORM library can interact with Rails - all you need is to implement the Active Model interface, which is just an abstract layer.
8.1 ORM abstraction and Action Pack interface
Part of the work of breaking apart the core components of Rails was to extract all the links in Active Record from the Action Pack. Now that this is complete, any ORM library just needs to implement the Active Model interfaces to simply access the Active Record.
More Information - Make Any Ruby Object Feel Like ActiveRecord
Validations 8.2
Validations migrated from Active Record to Active Model, thereby providing their interface to other ORM libraries.
Now there is a method
validates :attribute, options_hash
. You
options_hash
can transfer several different validations at once, including::acceptance => Boolean
:confirmation => Boolean
:exclusion => { :in => Ennumerable }
:inclusion => { :in => Ennumerable }
:format => { :with => Regexp, :on => :create }
:length => { :maximum => Fixnum }
:numericality => Boolean
:presence => Boolean
:uniqueness => Boolean
You can also pass a validator object that can be used in different objects of type ActiveModel. For instance:
Or for objects of type Active Record:class TitleValidator < ActiveModel::EachValidator
Titles = [‘Mr.’, ‘Mrs.’, ‘Dr.’]
def validate_each(record, attribute, value)
unless Titles.include?(value)
record.errors[attribute] << ‘must be a valid title’
end
end
end
class Person
include ActiveModel::Validations
attr_accessor :title
validates :title, :presence => true, :title => true
end
class Person < ActiveRecord::Base
validates :title, :presence => true, :title => true
end
Additional information :
9. Active Record
A lot of attention was paid to Active Record in Rails 3: abstraction in the Active Model, a completely updated query interface using Arel, updates in validations, and many other changes. All obsolete APIs from Rails 2.x will work as before, but with the release of Rails 3.1 they will have to say goodbye.
9.1 Request Interface
Any method in Active Record, thanks to the use of Arel, now returns
relation
. The existing API will be deprecated in Rails 3.1, and completely removed from the framework in Rails 3.2. Among the new methods that can be arranged in chains, there are the following:where
- provides a condition for reletion, i.e. what will be chosen.select
- selection of the required attribute from the database.group
- groups relation on the provided attribute.having
- an analogueGROUP BY
from SQL.joins
- merges relation'a with another table.clause
- an analogueJOIN
from SQL.includes
- includes others created earlier ralations.order
- Sorts relation according to the passed expression.limit
- sets a limit on the number of records in relation.lock
- blocks records coming from the database.readonly
- returns a copy of data in a read-only access mode.from
- makes it possible for relation'a to make a selection from several tables.scope
- (earliernamed_scope
) returns a relation object.with_scope
- likewith_exclusive_scope
, also returns a relation object.default_scope
- also works with relation'ami
9.2 Other improvements
- added
:destroyed?
to Active Record objects - Added
:inverse_of
for relationships, allowing you to get an already loaded relationship without accessing the database
9.3 Patches and termination of support
On top of that, many other changes have occurred in the Active Record branch:
- SQLite 2 has been discontinued in favor of SQLite 3.
- Implemented support for column ordering in MySQL.
- In the adapter for PostgreSQL fixed
TIME_ZONE
- no more erroneous values. - Support for multiple schemas for tables in PostgreSQL.
table_name
now cached.- Strong cleaning was carried out, along with multiple bugfixes of the adapter for the Oracle database.
named_scope
Active Record is deprecated and renamed toscope
- in the method
scope
you need to use relation methods instead of searching in style:condition => {}
. For instance::since, lambda {|time| where(“created_at > ?”, time) }
save(false)
deprecated in favorsave(:validate => false)
- I18n error messages for Active Record need to be changed from
:en.activerecord.errors.template
to:en.errors.template
model.errors.on
deprecated in favormodel.errors[]
validates_presence_of
now became:presence => true
ActiveRecord::Base.colorize_logging
andconfig.active_record.colorize_logging
are deprecated in favor ofRails::Subscriber.colorize_logging
orconfig.colorize_logging
.
10. Active Resourse
Active Resourse was also extracted into the Active Model, making it easy to use Active Resourse objects in the Action Pack.
- Validations added thanks to the Active Model.
- Added observing hooks.
- HTTP proxy support
- Added support for digest authentication.
- Model naming has been moved to the Active Model.
- Active Resource attributes changed to random access hash.
- Alias methods have been added
first
,last
andall
for the corresponding scope. find_every
no longer returns an errorResourceNotFound
if nothing is found- Added
save!
, which returnsResourceInvalid
in case the object is notvalid?
. - In the ActiveResource model,
update_attribute
and methods have been addedupdate_attributes
. - Now, to download deleted errors, Active Resources is
content-type
used instead of themformat
. - For a schema block is used
instance_eval
. - Fixed
ActiveResource::ConnectionError#to_s
where@response
did not respond to #code or #message (...). - Added support for JSON errors.
- Supported work
load
with arrays of numbers. - Answer 410 from a remote source, in case it was deleted, is now recognized correctly.
- In Active Resouce added is possible to set SSL options.
- Setting a timeout for a connection now also affects
Net::HTTP
open_timeout
.
save(false)
deprecated in favorsave(:validate => false)
- Ruby 1.9.2:
URI.parse
both.decode
are deprecated and are no longer used in the library
11. Active Support
We have achieved great success in working on Active Support, so now you don’t have to include the entire Active Support library just to use some small subset of its functions. Thus, many internal Rails modules began to work much faster.
- total cleaning of the entire library was carried out, many unused methods were also removed
- Active Support no longer provides methods from TZInfo , Memchache Client and Bundle : now all this needs to be included separately, pre-installed with the command
gem bundle
- added ActiveSupport :: SafeBuffer
- fixed
Array.uniq_by
andArray.uniq_by!
- fixed bug where it
TimeZone.seconds_to_utc_offset
returned the wrong value - layer added
ActiveSupport::Notifications
ActiveSupport.use_standard_json_time_format
now defaulttrue
ActiveSupport.escape_html_entities_in_json
now defaulttrue
Integer#multiple_of?
теперь принимает ноль в качестве аргумента, и если само число равно нулю — возвращаетfalse
string.chars
перемменован вstring.mb_chars
ActiveSupport::OrderedHash
теперь может быть де-сериализован через YAML- добавлен парсер на основе SAX для XmlMini, с использованием LibXML и Nokogiri
- добавлен метод
Object#presence
, который возвращает объект если он присутствует (иначе —nil
) - добавлен метод
String#exclude?
который возвращается отрицаниеinclude?
- добавлен метод
to_i
вDateTime
, вActive Support
, так что теперьto_yaml
работает верно на моделях с атрибутомDateTime
- добавлен метод
Enumerable#exclude?
чтобы составить компаниюEnumerable#include?
, избежав тем самым конструкций вида!x.include?
- XSS фильтрация теперь включена по умолчанию
- добавлена поддержка глубокого слияния в
ActiveSupport::HashWithIndifferentAccess
Enumerable#sum
теперь работает со всеми множествами, даже если они не отвечают на:size
inspect
on a zero time interval instead of an empty line now returns0
- in and
modelname
addedelement
collection
String#to_time
andString#to_datetime
allow fractional seconds- added support for new callbacks for the filter object that responds to
:before
and:after
used before and after callbacks - the method
ActiveSupport::OrderedHash#to_a
returns an ordered set of arrays (same asHash#to_a
from Ruby 1.9) MissingSourseFile
present as a constant, but its value is always equalLoadError
- added
Class#class_attribute
, thanks to which you can declare a class-level attribute whose value can be inherited and rewritten by child classes - finally
ActiveRecord
removedDeprecatedCallbacks
Integer#even?
andInteger#odd?
String#each_char
String#start_with?
andString#end_with?
(3rd person aliases still kept)String#bytesize
Object#tap
Symbol#to_proc
Object#instance_variable_defined?
Enumerable#none?
The following methods have been removed due to their uselessness:
Object#remove_subclasses_of
,Object#subclasses_of
,Object#extend_with_included_modules_from
Object#extended_by
Class#subclasses
,Class#reachable?
,Class#remove_class
Regexp#number_of_captures
Regexp.unoptionalize
,Regexp.optionalize
,Regexp#number_of_captures
12. Action Mailer
With the replacement of TMail with the new Mail , Action Mailer has received a completely new API. By itself, Action Mailer has been almost completely rewritten. As a result of the work done, now the Action Mailer simply inherits from Abstract Controller, and now wraps the Mail gem. This reduced the amount of code and duplicate libraries inside the Action Mailer.
- all senders are now in the default folder
app/mailers
- Now you can send email using the new API with three methods :
attachments
,headers
andmail
- all Action Mailer methods associated with mail now return a Mail :: Message object, which can then be sent using its own method
deliver
- mail delivery method can now accept a hash with all the necessary message headers
- The mail delivery method now works the same as
respond_block
in the Action Contoller, so you can now explicitly or implicitly render message templates. In addition, Action Mailer will now split the letter into several parts, if necessary - you can pass proc to a call
format.mime_type
inside the mail block, thereby explicitly rendering render text types, or adding new templates or layouts - all mailer unit tests have now become functional tests
:charset
,:content_type
,:mime_version
,:implicit_parts_order
Deprecated in favor of the relevant calls in styleActionMailer.default :key => value
- Dynamic methods
create_method_name
anddeliver_method_name
is now considered obsolete - just callmethod_name
that returns an objectMail::Message
. ActionMailer.deliver(message)
outdated, just callmessage.deliver
.template_root
deprecated - pass options to the render call inside the Proc-object from the methodformat.mime_type
inside the generation blockmail
.- The method
body
for defining instance variables is now also deprecated (body {:ivar => value}
), so now it is enough to declare instance variables directly inside the method - they will be visible in the view. - Mailers now moved from directory
app/models
toapp/mailer
.
13. Participants
Check out the full list of contributors who spent many hours contributing to Rails 3. Honor and praise to them all!
PS. Editing formatting, as well as correcting errors and inaccuracies in translation is in progress.
PPS Thanks to maratk for helping me find the bugs!