mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
eeee190882
Arguments * doc/syntax/methods.rdoc (Keyword Arguments): Described ** for gathering arbitrary keyword arguments. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38817 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
237 lines
5.8 KiB
Text
237 lines
5.8 KiB
Text
= 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, then the +end+ keyword. When called the method will execute the
|
|
body of the method. This method returns +2+.
|
|
|
|
== 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
|
|
|
|
== 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/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.
|
|
|
|
== 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:doc/syntax/exceptions.rdoc].
|
|
|