summaryrefslogtreecommitdiff
path: root/ruby_2_2/doc/syntax/methods.rdoc
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-12-14 15:09:35 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-12-14 15:09:35 +0000
commit1a74fa4b04da04bd2bb33103dd3cf431438df38e (patch)
treef4a1d6c2961339e0c1d653c0f8427a53315080f0 /ruby_2_2/doc/syntax/methods.rdoc
parenta5b755e50e2d9aabf28ba24bf58644ca22b01a4f (diff)
add tag v2_2_9
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v2_2_9@61257 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ruby_2_2/doc/syntax/methods.rdoc')
-rw-r--r--ruby_2_2/doc/syntax/methods.rdoc456
1 files changed, 456 insertions, 0 deletions
diff --git a/ruby_2_2/doc/syntax/methods.rdoc b/ruby_2_2/doc/syntax/methods.rdoc
new file mode 100644
index 0000000000..2c01810b4c
--- /dev/null
+++ b/ruby_2_2/doc/syntax/methods.rdoc
@@ -0,0 +1,456 @@
+= Methods
+
+Methods implement the functionality of your program. Here is a simple method
+definition:
+
+ def one_plus_one
+ 1 + 1
+ end
+
+A method definition consists of the +def+ keyword, a method name, the body of
+the method, +return+ value and the +end+ keyword. When called the method will
+execute the body of the method. This method returns +2+.
+
+This section only covers defining methods. See also the {syntax documentation
+on calling methods}[rdoc-ref:syntax/calling_methods.rdoc].
+
+== Method Names
+
+Method names may be one of the operators or must start a letter or a character
+with the eight bit set. It may contain letters, numbers, an <code>_</code>
+(underscore or low line) or a character with the eight bit set. The convention
+is to use underscores to separate words in a multiword method name:
+
+ def method_name
+ puts "use underscores to separate words"
+ end
+
+Ruby programs must be written in a US-ASCII-compatible character set such as
+UTF-8, ISO-8859-1 etc. In such character sets if the eight bit is set it
+indicates an extended character. Ruby allows method names and other identifiers
+to contain such characters. Ruby programs cannot contain some characters like
+ASCII NUL (<code>\x00<code>).
+
+The following are the examples of valid ruby methods:
+
+ def hello
+ "hello"
+ end
+
+ def こんにちは
+ puts "means hello in Japanese"
+ end
+
+Typically method names are US-ASCII compatible since the keys to type them
+exist on all keyboards.
+
+Method names may end with a <code>!</code> (bang or exclamation mark), a
+<code>?</code> (question mark) or <code>=</code> equals sign.
+
+The bang methods(<code>!</code> at the end of method name) are called and
+executed just like any other method. However, by convention, a method with an
+exclamation point or bang is considered dangerous. In ruby core library the
+dangerous method implies that when a method ends with a bang(<code>!</code>),
+it indicates that unlike its non-bang equivalent, permanently modifies its
+receiver. Almost always, Ruby core library will have a non-bang
+counterpart(method name which does NOT end with <code>!</code>) of every bang
+method (method name which does end with <code>!</code>) that has does not
+modify the receiver. This convention is typically true for ruby core libary but
+may/may not hold true for other ruby libraries.
+
+Methods that end with a question mark by convention return boolean. But they
+may not always return just +true+ or +false+. Often they will may return an
+object to indicate a true value (or "truthy" value).
+
+Methods that end with an equals sign indicate an assignment method. For
+assignment methods the return value is ignored, the arguments are returned
+instead.
+
+These are method names for the various ruby operators. Each of these
+operators accept only one argument. Following the operator is the typical
+use or name of the operator. Creating an alternate meaning for the operator
+may lead to confusion as the user expects plus to add things, minus to
+subtract things, etc. Additionally, you cannot alter the precedence of the
+operators.
+
+<code>+</code> :: add
+<code>-</code> :: subtract
+<code>*</code> :: multiply
+<code>**</code> :: power
+<code>/</code> :: divide
+<code>%</code> :: modulus division, String#%
+<code>&</code> :: AND
+<code>^</code> :: XOR (exclusive OR)
+<code>>></code> :: right-shift
+<code><<</code> :: left-shift, append
+<code>==</code> :: equal
+<code>!=</code> :: not equal
+<code>===</code> :: case equality. See Object#===
+<code>=~</code> :: pattern match. (Not just for regular expressions)
+<code>!~</code> :: does not match
+<code><=></code> :: comparison aka spaceship operator. See Comparable
+<code><</code> :: less-than
+<code><=</code> :: less-than or equal
+<code>></code> :: greater-than
+<code>>=</code> :: greater-than or equal
+
+To define unary methods minus, plus, tilde and not (<code>!</code>) follow the
+operator with an <code>@</code> as in <code>+@</code> or <code>!@</code>:
+
+ class C
+ def -@
+ puts "you inverted this object"
+ end
+ end
+
+ obj = C.new
+
+ -obj # prints "you inverted this object"
+
+Unary methods accept zero arguments.
+
+Additionally, methods for element reference and assignment may be defined:
+<code>[]</code> and <code>[]=</code> respectively. Both can take one or more
+arguments, and element reference can take none.
+
+ class C
+ def [](a, b)
+ puts a + b
+ end
+
+ def []=(a, b, c)
+ puts a * b + c
+ end
+ end
+
+ obj = C.new
+
+ obj[2, 3] # prints "5"
+ obj[2, 3] = 4 # prints "10"
+
+== Return Values
+
+By default, a method returns the last expression that was evaluated in the body
+of the method. In the example above, the last (and only) expression evaluated
+was the simple sum <code>1 + 1</code>. The +return+ keyword can be used to
+make it explicit that a method returns a value.
+
+ def one_plus_one
+ return 1 + 1
+ end
+
+It can also be used to make a method return before the last expression is
+evaluated.
+
+ def two_plus_two
+ return 2 + 2
+ 1 + 1 # this expression is never evaluated
+ end
+
+Note that for assignment methods the return value will always be ignored.
+Instead the argument will be returned:
+
+ def a=(value)
+ return 1 + value
+ end
+
+ p(a = 5) # prints 5
+
+== Scope
+
+The standard syntax to define a method:
+
+ def my_method
+ # ...
+ end
+
+adds the method to a class. You can define an instance method on a specific
+class with the +class+ keyword:
+
+ class C
+ def my_method
+ # ...
+ end
+ end
+
+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:
+
+ class C
+ def self.my_method
+ # ...
+ end
+ end
+
+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.
+
+The syntax for adding a method to an object is as follows:
+
+ greeting = "Hello"
+
+ def greeting.broaden
+ self + ", world!"
+ end
+
+ greeting.broaden # returns "Hello, world!"
+
++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:
+
+ def String.hello
+ "Hello, world!"
+ end
+
+A method defined like this is called a "singleton method". +broaden+ will only
+exist on the string instance +greeting+. Other strings will not have +broaden+.
+
+== Overriding
+
+When Ruby encounters the +def+ keyword, it doesn't consider it an error if the
+method already exists: it simply redefines it. This is called
+_overriding_. Rather like extending core classes, this is a potentially
+dangerous ability, and should be used sparingly because it can cause unexpected
+results. For example, consider this irb session:
+
+ >> "43".to_i
+ => 43
+ >> class String
+ >> def to_i
+ >> 42
+ >> end
+ >> end
+ => nil
+ >> "43".to_i
+ => 42
+
+This will effectively sabotage any code which makes use of the method
+<code>String#to_i</code> to parse numbers from strings.
+
+== Arguments
+
+A method may accept arguments. The argument list follows the method name:
+
+ def add_one(value)
+ value + 1
+ end
+
+When called, the user of the +add_one+ method must provide an argument. The
+argument is a local variable in the method body. The method will then add one
+to this argument and return the value. If given +1+ this method will
+return +2+.
+
+The parentheses around the arguments are optional:
+
+ def add_one value
+ value + 1
+ end
+
+Multiple arguments are separated by a comma:
+
+ def add_values(a, b)
+ a + b
+ end
+
+When called, the arguments must be provided in the exact order. In other
+words, the arguments are positional.
+
+=== Default Values
+
+Arguments may have default values:
+
+ def add_values(a, b = 1)
+ a + b
+ end
+
+The default value does not need to appear first, but arguments with defaults
+must be grouped together. This is ok:
+
+ def add_values(a = 1, b = 2, c)
+ a + b + c
+ end
+
+This will raise a SyntaxError:
+
+ def add_values(a = 1, b, c = 1)
+ a + b + c
+ end
+
+=== Array Decomposition
+
+You can decompose (unpack or extract values from) an Array using extra
+parentheses in the arguments:
+
+ def my_method((a, b))
+ p a: a, b: b
+ end
+
+ my_method([1, 2])
+
+This prints:
+
+ {:a=>1, :b=>2}
+
+If the argument has extra elements in the Array they will be ignored:
+
+ def my_method((a, b))
+ p a: a, b: b
+ end
+
+ my_method([1, 2, 3])
+
+This has the same output as above.
+
+You can use a <code>*</code> to collect the remaining arguments. This splits
+an Array into a first element and the rest:
+
+ def my_method((a, *b))
+ p a: a, b: b
+ end
+
+ my_method([1, 2, 3])
+
+This prints:
+
+ {:a=>1, :b=>[2, 3]}
+
+The argument will be decomposed if it responds to #to_ary. You should only
+define #to_ary if you can use your object in place of an Array.
+
+Use of the inner parentheses only uses one of the sent arguments. If the
+argument is not an Array it will be assigned to the first argument in the
+decomposition and the remaining arguments in the decomposition will be +nil+:
+
+ def my_method(a, (b, c), d)
+ p a: a, b: b, c: c, d: d
+ end
+
+ my_method(1, 2, 3)
+
+This prints:
+
+ {:a=>1, :b=>2, :c=>nil, :d=>3}
+
+You can nest decomposition arbitrarily:
+
+ def my_method(((a, b), c))
+ # ...
+ end
+
+=== Array/Hash Argument
+
+Prefixing an argument with <code>*</code> causes any remaining arguments to be
+converted to an Array:
+
+ def gather_arguments(*arguments)
+ p arguments
+ end
+
+ gather_arguments 1, 2, 3 # prints [1, 2, 3]
+
+The array argument must be the last positional argument, it must appear before
+any keyword arguments.
+
+The array argument will capture a Hash as the last entry if a hash was sent by
+the caller after all positional arguments.
+
+ gather_arguments 1, a: 2 # prints [1, {:a=>2}]
+
+However, this only occurs if the method does not declare any keyword arguments.
+
+ def gather_arguments_keyword(*positional, keyword: nil)
+ p positional: positional, keyword: keyword
+ end
+
+ gather_arguments_keyword 1, 2, three: 3
+ #=> raises: unknown keyword: three (ArgumentError)
+
+Also, note that a bare <code>*</code> can be used to ignore arguments:
+
+ def ignore_arguments(*)
+ end
+
+=== Keyword Arguments
+
+Keyword arguments are similar to positional arguments with default values:
+
+ def add_values(first: 1, second: 2)
+ first + second
+ end
+
+Arbitrary keyword arguments will be accepted with <code>**</code>:
+
+ def gather_arguments(first: nil, **rest)
+ p first, rest
+ end
+
+ gather_arguments first: 1, second: 2, third: 3
+ # prints 1 then {:second=>2, :third=>3}
+
+When calling a method with keyword arguments the arguments may appear in any
+order. If an unknown keyword argument is sent by the caller an ArgumentError
+is raised.
+
+When mixing keyword arguments and positional arguments, all positional
+arguments must appear before any keyword arguments.
+
+== Block Argument
+
+The block argument is indicated by <code>&</code> and must come last:
+
+ def my_method(&my_block)
+ my_block.call(self)
+ end
+
+Most frequently the block argument is used to pass a block to another method:
+
+ def each_item(&block)
+ @items.each(&block)
+ end
+
+If you are only going to call the block and will not otherwise manipulate it
+or send it to another method using <code>yield</code> without an explicit
+block parameter is preferred. This method is equivalent to the first method
+in this section:
+
+ def my_method
+ yield self
+ end
+
+There is also a performance benefit to using yield over a calling a block
+parameter. When a block argument is assigned to a variable a Proc object is
+created which holds the block. When using yield this Proc object is not
+created.
+
+If you only need to use the block sometimes you can use Proc.new to create a
+proc from the block that was passed to your method. See Proc.new for further
+details.
+
+== Exception Handling
+
+Methods have an implied exception handling block so you do not need to use
++begin+ or +end+ to handle exceptions. This:
+
+ def my_method
+ begin
+ # code that may raise an exception
+ rescue
+ # handle exception
+ end
+ end
+
+May be written as:
+
+ def my_method
+ # code that may raise an exception
+ rescue
+ # handle exception
+ end
+
+If you wish to rescue an exception for only part of your method use +begin+ and
++end+. For more details see the page on {exception
+handling}[rdoc-ref:syntax/exceptions.rdoc].
+