Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > 6d36cb72372cfb7c8fee63f4d6dc0530 > files > 149

ruby-docs-1.8.5-31.el5_9.x86_64.rpm

<html>
<head>
<title>Ruby FAQ: 
Methods
</title>
</head>
<body>
<a href="rubyfaq-4.html">Previous</a>
<a href="rubyfaq-6.html">Next</a>
<a href="rubyfaq.html#toc5">Table of contents</a>
<hr>
<h2><a name="s5">5. 
Methods
</a></h2>

<h2><a name="ss5.1">5.1 
How is the method searched when a messeage is sent to an object?
</a></h2>


The order of searching a method is singleton methods, methods defined in
its own class, methods defined in its superclasses including modules which
were mixed in.  You can see the order of searching by displaying 
Classname.ancestors,
which shows the classes and modules inherited.  If a method could not
be found, <code>method_missing</code> is searched in the same order.

<blockquote><code><pre>
Module Indexed
  def [](n)
    to_a[n]
  end
end
Class String
  include Indexed
end
p String.ancestors # [String, Indexed, Enumerable, Comparable, Object, Kernel]
p &quot;abcde&quot;.gsub!(/./, &quot;\\&amp;\n&quot;)[1]
</pre></code></blockquote>

This script does not return &quot;b\n&quot; as one expects, but returns 10.
This is because [] is searched and found in String class, before
searching Indexed.  You should directly redefine [] in Class String.

<h2><a name="ss5.2">5.2 
Are <code>+</code> and <code>-</code> operators?
</a></h2>


<code>+</code>, <code>-</code>, and the like are not operators but method calls.
Therefore these can be overloaded by new definitions.

<blockquote><code><pre>
class MyString &lt; String
  def +(other)
    print super(other)
  end
end
</pre></code></blockquote>

Followings are control structures and cannot be orverridden.

<blockquote><code><pre>
=, .., ..., !, not, &amp;&amp;, and, |, or, ~, ::
</pre></code></blockquote>

To overload or to define unary operators, you can use
<code>+@</code> and <code>-@</code> as the method names.
<br><br>
<code>=</code> is used in the access method definition as follows.
If operators like <code>+</code> and <code>-</code> are also defined,
you can use self assignment form like <code>+=</code>.

<blockquote><code><pre>
def attribute=(val)
  @attribute = val
end
</pre></code></blockquote>
<h2><a name="ss5.3">5.3 
Are there any functions?
</a></h2>


Those forms which resemble functions are actually methods for which 
receivers (<code>self</code>) are omitted, e.g.,

<blockquote><code><pre>
def writeln(str)
  print(str, &quot;\n&quot;)
end

writeln(&quot;Hello, World!&quot;)
</pre></code></blockquote>

<code>writeln</code> resembles a function but it is a method belonging to
the <code>Object</code> class and sent as a message to the hidden reciever 
<code>self</code>.  Thus Ruby is a pure OOL.
<br><br>
Of course you can use such methods as if they were functions.
 
<h2><a name="ss5.4">5.4 
Can I access an object instance variable?
</a></h2>


If referring methods to the instance variable are defined, you can
use those methods to know or set the value of an instance variable.
See <code>Module#attr</code>, <code>attr_reader</code>, <code>attr_writer</code>,
<code>attr_accessor</code>.
Of course you can define a referring method by yourself.
<br><br>
In a method definition of the style <code>method=</code>, you cannot insert
a space between <code>method</code> and <code>=</code>, but you can insert one
when you call
this style of a method.  You can also utilize self assignments like
<code>+=</code> and <code>-=</code>, if <code>+</code> or <code>-</code> methods are defined.

<h2><a name="ss5.5">5.5 
I cannot figure out the difference between <code>private</code> and
<code>protected</code>.
</a></h2>


A visibility keyword <code>private</code> means to make the method callable
only in a function form.  It cannot be called in receiver
designating form.
The private method is callable only within the class in which the
method was defined or in its subclasses.
<br><br>
Proteced methods are also called only within its own class or subclasses,
but both the function form and the receiver form can be used.
<br><br>
These features are required for capsulation of methods. 

<h2><a name="ss5.6">5.6 
I want to make an instance variable public.
</a></h2>


To make an instance variable public is not appropriate in view of
data capsulation.  You can access the instance variable through
access methods.  <code>attr</code> method is an easy way to define an
access method, and an instance variable behaves like variables
from outside.

<blockquote><code><pre>
class Foo
  def initialize(str)
    @name = str
  end
  attr(&quot;name&quot;)
  # This means:
  # def name
  #   return @name
  # end
end

foo = Foo.new(&quot;Tom&quot;)
print foo.name, &quot;\n&quot;         # Tom
</pre></code></blockquote>

If you put <code>true</code> to the second argument of <code>attr(name, public)</code>,
whose default value is false, you can define a value-setter.

<blockquote><code><pre>
class Foo
  def initialize(str)
    @name = str
  end
  attr(&quot;name&quot;, true)
  # This means:
  # def name
  #   return @name
  # end
  # def name=(str)
  #   @name = str
  # end
end

foo = Foo.new(&quot;Tom&quot;)
foo.name = &quot;Jim&quot;
print foo.name, &quot;\n&quot;    # Jim
</pre></code></blockquote>

See <code>Module#attr_reader</code>, <code>attr_writer</code>, and
<code>attr_accessor</code>.

<h2><a name="ss5.7">5.7 
How can I change the visibility of a method?
</a></h2>


Do you recall that a private method in Ruby means that it is only
called in a function form (without a receiver)?  It first seems
strange, doesn't it.
<br><br>
You cannot call a method from outside a (sub)class definition if you designate
one private.  It is better to claim private if you want a method
callable only from inside the (sub)class.
<br><br>
You can make a method private in following way.

<blockquote><code><pre>
class Foo
  def test
    print &quot;hello\n&quot;
  end
  private :test
end

foo = Foo.new
foo.test
# -&gt; test.rb:9: private method `test' called for #&lt;Foo:0x400f3eec&gt;(Foo)
</pre></code></blockquote>

You can make a class method private by using <code>private_class_method</code>.

<blockquote><code><pre>
class Foo
  def Foo.test
    print &quot;hello\n&quot;
  end
  private_class_method :test
end

Foo.test
# -&gt; test.rb:8: private method `test' called for Foo(Class)
</pre></code></blockquote>

You can make methods public using <code>public</code> or
<code>public_class_method</code>.
<br><br>
The default visibility is public for the methods defined in a class
except for initialize, and public for the methods defined at the toplevel.

<h2><a name="ss5.8">5.8 
Can I use an idenfier beginning with a capital letter for
a method name?
</a></h2>


Yes, you can.  But the parentheses surrounding arguments cannot be
omitted in a method call.

<h2><a name="ss5.9">5.9 
<code>super</code> yields an <code>ArgumentError</code>.
</a></h2>


Invoking <code>super</code> in a method definition passes all the arguments.
If the number of arguments disagrees with <code>super</code>, an
<code>ArgumentError</code> occurs.  You must specify explicitly the
parentheses to <code>super</code> and pass suitable number of arguments.

<h2><a name="ss5.10">5.10 
How can I call the same name method of two levels upper?
</a></h2>


<code>super</code> invokes the same name method one level upper.
Use <code>alias</code> before calling the same name method of more than that level.

<h2><a name="ss5.11">5.11 
How can I invoke the original built-in method after redfining it?
</a></h2>


In the method definition, you can use <code>super</code>.  Original definition is
reserved if you <code>alias</code> the original method beforehand.  Or, you can
call the original method as a singleton method of <code>Kernel</code>.

<a name="destructive"></a><h2><a name="ss5.12">5.12 
What is a destructive method?
</a></h2>


It is a method which alters the attribute of an object. String, Array,
and Hash have such king of methods.  There are methods with the same
name, one of which returns a copy of the object, and the other with
! appended is a destructive method.  There are destructive methods
without !, such as Array#filter.

<h2><a name="ss5.13">5.13 
When does an adverse effect occur using a method?
</a></h2>


If you invoke a destructive method to the actual argument. 

<blockquote><code><pre>
def foo(str)
  str.sub!(/foo/, &quot;baz&quot;)
end

obj = &quot;foo&quot;
foo(obj)
print obj
# -&gt; &quot;baz&quot;
</pre></code></blockquote>

In this case the actual argument is altered.  But this is the intended
action of the method.

<h2><a name="ss5.14">5.14 
Can I return multiple values from a method?
</a></h2>


You cannot return multiple values from a method, but never mind, 

<blockquote><code><pre>
return 1, 2, 3
</pre></code></blockquote>

returns an array containing three elements.

<blockquote><code><pre>
return [1, 2, 3]
</pre></code></blockquote>

This script gives the same result.
<br><br>
Using multiple assignment, you can get the effect of multiple return
values. For example,

<blockquote><code><pre>
def foo
  return 20, 4, 17
end

a, b, c = foo
print &quot;a:&quot;, a, &quot;\n&quot; # -&gt; a:20
print &quot;b:&quot;, b, &quot;\n&quot; # -&gt; b:4
print &quot;c:&quot;, c, &quot;\n&quot; # -&gt; c:17
</pre></code></blockquote>

<hr>
<a href="rubyfaq-4.html">Previous</a>
<a href="rubyfaq-6.html">Next</a>
<a href="rubyfaq.html#toc5">Table of contents</a>
</body>
<html>