aboutsummaryrefslogtreecommitdiffstats
path: root/railties/guides/source/initialization.textile
diff options
context:
space:
mode:
Diffstat (limited to 'railties/guides/source/initialization.textile')
-rw-r--r--railties/guides/source/initialization.textile215
1 files changed, 110 insertions, 105 deletions
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index e458413b35..7a44ef7c77 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -11,7 +11,7 @@ This guide first describes the process of +rails server+ then explains the Passe
h3. Launch!
-As of Rails 3, +script/server+ has become +rails server+. This was done to centralise all rails related commands to one common file.
+As of Rails 3, +script/server+ has become +rails server+. This was done to centralize all rails related commands to one common file.
The actual +rails+ command is kept in _railties/bin/rails_ and goes like this:
@@ -58,11 +58,8 @@ In +script/rails+ we see the following:
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
- ENV_PATH = File.expand_path('../../config/environment', __FILE__)
- BOOT_PATH = File.expand_path('../../config/boot', __FILE__)
- APP_PATH = File.expand_path('../../config/application', __FILE__)
-
- require BOOT_PATH
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
+ require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
</ruby>
@@ -79,15 +76,19 @@ h3. _config/boot.rb_
_config/boot.rb_ is the first stop for everything for initializing your application. This boot process does quite a bit of work for you and so this section attempts to go in-depth enough to explain what each of the pieces does.
<ruby>
- # Use Bundler (preferred)
+ require 'rubygems'
+
+ # Set up gems listed in the Gemfile.
+ gemfile = File.expand_path('../../Gemfile', __FILE__)
begin
- require File.expand_path('../../.bundle/environment', __FILE__)
- rescue LoadError
- require 'rubygems'
+ ENV['BUNDLE_GEMFILE'] = gemfile
require 'bundler'
Bundler.setup
- end
-
+ rescue Bundler::GemNotFound => e
+ STDERR.puts e.message
+ STDERR.puts "Try running `bundle install`."
+ exit!
+ end if File.exist?(gemfile)
</ruby>
h3. Bundled Rails (3.x)
@@ -140,8 +141,8 @@ Here the only two gems we need are +rails+ and +sqlite3-ruby+, so it seems. This
* activesupport-3.0.0.beta4.gem
* arel-0.4.0.gem
* builder-2.1.2.gem
-* bundler-0.9.26.gem
-* erubis-2.6.5.gem
+* bundler-1.0.0.beta.2.gem
+* erubis-2.6.6.gem
* i18n-0.4.1.gem
* mail-2.2.4.gem
* memcache-client-1.8.3.gem
@@ -156,7 +157,7 @@ Here the only two gems we need are +rails+ and +sqlite3-ruby+, so it seems. This
* sqlite3-ruby-1.3.0.gem
* text-format-1.0.0.gem
* text-hyphen-1.0.0.gem
-* thor-0.13.6.gem
+* thor-0.13.7.gem
* treetop-1.4.8.gem
* tzinfo-0.3.22.gem
@@ -164,33 +165,7 @@ TODO: Prettify when it becomes more stable.
I won't go into what each of these gems are, as that is really something that needs covering on a case-by-case basis. We will however just dig a little under the surface of Bundler.
-Back in _config/boot.rb_, the first line will try to include _.bundle/environment.rb_, which doesn't exist in a bare-bones Rails application and because this file does not exist Ruby will raise a +LoadError+ which will be rescued and run the following code:
-
-<ruby>
- require 'rubygems'
- require 'bundler'
- Bundler.setup
-</ruby>
-
-+Bundler.setup+ here will load and parse the +Gemfile+ and add the _lib_ directory of the gems mentioned **and** their dependencies (**and** their dependencies' dependencies, and so on) to the +$LOAD_PATH+.
-
-Now we will go down the alternate timeline where we generate a _.bundle/environment.rb_ file using the +bundle lock+ command. This command also creates a _Gemfile.lock_ file which is actually a YAML file loaded by this method in Bundler before it moves on to check for _Gemfile_:
-
-<ruby>
- def definition(gemfile = default_gemfile)
- configure
- root = Pathname.new(gemfile).dirname
- lockfile = root.join("Gemfile.lock")
- if lockfile.exist?
- Definition.from_lock(lockfile)
- else
- Definition.from_gemfile(gemfile)
- end
- end
-</ruby>
-
-
-The _.bundle/environment.rb_ file adds the _lib_ directory of all the gems specified in +Gemfile.lock+ to +$LOAD_PATH+.
+Back in _config/boot.rb_, we call +Bundler.setup+ which will load and parse the +Gemfile+ and add the _lib_ directory of the gems mentioned **and** their dependencies (**and** their dependencies' dependencies, and so on) to the +$LOAD_PATH+.
h3. Requiring Rails
@@ -326,6 +301,11 @@ As you can see for the duration of the +eager_autoload+ block the class variable
module ActiveSupport
extend ActiveSupport::Autoload
+ autoload :DescendantsTracker
+ autoload :FileUpdateChecker
+ autoload :LogSubscriber
+ autoload :Notifications
+
# TODO: Narrow this list down
eager_autoload do
autoload :BacktraceCleaner
@@ -348,7 +328,6 @@ As you can see for the duration of the +eager_autoload+ block the class variable
autoload :OptionMerger
autoload :OrderedHash
autoload :OrderedOptions
- autoload :Notifications
autoload :Rescuable
autoload :SecureRandom
autoload :StringInquirer
@@ -589,19 +568,20 @@ This file (_railties/lib/rails.rb_) requires the very, very basics that Rails ne
require 'action_dispatch/railtie'
</ruby>
-+require 'pathname'+ requires the Pathname class which is used for returning a Pathname object for +Rails.root+ so that instead of doing:
++require 'pathname'+ requires the Pathname class which is used for returning a Pathname object for +Rails.root+. Although is coming to use this path name to generate paths as below:
<ruby>
- File.join(Rails.root, "app/controllers")
+ Rails.root.join("app/controllers")
</ruby>
-You may do:
+Pathname can also be converted to string, so the following syntax is preferred:
<ruby>
- Rails.root.join("app/controllers")
+ "#{Rails.root}/app/controllers"
</ruby>
-Although this is not new to Rails 3 (it was available in 2.3.5), it is something worthwhile pointing out.
+
+This works because Ruby automatically handles file path conversions. Although this is not new to Rails 3 (it was available in 2.3.5), it is something worthwhile pointing out.
Inside this file there are other helpful helper methods defined, such as +Rails.root+, +Rails.env+, +Rails.logger+ and +Rails.application+.
@@ -1833,7 +1813,7 @@ We do not already have a +Rails.application+, so instead this resorts to calling
end
</ruby>
-This +called_from+ setting looks a little overwhelming to begin with, but the short end of it is that it returns the route to your application's config directory, something like: _/home/you/yourapp/config_. After +called_from+ has been set, +super+ is again called and this means the +Rails::Railtie#inherited+ method (in _railties/lib/rails/railtie.rb_):
+This +called_from+ setting looks a little overwhelming to begin with, but the short end of it is that it returns your application's root, something like: _/home/you/yourapp_. After +called_from+ has been set, +super+ is again called and this means the +Rails::Railtie#inherited+ method (in _railties/lib/rails/railtie.rb_):
<ruby>
def inherited(base)
@@ -3588,28 +3568,24 @@ h3. Appendix A
This file is _activesupport/lib/active_support/inflector/inflections.rb_ and defines the +ActiveSupport::Inflector::Inflections+ class which defines the +singularize+, +pluralize+, +humanize+, +tableize+, +titleize+ and +classify+ methods as well as the code to defining how to work out the irregular, singular, plural and human versions of words. These methods are called +irregular+, +singular+, +plural+ and +human+ respectively, as is the Rails way.
-This file is _activesupport/lib/active_support/inflector/transliterate.rb_ and defines two methods, +transliterate+ and +parameterize+. What +transliterate+ does depends on your Ruby version. If you have something greater than 1.9 installed it will just print out a warning message using the +Kernel#warn+ method (simply called using +warn+) reading "Ruby 1.9 doesn't support Unicode normalization yet". If you're running something that's not 1.9 it will attempt to convert +"föö"+ to +foo+ and if that fails then it'll redefine it.
+This file is _activesupport/lib/active_support/inflector/transliterate.rb_ and defines two methods, +transliterate+ and +parameterize+.
-This file first makes a require to _activesupport/lib/active_support/core_ext/string/multibyte.rb_ which then goes on to require _activesupport/lib/active_support/multibyte.rb_ and that requires _activesupport/core_ext/module/attribute_accessors.rb_. The _attribute_accessors.rb_ file is used to gain access to the +mattr_accessor+ (module attribute accessor) method which is called in _active_suport/multibyte.rb_. Also in _active_support/multibyte.rb_ there's a couple of autoloaded classes:
+This file first requires _activesupport/lib/active_support/core_ext/string/multibyte.rb_, which requires _activesupport/lib/active_support/multibyte.rb_, which subsequently requires _activesupport/core_ext/module/attribute_accessors.rb_. The _attribute_accessors.rb_ file is needed to gain access to the +mattr_accessor+ (module attribute accessor) method, which is called in _active_suport/multibyte.rb_. The file _active_support/multibyte.rb_ also autoloads three other classes:
<ruby>
module ActiveSupport #:nodoc:
module Multibyte
autoload :EncodingError, 'active_support/multibyte/exceptions'
autoload :Chars, 'active_support/multibyte/chars'
- autoload :UnicodeDatabase, 'active_support/multibyte/unicode_database'
- autoload :Codepoint, 'active_support/multibyte/unicode_database'
- autoload :UCD, 'active_support/multibyte/unicode_database'
- ...
+ autoload :Unicode, 'active_support/multibyte/unicode'
+ ...
end
end
</ruby>
-There's also these method definitions:
+There are also these method definitions:
<ruby>
- self.default_normalization_form = :kc
-
# The proxy class returned when calling mb_chars. You can use this accessor to configure your own proxy
# class so you can support other encodings. See the ActiveSupport::Multibyte::Chars implementation for
# an example how to do this.
@@ -3628,63 +3604,92 @@ There's also these method definitions:
These methods are used in _activesupport/lib/active_support/core_ext/string/multibyte.rb_.
-If we go back to _activesupport/lib/active_support/core_ext/string/multibyte.rb_, this file makes a couple of extensions to the +String+ class based on if your version of Ruby's +String+ class responds to the +force_encoding+ method. This method was introduced in Ruby 1.9. If you're using 1.9 the methods are defined like this:
-
-<ruby>
- def mb_chars #:nodoc
- self
- end
-
- def is_utf8? #:nodoc
- case encoding
- when Encoding::UTF_8
- valid_encoding?
- when Encoding::ASCII_8BIT, Encoding::US_ASCII
- dup.force_encoding(Encoding::UTF_8).valid_encoding?
- else
- false
- end
- end
-</ruby>
-
-You can see that calling +mb_chars+ on a +String+ instance in Ruby 1.9 will simply return that +String+ object. +String+ objects in Ruby 1.9 are already multibyte strings, so Rails does not need to do any conversion on them.
-
-The second method, +is_utf8?+ return +true+ if the +String+ object is of the UTF8 encoding or if it's able to be forced into that encoding and +false+ if it can't force its encoding or if the encoding of the string is neither +UTF8+, +ASCII_8BIT+ or +US_ASCII+.
-
-If you're using a Ruby version less than 1.9 there are 3 methods defined instead of 2, and they are defined like this:
+The file _activesupport/lib/active_support/core_ext/string/chars.rb_ defines the default proxy class that will be returned by +mb_chars+.
+
+Because Ruby 1.9's +String+ class has support for multibyte encodings, some methods are defined only for Ruby 1.8:
+
+* +self.wants?+
+* +++
+* +=~+
+* +=~+
+* +center+
+* +include?+
+* +index+
+* +insert+
+* +ljust+
+* +lstrip+, +lstrip!+
+* +ord+
+* +rindex+
+* +rjust+
+* +rstrip+, +rstrip!+
+* +size+
+* +strip+, +strip!+
+
+However, Ruby 1.9 lacks support for some needed operations, so the following methods are defined for both Ruby 1.8 and Ruby 1.9:
+
+* +<=>+
+* +[]=+
+* +capitalize+, +capitalize!+
+* +compose+
+* +decompose+
+* +downcase+, +downcase!+
+* +g_length+
+* +limit+
+* +normalize+
+* +reverse+, +reverse+!
+* +slice+, +slice!+
+* +split+
+* +tidy_bytes+, +tidy_bytes!+
+* +titleize+
+* +upcase+, +upcase!+
+
+<ruby>
+ class String
+ if RUBY_VERSION >= "1.9"
+ def mb_chars
+ if ActiveSupport::Multibyte.proxy_class.consumes?(self)
+ ActiveSupport::Multibyte.proxy_class.new(self)
+ else
+ self
+ end
+ end
-<ruby>
- def mb_chars
- if ActiveSupport::Multibyte.proxy_class.wants?(self)
- ActiveSupport::Multibyte.proxy_class.new(self)
+ def is_utf8? #:nodoc
+ case encoding
+ when Encoding::UTF_8
+ valid_encoding?
+ when Encoding::ASCII_8BIT, Encoding::US_ASCII
+ dup.force_encoding(Encoding::UTF_8).valid_encoding?
+ else
+ false
+ end
+ end
else
- self
- end
- end
-
- # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have
- # them), returns false otherwise.
- def is_utf8?
- ActiveSupport::Multibyte::Chars.consumes?(self)
- end
+ def mb_chars
+ if ActiveSupport::Multibyte.proxy_class.wants?(self)
+ ActiveSupport::Multibyte.proxy_class.new(self)
+ else
+ self
+ end
+ end
- unless '1.8.7 and later'.respond_to?(:chars)
- def chars
- ActiveSupport::Deprecation.warn('String#chars has been deprecated in favor of String#mb_chars.', caller)
- mb_chars
+ # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have
+ # them), returns false otherwise.
+ def is_utf8?
+ ActiveSupport::Multibyte::Chars.consumes?(self)
+ end
end
- end
-
</ruby>
+As you can see, +mb_chars+ is where the +proxy_class+ property comes in handy. This method will create a new instance of the configured proxy class using the instance of +String+ as a constructor argument. By default, the new +String+-like object will be an instance of the proxy class +ActiveSupport::Multibyte::Chars+. You can use +ActiveSupport::Multibyte.proxy_class=+ to set a different proxy class if you wish.
-As you can see, +mb_chars+ is where the +proxy_class+ method comes in handy. This will create a new instance of that class and pass in the +String+ object in order to make it multibyte-compatible. In this case the new +String+ object will be an instance of the +ActiveSupport::Multibyte::Chars+ class. You can use +ActiveSupport::Multibyte.proxy_class=+ to set this to be a different class if you're that way inclined.
-
-Here, +is_utf8?+ calls a +consumes+ method on the not-yet-loaded +ActiveSupport::Multibyte::Chars+ class. The keen-eye would have seen this was specified as an auto-load earlier, so that is what is going to happen if we call this method or +mb_chars+. This means that it'll require the file located at _activesupport/lib/active_support/multibyte/chars.rb_. This file includes _activesupport/lib/active_support/string/access.rb_ which defines methods such as +at+, +from+, +to+, +first+ and +last+. These methods will return parts of the string depending on what is passed to them and they are defined differently depending on if you're using Ruby 1.9 or not. The second file included is _activesupport/lib/active_support/string/behaviour.rb_ which defines a single method +acts_like_string?+ on +String+ which always returns +true+. This method is used through the +acts_like?+ method which is passed a single argument representing the downcased and symbolised version of the class you want to know if it acts like. In this case the code would be +acts_like?(:string)+.
+Here, +mb_chars+ invokes +is_utf8?+ to checks if the string can be treated as UTF-8. On 1.9, the string's +encoding+ property is checked. On 1.8, +wants?+ checks to see if +$KCODE+ is "UTF-8" and, and +consumes?+ checks whether the string can be unpacked as UTF-8 without raising an error.
-The +Chars+ class defines, along with +consumes?+, other methods such as the "spaceship" method +<=>+. This method is referenced by the methods defined in the included +Comparable+ module and will return either +-1+, +0+ or +1+ depending on if the word is before, identical or after the compared word. For example, +'é'.mb_chars <=> 'ü'.mb_chars+ returns +-1+ as e comes before u in the alphabet. Other methods are the commonly used +split+, +=~+, +insert+ and +include?+.
+The keen eye will have seen +ActiveSupport::Multibyte::Chars+ was specified as an +autoload+ earlier: _activesupport/lib/active_support/multibyte/chars.rb_ will be loaded without an explicit +require+ when we call +is_utf8+ on 1.8, or +mb_chars+ on any Ruby version. This file includes _activesupport/lib/active_support/string/access.rb_ which defines methods such as +at+, +from+, +to+, +first+ and +last+. These methods will return parts of the string depending on what is passed to them.
+The second file included is _activesupport/lib/active_support/string/behavior.rb_ which only defines +acts_like_string?+ on +String+, a method which always returns +true+. This method is used by +Object#acts_like?+, which accepts a single argument representing the downcased and symbolised version of a class, and returns true if the object's behavior is like that class. In this case the code would be +acts_like?(:string)+.
+The +Chars+ class also defines other important methods such as the "spaceship" method +<=>+, which is needed by the +Comparable+ module, in order to allow UTF-8-aware sorting.
h3. Common Includes