On 10.02.2009 19:42, David Masover wrote:
> Robert Klemme wrote:
>>> That's arguably better, but a bit more work at the beginning. Still, it's
>>> worth comparing to the Perl solution:
>>>
>>> sub init {
>>>  my($class, $self) = @_;
>>>  bless $self => $class;
>>> }
>>>     
>> But this does not set properties, does it?
> 
> It does, actually, assuming you called it with a hash of options. Perl 
> objects are most commonly a blessed hash.

That's the first flaw of Perl's OO: you have the free choice to use 
hashes or arrays (or even scalars?) as objects.

>>> JavaScript is similar, in some respects. Suppose someone passes me in a hash
>>> of options. Well, hashes are objects, so I can just do this:
>>>
>>> function Foo(obj) {
>>>  for (var property in obj) {
>>>   this[property] = obj[property]
>>>  }
>>> };
>>>
>>> Bam. Not only instant options, but instant extensibility -- nothing prevents
>>> a user from passing in a function to override one of mine, thus creating a
>>> singleton descendant of my class.
>>>     
>> -> OpenStruct
>>   
> 
> Maybe I should read the docs, but as I understand it, in Javascript, I 
> can do this:
> 
> f = Foo({
>   a: 'some_string',
>   b: 12345,
>   c: function() {
>     // some method
>   }
> });
> 
> I could even do:
> 
> f = Foo(new Bar());
> 
> thus creating a spontaneous new child of both Foo and Bar. Keep in mind 
> that both Foo and Bar are classes, each of which may have methods of 
> their own -- in this case, Bar's methods (or properties) override Foo's.

Really?  I'd say they are overridden by Foo's because this comes later. 
  But I'm not a JavaScript expert.

> To get something even close in Ruby, I'd have to do this:
> 
> f = OpenStruct.new
> class << f
>   def c
>     #some method
>   end
> end

No.  This is a one off shot.  To get the equivalent of the JavaScript 
version (if my JS does not fail me), you need to define a method which 
does the initialization, e.g.

def Foo(o = Object.new)
   class <<o
     attr_accessor :bar, :baz

     def c
       printf "bar=%4d, baz=%4d\n", bar, baz
     end
   end

   o.bar = 123
   o.baz = 890

   o
end

Then you can do

x = Foo
y = Foo(Bar.new)
z = Foo(any_other_expression)

Although I have to say that I'd rather package this in a module and do

module Foo
   def self.create(o = Object.new)
     o.extend(self)
     o.bar = 123
     o.baz = 890
     o
   end

   attr_accessor :bar, :baz

   def c
     printf "bar=%4d, baz=%4d\n", bar, baz
   end
end

<snip/>

The details really do not matter.  My point is simply this: I prefer to 
use Ruby over Perl because of the clean syntax as well as the profound 
OO.  And I still have all (or at least most of) the options I have in 
Perl's bare metal world.  I find the balance in Ruby highly superior.

>> Because in Ruby hackery (or call it "metaprogramming") is an add on,
>> i.e. you can use it in special situations, while in Perl you need to
>> do it to get basic things (OO) to work.
> 
> There are, however, libraries to make the OO less painful in Perl.

Which still makes them non core artifacts and leave the option for 
multiple OO models in the same program.  Doesn't sound healthy to me.

> Now, not doing that often is probably a good idea -- not using 
> Kernel#eval often might also be a good idea. But I don't like it when a 
> tool tells me what I may or may not do, simply because it's not a good idea.

Maybe you haven't come to appreciate the power gained from restriction. 
  Often more creativity and productivity is unleashed in more restricted 
environments.

> I'm not trying to sell Perl's OO as the best thing, or even "better". 
> But I'm defending it as inherently less useful than Ruby's.

Is this really what you intended to say?

> Someone 
> might as easily say that Ruby's OO is inherently less useful than 
> Java's, because Java does stricter (static) type-checking.

As always it depends on the point of view - or the criteria you apply. 
I do mostly OO programming - even in scripts - and for that I appreciate 
the way OO is done much more than Perl's way.

Cheers

	robert