Pascal said:
Hi everybody,
i learned about OOP through C++, knowing that I was previously working in
C, so here is my background.
Being now interested in ruby, i try to make my mind from this background to
Ruby, and didn't find several possibilities.
Could you give me an enlightment about :
- polymorphism (method overloading, virtual methods)
Virtual methods. No need for them in ruby as ALL methods in any ruby
class are (potentially) virtual methods. Just create an inherited
class and override the method. Using the word "super" calls the same
member function in the inherited class. "super" with no arguments just
repeats all the parameters passed to the function. "super(..)" allows
you to change the parameters.
class A
def func(x)
puts "A::func() #{x}"
end
end
class B < A
def func(x)
puts "B::func()"
super
end
end
a = B.new
a.func(10)
As multiple inheritance is not used, the C++ syntax of Class::func() is
not used.
If you have, A.func(), B.func(), C.func()... C.func() can still call
A.func() directly (skipping over B.func()) with some ruby hackery,
albeit this is probably not encouraged.
------------------------------------
Method overloading is not supported in ruby. However, you can create
the equivalent of overloading a function or method by using a *args
syntax.
The *args syntax allows a function to receive any number of parameters,
which get shuffled into the array args. So, args[0] contains your
first argument, args[1] contains the second, args.size has the # of
arguments, and
args[0].kind_of() can give you the type of the first argument, etc.
Thus, to implement an overloaded function in ruby, you can do something
akin to:
def func(*args)
if args.size != 1
raise "func() needs one argument, not #{args.size}"
end
if args[0].kind_of?(String)
puts "using func() as a string"
elsif args[0].kind_of?(Fixnum)
puts "Using func() as fixnum"
else
raise "Invoked func() with improper argument"
end
end
func(1)
func("hello")
func(1,2) # raises error at runtime
a = []
func(a) # raises error at runtime
- pointers (i know these can be described as having some problems with them,
how to implement (for example, linked lists, binary trees, and so on)
There is no need for pointers in ruby. Ruby manages this almost
transparently to you.
All complex objects (strings, classes, arrays, hashes, etc) in ruby are
stored as references. For example:
irb> a = "hello"
irb> b = 1
irb> c = [a, b]
irb> c[0] << "xx" # << appends stuff to a string
irb> a # returns "helloxx", same as c[0]
All these elements' memory is automatically managed by ruby's gargabe
collector, which is aware of cyclic dependancies. The ruby GC gets run
every now and then by ruby to collect unused data.
If that's no fast enough for you, you can force the freeing of objects
yourself by removing all references to that object and then manually
invoking GC.start. For example:
irb> a = "hello"
irb> b = a
irb> a = nil
irb> GC.start # "hello" still exists, as b points to it.
irb> b = nil
irb> GC.start # "hello" no longer exists, as nothing points to it.