C++ equivs in Ruby

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)
- 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)
kind regards

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 t= o Ruby, and
didn't find several possibilities.
Could you give me an enlightment about :
- polymorphism (method overloading, virtual methods)

- 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)

Everything in Ruby is passed/stored by reference, so you don't need
pointers. This book should interest you:

http://www.brpreiss.com/books/opus8/

martin

···

Pascal GUICHARD <pascal.guichard@gmail.com> wrote:

Pascal GUICHARD wrote:

Could you give me an enlightment about :
- polymorphism (method overloading, virtual methods)

class A
  def fun(arg); puts "Hello, #{arg}!" end
end
class B
  def fun(baz); puts "Hiya, #{baz}!" end
end
def greet(obj)
  obj.fun
end
greet A.new
greet B.new

Unlike statically typed languages, there is no need for inheritance to achieve polymorphism.

- 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)

What Martin said. All variables are pointers. (Contrast 'variable' with 'return value', for instance. You can't [easily] return a pointer to an object. However, there are plenty of subsitutes, usually better.)

Devin

Pascal GUICHARD wrote:

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"
b = 1
c = [a, b]
c[0] << "xx" # << appends stuff to a string
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:

a = "hello"
b = a
a = nil
GC.start # "hello" still exists, as b points to it.
b = nil
GC.start # "hello" no longer exists, as nothing points to it.

thanks

···

On 10/2/05, Martin DeMello <martindemello@yahoo.com> wrote:

Pascal GUICHARD <pascal.guichard@gmail.com> wrote:
>
> 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 t= o Ruby, and
> didn't find several possibilities.
> Could you give me an enlightment about :
> - polymorphism (method overloading, virtual methods)

http://rubygarden.org/ruby?RubyFromOtherLanguages

> - 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)

Everything in Ruby is passed/stored by reference, so you don't need
pointers. This book should interest you:

brpreiss.com

martin

my point is :
- on pymorphism, i have seen ruby code that is testing what is the type
(class, name) that is calling this pice of code, and that sounds very
strange to me,
- on pointers, i try to understand (howto implement) datastructures in which
you need to mix values and references/poiters

Pascal

···

On 10/2/05, Devin Mullins <twifkak@comcast.net> wrote:

Pascal GUICHARD wrote:

> Could you give me an enlightment about :
> - polymorphism (method overloading, virtual methods)
>
>
class A
def fun(arg); puts "Hello, #{arg}!" end
end
class B
def fun(baz); puts "Hiya, #{baz}!" end
end
def greet(obj)
obj.fun
end
greet A.new
greet B.new

Unlike statically typed languages, there is no need for inheritance to
achieve polymorphism.

>- 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)
>
>
What Martin said. All variables are pointers. (Contrast 'variable' with
'return value', for instance. You can't [easily] return a pointer to an
object. However, there are plenty of subsitutes, usually better.)

Devin

my point is :
- on pymorphism, i have seen ruby code that is testing what is the type
(class, name) that is calling this pice of code, and that sounds very
strange to me,

In this case the polymorphism based on types that C++ and Java might
do has to be done by hand in Ruby, since parameters are typeless. But
in most cases this is not needed and usually "duck typing" is used, in
other words if a particular variable responds to certain messages
(quacks like a duck), that is all we care about. For example a method
that can take either Symbols or Strings could always call to_s on the
parameter being passed in, since both Symbol and String implement this
method (in the case of String it just returns itself.) If things
aren't quite so convenient then parameters can be queried with the
responds_to method to see if they respond to a particular method
before that method is called.

- on pointers, i try to understand (howto implement) datastructures in which
you need to mix values and references/poiters

You just don't have to worry about this in Ruby. Forget that the
pointer type even exists. For example if you have a linked list, each
node won't consist of a pointer and data, it will consist of two
references, one which points to the next node, and one which points to
some kind of data (that could be any type.)

Ryan

···

On 10/2/05, Pascal GUICHARD <pascal.guichard@gmail.com> wrote:

You cannot use values in Ruby directly. There are only references. Think of Ruby as Java without POD's. In practice there are some optimizations for Fixnums, Symbols and some other types but conceptually (i.e. from a usage point of view) you never see values directly.

x = nil
x = Object.new
x = "foo"
x = 123

Here "x" is always a reference variable - like every other variable is a reference variable. It's so simple but sometimes difficult to get used to - especially when coming from other programming languages.

Kind regards

    robert

···

Pascal GUICHARD <pascal.guichard@gmail.com> wrote:

- on pointers, i try to understand (howto implement) datastructures
in which you need to mix values and references/poiters

Hi --

- on pointers, i try to understand (howto implement) datastructures
in which you need to mix values and references/poiters

You cannot use values in Ruby directly. There are only references. Think of Ruby as Java without POD's. In practice there are some optimizations for Fixnums, Symbols and some other types but conceptually (i.e. from a usage point of view) you never see values directly.

x = nil
x = Object.new
x = "foo"
x = 123

Here "x" is always a reference variable - like every other variable is a reference variable. It's so simple but sometimes difficult to get used to - especially when coming from other programming languages.

I think the "immediate value" status of Fixnums etc. goes beyond just
being an optimization, though, and has some practical consequences and
even some explanatory power. In particular, in:

   x = 123

x holds the immediate value 123, rather than a reference to it, which
is the rationale Matz has always given for not having x++ (i.e., it
would be equivalent to doing 123++ and that would make no sense).

David

···

On Mon, 3 Oct 2005, Robert Klemme wrote:

Pascal GUICHARD <pascal.guichard@gmail.com> wrote:

--
David A. Black
dblack@wobblini.net

David A. Black wrote:

  x = 123

x holds the immediate value 123, rather than a reference to it, which
is the rationale Matz has always given for not having x++ (i.e., it
would be equivalent to doing 123++ and that would make no sense).

I don't think that's sufficient, else x += 1 would be equivalent to 123 += 1. As the RubyGarden wiki says, x++ could easily be syntactic sugar for x = x.succ. Rather, I imagine it's an aesthetic matter of: if an operation changes the .object_id of a variable, it better contain an equals sign in it.

Devin

Hi --

- on pointers, i try to understand (howto implement) datastructures
in which you need to mix values and references/poiters

You cannot use values in Ruby directly. There are only references. Think of Ruby as Java without POD's. In practice there are some
optimizations for Fixnums, Symbols and some other types but
conceptually (i.e. from a usage point of view) you never see values
directly. x = nil
x = Object.new
x = "foo"
x = 123

Here "x" is always a reference variable - like every other variable
is a reference variable. It's so simple but sometimes difficult to
get used to - especially when coming from other programming
languages.

I think the "immediate value" status of Fixnums etc. goes beyond just
being an optimization, though, and has some practical consequences

Which?

and
even some explanatory power. In particular, in:

  x = 123

x holds the immediate value 123, rather than a reference to it,

But this does not make a difference from a usage point of view: for doing x = x + 1 (or short x += 1) it doesn't make a difference. Also invocation of methods is the same for every x that I showed above. You wouldn't be able to distinguish this from a real reference apart from, maybe, in some esoteric circumstances or in C extensions because basically immediate values are just an optimization.

IMHO when starting to use Ruby it's the easiest and least irritating to just assume that every value (aka instance) is referenced and there are no values (at least not directly accessible). If you do numerical calculations you will later start to wonder how Ruby works under the hood and how you make best (most efficient) use of Fixnums etc. But I find it confusing to start with this matter.

which
is the rationale Matz has always given for not having x++ (i.e., it
would be equivalent to doing 123++ and that would make no sense).

Hm... I don't know whether I can follow this argument. *If* there was a ++ operator in Ruby, it would probably be the equivalent of

x++ <=> ($_,x=x,x.succ;$_)
++x <=> (x=x.succ)

Maybe Matz found this (especially in the first case) a too complex construct to be hidden by this unary operator. Dunno. But at the moment I fail to see how this unary operator relates to the fact of "immediate values".

Somehow I feel I did not directly hit the point. Darn...

Kind regards

    robert

···

David A. Black <dblack@wobblini.net> wrote:

On Mon, 3 Oct 2005, Robert Klemme wrote:

Pascal GUICHARD <pascal.guichard@gmail.com> wrote:

Hi --

David A. Black wrote:

  x = 123

x holds the immediate value 123, rather than a reference to it, which
is the rationale Matz has always given for not having x++ (i.e., it
would be equivalent to doing 123++ and that would make no sense).

I don't think that's sufficient, else x += 1 would be equivalent to 123 += 1.

Not necessarily. There's no cause and effect link here; each thing is
decided by Matz. I was talking about my impression over the years of
Matz's rationale.

Actually, as I re-research it, I see several objections to ++ on the
part of Matz, even for cases where the variable does not hold an
immediate value (e.g., strings). I tend to agree; I think if you did:

   str = "abc"
   str++

neither possibility (the variable str being reassigned, or having ++
be a succ! equivalent) would really fit. (The parser *could* do it,
of course; I'm talking about the logic and design.)

David

···

On Mon, 3 Oct 2005, Devin Mullins wrote:

--
David A. Black
dblack@wobblini.net

immediate values don't show up in ObjectSpace, can't add Singleton
methods

Robert Klemme wrote:

···

David A. Black <dblack@wobblini.net> wrote:

>> Here "x" is always a reference variable - like every other variable
>> is a reference variable. It's so simple but sometimes difficult to
>> get used to - especially when coming from other programming
>> languages.
>
> I think the "immediate value" status of Fixnums etc. goes beyond just
> being an optimization, though, and has some practical consequences

Which?

Hi --

Hi --

- on pointers, i try to understand (howto implement) datastructures
in which you need to mix values and references/poiters

You cannot use values in Ruby directly. There are only references. Think of Ruby as Java without POD's. In practice there are some
optimizations for Fixnums, Symbols and some other types but
conceptually (i.e. from a usage point of view) you never see values
directly. x = nil
x = Object.new
x = "foo"
x = 123

Here "x" is always a reference variable - like every other variable
is a reference variable. It's so simple but sometimes difficult to
get used to - especially when coming from other programming
languages.

I think the "immediate value" status of Fixnums etc. goes beyond just
being an optimization, though, and has some practical consequences

Which?

Mainly the explanatory thing :slight_smile: But also the fact that:

   a = :sym
   b = :sym

a and b are the same object. I do realize, though, that this is not
specifically a matter of immediacy of value, but more of uniqueness
and immutability on the part of symbols. I guess I don't have too
many concrete ideas about it.... I've just always felt (though I
realize you don't) that it's easier to understand the whole
immediate/unique/immutable nature of integers, symbols, nil, true,
false if one understands it all at the same time.

Pretty non-technical, I admit.

and
even some explanatory power. In particular, in:

  x = 123

x holds the immediate value 123, rather than a reference to it,

But this does not make a difference from a usage point of view: for doing x = x + 1 (or short x += 1) it doesn't make a difference.

Right; I said *explanatory* power :slight_smile:

[...]

Hm... I don't know whether I can follow this argument. *If* there was a ++ operator in Ruby, it would probably be the equivalent of

x++ <=> ($_,x=x,x.succ;$_)
++x <=> (x=x.succ)

Maybe Matz found this (especially in the first case) a too complex construct to be hidden by this unary operator. Dunno. But at the moment I fail to see how this unary operator relates to the fact of "immediate values".

Because if x actually *is* a number, then:

   x = 1
   x++

suggests 1++, which makes no sense. It's not that it could not be
made to parse as x = x.succ or whatever; it's that (as I understand
Matz's reasoning) x++ conventionally suggests an operation on a
variable, which obscures the fact that in Ruby, a variable with an
integer in it is exactly that integer object.

Another way to put it is: assuming that eventually people are going
to learn that integers in variables are immediate values, having an
overly-sugary x++ would give rise to people asking, "How can you
increment an actual integer?" Right now what happens is people ask,
"Why can't you do x=1; x++ ?" and then they learn about immediate
values :slight_smile:

David

···

On Mon, 3 Oct 2005, Robert Klemme wrote:

David A. Black <dblack@wobblini.net> wrote:

On Mon, 3 Oct 2005, Robert Klemme wrote:

Pascal GUICHARD <pascal.guichard@gmail.com> wrote:

--
David A. Black
dblack@wobblini.net

David A. Black wrote:

  x = 123

x holds the immediate value 123, rather than a reference to it, which
is the rationale Matz has always given for not having x++ (i.e., it
would be equivalent to doing 123++ and that would make no sense).

I don't think that's sufficient, else x += 1 would be equivalent to 123 += 1.

Not necessarily. There's no cause and effect link here; each thing is
decided by Matz. I was talking about my impression over the years of
Matz's rationale.

No, I meant the rationale in the above paragraph wasn't sufficient to draw the conclusion that ++ made no sense, as my counter-example showed. I realize that Matz has final say, and I also don't really care about the lack of a ++, so I wasn't trying to argue for it.

neither possibility (the variable str being reassigned, or having ++
be a succ! equivalent) would really fit.

You know what I'd really like? A "x .= :succ" notation. I know it's, like, totally counter to established Ruby semantics, but it'd save, like, (variable_name.size - 2) characters. Sample implementation in Ruby, for the * operator:

require 'enumerator'
ObjectSpace.enum_for(:each_object).find_all { |klazz|
  Class === klazz and klazz.instance_methods.include?("*") || klazz == Object
}.each do |klazz|
    p klazz
    klazz.class_eval do
      def *(*a); send(*a) end
    end
end

(I'm not recommending that "." be overrideable, just that .= be some builtin shortcut. Actually, I'm not really recommending it. Just an extended joke.)

Devin

David A. Black wrote:

Hi --

Hi --

- on pointers, i try to understand (howto implement)
datastructures in which you need to mix values and
references/poiters

You cannot use values in Ruby directly. There are only
references. Think of Ruby as Java without POD's. In practice
there are some
optimizations for Fixnums, Symbols and some other types but
conceptually (i.e. from a usage point of view) you never see values
directly. x = nil
x = Object.new
x = "foo"
x = 123

Here "x" is always a reference variable - like every other variable
is a reference variable. It's so simple but sometimes difficult to
get used to - especially when coming from other programming
languages.

I think the "immediate value" status of Fixnums etc. goes beyond
just being an optimization, though, and has some practical
consequences

Which?

Mainly the explanatory thing :slight_smile: But also the fact that:

   a = :sym
   b = :sym

a and b are the same object. I do realize, though, that this is not
specifically a matter of immediacy of value, but more of uniqueness
and immutability on the part of symbols.

IMHO the issue here is behavior of a certain type of expression. Besides
the usual constructors (MyClass.new) Ruby has a number of other
expressions types built intp the language that return objects - sometimes
new objects (like with "foo", 'foo', , {}) and sometimes the same (like
with 1, 2, 3, :sym).

I guess I don't have too
many concrete ideas about it.... I've just always felt (though I
realize you don't) that it's easier to understand the whole
immediate/unique/immutable nature of integers, symbols, nil, true,
false if one understands it all at the same time.

Pretty non-technical, I admit.

I guess folks are different and what works for some best for me is likely
different from what works best for you.

and
even some explanatory power. In particular, in:

  x = 123

x holds the immediate value 123, rather than a reference to it,

But this does not make a difference from a usage point of view: for
doing x = x + 1 (or short x += 1) it doesn't make a difference.

Right; I said *explanatory* power :slight_smile:

[...]

Hm... I don't know whether I can follow this argument. *If* there
was a ++ operator in Ruby, it would probably be the equivalent of

x++ <=> ($_,x=x,x.succ;$_)
++x <=> (x=x.succ)

Maybe Matz found this (especially in the first case) a too complex
construct to be hidden by this unary operator. Dunno. But at the
moment I fail to see how this unary operator relates to the fact of
"immediate values".

Because if x actually *is* a number, then:

   x = 1
   x++

suggests 1++, which makes no sense. It's not that it could not be
made to parse as x = x.succ or whatever; it's that (as I understand
Matz's reasoning) x++ conventionally suggests an operation on a
variable, which obscures the fact that in Ruby, a variable with an
integer in it is exactly that integer object.

Another way to put it is: assuming that eventually people are going
to learn that integers in variables are immediate values, having an
overly-sugary x++ would give rise to people asking, "How can you
increment an actual integer?" Right now what happens is people ask,
"Why can't you do x=1; x++ ?" and then they learn about immediate
values :slight_smile:

I'll have to think about this a bit more. Unfortunately I don't have the
time right now... :frowning:

Kind regards

    robert

···

On Mon, 3 Oct 2005, Robert Klemme wrote:

David A. Black <dblack@wobblini.net> wrote:

On Mon, 3 Oct 2005, Robert Klemme wrote:

Pascal GUICHARD <pascal.guichard@gmail.com> wrote: