summaryrefslogtreecommitdiff
path: root/doc/syntax
diff options
context:
space:
mode:
authorzverok <zverok.offline@gmail.com>2020-12-24 11:06:26 +0200
committerNobuyoshi Nakada <nobu@ruby-lang.org>2020-12-25 22:10:09 +0900
commit255ee4de8ce8f1db044c04843bef25c78e2c28ac (patch)
tree9ee6dfafa61388f3e2c870ea51315dc3028690bd /doc/syntax
parentaaf0474e76ecf8d8fc675c3e56a803d887e63965 (diff)
Update method definition documentation
* Add endless methods * Add argument forwarding ...
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3997
Diffstat (limited to 'doc/syntax')
-rw-r--r--doc/syntax/methods.rdoc86
1 files changed, 86 insertions, 0 deletions
diff --git a/doc/syntax/methods.rdoc b/doc/syntax/methods.rdoc
index 241913cc1a..d5b23bfb33 100644
--- a/doc/syntax/methods.rdoc
+++ b/doc/syntax/methods.rdoc
@@ -11,6 +11,11 @@ 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+.
+Since Ruby 3.0, there is also shorthand syntax for methods consisting of exactly
+one expression:
+
+ def one_plus_one = 1 + 1
+
This section only covers defining methods. See also the {syntax documentation
on calling methods}[rdoc-ref:syntax/calling_methods.rdoc].
@@ -64,6 +69,23 @@ object to indicate a true value (or "truthy" value).
Methods that end with an equals sign indicate an assignment method.
+ class C
+ def attr
+ @attr
+ end
+
+ def attr=(val)
+ @attr = val
+ end
+ end
+
+ c = C.new
+ c.attr #=> nil
+ c.attr = 10 # calls "attr="
+ c.attr #=> 10
+
+Assignment methods can't be defined with shorthand syntax.
+
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
@@ -258,6 +280,13 @@ The parentheses around the arguments are optional:
value + 1
end
+The parentheses are mandatory in shorthand method definition:
+
+ # OK
+ def add_one(value) = value + 1
+ # SyntaxError
+ def add_one value = value + 1
+
Multiple arguments are separated by a comma:
def add_values(a, b)
@@ -563,6 +592,63 @@ in this section:
yield self
end
+=== Argument forwarding
+
+Since Ruby 2.7, all-arguments forwarding syntax is available:
+
+ def concrete_method(*positional_args, **keyword_args, &block)
+ [positional_args, keyword_args, block]
+ end
+
+ def forwarding_method(...)
+ concrete_method(...)
+ end
+
+ forwarding_method(1, b: 2) { puts 3 }
+ #=> [[1], {:b=>2}, #<Proc:...skip...>]
+
+Calling with forwarding <code>...</code> available only in methods defined with
+<code>...</code>.
+
+ def regular_method(arg, **kwarg)
+ other_method(...) # Syntax error
+ end
+
+There could be leading arguments before <code>...</code> both in definition and
+in invokation (but in definition they can be only positional arguments without
+default values).
+
+ def request(method, path, **headers)
+ puts "#{method.upcase} #{path} #{headers}"
+ end
+
+ def get(...)
+ request(:GET, ...) # leading argument in invoking
+ end
+
+ get('http://ruby-lang.org', 'Accept' => 'text/html')
+ # Prints: GET http://ruby-lang.org {"Accept"=>"text/html"}
+
+ def logged_get(msg, ...) # leading argument on definition
+ puts "Invoking #get: #{msg}"
+ get(...)
+ end
+
+ logged_get('Ruby site', 'http://ruby-lang.org')
+ # Prints:
+ # Invoking #get: Ruby site
+ # GET http://ruby-lang.org {}
+
+Note that omitting parentheses in forwarding calls may lead to unexpected results:
+
+ def log(...)
+ puts ... # This would be treated as puts()..., e.g. endless range from puts result
+ end
+
+ log("test")
+ # Prints: warning: ... at EOL, should be parenthesized?
+ # ...and then empty line
+
== Exception Handling
Methods have an implied exception handling block so you do not need to use