Skip to content
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

Closed
wants to merge 4 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 112 additions & 10 deletions doc/syntax/methods.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

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.

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:


Copy link
Member

Choose a reason for hiding this comment

The 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be:

You can define an instance method on a specific class with the <tt>class</tt> keyword.


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.
Copy link
Member

Choose a reason for hiding this comment

The 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>:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer this from before:

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:


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

Expand Down