diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-01-05 01:23:49 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-01-05 01:23:49 +0000 |
commit | a13aee62d243105ffd3b5178a4d4d6b99c2b2755 (patch) | |
tree | 973b21562aa69be7b00eda319db71c62cf6e001b /doc | |
parent | 1da85070b0be2aa81ab68adf96ec10c99ba2baf1 (diff) |
* doc/syntax/modules_and_classes.rdoc: Added documentation of syntax
for Modules and Classes.
* doc/syntax/methods.rdoc: Moved some text to the Modules and
Classes syntax document.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38701 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'doc')
-rw-r--r-- | doc/syntax/methods.rdoc | 32 | ||||
-rw-r--r-- | doc/syntax/modules_and_classes.rdoc | 288 |
2 files changed, 290 insertions, 30 deletions
diff --git a/doc/syntax/methods.rdoc b/doc/syntax/methods.rdoc index b3233e647a..832ba269b0 100644 --- a/doc/syntax/methods.rdoc +++ b/doc/syntax/methods.rdoc @@ -38,7 +38,7 @@ The standard syntax to define a method: # ... end -add the method to a class. You can define an instance method on a specific +adds the method to a class. You can define an instance method on a specific class with the +class+ keyword: class C @@ -47,24 +47,6 @@ class with the +class+ keyword: end end -In many languages, the +class+ keyword lets the compiler know that you're -creating a class. This is true in Ruby, too, the first time you use the -_class_ keyword: when it sees that you're _opening_ a class for -the first time, it creates it. When you open a class that already exists, Ruby -enables to you _extend_ it with new methods. You can even extend core -classes: - - class String - def hello - "Hello, world!" - end - end - - "".hello # returns "Hello, world!" - -However, This is somewhat risky due to namespace pollution so this ability is -best used sparingly. - A method may be defined on another object. You may define a "class method" (a method that is defined on the class, not an instance of the class) like this: @@ -74,16 +56,6 @@ method that is defined on the class, not an instance of the class) like this: end end -or a more concrete example: - - class String - def self.hello - "Hello, world!" - end - end - - String.hello # returns "Hello, world!" - However, this is simply a special case of a greater syntactical power in Ruby, the ability to add methods to any object. Classes are objects, so adding class methods is simply adding methods to the Class object. @@ -98,7 +70,7 @@ The syntax for adding a method to an object is as follows: greeting.broaden # returns "Hello, world!" -_self_ is a keyword referring to the current object under consideration ++self+ is a keyword referring to the current object under consideration by the compiler, which might make the use of +self+ in defining a class method above a little clearer. Indeed, the example of adding a +hello+ method to the class +String+ can be rewritten thus: diff --git a/doc/syntax/modules_and_classes.rdoc b/doc/syntax/modules_and_classes.rdoc new file mode 100644 index 0000000000..4710dcf3cb --- /dev/null +++ b/doc/syntax/modules_and_classes.rdoc @@ -0,0 +1,288 @@ += 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 +Curses namespace provides functionality for curses that prevents a collision +for the common name "Window". + +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 classes is a very powerful feature of Ruby, but it is best to only +reopen classes you own. Reopening classes 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 + +Class methods (also known as module functions, see Module#module_function) may +be called directly. + +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 be a subclass of the receiver or the receiver must be a subclass of +the sender. 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 not be called with a +receiver, not even +self+. If a private method is called with a receiver a +NoMethodError will be raised. + += 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. + +== 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. + |