File: C:/Ruby27-x64/share/doc/ruby/html/syntax/methods_rdoc.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>methods - RDoc Documentation</title>
<script type="text/javascript">
var rdoc_rel_prefix = "../";
var index_rel_prefix = "../";
</script>
<script src="../js/navigation.js" defer></script>
<script src="../js/search.js" defer></script>
<script src="../js/search_index.js" defer></script>
<script src="../js/searcher.js" defer></script>
<script src="../js/darkfish.js" defer></script>
<link href="../css/fonts.css" rel="stylesheet">
<link href="../css/rdoc.css" rel="stylesheet">
<body id="top" role="document" class="file">
<nav role="navigation">
<div id="project-navigation">
<div id="home-section" role="region" title="Quick navigation" class="nav-section">
<h2>
<a href="../index.html" rel="home">Home</a>
</h2>
<div id="table-of-contents-navigation">
<a href="../table_of_contents.html#pages">Pages</a>
<a href="../table_of_contents.html#classes">Classes</a>
<a href="../table_of_contents.html#methods">Methods</a>
</div>
</div>
<div id="search-section" role="search" class="project-section initially-hidden">
<form action="#" method="get" accept-charset="utf-8">
<div id="search-field-wrapper">
<input id="search-field" role="combobox" aria-label="Search"
aria-autocomplete="list" aria-controls="search-results"
type="text" name="search" placeholder="Search" spellcheck="false"
title="Type to search, Up and Down to navigate, Enter to load">
</div>
<ul id="search-results" aria-label="Search Results"
aria-busy="false" aria-expanded="false"
aria-atomic="false" class="initially-hidden"></ul>
</form>
</div>
</div>
<div class="nav-section">
<h3>Table of Contents</h3>
<ul class="link-list" role="directory">
<li><a href="#label-Methods">Methods</a>
<li><a href="#label-Method+Names">Method Names</a>
<li><a href="#label-Return+Values">Return Values</a>
<li><a href="#label-Scope">Scope</a>
<li><a href="#label-Overriding">Overriding</a>
<li><a href="#label-Arguments">Arguments</a>
<li><a href="#label-Default+Values">Default Values</a>
<li><a href="#label-Array+Decomposition">Array Decomposition</a>
<li><a href="#label-Array-2FHash+Argument">Array/Hash Argument</a>
<li><a href="#label-Keyword+Arguments">Keyword Arguments</a>
<li><a href="#label-Keyword+and+Positional+Argument+Separation">Keyword and Positional Argument Separation</a>
<li><a href="#label-Conversion+of+Hash+to+Keywords">Conversion of Hash to Keywords</a>
<li><a href="#label-Conversion+of+Keywords+to+Positional+Arguments">Conversion of Keywords to Positional Arguments</a>
<li><a href="#label-Splitting+of+Positional+Hashes+or+Keywords">Splitting of Positional Hashes or Keywords</a>
<li><a href="#label-Block+Argument">Block Argument</a>
<li><a href="#label-Exception+Handling">Exception Handling</a>
</ul>
</div>
<div id="project-metadata">
<div id="fileindex-section" class="nav-section">
<h3>Pages</h3>
<ul class="link-list">
<li><a href="../CONTRIBUTING_md.html">CONTRIBUTING</a>
<li><a href="../COPYING.html">COPYING</a>
<li><a href="../COPYING_ja.html">COPYING.ja</a>
<li><a href="../LEGAL.html">LEGAL</a>
<li><a href="../NEWS.html">NEWS</a>
<li><a href="../NEWS-1_8_7.html">NEWS-1.8.7</a>
<li><a href="../NEWS-1_9_1.html">NEWS-1.9.1</a>
<li><a href="../NEWS-1_9_2.html">NEWS-1.9.2</a>
<li><a href="../NEWS-1_9_3.html">NEWS-1.9.3</a>
<li><a href="../NEWS-2_0_0.html">NEWS-2.0.0</a>
<li><a href="../NEWS-2_1_0.html">NEWS-2.1.0</a>
<li><a href="../NEWS-2_2_0.html">NEWS-2.2.0</a>
<li><a href="../NEWS-2_3_0.html">NEWS-2.3.0</a>
<li><a href="../NEWS-2_4_0.html">NEWS-2.4.0</a>
<li><a href="../NEWS-2_5_0.html">NEWS-2.5.0</a>
<li><a href="../NEWS-2_6_0.html">NEWS-2.6.0</a>
<li><a href="../README_ja_md.html">README.ja</a>
<li><a href="../README_md.html">README</a>
<li><a href="../bug_triaging_rdoc.html">bug_triaging</a>
<li><a href="../contributing_rdoc.html">contributing</a>
<li><a href="../contributors_rdoc.html">contributors</a>
<li><a href="../dtrace_probes_rdoc.html">dtrace_probes</a>
<li><a href="../extension_ja_rdoc.html">extension.ja</a>
<li><a href="../extension_rdoc.html">extension</a>
<li><a href="../globals_rdoc.html">globals</a>
<li><a href="../keywords_rdoc.html">keywords</a>
<li><a href="../lib/racc/pre-setup.html">pre-setup</a>
<li><a href="../lib/racc/rdoc/grammar_en_rdoc.html">grammar.en</a>
<li><a href="../maintainers_rdoc.html">maintainers</a>
<li><a href="../marshal_rdoc.html">marshal</a>
<li><a href="../regexp_rdoc.html">regexp</a>
<li><a href="../security_rdoc.html">security</a>
<li><a href="../signals_rdoc.html">signals</a>
<li><a href="../standard_library_rdoc.html">standard_library</a>
<li><a href="../syntax_rdoc.html">syntax</a>
<li><a href="../syntax/assignment_rdoc.html">assignment</a>
<li><a href="../syntax/calling_methods_rdoc.html">calling_methods</a>
<li><a href="../syntax/comments_rdoc.html">comments</a>
<li><a href="../syntax/control_expressions_rdoc.html">control_expressions</a>
<li><a href="../syntax/exceptions_rdoc.html">exceptions</a>
<li><a href="../syntax/literals_rdoc.html">literals</a>
<li><a href="../syntax/methods_rdoc.html">methods</a>
<li><a href="../syntax/miscellaneous_rdoc.html">miscellaneous</a>
<li><a href="../syntax/modules_and_classes_rdoc.html">modules_and_classes</a>
<li><a href="../syntax/precedence_rdoc.html">precedence</a>
<li><a href="../syntax/refinements_rdoc.html">refinements</a>
<li><a href="../win32/README_win32.html">README.win32</a>
</ul>
</div>
</div>
</nav>
<main role="main" aria-label="Page syntax/methods.rdoc">
<h1 id="label-Methods">Methods<span><a href="#label-Methods">¶</a> <a href="#top">↑</a></span></h1>
<p>Methods implement the functionality of your program. Here is a simple method definition:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">one_plus_one</span>
<span class="ruby-value">1</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">end</span>
</pre>
<p>A method definition consists of the <code>def</code> keyword, a method name, the body of the method, <code>return</code> value and the <code>end</code> keyword. When called the method will execute the body of the method. This method returns <code>2</code>.</p>
<p>This section only covers defining methods. See also the <a href="calling_methods_rdoc.html">syntax documentation on calling methods</a>.</p>
<h2 id="label-Method+Names"><a href="../Method.html"><code>Method</code></a> Names<span><a href="#label-Method+Names">¶</a> <a href="#top">↑</a></span></h2>
<p><a href="../Method.html"><code>Method</code></a> names may be one of the operators or must start a letter or a character with the eighth bit set. It may contain letters, numbers, an <code>_</code> (underscore or low line) or a character with the eighth bit set. The convention is to use underscores to separate words in a multiword method name:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">method_name</span>
<span class="ruby-identifier">puts</span> <span class="ruby-string">"use underscores to separate words"</span>
<span class="ruby-keyword">end</span>
</pre>
<p>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 eighth 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>).</p>
<p>The following are examples of valid Ruby methods:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">hello</span>
<span class="ruby-string">"hello"</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">こんにちは</span>
<span class="ruby-identifier">puts</span> <span class="ruby-string">"means hello in Japanese"</span>
<span class="ruby-keyword">end</span>
</pre>
<p>Typically method names are US-ASCII compatible since the keys to type them exist on all keyboards.</p>
<p><a href="../Method.html"><code>Method</code></a> names may end with a <code>!</code> (bang or exclamation mark), a <code>?</code> (question mark), or <code>=</code> (equals sign).</p>
<p>The bang methods (<code>!</code> at the end of the 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's 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, the 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 does not modify the receiver. This convention is typically true for the Ruby core library but may or may not hold true for other Ruby libraries.</p>
<p>Methods that end with a question mark by convention return boolean, but they may not always return just <code>true</code> or <code>false</code>. Often, they will return an object to indicate a true value (or “truthy” value).</p>
<p>Methods that end with an equals sign indicate an assignment method.</p>
<p>These are method names for the various Ruby operators. Each of these operators accepts 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.</p>
<dl class="rdoc-list note-list"><dt><code>+</code>
<dd>
<p>add</p>
</dd><dt><code>-</code>
<dd>
<p>subtract</p>
</dd><dt><code>*</code>
<dd>
<p>multiply</p>
</dd><dt><code>**</code>
<dd>
<p>power</p>
</dd><dt><code>/</code>
<dd>
<p>divide</p>
</dd><dt><code>%</code>
<dd>
<p>modulus division, <a href="../String.html#method-i-25"><code>String#%</code></a></p>
</dd><dt><code>&</code>
<dd>
<p>AND</p>
</dd><dt><code>^</code>
<dd>
<p>XOR (exclusive OR)</p>
</dd><dt><code>>></code>
<dd>
<p>right-shift</p>
</dd><dt><code><<</code>
<dd>
<p>left-shift, append</p>
</dd><dt><code>==</code>
<dd>
<p>equal</p>
</dd><dt><code>!=</code>
<dd>
<p>not equal</p>
</dd><dt><code>===</code>
<dd>
<p>case equality. See <a href="../Object.html#method-i-3D-3D-3D"><code>Object#===</code></a></p>
</dd><dt><code>=~</code>
<dd>
<p>pattern match. (Not just for regular expressions)</p>
</dd><dt><code>!~</code>
<dd>
<p>does not match</p>
</dd><dt><code><=></code>
<dd>
<p>comparison aka spaceship operator. See <a href="../Comparable.html"><code>Comparable</code></a></p>
</dd><dt><code><</code>
<dd>
<p>less-than</p>
</dd><dt><code><=</code>
<dd>
<p>less-than or equal</p>
</dd><dt><code>></code>
<dd>
<p>greater-than</p>
</dd><dt><code>>=</code>
<dd>
<p>greater-than or equal</p>
</dd></dl>
<p>To define unary methods minus and plus, follow the operator with an <code>@</code> as in <code>+@</code>:</p>
<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">C</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">-@</span>
<span class="ruby-identifier">puts</span> <span class="ruby-string">"you inverted this object"</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">obj</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">new</span>
<span class="ruby-operator">-</span><span class="ruby-identifier">obj</span> <span class="ruby-comment"># prints "you inverted this object"</span>
</pre>
<p>The <code>@</code> is needed to differentiate unary minus and plus operators from binary minus and plus operators.</p>
<p>You can also follow tilde and not (<code>!</code>) unary methods with <code>@</code>, but it is not required as there are no binary tilde and not operators.</p>
<p>Unary methods accept zero arguments.</p>
<p>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.</p>
<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">C</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">[]</span>(<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-identifier">puts</span> <span class="ruby-identifier">a</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">[]=</span>(<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span>, <span class="ruby-identifier">c</span>)
<span class="ruby-identifier">puts</span> <span class="ruby-identifier">a</span> <span class="ruby-operator">*</span> <span class="ruby-identifier">b</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">c</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">obj</span> = <span class="ruby-constant">C</span>.<span class="ruby-identifier">new</span>
<span class="ruby-identifier">obj</span>[<span class="ruby-value">2</span>, <span class="ruby-value">3</span>] <span class="ruby-comment"># prints "5"</span>
<span class="ruby-identifier">obj</span>[<span class="ruby-value">2</span>, <span class="ruby-value">3</span>] = <span class="ruby-value">4</span> <span class="ruby-comment"># prints "10"</span>
</pre>
<h2 id="label-Return+Values">Return Values<span><a href="#label-Return+Values">¶</a> <a href="#top">↑</a></span></h2>
<p>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 <code>return</code> keyword can be used to make it explicit that a method returns a value.</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">one_plus_one</span>
<span class="ruby-keyword">return</span> <span class="ruby-value">1</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">end</span>
</pre>
<p>It can also be used to make a method return before the last expression is evaluated.</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">two_plus_two</span>
<span class="ruby-keyword">return</span> <span class="ruby-value">2</span> <span class="ruby-operator">+</span> <span class="ruby-value">2</span>
<span class="ruby-value">1</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span> <span class="ruby-comment"># this expression is never evaluated</span>
<span class="ruby-keyword">end</span>
</pre>
<p>Note that for assignment methods the return value will be ignored when using the assignment syntax. Instead, the argument will be returned:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">a=</span>(<span class="ruby-identifier">value</span>)
<span class="ruby-keyword">return</span> <span class="ruby-value">1</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">value</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">p</span>(<span class="ruby-keyword">self</span>.<span class="ruby-identifier">a</span> = <span class="ruby-value">5</span>) <span class="ruby-comment"># prints 5</span>
</pre>
<p>The actual return value will be returned when invoking the method directly:</p>
<pre class="ruby"><span class="ruby-identifier">p</span> <span class="ruby-identifier">send</span>(<span class="ruby-value">:a=</span>, <span class="ruby-value">5</span>) <span class="ruby-comment"># prints 6</span>
</pre>
<h2 id="label-Scope">Scope<span><a href="#label-Scope">¶</a> <a href="#top">↑</a></span></h2>
<p>The standard syntax to define a method:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>
<span class="ruby-comment"># ...</span>
<span class="ruby-keyword">end</span>
</pre>
<p>adds the method to a class. You can define an instance method on a specific class with the <code>class</code> keyword:</p>
<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">C</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>
<span class="ruby-comment"># ...</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
</pre>
<p>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:</p>
<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">C</span>
<span class="ruby-keyword">def</span> <span class="ruby-keyword">self</span>.<span class="ruby-identifier ruby-title">my_method</span>
<span class="ruby-comment"># ...</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
</pre>
<p>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 <a href="../Class.html"><code>Class</code></a> object.</p>
<p>The syntax for adding a method to an object is as follows:</p>
<pre class="ruby"><span class="ruby-identifier">greeting</span> = <span class="ruby-string">"Hello"</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">greeting</span>.<span class="ruby-identifier">broaden</span>
<span class="ruby-keyword">self</span> <span class="ruby-operator">+</span> <span class="ruby-string">", world!"</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">greeting</span>.<span class="ruby-identifier">broaden</span> <span class="ruby-comment"># returns "Hello, world!"</span>
</pre>
<p><code>self</code> is a keyword referring to the current object under consideration by the compiler, which might make the use of <code>self</code> in defining a class method above a little clearer. Indeed, the example of adding a <code>hello</code> method to the class <code>String</code> can be rewritten thus:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-constant">String</span>.<span class="ruby-identifier ruby-title">hello</span>
<span class="ruby-string">"Hello, world!"</span>
<span class="ruby-keyword">end</span>
</pre>
<p>A method defined like this is called a “singleton method”. <code>broaden</code> will only exist on the string instance <code>greeting</code>. Other strings will not have <code>broaden</code>.</p>
<h2 id="label-Overriding">Overriding<span><a href="#label-Overriding">¶</a> <a href="#top">↑</a></span></h2>
<p>When Ruby encounters the <code>def</code> keyword, it doesn't consider it an error if the method already exists: it simply redefines it. This is called <em>overriding</em>. 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:</p>
<pre>>> "43".to_i
=> 43
>> class String
>> def to_i
>> 42
>> end
>> end
=> nil
>> "43".to_i
=> 42</pre>
<p>This will effectively sabotage any code which makes use of the method <code>String#to_i</code> to parse numbers from strings.</p>
<h2 id="label-Arguments">Arguments<span><a href="#label-Arguments">¶</a> <a href="#top">↑</a></span></h2>
<p>A method may accept arguments. The argument list follows the method name:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_one</span>(<span class="ruby-identifier">value</span>)
<span class="ruby-identifier">value</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">end</span>
</pre>
<p>When called, the user of the <code>add_one</code> 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 <code>1</code> this method will return <code>2</code>.</p>
<p>The parentheses around the arguments are optional:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_one</span> <span class="ruby-identifier">value</span>
<span class="ruby-identifier">value</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
<span class="ruby-keyword">end</span>
</pre>
<p>Multiple arguments are separated by a comma:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_values</span>(<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span>)
<span class="ruby-identifier">a</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">end</span>
</pre>
<p>When called, the arguments must be provided in the exact order. In other words, the arguments are positional.</p>
<h3 id="label-Default+Values">Default Values<span><a href="#label-Default+Values">¶</a> <a href="#top">↑</a></span></h3>
<p>Arguments may have default values:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_values</span>(<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span> = <span class="ruby-value">1</span>)
<span class="ruby-identifier">a</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">end</span>
</pre>
<p>The default value does not need to appear first, but arguments with defaults must be grouped together. This is ok:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_values</span>(<span class="ruby-identifier">a</span> = <span class="ruby-value">1</span>, <span class="ruby-identifier">b</span> = <span class="ruby-value">2</span>, <span class="ruby-identifier">c</span>)
<span class="ruby-identifier">a</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">b</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">c</span>
<span class="ruby-keyword">end</span>
</pre>
<p>This will raise a SyntaxError:</p>
<pre>def add_values(a = 1, b, c = 1)
a + b + c
end</pre>
<p>Default argument values can refer to arguments that have already been evaluated as local variables, and argument values are always evaluated left to right. So this is allowed:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_values</span>(<span class="ruby-identifier">a</span> = <span class="ruby-value">1</span>, <span class="ruby-identifier">b</span> = <span class="ruby-identifier">a</span>)
<span class="ruby-identifier">a</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">add_values</span>
<span class="ruby-comment"># => 2</span>
</pre>
<p>But this will raise a <code>NameError</code> (unless there is a method named <code>b</code> defined):</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_values</span>(<span class="ruby-identifier">a</span> = <span class="ruby-identifier">b</span>, <span class="ruby-identifier">b</span> = <span class="ruby-value">1</span>)
<span class="ruby-identifier">a</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">add_values</span>
<span class="ruby-comment"># NameError (undefined local variable or method `b' for main:Object)</span>
</pre>
<h3 id="label-Array+Decomposition"><a href="../Array.html"><code>Array</code></a> Decomposition<span><a href="#label-Array+Decomposition">¶</a> <a href="#top">↑</a></span></h3>
<p>You can decompose (unpack or extract values from) an <a href="../Array.html"><code>Array</code></a> using extra parentheses in the arguments:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>((<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span>))
<span class="ruby-identifier">p</span> <span class="ruby-value">a:</span> <span class="ruby-identifier">a</span>, <span class="ruby-value">b:</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>([<span class="ruby-value">1</span>, <span class="ruby-value">2</span>])
</pre>
<p>This prints:</p>
<pre class="ruby">{<span class="ruby-value">:a</span><span class="ruby-operator">=></span><span class="ruby-value">1</span>, <span class="ruby-value">:b</span><span class="ruby-operator">=></span><span class="ruby-value">2</span>}
</pre>
<p>If the argument has extra elements in the <a href="../Array.html"><code>Array</code></a> they will be ignored:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>((<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span>))
<span class="ruby-identifier">p</span> <span class="ruby-value">a:</span> <span class="ruby-identifier">a</span>, <span class="ruby-value">b:</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>([<span class="ruby-value">1</span>, <span class="ruby-value">2</span>, <span class="ruby-value">3</span>])
</pre>
<p>This has the same output as above.</p>
<p>You can use a <code>*</code> to collect the remaining arguments. This splits an <a href="../Array.html"><code>Array</code></a> into a first element and the rest:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>((<span class="ruby-identifier">a</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">b</span>))
<span class="ruby-identifier">p</span> <span class="ruby-value">a:</span> <span class="ruby-identifier">a</span>, <span class="ruby-value">b:</span> <span class="ruby-identifier">b</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>([<span class="ruby-value">1</span>, <span class="ruby-value">2</span>, <span class="ruby-value">3</span>])
</pre>
<p>This prints:</p>
<pre class="ruby">{<span class="ruby-value">:a</span><span class="ruby-operator">=></span><span class="ruby-value">1</span>, <span class="ruby-value">:b</span><span class="ruby-operator">=></span>[<span class="ruby-value">2</span>, <span class="ruby-value">3</span>]}
</pre>
<p>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 <a href="../Array.html"><code>Array</code></a>.</p>
<p>Use of the inner parentheses only uses one of the sent arguments. If the argument is not an <a href="../Array.html"><code>Array</code></a> it will be assigned to the first argument in the decomposition and the remaining arguments in the decomposition will be <code>nil</code>:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(<span class="ruby-identifier">a</span>, (<span class="ruby-identifier">b</span>, <span class="ruby-identifier">c</span>), <span class="ruby-identifier">d</span>)
<span class="ruby-identifier">p</span> <span class="ruby-value">a:</span> <span class="ruby-identifier">a</span>, <span class="ruby-value">b:</span> <span class="ruby-identifier">b</span>, <span class="ruby-value">c:</span> <span class="ruby-identifier">c</span>, <span class="ruby-value">d:</span> <span class="ruby-identifier">d</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>(<span class="ruby-value">1</span>, <span class="ruby-value">2</span>, <span class="ruby-value">3</span>)
</pre>
<p>This prints:</p>
<pre class="ruby">{<span class="ruby-value">:a</span><span class="ruby-operator">=></span><span class="ruby-value">1</span>, <span class="ruby-value">:b</span><span class="ruby-operator">=></span><span class="ruby-value">2</span>, <span class="ruby-value">:c</span><span class="ruby-operator">=></span><span class="ruby-keyword">nil</span>, <span class="ruby-value">:d</span><span class="ruby-operator">=></span><span class="ruby-value">3</span>}
</pre>
<p>You can nest decomposition arbitrarily:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(((<span class="ruby-identifier">a</span>, <span class="ruby-identifier">b</span>), <span class="ruby-identifier">c</span>))
<span class="ruby-comment"># ...</span>
<span class="ruby-keyword">end</span>
</pre>
<h3 id="label-Array-2FHash+Argument">Array/Hash Argument<span><a href="#label-Array-2FHash+Argument">¶</a> <a href="#top">↑</a></span></h3>
<p>Prefixing an argument with <code>*</code> causes any remaining arguments to be converted to an Array:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">gather_arguments</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
<span class="ruby-identifier">p</span> <span class="ruby-identifier">arguments</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">gather_arguments</span> <span class="ruby-value">1</span>, <span class="ruby-value">2</span>, <span class="ruby-value">3</span> <span class="ruby-comment"># prints [1, 2, 3]</span>
</pre>
<p>The array argument must appear before any keyword arguments.</p>
<p>It is possible to gather arguments at the beginning or in the middle:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">gather_arguments</span>(<span class="ruby-identifier">first_arg</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">middle_arguments</span>, <span class="ruby-identifier">last_arg</span>)
<span class="ruby-identifier">p</span> <span class="ruby-identifier">middle_arguments</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">gather_arguments</span> <span class="ruby-value">1</span>, <span class="ruby-value">2</span>, <span class="ruby-value">3</span>, <span class="ruby-value">4</span> <span class="ruby-comment"># prints [2, 3]</span>
</pre>
<p>The array argument will capture a <a href="../Hash.html"><code>Hash</code></a> as the last entry if a hash was sent by the caller after all positional arguments.</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">gather_arguments</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">arguments</span>)
<span class="ruby-identifier">p</span> <span class="ruby-identifier">arguments</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">gather_arguments</span> <span class="ruby-value">1</span>, <span class="ruby-value">a:</span> <span class="ruby-value">2</span> <span class="ruby-comment"># prints [1, {:a=>2}]</span>
</pre>
<p>However, this only occurs if the method does not declare any keyword arguments.</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">gather_arguments_keyword</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">positional</span>, <span class="ruby-value">keyword:</span> <span class="ruby-keyword">nil</span>)
<span class="ruby-identifier">p</span> <span class="ruby-value">positional:</span> <span class="ruby-identifier">positional</span>, <span class="ruby-value">keyword:</span> <span class="ruby-identifier">keyword</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">gather_arguments_keyword</span> <span class="ruby-value">1</span>, <span class="ruby-value">2</span>, <span class="ruby-value">three:</span> <span class="ruby-value">3</span>
<span class="ruby-comment">#=> raises: unknown keyword: three (ArgumentError)</span>
</pre>
<p>Also, note that a bare <code>*</code> can be used to ignore arguments:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">ignore_arguments</span>(<span class="ruby-operator">*</span>)
<span class="ruby-keyword">end</span>
</pre>
<h3 id="label-Keyword+Arguments">Keyword Arguments<span><a href="#label-Keyword+Arguments">¶</a> <a href="#top">↑</a></span></h3>
<p>Keyword arguments are similar to positional arguments with default values:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_values</span>(<span class="ruby-value">first:</span> <span class="ruby-value">1</span>, <span class="ruby-value">second:</span> <span class="ruby-value">2</span>)
<span class="ruby-identifier">first</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">second</span>
<span class="ruby-keyword">end</span>
</pre>
<p>Arbitrary keyword arguments will be accepted with <code>**</code>:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">gather_arguments</span>(<span class="ruby-value">first:</span> <span class="ruby-keyword">nil</span>, <span class="ruby-operator">**</span><span class="ruby-identifier">rest</span>)
<span class="ruby-identifier">p</span> <span class="ruby-identifier">first</span>, <span class="ruby-identifier">rest</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">gather_arguments</span> <span class="ruby-value">first:</span> <span class="ruby-value">1</span>, <span class="ruby-value">second:</span> <span class="ruby-value">2</span>, <span class="ruby-value">third:</span> <span class="ruby-value">3</span>
<span class="ruby-comment"># prints 1 then {:second=>2, :third=>3}</span>
</pre>
<p>When calling a method with keyword arguments the arguments may appear in any order. If an unknown keyword argument is sent by the caller, and the method does not accept arbitrary keyword arguments, an <a href="../ArgumentError.html"><code>ArgumentError</code></a> is raised.</p>
<p>To require a specific keyword argument, do not include a default value for the keyword argument:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">add_values</span>(<span class="ruby-value">first:</span>, <span class="ruby-value">second:</span>)
<span class="ruby-identifier">first</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">second</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">add_values</span>
<span class="ruby-comment"># ArgumentError (missing keywords: first, second)</span>
<span class="ruby-identifier">add_values</span>(<span class="ruby-value">first:</span> <span class="ruby-value">1</span>, <span class="ruby-value">second:</span> <span class="ruby-value">2</span>)
<span class="ruby-comment"># => 3</span>
</pre>
<p>When mixing keyword arguments and positional arguments, all positional arguments must appear before any keyword arguments.</p>
<p>Also, note that <code>**</code> can be used to ignore keyword arguments:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">ignore_keywords</span>(<span class="ruby-operator">**</span>)
<span class="ruby-keyword">end</span>
</pre>
<p>To mark a method as accepting keywords, but not actually accepting keywords, you can use the <code>**nil</code>:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">no_keywords</span>(<span class="ruby-operator">**</span><span class="ruby-keyword">nil</span>)
<span class="ruby-keyword">end</span>
</pre>
<p>Calling such a method with keywords or a non-empty keyword splat will result in an <a href="../ArgumentError.html"><code>ArgumentError</code></a>. This syntax is supported so that keywords can be added to the method later without affected backwards compatibility.</p>
<h3 id="label-Keyword+and+Positional+Argument+Separation">Keyword and Positional Argument Separation<span><a href="#label-Keyword+and+Positional+Argument+Separation">¶</a> <a href="#top">↑</a></span></h3>
<p>Between Ruby 2.0 and 2.6, keyword and positional arguments were not separated, and a keyword argument could be used as a positional argument and vice-versa. In Ruby 3.0, keyword and positional arguments will be separated if the method definition includes keyword arguments. In Ruby 3.0, if the method definition does not include keyword arguments, keyword arguments provided when calling the method will continue to be treated as a final positional hash argument.</p>
<p>Currently, the keyword and positional arguments are not separated, but cases where behavior will change in Ruby 3.0 will result in a warning being emitted.</p>
<p>There are a few different types of keyword argument separation issues.</p>
<h4 id="label-Conversion+of+Hash+to+Keywords">Conversion of <a href="../Hash.html"><code>Hash</code></a> to Keywords<span><a href="#label-Conversion+of+Hash+to+Keywords">¶</a> <a href="#top">↑</a></span></h4>
<p>If a method is called with the hash, the hash could be treated as keywords:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(<span class="ruby-operator">**</span><span class="ruby-identifier">keywords</span>)
<span class="ruby-identifier">keywords</span>
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>({<span class="ruby-value">a:</span> <span class="ruby-value">1</span>}) <span class="ruby-comment"># {:a => 1}</span>
</pre>
<p>This occurs even if the hash could be an optional positional argument or an element of a rest argument:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(<span class="ruby-identifier">hash</span>=<span class="ruby-keyword">nil</span>, <span class="ruby-operator">**</span><span class="ruby-identifier">keywords</span>)
[<span class="ruby-identifier">hash</span>, <span class="ruby-identifier">keywords</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>({<span class="ruby-value">a:</span> <span class="ruby-value">1</span>}) <span class="ruby-comment"># [nil, {:a => 1}]</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>, <span class="ruby-operator">**</span><span class="ruby-identifier">keywords</span>)
[<span class="ruby-identifier">args</span>, <span class="ruby-identifier">keywords</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>({<span class="ruby-value">a:</span> <span class="ruby-value">1</span>}) <span class="ruby-comment"># [[], {:a => 1}]</span>
</pre>
<p>However, if the hash is needed for a mandatory positional argument, it would not be treated as keywords:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(<span class="ruby-identifier">hash</span>, <span class="ruby-operator">**</span><span class="ruby-identifier">keywords</span>)
[<span class="ruby-identifier">hash</span>, <span class="ruby-identifier">keywords</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>({<span class="ruby-value">a:</span> <span class="ruby-value">1</span>}) <span class="ruby-comment"># [{:a => 1}, {}]</span>
</pre>
<h4 id="label-Conversion+of+Keywords+to+Positional+Arguments">Conversion of Keywords to Positional Arguments<span><a href="#label-Conversion+of+Keywords+to+Positional+Arguments">¶</a> <a href="#top">↑</a></span></h4>
<p>If a method is called with keywords, but it is missing one mandatory positional argument, the keywords are converted to a hash and the hash used as the mandatory positional argument:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(<span class="ruby-identifier">hash</span>, <span class="ruby-operator">**</span><span class="ruby-identifier">keywords</span>)
[<span class="ruby-identifier">hash</span>, <span class="ruby-identifier">keywords</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>(<span class="ruby-value">a:</span> <span class="ruby-value">1</span>) <span class="ruby-comment"># [{:a => 1}, {}]</span>
</pre>
<p>This is also true for empty keyword splats:</p>
<pre class="ruby"><span class="ruby-identifier">kw</span> = {}
<span class="ruby-identifier">my_method</span>(<span class="ruby-operator">**</span><span class="ruby-identifier">kw</span>) <span class="ruby-comment"># [{}, {}]</span>
</pre>
<h4 id="label-Splitting+of+Positional+Hashes+or+Keywords">Splitting of Positional Hashes or Keywords<span><a href="#label-Splitting+of+Positional+Hashes+or+Keywords">¶</a> <a href="#top">↑</a></span></h4>
<p>If a method definition accepts specific keywords and not arbitrary keywords, keywords or a positional hash may be split if the hash includes both <a href="../Symbol.html"><code>Symbol</code></a> keys and non-Symbol keys and the keywords or positional hash are not needed as a mandatory positional argument. In this case, the non-Symbol keys are separated into a positional argument hash, and the <a href="../Symbol.html"><code>Symbol</code></a> keys are used as the keyword arguments:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(<span class="ruby-identifier">hash</span>=<span class="ruby-value">3</span>, <span class="ruby-value">a:</span> <span class="ruby-value">4</span>)
[<span class="ruby-identifier">hash</span>, <span class="ruby-identifier">a</span>]
<span class="ruby-keyword">end</span>
<span class="ruby-identifier">my_method</span>(<span class="ruby-value">a:</span> <span class="ruby-value">1</span>, <span class="ruby-string">'a'</span> <span class="ruby-operator">=></span> <span class="ruby-value">2</span>) <span class="ruby-comment"># [{"a"=>2}, 1]</span>
<span class="ruby-identifier">my_method</span>({<span class="ruby-value">a:</span> <span class="ruby-value">1</span>, <span class="ruby-string">'a'</span> <span class="ruby-operator">=></span> <span class="ruby-value">2</span>}) <span class="ruby-comment"># [{"a"=>2}, 1]</span>
</pre>
<h2 id="label-Block+Argument">Block Argument<span><a href="#label-Block+Argument">¶</a> <a href="#top">↑</a></span></h2>
<p>The block argument is indicated by <code>&</code> and must come last:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>(<span class="ruby-operator">&</span><span class="ruby-identifier">my_block</span>)
<span class="ruby-identifier">my_block</span>.<span class="ruby-identifier">call</span>(<span class="ruby-keyword">self</span>)
<span class="ruby-keyword">end</span>
</pre>
<p>Most frequently the block argument is used to pass a block to another method:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">each_item</span>(<span class="ruby-operator">&</span><span class="ruby-identifier">block</span>)
<span class="ruby-ivar">@items</span>.<span class="ruby-identifier">each</span>(<span class="ruby-operator">&</span><span class="ruby-identifier">block</span>)
<span class="ruby-keyword">end</span>
</pre>
<p>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:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>
<span class="ruby-keyword">yield</span> <span class="ruby-keyword">self</span>
<span class="ruby-keyword">end</span>
</pre>
<h2 id="label-Exception+Handling"><a href="../Exception.html"><code>Exception</code></a> Handling<span><a href="#label-Exception+Handling">¶</a> <a href="#top">↑</a></span></h2>
<p>Methods have an implied exception handling block so you do not need to use <code>begin</code> or <code>end</code> to handle exceptions. This:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>
<span class="ruby-keyword">begin</span>
<span class="ruby-comment"># code that may raise an exception</span>
<span class="ruby-keyword">rescue</span>
<span class="ruby-comment"># handle exception</span>
<span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
</pre>
<p>May be written as:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>
<span class="ruby-comment"># code that may raise an exception</span>
<span class="ruby-keyword">rescue</span>
<span class="ruby-comment"># handle exception</span>
<span class="ruby-keyword">end</span>
</pre>
<p>Similarly, if you wish to always run code even if an exception is raised, you can use <code>ensure</code> without <code>begin</code> and <code>end</code>:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>
<span class="ruby-comment"># code that may raise an exception</span>
<span class="ruby-keyword">ensure</span>
<span class="ruby-comment"># code that runs even if previous code raised an exception</span>
<span class="ruby-keyword">end</span>
</pre>
<p>You can also combine <code>rescue</code> with <code>ensure</code> and/or <code>else</code>, without <code>begin</code> and <code>end</code>:</p>
<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">my_method</span>
<span class="ruby-comment"># code that may raise an exception</span>
<span class="ruby-keyword">rescue</span>
<span class="ruby-comment"># handle exception</span>
<span class="ruby-keyword">else</span>
<span class="ruby-comment"># only run if no exception raised above</span>
<span class="ruby-keyword">ensure</span>
<span class="ruby-comment"># code that runs even if previous code raised an exception</span>
<span class="ruby-keyword">end</span>
</pre>
<p>If you wish to rescue an exception for only part of your method, use <code>begin</code> and <code>end</code>. For more details see the page on <a href="exceptions_rdoc.html">exception handling</a>.</p>
</main>
<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.2.1.1.
<p>Based on <a href="http://deveiate.org/projects/Darkfish-RDoc/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.
</footer>