Self and Ruby Comparisons

Hi

I could not locate any Self and Ruby comparison. Any links?

Thanks,

Mystifier

I don't know if there is much comparision out there. You can have a
look at the suby-muse and suby-ruby archives. You may find a little bit
of info on the subject there --on occassion we have discussed of
prototype-based Ruby.

T.

In Self really everything is message passing. Unlike Ruby and unlike
Smalltalk! Assignment is a special thing even in Smalltalk. In Self, you
are free to add/modify slots of objects from outside, and assignment is
in fact just a message which does this. (I think so.)

Recently I've been playing with Io (http://www.iolanguage.com/\) (the
place where I heard of it is this very list). It has a similar object
model to Self, and is very compact, so it's easy to get a grasp on it
and see how that prototype based object model works. As an addition, the
syntax is very clever and clean. It's in fact a simple sexp-based
syntax, but you won't notice this fact unless you watch heavily.
(Basicly the syntax consists of nothing else just expressions lke "a
b(c,d) e(f)", which means something like "a.b(c,d).e(f)" in ruby (but,
as we know, in ruby there is more syntax than these kind of
expressions); besides, there is some sugaring for more intuitive usage
of operators (which are, of course, ordinary methods). It uses the same
great idea as ruby for separating expressions: you can use either a
semicolon or a newline).

Btw, I hope you know that Ruby has almost full support for prototype
based programming.

Csaba

···

On 2005-01-23, Mystifier <mystifier@users.berlios.de> wrote:

I could not locate any Self and Ruby comparison. Any links?

for one, self doesn't have a ruby keyword...

right. i'll get my coat.

martin

···

Trans <tsawyer@gmail.com> wrote:

I don't know if there is much comparision out there. You can have a
look at the suby-muse and suby-ruby archives. You may find a little bit
of info on the subject there --on occassion we have discussed of
prototype-based Ruby.

Btw, I hope you know that Ruby has almost full support
for prototype based programming.

1) I would like to see a simple demonstration of this, I think while
basically possible, things like traits aren't so easily doable.

2) And even so, the "class-way" will be too tempting for lack of syntax
sugars, I think.

3) Also programming Ruby in this way would likely incur more overahead,
rather than less like in io (I imagine).

Thanks for the info.
T.

Actually, Perl has it better, because you can change the class of an
object, and you can change the list of superclasses of any class.

However, this is only a slight advantage, as some other people have
demonstrated you can do the same for Ruby using not that many lines of C
code.

So the only difference is that in Ruby you can't do full prototype-based
programming using just 100%-Ruby.

···

On Mon, 24 Jan 2005, Csaba Henk wrote:

On 2005-01-23, Mystifier <mystifier@users.berlios.de> wrote:
Btw, I hope you know that Ruby has almost full support for prototype
based programming.

_____________________________________________________________________
Mathieu Bouchard -=- Montréal QC Canada -=- http://artengine.ca/matju

for one, self doesn't have a ruby keyword...

right. i'll get my coat.

:slight_smile:

Btw, I hope you know that Ruby has almost full support
for prototype based programming.

1) I would like to see a simple demonstration of this, I think while
basically possible, things like traits aren't so easily doable.

Uh, to admit, my above claim is somewhat intuitive.

I have a general understanding of what a prototype based object model
is, and I made a mental experiment what components are needed to support
it, and how these can be implemented in ruby, and I found that they can
be implemented quite easily and naturally.

I don't know what such "subtleties" like traits are. If you gave me a
concise explanation, I'd appreciate that. And then we could think about
my implementation, can/should it be extended to have that feature?

So, my idea is as follows:

A prototype is a module which extends itself.

Cloning is supported out of the box. The good question is inheritance
and that how you realize different method (slot) lookup schemes.

As my prototype is a module, a modification in an instance method is
inherited. You can add/modify methods of a prototype such that its
children are not affected by means of module/singleton methods.

There is also another way of cloning:

module Foo; extend self; end
# Bar will be children of Foo
module Bar; extend self; extend Foo; end

In fact, this is the proper way of cloning. If you do so, sending a
message to Bar which is defined in Foo will be properly dispatched at
Foo. You also get reflection for free: existing methods like
Module#ancerstors will give the correct info here as well.

By mixing in prototypes you gain a nice mechanism to have your prototype
based world interact with traditional ruby code (if it weren't an
important criterion, you could put together custom object models in any
language supporting closures). If you want more, by method_missing you
can make proxy modules to existing objects which give you all the freedom
that you enjoy with prototypes.

You can get your (ie. not basic or third party) classes involved to the
game (of communicating with prototypes, ie. making them possible to be
mixed in; I don't mean here converting them to a prototype based model)
by changing the "class Foo" type opening stanza to "module Foo", and
defining a "new" module method like

def new(*a,&b)
  o=Object.new
  o.extend self
  o.initialize(*a,&b)
  o
end

(some subtleties like the "class" instance method need to be worked out
here). Or, you can just use project evil's class-to-module transformer
:slight_smile:

It's also nice that the initial copy of your prototype can be created in
the usual way, by assigning it to a constant with the

module Foo
...
end

syntax, but copies of it don't need to occupy costants, there you can
use Module.new.

Maybe it would be worth to consider creating a Prototype < Module class
which sugares all these actions (the initialize method of Prototype
would care about the self-extension, etc.)

So, I'm just curious what you think of the power of this approach; is
anything essential missing?

2) And even so, the "class-way" will be too tempting for lack of syntax
sugars, I think.

By my opinion the watershed is not having a class keyword or type or
metatype not, but that in what extent are the important OO mechanisms
(inheritance and co.) are available for "ordinary" objects. By having
singleton methods, the "clone" operation, fully objectified
classes/modules and the possibility of creating proxy modules, the
situation is quite good in ruby.

I don't think of the usual class-based structure as a temptation to
avoid. I do think of prototype-like techniques as a powerful tool which
can be utilized at the right time.

Eg., I tell you about the circumstances amongst which I meditated over
these things.

I was writing a small utility for displaying tree-like structures (in
ascii art in my case, but that could be easily replaced by other
rendering engines, so it's not important). For first, I wrote the code
in mind with that I got serial data to be properly allocated in a fresh
custom structure (eg., reading a directory tree from disk or from the
content listing of a tarball), so I created the necessary classes which
provided this structure.

But then I realized that if I want good, flexible code, I can't exclude
the possibility of displaying something which is not serial, and already
has an implicit tree-like structure (like (nested) Arrays). Converting
such things ("clients") instance-by-instance to my custom structure
(which can be passed to the renderer) is a superfluous overhead. So
rather than doing this, I just wanted to make the implicit structure
explicit by adding the methods to the clients needed by the renderer. I
then converted a bunch of classes to modules, but it was not that easy,
because both class and istance methods were necessary to be added to the
clients to make the renderer happy. The solultion was both extending and
including a module in the client class.

That is, upon necessity, you have alternatives to the stock
"class A < B; include C; ... end; a=A.new" OO. And it's good enough for
me.

I've also seen techniques like self-extending modules, and instead of
having an Foo::Bar type module or class for some task in the context of
Foo, having just a simple Bar object like

module Foo
  Bar = Object.new
  class << Bar
....
end

in other people's code so I think these ideas are existing ruby
patterns, not just my deviance. Kernel itself is a self-extending
module.

3) Also programming Ruby in this way would likely incur more overahead,
rather than less like in io (I imagine).

I don't think that any of the above would mean an overhead for the
interpreter. As for the programmer, it depends on her needs. If she
wants to use these techniques in a clear, explicit way, she will be able
to add the necessary sugar. Ruby does a good job in this respect.

Csaba

···

On 2005-01-24, Trans <transfire@gmail.com> wrote:

Actually, Perl has it better, because you can change the class of an
object, and you can change the list of superclasses of any class.

and you forget to say that in this P language array, hash, ... are not
objects.

Always easy to change the class when you work with only *one* type.

However, this is only a slight advantage, as some other people have
demonstrated you can do the same for Ruby using not that many lines of C
code.

You are right, the demonstration was made that a few lines of C can crash
easily ruby ... (personnaly I just need one line to crash ruby)

Guy Decoux

"Mathieu Bouchard" <matju@sympatico.ca> schrieb im Newsbeitrag
news:Pine.LNX.4.21.0501250404130.16754-100000@mondrian.artengine.ca...

> Btw, I hope you know that Ruby has almost full support for prototype
> based programming.

Actually, Perl has it better, because you can change the class of an
object, and you can change the list of superclasses of any class.

However, this is only a slight advantage, as some other people have
demonstrated you can do the same for Ruby using not that many lines of C
code.

And if a copy is sufficient you can do this even in pure Ruby:

class Object
  def cast(target_class)
    copy = target_class.allocate

    instance_variables.each do |var|
      copy.instance_variable_set(var, instance_variable_get(var))
    end

    copy
  end
end

class Foo
  attr_accessor :name, :val
end

=> nil

class Bar
  attr_accessor :name, :val
end

=> nil

f=Foo.new

=> #<Foo:0x100c4220>

f.name="nnn"

=> "nnn"

f.val="vvv"

=> "vvv"

b=f.cast Bar

=> #<Bar:0x101a7238 @val="vvv", @name="nnn">

b.class

=> Bar

So the only difference is that in Ruby you can't do full prototype-based
programming using just 100%-Ruby.

Do you have a link or explanation that demonstrates the merits of the
capability to change an instance's class at runtime? Currently I don't
have a clue in which situations I would want this. Thx!

Kind regards

    robert

···

On Mon, 24 Jan 2005, Csaba Henk wrote:
> On 2005-01-23, Mystifier <mystifier@users.berlios.de> wrote:

Mathieu Bouchard wrote:

Actually, Perl has it better, because you can change the class of an
object, and you can change the list of superclasses of any class.

Note that this can be mostly done with EvilRuby. You can change the direct superclass via Class#superclass= and the class via Object#class=. You can also insert new Classes into the inheritance chain with Class#inherit (which works by doing include(klass.as_module)). Note that there are still some limitations, sanity checks are a big one and there's still no way of removing items from the inheritance chain.

Ah, and one more neat trick: as prototype based objects are instances of
the same class Module (or a customized Prototype class), you can get
just one particular method of one p.b.o as UnboundMethod, and bind it to
another p.b.o. ... You also use here that p.b.o-s extend themselves.

Csaba

···

On 2005-01-24, Csaba Henk <csaba@phony_for_avoiding_spam.org> wrote:

In fact, this is the proper way of cloning. If you do so, sending a
message to Bar which is defined in Foo will be properly dispatched at
Foo. You also get reflection for free: existing methods like
Module#ancerstors will give the correct info here as well.

How about migrating legacy objects to new objects at run-time?

Nick

···

On Tue, 25 Jan 2005 19:30:54 +0900, Robert Klemme <bob.news@gmx.net> wrote:

"Mathieu Bouchard" <matju@sympatico.ca> schrieb im Newsbeitrag
news:Pine.LNX.4.21.0501250404130.16754-100000@mondrian.artengine.ca...
>
> On Mon, 24 Jan 2005, Csaba Henk wrote:
>
> > On 2005-01-23, Mystifier <mystifier@users.berlios.de> wrote:
> > Btw, I hope you know that Ruby has almost full support for prototype
> > based programming.
>
> Actually, Perl has it better, because you can change the class of an
> object, and you can change the list of superclasses of any class.
>
> However, this is only a slight advantage, as some other people have
> demonstrated you can do the same for Ruby using not that many lines of C
> code.

And if a copy is sufficient you can do this even in pure Ruby:

class Object
  def cast(target_class)
    copy = target_class.allocate

    instance_variables.each do |var|
      copy.instance_variable_set(var, instance_variable_get(var))
    end

    copy
  end
end

>> class Foo
>> attr_accessor :name, :val
>> end
=> nil
>> class Bar
>> attr_accessor :name, :val
>> end
=> nil
>> f=Foo.new
=> #<Foo:0x100c4220>
>> f.name="nnn"
=> "nnn"
>> f.val="vvv"
=> "vvv"
>> b=f.cast Bar
=> #<Bar:0x101a7238 @val="vvv", @name="nnn">
>> b.class
=> Bar

> So the only difference is that in Ruby you can't do full prototype-based
> programming using just 100%-Ruby.

Do you have a link or explanation that demonstrates the merits of the
capability to change an instance's class at runtime? Currently I don't
have a clue in which situations I would want this. Thx!

Kind regards

    robert

--
Nicholas Van Weerdenburg

"Robert Klemme" <bob.news@gmx.net> schrieb im Newsbeitrag
news:35mlboF4m5ql5U1@individual.net...

"Mathieu Bouchard" <matju@sympatico.ca> schrieb im Newsbeitrag
news:Pine.LNX.4.21.0501250404130.16754-100000@mondrian.artengine.ca...
>
>
> > Btw, I hope you know that Ruby has almost full support for prototype
> > based programming.
>
> Actually, Perl has it better, because you can change the class of an
> object, and you can change the list of superclasses of any class.
>
> However, this is only a slight advantage, as some other people have
> demonstrated you can do the same for Ruby using not that many lines of

C

> code.

And if a copy is sufficient you can do this even in pure Ruby:

class Object
  def cast(target_class)
    copy = target_class.allocate

    instance_variables.each do |var|
      copy.instance_variable_set(var, instance_variable_get(var))
    end

    copy
  end
end

A slightly more sophisticated version:

class Object
  def cast(target_class)
    copy = case target_class
      when Class; target_class.allocate
      when Module; dup.extend(target_class)
      else target_class.class.allocate
    end

    instance_variables.each do |var|
      copy.instance_variable_set(var, instance_variable_get(var))
    end

    copy
  end
end

Cheers

    robert

···

> On Mon, 24 Jan 2005, Csaba Henk wrote:
> > On 2005-01-23, Mystifier <mystifier@users.berlios.de> wrote:

robert,

Class swapping was brought up on suby-ruby awhile ago under the topic
of "Soul of a New Machine" (among others). The basic idea was an
anology along the following lines:

Lets say you have a Person, that preson does all the usual person
things. But today that person has a job as a Fireman, so he goes to
work and changes modes. Perhaps at night he goes home and must change
modes again and be a Boyfriend (hopefully that means some fun methods
are involved :wink:

Okay so the notion is that an object can take on another level of
abstraction, such that it's instance vars are essentially its "soul"
and they can be embuded into different classes.

It's sort of an inverted way to look the use of #become. But I think, a
much more undersandable and applicable way to look at.

T.

Csaba,

<quote>
I don't know what such "subtleties" like traits are. If you gave me a
concise explanation, I'd appreciate that. And then we could think about
my implementation, can/should it be extended to have that feature?
</quote>

Well, I'm not an expert by any means but I do my best. A trait is
simply a specially designated slot that acts as a parent. I guess
that's key, everything is slot based. I think your proposal has merits
but extending modules does not quite coorespond to trait slots. The
obvious distinction being that one can change a slot on the fly, but
not so for module extensions.

<quote>
I don't think of the usual class-based structure as a temptation to
avoid. I do think of prototype-like techniques as a powerful tool which
can be utilized at the right time.
</quote>

I see your point, and I think prototype-like tools can be used (and are
used) in a class-based language. But IMHO you loose some of the reason
and foundationary advantage of prototype-based OOP --primarily that the
whole object hieracrhy and its use become radically simplified.

Even so, like I said, your approach does have merits, and is certainly
a good way to give prototype-based OOP some play in Ruby. If your are
interested I would enjoy developing a dedicated library together. We
can work on it over at suby-ruby (keep in mind I can't devote too muh
time on it at the moment, but I willl certainly be happy to help/get
started.)

T.

> Actually, Perl has it better, because you can change the class of an
> object, and you can change the list of superclasses of any class.
And if a copy is sufficient you can do this even in pure Ruby:

No, a copy is _not_ sufficient.

Do you have a link or explanation that demonstrates the merits of the
capability to change an instance's class at runtime? Currently I don't
have a clue in which situations I would want this. Thx!

Just like almost any other programming concept invented to improve
structured programming, it's about replacing if/case expressions by tables
functionpointers such that it creates a "separation of concerns". (i mean
all the various forms of polymorphisms)

Now, for that feature in particular, think of a File which may be open or
closed, and you have to write at the start of each damn method:

  if not @file then raise "file not open" end

well, this could be solved by changing the set of all methods of that
class.

In general an object that has a few major cases of behaviour like that,
can benefit from switching methodtables.

In Ruby, my way to solve this problem is instead to use one object
representing a File that may be open or not, and one object that
represents a File guaranteed to be open, and then use message-forwarding
using Object#method_missing.

···

On Tue, 25 Jan 2005, Robert Klemme wrote:

_____________________________________________________________________
Mathieu Bouchard -=- Montréal QC Canada -=- http://artengine.ca/matju

What about instantly changing the class of an activerecord object based on modification of the "class" column.

···

Do you have a link or explanation that demonstrates the merits of the
capability to change an instance's class at runtime? Currently I don't
have a clue in which situations I would want this. Thx!

Kind regards

   robert

How about migrating legacy objects to new objects at run-time?

Nick

Sorry about the wierd punctuation. Google Groups is doing it.Not me!
~T.

"Trans" <transfire@gmail.com> schrieb im Newsbeitrag
news:1106671007.050300.117620@z14g2000cwz.googlegroups.com...

robert,

Class swapping was brought up on suby-ruby awhile ago under the topic
of "Soul of a New Machine" (among others). The basic idea was an
anology along the following lines:

Lets say you have a Person, that preson does all the usual person
things. But today that person has a job as a Fireman, so he goes to
work and changes modes. Perhaps at night he goes home and must change
modes again and be a Boyfriend (hopefully that means some fun methods
are involved :wink:

Okay so the notion is that an object can take on another level of
abstraction, such that it's instance vars are essentially its "soul"
and they can be embuded into different classes.

It's sort of an inverted way to look the use of #become. But I think, a
much more undersandable and applicable way to look at.

I missed the term "role" in your explanation. Cause that's the way I had
described this: the person changes her roles over time. Changing the
class is certainly an option here although in this example you would
likely want to restrict classes to sub classes of Person.

But what do you do if the Person needs to play several roles at a time?
Change the class for each method invocation? That's likely going to be
inefficient - and considering multiple threads it restricts concurrency
dramatically.

In Ruby the ideal way IMHO would be to have the reverse method of #extend
so if an instance takes on a role it uses a special mixin module's methods
and un-mixes this module when it leaves the role. Of course other
approaches are feasible, too. (Delegator instances that extend the role
module for example.)

Kind regards

    robert