summaryrefslogtreecommitdiff
path: root/doc/syntax/methods.rdoc
diff options
context:
space:
mode:
Diffstat (limited to 'doc/syntax/methods.rdoc')
-rw-r--r--doc/syntax/methods.rdoc110
1 files changed, 32 insertions, 78 deletions
diff --git a/doc/syntax/methods.rdoc b/doc/syntax/methods.rdoc
index b9ec8da5ff..14810a188f 100644
--- a/doc/syntax/methods.rdoc
+++ b/doc/syntax/methods.rdoc
@@ -100,6 +100,7 @@ operators.
<code>/</code> :: divide
<code>%</code> :: modulus division, String#%
<code>&</code> :: AND
+<code>|</code> :: OR
<code>^</code> :: XOR (exclusive OR)
<code>>></code> :: right-shift
<code><<</code> :: left-shift, append
@@ -418,8 +419,8 @@ It is possible to gather arguments at the beginning or in the middle:
gather_arguments 1, 2, 3, 4 # prints [2, 3]
-The array argument will capture a Hash as the last entry if a hash was sent by
-the caller after all positional arguments.
+The array argument will capture a Hash as the last entry if keywords were
+provided by the caller after all positional arguments.
def gather_arguments(*arguments)
p arguments
@@ -441,6 +442,13 @@ Also, note that a bare <code>*</code> can be used to ignore arguments:
def ignore_arguments(*)
end
+You can also use a bare <code>*</code> when calling a method to pass the
+arguments directly to another method:
+
+ def delegate_arguments(*)
+ other_method(*)
+ end
+
=== Keyword Arguments
Keyword arguments are similar to positional arguments with default values:
@@ -481,6 +489,13 @@ Also, note that <code>**</code> can be used to ignore keyword arguments:
def ignore_keywords(**)
end
+You can also use <code>**</code> when calling a method to delegate
+keyword arguments to another method:
+
+ def delegate_keywords(**)
+ other_method(**)
+ end
+
To mark a method as accepting keywords, but not actually accepting
keywords, you can use the <code>**nil</code>:
@@ -491,83 +506,15 @@ Calling such a method with keywords or a non-empty keyword splat will
result in an ArgumentError. This syntax is supported so that keywords
can be added to the method later without affected backwards compatibility.
-=== Keyword and Positional Argument Separation
-
-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.
-
-In Ruby 2.7, 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.
-
-There are a few different types of keyword argument separation issues.
-
-==== Conversion of Hash to Keywords
-
-If a method is called with the hash, the hash could be treated as
-keywords:
-
- def my_method(**keywords)
- keywords
- end
- my_method({a: 1}) # {:a => 1}
-
-This occurs even if the hash could be an optional positional argument
-or an element of a rest argument:
-
- def my_method(hash=nil, **keywords)
- [hash, keywords]
- end
- my_method({a: 1}) # [nil, {:a => 1}]
-
- def my_method(*args, **keywords)
- [args, keywords]
- end
- my_method({a: 1}) # [[], {:a => 1}]
-
-However, if the hash is needed for a mandatory positional argument,
-it would not be treated as keywords:
-
- def my_method(hash, **keywords)
- [hash, keywords]
- end
- my_method({a: 1}) # [{:a => 1}, {}]
-
-==== Conversion of Keywords to Positional Arguments
-
-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:
-
- def my_method(hash, **keywords)
- [hash, keywords]
- end
- my_method(a: 1) # [{:a => 1}, {}]
-
-This is also true for empty keyword splats:
-
- kw = {}
- my_method(**kw) # [{}, {}]
-
-==== Splitting of Positional Hashes or Keywords
+If a method definition does not accept any keywords, and the
+<code>**nil</code> syntax is not used, any keywords provided when calling
+the method will be converted to a Hash positional argument:
-If a method definition accepts specific keywords and not arbitrary keywords,
-keywords or a positional hash may be split if the hash includes both Symbol
-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 Symbol keys are used
-as the keyword arguments:
-
- def my_method(hash=3, a: 4)
- [hash, a]
+ def meth(arg)
+ arg
end
- my_method(a: 1, 'a' => 2) # [{"a"=>2}, 1]
- my_method({a: 1, 'a' => 2}) # [{"a"=>2}, 1]
+ meth(a: 1)
+ # => {:a=>1}
=== Block Argument
@@ -583,8 +530,15 @@ Most frequently the block argument is used to pass a block to another method:
@items.each(&block)
end
+You are not required to give a name to the block if you will just be passing
+it to another method:
+
+ def each_item(&)
+ @items.each(&)
+ 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
+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: