method_missing
is searched in the same order.
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]
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.
+
and -
operators?
+
, -
, and the like are not operators but method calls.
Therefore these can be overloaded by new definitions.
class MyString < String
def +(other)
print super(other)
end
end
Followings are control structures and cannot be orverridden.
=, .., ..., !, not, &&, and, |, or, ~, ::
To overload or to define unary operators, you can use
+@
and -@
as the method names.
=
is used in the access method definition as follows.
If operators like +
and -
are also defined,
you can use self assignment form like +=
.
def attribute=(val)
@attribute = val
end
self
) are omitted, e.g.,
def writeln(str)
print(str, "\n")
end
writeln("Hello, World!")
writeln
resembles a function but it is a method belonging to
the Object
class and sent as a message to the hidden reciever
self
. Thus Ruby is a pure OOL.
Module#attr
, attr_reader
, attr_writer
,
attr_accessor
.
Of course you can define a referring method by yourself.
method=
, you cannot insert
a space between method
and =
, but you can insert one
when you call
this style of a method. You can also utilize self assignments like
+=
and -=
, if +
or -
methods are defined.
private
and
protected
.
private
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.
attr
method is an easy way to define an
access method, and an instance variable behaves like variables
from outside.
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
If you put true
to the second argument of attr(name, public)
,
whose default value is false, you can define a value-setter.
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
See Module#attr_reader
, attr_writer
, and
attr_accessor
.
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)
You can make a class method private by using private_class_method
.
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)
You can make methods public using public
or
public_class_method
.
super
yields an ArgumentError
.
super
in a method definition passes all the arguments.
If the number of arguments disagrees with super
, an
ArgumentError
occurs. You must specify explicitly the
parentheses to super
and pass suitable number of arguments.
super
invokes the same name method one level upper.
Use alias
before calling the same name method of more than that level.
super
. Original definition is
reserved if you alias
the original method beforehand. Or, you can
call the original method as a singleton method of Kernel
.
def foo(str)
str.sub!(/foo/, "baz")
end
obj = "foo"
foo(obj)
print obj
# -> "baz"
In this case the actual argument is altered. But this is the intended
action of the method.
return 1, 2, 3
returns an array containing three elements.
return [1, 2, 3]
This script gives the same result.
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