<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 "abcde".gsub!(/./, "\\&\n")[1] </pre></code></blockquote> This script does not return "b\n" 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 < String def +(other) print super(other) end end </pre></code></blockquote> Followings are control structures and cannot be orverridden. <blockquote><code><pre> =, .., ..., !, not, &&, 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, "\n") end writeln("Hello, World!") </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("name") # This means: # def name # return @name # end end foo = Foo.new("Tom") print foo.name, "\n" # 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("name", true) # This means: # def name # return @name # end # def name=(str) # @name = str # end end foo = Foo.new("Tom") foo.name = "Jim" print foo.name, "\n" # 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 "hello\n" end private :test end foo = Foo.new foo.test # -> test.rb:9: private method `test' called for #<Foo:0x400f3eec>(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 "hello\n" end private_class_method :test end Foo.test # -> 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/, "baz") end obj = "foo" foo(obj) print obj # -> "baz" </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 "a:", a, "\n" # -> a:20 print "b:", b, "\n" # -> b:4 print "c:", c, "\n" # -> 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>