-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Syntax documentation: method return values and expanded documentation of singletons #227
Changes from all commits
31ef1f7
be1dc95
70fe821
0f31d88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,26 +11,128 @@ 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 <tt>2</tt>. | ||
|
||
A method may be defined on another object. You may define a "class | ||
method" (a method that is called on the class, not an instance of the class) | ||
like this: | ||
== 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 <tt>1 + 1</tt>. The <tt>return</tt> 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: | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. whitespace |
||
def my_method | ||
# ... | ||
end | ||
|
||
add the method to a class. You specify the class you're adding methods to with | ||
the "class" keyword. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be:
|
||
|
||
class C | ||
def my_method | ||
# ... | ||
end | ||
end | ||
|
||
In many languages, the <tt>class</tt> keyword lets the compiler know that you're | ||
creating a class. This is true in Ruby, too, the first time you use the | ||
<tt>class</tt> keyword: when it sees that you're <em>opening</em> a class for | ||
the first time, it creates it. When you open a class that already exists, Ruby | ||
enables to you <em>extend</em> it with new methods. You can even extend core | ||
classes: | ||
|
||
class String | ||
def hello | ||
"Hello, world!" | ||
end | ||
end | ||
|
||
"".hello # returns "Hello, world!" | ||
|
||
This is, however, as you might expect, somewhat risky, so this ability is best | ||
used sparingly. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it risky? I think you might add something about "polluting the namespaces" |
||
|
||
You can use <tt>def</tt> to add a method directly to a class, so that you can | ||
evaluate it with <tt>Class.my_method</tt>: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer this from before:
|
||
|
||
class C | ||
def self.my_method | ||
# ... | ||
end | ||
end | ||
|
||
You may also define methods this way on any object: | ||
or a more concrete example: | ||
|
||
string = "my string" | ||
def string.my_method | ||
# ... | ||
class String | ||
def self.hello | ||
"Hello, world!" | ||
end | ||
end | ||
|
||
String.hello # returns "Hello, world!" | ||
|
||
However, this is simply a special case of a greater syntactical power in Ruby: | ||
the ability to add methods to arbitrary objects. Classes are, themselves, | ||
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!" | ||
|
||
<tt>self</tt> is a keyword referring to the current object under consideration | ||
by the compiler, which might make the use of <tt>self</tt> in defining a class | ||
method above a little clearer. Indeed, the example of adding a <tt>hello</tt> | ||
method to the class <tt>String</tt> can be rewritten thus: | ||
|
||
def String.hello | ||
"Hello, world!" | ||
end | ||
|
||
This is called a "singleton method". +my_method+ will only exist on this | ||
string instance. Other strings will not have +my_method+. You may also | ||
override existing methods on just one object this way. | ||
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 | ||
<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: | ||
|
||
irb(main):001:0> "69".to_i | ||
=> 69 | ||
irb(main):002:0> class String | ||
irb(main):003:1> def to_i | ||
irb(main):004:2> 42 | ||
irb(main):005:2> end | ||
irb(main):006:1> end | ||
=> nil | ||
irb(main):007:0> "69".to_i | ||
=> 42 | ||
irb(main):008:0> :) [~] | ||
|
||
This will effectively sabotage any code which makes use of the method | ||
+String#to_i+ to parse numbers from strings. | ||
|
||
== Arguments | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should keep this block above the class method example, it is good.