summaryrefslogtreecommitdiff
path: root/doc/syntax/modules_and_classes.rdoc
diff options
context:
space:
mode:
Diffstat (limited to 'doc/syntax/modules_and_classes.rdoc')
-rw-r--r--doc/syntax/modules_and_classes.rdoc398
1 files changed, 398 insertions, 0 deletions
diff --git a/doc/syntax/modules_and_classes.rdoc b/doc/syntax/modules_and_classes.rdoc
new file mode 100644
index 0000000000..9e05c5c774
--- /dev/null
+++ b/doc/syntax/modules_and_classes.rdoc
@@ -0,0 +1,398 @@
+= Modules
+
+Modules serve two purposes in Ruby, namespacing and mix-in functionality.
+
+A namespace can be used to organize code by package or functionality that
+separates common names from interference by other packages. For example, the
+IRB namespace provides functionality for irb that prevents a collision
+for the common name "Context".
+
+Mix-in functionality allows sharing common methods across multiple classes or
+modules. Ruby comes with the Enumerable mix-in module which provides many
+enumeration methods based on the +each+ method and Comparable allows comparison
+of objects based on the <code><=></code> comparison method.
+
+Note that there are many similarities between modules and classes. Besides the
+ability to mix-in a module, the description of modules below also applies to
+classes.
+
+== Module Definition
+
+A module is created using the +module+ keyword:
+
+ module MyModule
+ # ...
+ end
+
+A module may be reopened any number of times to add, change or remove
+functionality:
+
+ module MyModule
+ def my_method
+ end
+ end
+
+ module MyModule
+ alias my_alias my_method
+ end
+
+ module MyModule
+ remove_method :my_method
+ end
+
+Reopening modules (or classes) is a very powerful feature of Ruby, but it is
+best to only reopen modules you own. Reopening modules you do not own may lead
+to naming conflicts or difficult to diagnose bugs.
+
+== Nesting
+
+Modules may be nested:
+
+ module Outer
+ module Inner
+ end
+ end
+
+Many packages create a single outermost module (or class) to provide a
+namespace for their functionality.
+
+You may also define inner modules using <code>::</code> provided the outer
+modules (or classes) are already defined:
+
+ module Outer::Inner::GrandChild
+ end
+
+Note that this will raise a +NameError+ if +Outer+ and
+<code>Outer::Inner</code> are not already defined.
+
+This style has the benefit of allowing the author to reduce the amount
+of indentation. Instead of 3 levels of indentation only one is necessary.
+However, the scope of constant lookup is different for creating a namespace
+using this syntax instead of the more verbose syntax.
+
+== Scope
+
+=== +self+
+
++self+ refers to the object that defines the current scope. +self+ will change
+when entering a different method or when defining a new module.
+
+=== Constants
+
+Accessible constants are different depending on the module nesting (which
+syntax was used to define the module). In the following example
+the constant <code>A::Z</code> is accessible from B as A is part of the
+nesting:
+
+ module A
+ Z = 1
+
+ module B
+ p Module.nesting #=> [A::B, A]
+ p Z #=> 1
+ end
+ end
+
+However, if you use <code>::</code> to define <code>A::B</code> without
+nesting it inside +A+, a NameError exception will be raised because the nesting
+does not include +A+:
+
+ module A
+ Z = 1
+ end
+
+ module A::B
+ p Module.nesting #=> [A::B]
+ p Z #=> raises NameError
+ end
+
+If a constant is defined at the top-level you may preceded it with
+<code>::</code> to reference it:
+
+ Z = 0
+
+ module A
+ Z = 1
+
+ module B
+ p ::Z #=> 0
+ end
+ end
+
+=== Methods
+
+For method definition documentation see the {syntax documentation for
+methods}[rdoc-ref:syntax/methods.rdoc].
+
+Class methods may be called directly. (This is slightly confusing, but a
+method on a module is often called a "class method" instead of a "module
+method". See also Module#module_function which can convert an instance method
+into a class method.)
+
+When a class method references a constant, it uses the same rules as referencing
+it outside the method as the scope is the same.
+
+Instance methods defined in a module are only callable when included. These
+methods have access to the constants defined when they were included through
+the ancestors list:
+
+ module A
+ Z = 1
+
+ def z
+ Z
+ end
+ end
+
+ include A
+
+ p self.class.ancestors #=> [Object, A, Kernel, BasicObject]
+ p z #=> 1
+
+=== Visibility
+
+Ruby has three types of visibility. The default is +public+. A public method
+may be called from any other object.
+
+The second visibility is +protected+. When calling a protected method the
+sender must inherit the Class or Module which defines the method. Otherwise a
+NoMethodError will be raised.
+
+Protected visibility is most frequently used to define <code>==</code> and
+other comparison methods where the author does not wish to expose an object's
+state to any caller and would like to restrict it only to inherited classes.
+
+Here is an example:
+
+ class A
+ def n(other)
+ other.m
+ end
+ end
+
+ class B < A
+ def m
+ 1
+ end
+
+ protected :m
+
+ end
+
+ class C < B
+ end
+
+ a = A.new
+ b = B.new
+ c = C.new
+
+ c.n b #=> 1 -- C is a subclass of B
+ b.n b #=> 1 -- m called on defining class
+ a.n b # raises NoMethodError A is not a subclass of B
+
+The third visibility is +private+. A private method may only be called from
+inside the owner class without a receiver, or with a literal +self+
+as a receiver. If a private method is called with a
+receiver other than a literal +self+, a NoMethodError will be raised.
+
+ class A
+ def without
+ m
+ end
+
+ def with_self
+ self.m
+ end
+
+ def with_other
+ A.new.m
+ end
+
+ def with_renamed
+ copy = self
+ copy.m
+ end
+
+ def m
+ 1
+ end
+
+ private :m
+ end
+
+ a = A.new
+ a.without #=> 1
+ a.with_self #=> 1
+ a.with_other # NoMethodError (private method `m' called for #<A:0x0000559c287f27d0>)
+ a.with_renamed # NoMethodError (private method `m' called for #<A:0x0000559c285f8330>)
+
+=== +alias+ and +undef+
+
+You may also alias or undefine methods, but these operations are not
+restricted to modules or classes. See the {miscellaneous syntax
+section}[rdoc-ref:syntax/miscellaneous.rdoc] for documentation.
+
+= Classes
+
+Every class is also a module, but unlike modules a class may not be mixed-in to
+another module (or class). Like a module, a class can be used as a namespace.
+A class also inherits methods and constants from its superclass.
+
+== Defining a class
+
+Use the +class+ keyword to create a class:
+
+ class MyClass
+ # ...
+ end
+
+If you do not supply a superclass your new class will inherit from Object. You
+may inherit from a different class using <code><</code> followed by a class
+name:
+
+ class MySubclass < MyClass
+ # ...
+ end
+
+There is a special class BasicObject which is designed as a blank class and
+includes a minimum of built-in methods. You can use BasicObject to create an
+independent inheritance structure. See the BasicObject documentation for
+further details.
+
+Just like modules, classes can also be reopened. You can omit its superclass
+when you reopen a class. Specifying a different superclass than the previous
+definition will raise an error.
+
+ class C
+ end
+
+ class D < C
+ end
+
+ # OK
+ class D < C
+ end
+
+ # OK
+ class D
+ end
+
+ # TypeError: superclass mismatch for class D
+ class D < String
+ end
+
+== Inheritance
+
+Any method defined on a class is callable from its subclass:
+
+ class A
+ Z = 1
+
+ def z
+ Z
+ end
+ end
+
+ class B < A
+ end
+
+ p B.new.z #=> 1
+
+The same is true for constants:
+
+ class A
+ Z = 1
+ end
+
+ class B < A
+ def z
+ Z
+ end
+ end
+
+ p B.new.z #=> 1
+
+You can override the functionality of a superclass method by redefining the
+method:
+
+ class A
+ def m
+ 1
+ end
+ end
+
+ class B < A
+ def m
+ 2
+ end
+ end
+
+ p B.new.m #=> 2
+
+If you wish to invoke the superclass functionality from a method use +super+:
+
+ class A
+ def m
+ 1
+ end
+ end
+
+ class B < A
+ def m
+ 2 + super
+ end
+ end
+
+ p B.new.m #=> 3
+
+When used without any arguments +super+ uses the arguments given to the
+subclass method. To send no arguments to the superclass method use
+<code>super()</code>. To send specific arguments to the superclass method
+provide them manually like <code>super(2)</code>.
+
++super+ may be called as many times as you like in the subclass method.
+
+= Singleton Classes
+
+The singleton class (also known as the metaclass or eigenclass) of an object is
+a class that holds methods for only that instance. You can access the
+singleton class of an object using <code>class << object</code> like this:
+
+ class C
+ end
+
+ class << C
+ # self is the singleton class here
+ end
+
+Most frequently you'll see the singleton class accessed like this:
+
+ class C
+ class << self
+ # ...
+ end
+ end
+
+This allows definition of methods and attributes on a class (or module) without
+needing to write <code>def self.my_method</code>.
+
+Since you can open the singleton class of any object this means that this code
+block:
+
+ o = Object.new
+
+ def o.my_method
+ 1 + 1
+ end
+
+is equivalent to this code block:
+
+ o = Object.new
+
+ class << o
+ def my_method
+ 1 + 1
+ end
+ end
+
+Both objects will have a +my_method+ that returns +2+.