OOP in Ruby?

On May 25, 2008, at 9:57 AM, Huw C. wrote:

I wrote a series of articles in which Smalltalk and Ruby OOP are
compared which, perhaps, you may find of some interest. Here are the
links:

http://www.sapphiresteel.com/Ruby-The-Smalltalk-Way
http://www.sapphiresteel.com/Ruby-The-Smalltalk-Way-1
http://www.sapphiresteel.com/Ruby-The-Smalltalk-Way-2-A
http://www.sapphiresteel.com/Ruby-The-Smalltalk-Way-3-The-World

Using the late, lamented Dolphin Smalltalk. RIP. :frowning:

///ark

On 22 May, 09:29, Phillip G. [email protected]
wrote:

| Hi,
|
| Anyone know of any good resources regarding OOP in Ruby?

Err, about everything, I guess. :stuck_out_tongue_winking_eye:

~From personal experience: The PickAxe (Programming Ruby), and The Ruby
Way by Hal F. cover this nicely. And I suspect the O’Reilly book The
Ruby P.ming Language (co-written by Matz) covers that in-depth, too.

Pickaxe informs us about Ruby, but not OOA\D\P. Like Python and Java,
with Ruby you can still implement procedurally.

Aidy

On 22 May, 10:03, Dave B. [email protected] wrote:

Ruby is so object oriented that’s it’s almost impossible not to learn
about OOP by using it.

I feel that you could learn about OO Ruby, but the language does not
necessitate OO development. I could write everything in modules. I
could use classes as a container but not in an OO way (inheritance,
polymorphism and encapsulation).

Aidy

On May 25, 2008, at 1:14 PM, Huw C. wrote:

Mark W. wrote:

Using the late, lamented Dolphin Smalltalk. RIP. :frowning:

It’s not quite as dead as it seemed. At any rate, in August they
announced the end of development. Then in January, they announcded a
new
beta: http://www.object-arts.com/content/news/x61beta1.html

That news made my day. I don’t use Smalltalk or even Windows anymore,
but the six months or so I spent working on a Smalltalk project with
Dolphin was the most enjoyable of my whole career.

Dolphin is the best IDE I’ve ever used. Next comes Visual Studio. :slight_smile:

///ark

In Ruby, everything is an object.
First you must learn OOP (Object Orienter Programming), if you know oop
then Ruby’s OOP.

Blog: Ruby P.ming Language - http://ruby.unlimitedandfree.com

On May 26, 3:59 pm, luka luka [email protected] wrote:

In Ruby, everything is an object.

The ‘if’ expression is not an object.

Aidy

aidy wrote:

On May 26, 3:59 pm, luka luka [email protected] wrote:

In Ruby, everything is an object.

The ‘if’ expression is not an object.

There are many things in Ruby that are not objects - not only keywords
but also, for example, blocks. While blocks can be ‘converted’ into
objects (Proc objects), unlike in some other languages (such as
Smalltalk), Ruby blocks do not automatically have an independent
existence - that is, just writing a block in code does not make it an
instance of a Block (or Proc) class.

best wishes
Huw

SapphireSteel Software
Ruby and Rails In Visual Studio
http://www.sapphiresteel.com

On Tue, May 27, 2008 at 2:20 PM, Huw C. [email protected]
wrote:

Smalltalk), Ruby blocks do not automatically have an independent
existence
I agree upto here, but…

  • that is, just writing a block in code does not make it an
    instance of a Block (or Proc) class.
    I however believe it does, if you write a block in Ruby it is always
    passed on to a method, let that be Kernel#proc, Enumerable#map or
    whatever, that means that a Proc object referring to the block is
    always accessible via either the prefixed &blk parameter in this
    method or in case there is not &blk parameter and yield is used in the
    method it still is accessible as Proc::new without parameters

Example from a unit test

def a &blk
b = Proc::new
assert_equal blk, b
assert_equal b, Proc::new
assert_kind_of Proc, blk
end

Not using this reference does not mean it does not exist IMHO.
Cheers
Robert

–
http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Robert D. wrote:

I agree upto here, but…

  • that is, just writing a block in code does not make it an
    instance of a Block (or Proc) class.
    I however believe it does, if you write a block in Ruby it is always
    passed on to a method

Therein lies the difference. If you write a block in Smalltalk it has an
independent existence. It does not demand a receiver method in order to
justify its existence. In other words, a Smalltalk block is just the
same as an other object. It is an instance of its class and comes with
all the methods of its class. In fact, send it the ‘class’ message and
it will reply Block (or BlockClosure or whatever a specific Smalltalk
class library may have named it).

In Ruby, if you create a free-standing block, Ruby regards it as a
syntax error. So, unless a Proc object is instantiated using a block, I
don’t believe that a Ruby block meets the essential criterion required
to be described as an object.

best wishes
Huw

SapphireSteel Software
Ruby and Rails In Visual Studio
http://www.sapphiresteel.com

On Tue, May 27, 2008 at 4:02 PM, Huw C. [email protected]
wrote:

Robert D. wrote:

I agree upto here, but…

  • that is, just writing a block in code does not make it an
    instance of a Block (or Proc) class.
    I however believe it does, if you write a block in Ruby it is always
    passed on to a method

In Ruby, if you create a free-standing block, Ruby regards it as a
syntax error. So, unless a Proc object is instantiated using a block, I
don’t believe that a Ruby block meets the essential criterion required
to be described as an object.
This might become very interesting, please do not take any offense but
I really cannot follow you.
Anyway, I will tell you what is important to me:
Blocks in Ruby are Proc objects, always, can you agree with this
statement, if I render to your subtle arguement about the conditions
blocks need to exist?

I feel this is more important to a nuby than comparing to Smalltalk as
you did, although it is a very interesting thing. I however feel that
the substential difference is what Rick said in his post.

Please note also Eric’s patch making
{|x| x} equivalent to
lambda{|x| x}
this shows clearly that we are talking syntax here and not object
semantics.

Cheers
Robert D.

–
http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

On Tue, May 27, 2008 at 10:02 AM, Huw C. [email protected]
wrote:

Robert D. wrote:

I agree upto here, but…

  • that is, just writing a block in code does not make it an
    instance of a Block (or Proc) class.
    I however believe it does, if you write a block in Ruby it is always
    passed on to a method

Therein lies the difference. If you write a block in Smalltalk it has an
independent existence.

In theory, but not necessarily in practice. In reality most Smalltalk
implementations will not reify the “block” arguments to methods like
ifTrue:, ifFalse:, ifTrue:ifFalse, and ifFalse:ifTrue: instead they
cheat and compile test and branch bytecodes, and throw an exception if
the ‘receiver’ isn’t a boolean.

http://talklikeaduck.denhaven2.com/articles/2008/05/21/what-would-you-miss-if-you-had-to-stop-using-ruby-and-go-back-to-smalltalk

The real difference, I think, is that in Smalltalk you can have
multiple arguments in a message which are coded as block literals,
where as in Ruby block literals can only be used as the final argument
to a method, and that that argument doesn’t need to be explicitly
named if is invoked by the method using yield, or if it’s ignored by
the method.

There’s quite a discussion going on right now on ruby-core about the
esthetics of the new ‘->’ “fallen over lambda” operator in 1.9 and
whether it would be better to allow a call like:

a.m({|b|…}, {|| …})

where the |…| distinguish a block from a hash.

I don’t know the ultimate fate of the proposal, but it DOES make ruby
syntax look a bit more like Smalltalk.

It makes me wonder what Ruby would look like had Matz chosen square
brackets rather than braces to delimit block literals.

Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Tue, May 27, 2008 at 11:14 AM, Robert D. [email protected]
wrote:

Anyway, I will tell you what is important to me:
Blocks in Ruby are Proc objects, always, can you agree with this
statement,

I don’t think that this is true Robert.

For example:

def foo
yield
end

foo {}

doesn’t create a proc.

Please note also Eric’s patch making
{|x| x} equivalent to
lambda{|x| x}
this shows clearly that we are talking syntax here and not object semantics.

Except that Eric had to redo the patch because he ran into an issue
with yield vs. call semantics.

–
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

No one’s mentioned “A Little Ruby, A Lot of Objects”!
http://www.visibleworkings.com/little-ruby/

Robert D. wrote:

I however believe it does, if you write a block in Ruby it is always
passed on to a method, let that be Kernel#proc, Enumerable#map or
whatever, that means that a Proc object referring to the block is
always accessible via either the prefixed &blk parameter in this
method or in case there is not &blk parameter and yield is used in the
method it still is accessible as Proc::new without parameters

def foo
p ObjectSpace.each_object(Proc){}
end

def bar(&bl)
p ObjectSpace.each_object(Proc){}
end

GC.disable
foo {} # ==> 59
foo {} # ==> 59
foo {} # ==> 59
bar {} # ==> 60
bar {} # ==> 61
bar {} # ==> 62

Hi –

On Wed, 28 May 2008, Huw C. wrote:

may appear to be more or less the same:
[snip]

It’s a subtle point, I know, and I don’t want to make any big deal of
it. After all, when a Proc object block is explicitly created from a
Ruby block, it works in a comparable way to a Smalltalk block. However,
that doesn’t alter the fact that, in Ruby, blocks (chunks of code
delimited by {…} or do…end) are not normally instances of the Proc
class. They are, well, just chuncks of code but not objects. To
demonstrate that, try evaluating a block:

I agree that this subtle point is important. It’s one of these things
where it seems like splitting hairs to say that the code block is
syntax and the Proc is an object, but if one doesn’t make that
distinction, then there’s a kind of off-by-one condition later on,
when things like Proc.new taking a block starts to seem weird (why
would Proc.new take a Proc?).

It’s similar, I think, to hair-splitting between “message-sending” and
“method-calling”. Much of the time it doesn’t matter, but if there’s
no separation of the terminology, then the very concept of sending an
object a message it can’t map to a method gets harder, rather than
easier, to grasp.

David

Robert D. wrote:

Anyway, I will tell you what is important to me:
Blocks in Ruby are Proc objects, always, can you agree with this
statement,

No, it doesn’t seem to me that they are. As I said before, in Ruby a
block does not, by default, have its own independent existence. Let me
illustrate by comparison with Smalltalk. When we write blocks and use
them with methods (e.g. times in Ruby or timesRepeat: in Smalltalk) they
may appear to be more or less the same:

  1. SMALLTALK

i := 0.
10 timesRepeat: [ i := i + 1 ].
i.

  1. RUBY

i = 0
10.times{ i += 1 }
puts( i )

BUT, a Smalltalk Block can be its own object. It is not obliged to be
used with some ‘block-aware’ method. Compare the following:

  1. SMALLTALK

i := 0.
myBlock := [ i := i + 1 ].
10 timesRepeat: myBlock.

  1. RUBY (a)

i = 0
myBlock = { i += 1 } # <= error: Ruby thinks this is a hash
10.times{ i += 1 }
puts( i )

  1. RUBY (b)

i = 0
myBlock = { || i += 1 } # <= syntax error
10.times{ i += 1 }
puts( i )

  1. RUBY (c)

i = 0
myBlock = proc{ i += 1 } #<= Hurrah! Works by explictly ‘converting’ to
Proc
10.times{ i += 1 }
puts( i )

In Smalltalk, a block is always an instance of its class. e.g.

myBlock := [ i := i + 1 ].
myBlock class.
…Smalltalk replies: BlockClosure.

It’s a subtle point, I know, and I don’t want to make any big deal of
it. After all, when a Proc object block is explicitly created from a
Ruby block, it works in a comparable way to a Smalltalk block. However,
that doesn’t alter the fact that, in Ruby, blocks (chunks of code
delimited by {…} or do…end) are not normally instances of the Proc
class. They are, well, just chuncks of code but not objects. To
demonstrate that, try evaluating a block:

  1. SMALLTALK
    [ i := i + 1 ] class.
    …Answers: BlockClosure

  2. RUBY
    { i += 1 }.class
    …Answers: syntax error, unexpected ‘}’, expecting $end { || i += 1
    }.class

do i += 1 end.class
…Anwsers: syntax error, unexpected kEND, expecting $end do i += 1
end.class

best wishes
Huw

SapphireSteel Software
Ruby and Rails In Visual Studio
http://www.sapphiresteel.com

In Ruby you only need to add “lambda” to make a block into an object:

irb(main):006:0> x = lambda { i += 1 }
=> #Proc:0x02e13cf8@:6(irb)
irb(main):007:0> x.class
=> Proc
irb(main):008:0> lambda { i += 1 }.class
=> Proc

I suppose the need to prepend “lambda” is a good thing in that it gives
you the flexibility of choosing whether you want to make your block into
an object or not, whereas in Smalltalk presumably all blocks are
automatically objects. There may be some small overhead associated with
this, I don’t know.

Declaring blocks with “lambda” is a bit like declaring variables before
you can use them, something I miss with Ruby.

On Tue, May 27, 2008 at 7:36 PM, David A. Black [email protected]
wrote:
Rick, Huw, David

you might be right, I finally understand what you mean know :).

I can esaily imagine a conceptual view in which you are right

def foo
yield
end

foo {}

does not create a Proc object, I however believe, but agree that this
of minor importance,
that the interpreter creates a temporary proc object, how else could
Proc::new return the correct value?

I feel it is important to know that you can always get to an object
representing the block, that was good enough for me.

I start understanding better that indeed the lack of syntactic
facilities can be interpreted how you did, but it took me a while to
work it out :slight_smile:

Just to be double sure I get you right, if one implemented Eric’s
patch and we could write
pr = do 42 end
or = {|| 42 }
would you agree with my original statement?

Cheers
Robert

–
http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

On Wed, May 28, 2008 at 11:24 AM, Dave B. [email protected]
wrote:

I suppose the need to prepend “lambda” is a good thing in that it gives
you the flexibility of choosing whether you want to make your block into
an object or not, whereas in Smalltalk presumably all blocks are
automatically objects. There may be some small overhead associated with
this, I don’t know.
I am not sure, is it not simply a question of optimization, assume this
case

def a &blk
end
a {}
Ruby could not create an object for {}, but does it, I do not think so
for 1.8, maybe in 1.9?

Same thing in Smalltalk
…
[ :i | i + 1 ].
…
Smalltalk could as well not compile this code at all or create a NOP,
probably most Smalltalk implementations will ignore it I guess

Declaring blocks with “lambda” is a bit like declaring variables before
you can use them, something I miss with Ruby.
And I am missing your unit tests, that said it might be a good feature
safeguarding you against typos in quick hacks sometimes.
Overall I still think it is not worth it, maybe your methods are a tad
too long too?

Cheers
Robert