Forum: Rails Spinoffs (closed, excessive spam) Mixing In JS Getters and Setters with Class.create

Posted by Antoine Quint (Guest)
on 2008-07-02 14:52
(Received via mailing list)
Hi,

I'm trying to mix native JS getters and setters with Class.create,
with little success so far. Here's what I tried:

=====8<=====

var MyClass = {};

MyClass.__defineGetter__('test', function() {
  alert('inside getter');
  return 'foo';
});

MyClass.__defineSetter__('test', function(new_value) {
  alert('inside setter');
  return new_value;
});

MyClass = Class.create(MyClass);

var foo = new MyClass();
foo.test; // should alert 'inside getter'
foo.test = 'bar'; // should alert 'inside setter'

=====>8=====

Evaluating this code with prototype 1.6.0.2 I only get the 'inside
getter' message alerted, but not the setter one, so getters resist
Class.create but not setters. Is there something wrong I'm doing or
are setters just not supported in prototype?

I'll note that I'm working against Safari on iPhone only so I'm not
worried about compatibility issues while using JS getters and setters.

Thanks for your help,

Antoine
Posted by darrin (Guest)
on 2008-07-02 16:29
(Received via mailing list)
Interesting, first time I've seen this. The alert is actually coming
out of Class.create call. What about this....

var MyClass = Class.create({
  initialize: function() {
    this.__defineGetter__('test', function() {
      alert('inside getter');
      return 'foo';
    });

    this.__defineSetter__('test', function(new_value) {
      alert('inside setter');
      return new_value;
    });
  }
});
Posted by Antoine Quint (Guest)
on 2008-07-02 16:53
(Received via mailing list)
Hi Darrin,

On Jul 2, 2008, at 16:28 , darrin wrote:

>    this.__defineSetter__('test', function(new_value) {
>      alert('inside setter');
>      return new_value;
>    });
>  }
> });

That works fine indeed. Do you have any idea why that is while the
previous snippet did not work?

The reason I ask is because I personally dislike the programming style
where properties are defined inline the object passed as the parameter
to Class.create(), and I prefer to have separate "MyClass.aFunction =
function ()" calls. Do you think there is a way to get getters and
setters to work in this style?

Thanks a lot for your help,

Antoine
Posted by Ryan Gahl (Guest)
on 2008-07-02 17:01
(Received via mailing list)
It probably has something to do with the fact that you are defining the
getter/setter statically on the class itself, where in the second 
example,
you are actually defining them at the instance level, which is what you
want.

In your first example, I'll bet if you just do MyClass.test = "blah" it
would give you your alert...

You probably just need to a) do your Class.create() first, and b) then 
apply
your getters/setters via the prototype object of the class function:

var MyClass = Class.create();
MyClass.prototype.__defineGetter__("test", someFunction);


...etc...


On Wed, Jul 2, 2008 at 9:52 AM, Antoine Quint <antoine@graougraou.com>
wrote:

> >    this.__defineGetter__('test', function() {
>
>
> Antoine
>
> >
>


--
Ryan Gahl
Manager, Senior Software Engineer
Nth Penguin, LLC
http://www.nthpenguin.com
--
WebWidgetry.com / MashupStudio.com
Future Home of the World's First Complete Web Platform
--
Inquire: 1-920-574-2218
Blog: http://www.someElement.com
LinkedIn Profile: http://www.linkedin.com/in/ryangahl
Posted by Antoine Quint (Guest)
on 2008-07-02 17:09
(Received via mailing list)
Hi Ryan,

On Jul 2, 2008, at 17:01 , Ryan Gahl wrote:

> It probably has something to do with the fact that you are defining  
> the getter/setter statically on the class itself, where in the  
> second example, you are actually defining them at the instance  
> level, which is what you want.

I don't intend to have them defined on the class itself. I define them
on MyClass indeed, but when I do "MyClass = Class.create(MyClass)", I
think that should have copied class members onto the MyClass
prototype, isn't that right?

I guess the issue there is that these special __defineGetter__ and
__defineSetter__ members are not recognized by Class.create() and thus
aren't copied onto the prototype.

Antoine
Posted by Ryan Gahl (Guest)
on 2008-07-02 17:12
(Received via mailing list)
Why would Class.create() copy static class members to the prototype? 
That
doesn't make any sense. That completely rules out the possibility that 
the
developer, you know, wanted them to remain static...





On Wed, Jul 2, 2008 at 10:08 AM, Antoine Quint <antoine@graougraou.com>
wrote:

> I don't intend to have them defined on the class itself. I define them
> >
>


--
Ryan Gahl
Manager, Senior Software Engineer
Nth Penguin, LLC
http://www.nthpenguin.com
--
WebWidgetry.com / MashupStudio.com
Future Home of the World's First Complete Web Platform
--
Inquire: 1-920-574-2218
Blog: http://www.someElement.com
LinkedIn Profile: http://www.linkedin.com/in/ryangahl
Posted by Antoine Quint (Guest)
on 2008-07-02 17:16
(Received via mailing list)
On Jul 2, 2008, at 17:11 , Ryan Gahl wrote:

> Why would Class.create() copy static class members to the prototype?  
> That doesn't make any sense. That completely rules out the  
> possibility that the developer, you know, wanted them to remain  
> static...

As far as I know, that's how Class.create works. See 
http://prototypejs.org/learn/class-inheritance
  and more particularly the Defining class methods section: "There is
no special support for class methods in Prototype 1.6.0. Simply define
them on your existing classes". Then the example shows how class
methods need to be defined _after_ the Class.create() call.

Antoine
Posted by Ryan Gahl (Guest)
on 2008-07-02 17:28
(Received via mailing list)
Nowhere on that page does it say that static class methods are copied to 
the
prototype. If, for whatever reason, it actually IS supposed to work that
way, it's a major flaw, and should be fixed immediately. But like I 
said, it
wouldn't make any sense if it worked like that, and so it doesn't.

So, with that - just do what darrin suggests (which is the best way to
ensure your instance methods are truly instance only methods)... or 
attach
them directly to the prototype object after Class.create() is called.


On Wed, Jul 2, 2008 at 10:15 AM, Antoine Quint <antoine@graougraou.com>
wrote:

>  and more particularly the Defining class methods section: "There is
> no special support for class methods in Prototype 1.6.0. Simply define
> them on your existing classes". Then the example shows how class
> methods need to be defined _after_ the Class.create() call.
>
> Antoine
>
>
> >
>


--
Ryan Gahl
Manager, Senior Software Engineer
Nth Penguin, LLC
http://www.nthpenguin.com
--
WebWidgetry.com / MashupStudio.com
Future Home of the World's First Complete Web Platform
--
Inquire: 1-920-574-2218
Blog: http://www.someElement.com
LinkedIn Profile: http://www.linkedin.com/in/ryangahl
Posted by Antoine Quint (Guest)
on 2008-07-02 17:44
(Received via mailing list)
On Jul 2, 2008, at 17:27 , Ryan Gahl wrote:

> Nowhere on that page does it say that static class methods are  
> copied to the prototype.

I think there are only ever static class methods passed in
Class.create(). When you do this:

Class.create({
   initialize: function() {
     // some code here
   }
});

you are passing Class.create an anonymous object with a single static
method defined on it. That object could not be used to create a class
with the "new" construct, it has no constructor to speak of. That's
the whole premise of Class.create as I understand it, you pass it an
anonymous object which really is just a class definition.

The style I use to create classes with Class.create is to actually
name that anonymous object, define what will be instance methods as
static methods on it, pass that object to Class.create() and update
the object with what is returned. So what I wrote above is rewritten
that way and is equivalent as I understand it.

MyClass = {};

MyClass.initialize = function () {
   // some code here
};

MyClass = Class.create(MyClass);

> If, for whatever reason, it actually IS supposed to work that way,  
> it's a major flaw, and should be fixed immediately. But like I said,  
> it wouldn't make any sense if it worked like that, and so it doesn't.

I think it's a pretty elegant design and it's actually the reason I
chose Prototype as a base framework, because I really liked how it
lets one define classes.

> So, with that - just do what darrin suggests (which is the best way  
> to ensure your instance methods are truly instance only methods)...  
> or attach them directly to the prototype object after Class.create()  
> is called.


I think I'll just have a special method called in .initialize that
will map the getters and setters automatically. I was just hoping that
Prototype might already have a way to deal with JS getters and setters
outside of the constructor.

Antoine
Posted by kangax (Guest)
on 2008-07-02 18:37
(Received via mailing list)
On Jul 2, 11:43 am, Antoine Quint <anto...@graougraou.com> wrote:
>      // some code here
>    }
>
> });
>
> you are passing Class.create an anonymous object with a single static
> method defined on it. That object could not be used to create a class

There are no "static" or "instance" methods on js objects really : )
I understand what you mean, but it just sounds confusing.

> MyClass = {};
>
> MyClass.initialize = function () {
>    // some code here
>
> };
>
> MyClass = Class.create(MyClass);
>

I've never seen such way of defining "classes". It seems weird to
first create a reference to an empty object literal, then redefine it
to point to a "class" definition. Whatever works for you.

> > If, for whatever reason, it actually IS supposed to work that way,
> > it's a major flaw, and should be fixed immediately. But like I said,
> > it wouldn't make any sense if it worked like that, and so it doesn't.
>
> I think it's a pretty elegant design and it's actually the reason I
> chose Prototype as a base framework, because I really liked how it
> lets one define classes.
>

Prototype doesn't provide any special facility for defining "static"
members (as majority defines it). All it takes is to declare them as
members of "class" function.

var Foo = Class.create({ ... })
Foo.blah = 'my static property';

> > So, with that - just do what darrin suggests (which is the best way
> > to ensure your instance methods are truly instance only methods)...
> > or attach them directly to the prototype object after Class.create()
> > is called.
>
> I think I'll just have a special method called in .initialize that
> will map the getters and setters automatically. I was just hoping that
> Prototype might already have a way to deal with JS getters and setters
> outside of the constructor.
>

You could do that, though "fat" constructors is usually not a good
idea. It would also cripple performance if constructor is called
frequently.

-- kangax
Posted by Antoine Quint (Guest)
on 2008-07-02 19:06
(Received via mailing list)
Hi,

On Jul 2, 2008, at 18:36 , kangax wrote:

>> Prototype doesn't provide any special facility for defining "static"
> members (as majority defines it). All it takes is to declare them as
> members of "class" function.
>
> var Foo = Class.create({ ... })
> Foo.blah = 'my static property';

Yeah, that's what I do and it works just fine.

>> outside of the constructor.
>>
>
> You could do that, though "fat" constructors is usually not a good
> idea. It would also cripple performance if constructor is called
> frequently.

I think it might be worth asking for JS getters and setters to be
handled directly by Class.create(). I'll try to add support for them
in Class.create() and submit a patch...

Antoine
Posted by Ryan Gahl (Guest)
on 2008-07-02 19:12
(Received via mailing list)
>
> There are no "static" or "instance" methods on js objects really : )
> I understand what you mean, but it just sounds confusing.


Of course there are. To say otherwise is confusing.

You could do that, though "fat" constructors is usually not a good
> idea. It would also cripple performance if constructor is called
> frequently.


Not true at all. "fat" constructors? Let's not make up FUD terms here :)

The truth is, defining methods and properties from within the 
constructor is
the ONLY way to achieve truly instance only members, and the only way to
create truly private/public members on the instance (instead of people 
just
adding an underscore character to a public member and calling it 
private).

For 95% of classes, there will be no noticeable performance issues.
Posted by kangax (Guest)
on 2008-07-02 21:11
(Received via mailing list)
On Jul 2, 1:12 pm, "Ryan Gahl" <ryan.g...@gmail.com> wrote:

> Of course there are. To say otherwise is confusing.

I'm not sure I understand what you mean, Ryan.
JavaScript doesn't have a notion of "static" (except for a reserved
keyword that's not even implemented). There are "direct" members and
members shared via object's [[Prototype]]. Since prototype.js
simulates "classes" a reasonable definition of static would be:
properties of a Function object created via Class.create. The way
Antoine put it sounds confusing to me (and I'm sure to other folks as
well)

> You could do that, though "fat" constructors is usually not a good
>
> > idea. It would also cripple performance if constructor is called
> > frequently.
>
> Not true at all. "fat" constructors? Let's not make up FUD terms here :)
>

Doesn't really matter how we call it : )
Having bunch of logic in constructor is not a good design (in my
experience)

> The truth is, defining methods and properties from within the constructor is
> the ONLY way to achieve truly instance only members, and the only way to

"instance only" members could be easily created by assigning functions
to properties of object's prototype. I don't see a need for
constructor.

> create truly private/public members on the instance (instead of people just
> adding an underscore character to a public member and calling it private).
>
> For 95% of classes, there will be no noticeable performance issues.

It's obviously a matter of priorities. For me, performance is usually
one of the key factors. Simulating "private" properties (in a highly
dynamic language) does not compensate for the decreased speed.

-- kangax
Posted by Ryan Gahl (Guest)
on 2008-07-02 21:36
(Received via mailing list)
>
> It's obviously a matter of priorities. For me, performance is usually
> one of the key factors. Simulating "private" properties (in a highly
> dynamic language) does not compensate for the decreased speed.


But, there is no decreased speed noticeable, is what I'm saying. So 
you're
sacrificing nothing to gain the benefits of private members, with public
accessors. And, it's not a "simulation" -- adding an underscore and 
calling
it private is closer to simulation. What I'm talking about is TRUE 
public
vs. private exposure. There is nothing simulated about it.

Doesn't really matter how we call it : )
> Having bunch of logic in constructor is not a good design (in my
> experience)


You're experience is wrong here, if it tells you that implementing 
instance
only members, and truly private members, is not good design. It's an
extremely valuable pattern, with very clear benefits. Your way is 
another
pattern, with its own benefits. In MY experience (building massive 
single
page high performance RIAs for large clients)... the benefits of 
projecting
the long used classical OO paradigm (which as we all know is really one 
of
the points of Prototype.js) into javascript far outweigh the (completely
unnoticeable) performance issues. The assignment of a series of 
properties
and methods within a contructor is NOT the same as the processing that 
those
methods eventually do when they get called. You will never see a 
difference
in performance in a live application. You can run some wildly inaccurate
"create a million instances" side by side tests... and still only see a
minor difference. Your claims simply have no basis, and it really is
borderline FUD.

Even assigning a member via a constructor function's prototype is
technically not instance only, because of the simple fact that it sill
possible to access the member statically be doing
"someClass.prototype.doSomething()". YES, I know this is not a real 
issue,
because not many (smart) people will be calling methods directly against 
the
prototype object... but does illustrate what I mean by TRULY 
instance-only.

For more information:
http://www.someelement.com/2007/03/multiple-inheri...

About half way down I explain a little more about what I mean by "truly
instance-only" vs "prototype-static".

It's most definitely a major departure from how most js devs think. But,
again, in MY experience, there are very real long term benefits to this
approach, all centered around code longevity and maintainability across 
the
diversely distributed skill levels of team members.... and almost NO
downside.


On Wed, Jul 2, 2008 at 2:10 PM, kangax <kangax@gmail.com> wrote:

> members shared via object's [[Prototype]]. Since prototype.js
> > Not true at all. "fat" constructors? Let's not make up FUD terms here :)
> "instance only" members could be easily created by assigning functions
> It's obviously a matter of priorities. For me, performance is usually
> one of the key factors. Simulating "private" properties (in a highly
> dynamic language) does not compensate for the decreased speed.
>
> -- kangax
> >
>


--
Ryan Gahl
Manager, Senior Software Engineer
Nth Penguin, LLC
http://www.nthpenguin.com
--
WebWidgetry.com / MashupStudio.com
Future Home of the World's First Complete Web Platform
--
Inquire: 1-920-574-2218
Blog: http://www.someElement.com
LinkedIn Profile: http://www.linkedin.com/in/ryangahl
Posted by kangax (Guest)
on 2008-07-02 23:14
(Received via mailing list)
On Jul 2, 3:36 pm, "Ryan Gahl" <ryan.g...@gmail.com> wrote:
> Doesn't really matter how we call it : )
I should have been more specific about performance decrease. Speed of
constructor execution has little to do with it. What matters is that
instances don't share methods via their prototype chain. Instead they
carry them as direct members. This leads to an increased memory
footprint and means that instead of O(1) you get O(N). Clearly there
are benefits : ) I find "true" private members (as you call them) of
little necessity when it comes to encapsulation. JavaScript is a
prototypal language. Members are meant to be shared via prototype
chains. Having common conventions like underscored names is a much
more efficient approach (in my experience).

> the points of Prototype.js) into javascript far outweigh the (completely
> possible to access the member statically be doing
> again, in MY experience, there are very real long term benefits to this
> approach, all centered around code longevity and maintainability across the
> diversely distributed skill levels of team members.... and almost NO
> downside.
>

My goal was not to go into discussion of "truly" private members
pattern. I know exactly which benefits come with it and I'm glad it
works for you. JavaScript happens to be designed in such way that
"truly" private members (as we know them) destroy one of its main
concepts. This has little to do with general usefulness of
encapsulation patterns and - yes - it does have real life performance
implications. I would appreciate if my reasonings weren't claimed to
be "FUD" : )

Best,
kangax
Posted by Ryan Gahl (Guest)
on 2008-07-02 23:30
(Received via mailing list)
>
> I would appreciate if my reasonings weren't claimed to
> be "FUD" : )


I said "borderline FUD"   :)

And ok. It's not FUD. It's just not correct.

But once again I disagree with both statements, where you say private
members destroy any features of javascript. In fact, they are 
implemented by
taking advantage of the features of javascript. So you are saying "using 
the
dynamic nature of javascript to implement true levels of member
accessibility is destroying X? (where i have no idea what X is)". The 
other
statement being your claims on performance.

The only thing I can see is your memory argument. But that is mitigated 
by
good object design, and good resource management. We build applications 
that
run in a single page and create thousands of widget instances. We have a
component model that employs a "disposable" interface, where when an
instance is no longer needed, dispose() is called on it and its memory
allocations are cleaned up (including auto unhooking dom events).

If you create an application that creates so many object instances, 
where
you're using up too much memory and you notice a slow down... then 
you've
got other problems, and no features of javascript are going to save your
design.

You're making just plainly false assumptions about a pattern you've 
clearly
never tested. It's different than what you've always done... and 
therefore
somehow bad.

Look, this got a bit sidetracked from the OP... but trust me, the 
pattern is
sound and works in very large scale applications.
Posted by Ryan Gahl (Guest)
on 2008-07-02 23:48
(Received via mailing list)
One more little illustration:

var blah = Class.create({
someArray: [],
initialize: function() {}
});

var foo1 = new blah();
var foo2 = new blah();
foo1.someArray.push("blahblah");
alert(foo2.someArray.length); //alerts 1, most people new to js will 
expect
0

How many times has this issue been posted about here? People write 
something
like this, and expect the array to be unique for both instances, when in
fact it's shared (also known as static)... when in fact they really 
wanted:


var blah = Class.create({
initialize: function() {
this.someArray = [];
}
});
Posted by Dan Dorman (Guest)
on 2008-07-03 00:01
(Received via mailing list)
It's gotten a bit testy, but I just wanted to say that I, for one,
have appreciated the discussion thus far ;-)

:Dan
Posted by kangax (Guest)
on 2008-07-03 00:37
(Received via mailing list)
I'm not sure what this has to do with anything.
If a person doesn't know what Class.create does with an object (passed
to it), it's their problem ; )
Bending language (and clogging performance) to meet inept programmers
expectations doesn't seem like a wise thing to do.
Adapting a "private members" pattern, on the other hand, is a decision
every person/team has to decide for itself (as there are clear pros/
cons in each situation).

-- kangax
Posted by Ryan Gahl (Guest)
on 2008-07-03 01:18
(Received via mailing list)
Seriously, stop with the performance stuff - it's not an issue. You keep
bringing it up and I'm here to tell you it's just plain wrong. And my
example is a perfect example of the benefit of the assignment of 
instance
members within the constructor as rule. In fact, in this example, it's 
the
ONLY way to make someArray be an instance member across instances (vs.
shared across instances, again, also know as static).

Bending language (and clogging performance) to meet inept programmers
> expectations doesn't seem like a wise thing to do.


You're clearly not in charge of a team of developers doing long term 
large
scale application development, with a statement like that. You MUST 
account
for programmer skill level disparity. Not doing so IS unwise. This is 
one of
the most critical issues for an architect and project manager... being 
able
to plug in new team members and ensure, to whatever extent is possible, 
that
the basic skillsets needed are as standard as possible and that the code
output is consistent. You just will not find a homogeneous team of 
rockstars
that can navigate easily through all the intricacies of the target
platform/language and instantly grok everyone else's "uber" coding 
styles.
And once again, the "clogging performance" statement is erroneous.

All the above said, that's not even the point of my argument (but it's
important and is quite contrary to your quote above).

All I'm saying, is that you're wrong about the pattern. I'm not here to
convince you to use it, but you are just wrong. It lends itself to 
extreme
scalability, and does not, I repeat, does not adversely affect 
performance.
That's a lie that someone told you, that you never tested, and I just 
want
to stop the propagation of this falsity... lest someone else believe it.
Posted by Ryan Gahl (Guest)
on 2008-07-03 01:33
(Received via mailing list)
Just re-read my last post - kangax, sorry for getting all "DUDE!!" on 
you...
I'll try to keep my tone down if we continue the exchange :)
Posted by Ryan Gahl (Guest)
on 2008-07-03 01:41
(Received via mailing list)
>
> It's gotten a bit testy, but I just wanted to say that I, for one,
> have appreciated the discussion thus far ;-)


Sorry about the feistiness, but glad someone is finding it valuable.
Posted by kangax (Guest)
on 2008-07-03 07:49
(Received via mailing list)
Ryan, no need to get offensive about patterns that work for you (and
your team).
I am certainly not throwing pointless arguments about some
hypothetical performance issues. Everything I said comes from
experience in applications I have worked on. It also comes from people
who worked on JS applications of a much larger scale than I have ever
had (and who I learned a great deal of JavaScript from). I have no
intentions of spreading heresy around this place. Your attitude is
surprising at best. Constantly repeating how I'm "plain wrong" and
making up assumptions about my reasonings, my experience and skills is
not something I would expect of you.
I gave a simple explanation of what "static" is referred to in
JavaScript (or rather prototype.js). I also pointed out caveats of
"private members" pattern.
The truth is that there are no silver bullets (that you seem so
desperately convince me to follow).
There are also no "wrong" or "right". There are patterns that work in
one environment and don't work in others.

Regards.
Posted by Ryan Gahl (Guest)
on 2008-07-03 08:09
(Received via mailing list)
>
> Constantly repeating how I'm "plain wrong" and
> making up assumptions about my reasonings, my experience and skills is
> not something I would expect of you.


You are saying things about a pattern that are wrong, and there's no 
other
kind of wrong other than plain :). The only thing I said that was an
assumption about your experience was related to the comment you made 
about
"inept developers" - I felt it showed a level of inexperience working on
large development teams. I never said anything, however, about your 
skills.
I respect your skills. Especially your skills with a bowstaff and with
numchucks :) <napolean dynamite reference>

The truth is that there are no silver bullets (that you seem so
> desperately convince me to follow).
> There are also no "wrong" or "right". There are patterns that work in
> one environment and don't work in others.


First of all, I'm not trying to convince you or anyone else to use one
pattern over another. This all started when you made false claims about
"fat" constructors and calling it bad design to assign instance 
properties
from within the constructor, saying it "clogs performance".... all 
untrue
statements. That's all I was doing - pointing out that you are incorrect
about the pattern. I never said the pattern was more correct vs another
pattern. I was simply explaining the benefits, why we use it, and 
debunking
the myths around it, that you seemed to be defending with really no 
basis.

Ryan, no need to get offensive


I am sorry if my rebuttals got a bit "point blank". I don't think I 
really
said anything too offensive, but if I did I truly do apologize. Hope 
there's
no hard feelings. After all, there's nothing like a heated debate once 
in a
while to fill in the gaps of a busy day :)
Posted by RobG (Guest)
on 2008-07-03 12:50
(Received via mailing list)
On Jul 3, 4:09 pm, "Ryan Gahl" <ryan.g...@gmail.com> wrote:
> > Constantly repeating how I'm "plain wrong" and
> > making up assumptions about my reasonings, my experience and skills is
> > not something I would expect of you.
>
> You are saying things about a pattern that are wrong, and there's no other
> kind of wrong other than plain :).

When claiming something as categorically wrong, there only needs to be
one exception to disprove the claim.

Kangax's point might be moot for simple constructors, but that doesn't
make it "plain wrong".  Suppose you have a constructor with 100
methods and you want 100 instances, is it better to define each and
every method on each and every instance, or put them on the
constuctor's prototype?  More simply, would you consider it OK to
create 10,000 function objects when 100 will do the job?

If you are unequivocally right, then Prototype.js should stick with
the strategy employed for IE of adding methods to every DOM element it
encounters as there would be no point in extending HTMLElement
instead.

Much of the argument in this thread comes from the fact that
javascript doesn't have classes, or instance variables, or static
members: but there are various ways of emulating them.  What you are
really arguing about are implementation preferences.

Concepts of good, bad, right and wrong are purely subjective.  What is
lost in the bluster is that javascript is flexible enough to emulate
just about any OO paradigm you want.


--
Rob
Posted by Ryan Gahl (Guest)
on 2008-07-03 16:35
(Received via mailing list)
>
> Kangax's point might be moot for simple constructors, but that doesn't
> make it "plain wrong".  Suppose you have a constructor with 100
> methods and you want 100 instances, is it better to define each and
> every method on each and every instance, or put them on the
> constuctor's prototype?  More simply, would you consider it OK to
> create 10,000 function objects when 100 will do the job?


That's one of those irrelevant, contrived examples of something you'll 
never
see in a full blown real life application. Even then, you just will not 
see
a significant slowdown. Yes, if you, for some reason other than running 
an
ill conceived test, create 10,000 functions at once, you're not making
optimal use of memory. Your example assumes 100 instances of the same 
class
(that for some reason has 100 functions??) are ever going to exist, 
which
just will not happen unless you are talking about one of the worst
architects on the planet, and once again no use of shared memory tactics
will save that project from failure. Please keep in mind I'm not talking
about things like "HtmlElement". I'm talking about application classes.

If you are unequivocally right, then Prototype.js should stick with
> the strategy employed for IE of adding methods to every DOM element it
> encounters as there would be no point in extending HTMLElement
> instead.


You guys are confusing what I'm saying. Kangax said encapsulating
private/public, instance only members within the constructor is bad 
design
and HE is the one that said this without considering that what he was 
saying
was not categorically correct. I simply jumped in to defend the pattern 
as a
sound and scalable approach to large scale application development, 
citing
the merits of using it. (NOTE: once again, I am not saying that NOT 
using it
is wrong or that your code is not good, simply defending the usage of it 
as
not "bad design")

I never once said Prototype, or you, or kangax, or the OP, should USE it
compared to anything else.

Much of the argument in this thread comes from the fact that
> javascript doesn't have classes, or instance variables, or static
> members: but there are various ways of emulating them.  What you are
> really arguing about are implementation preferences.


Javascript does not have classes, true. Javascript does have instance
variables, and does have static members (where in the world are you 
getting
this stuff). You're kind of saying "javascript is not object oriented",
which it is. Does javascript have instances? Yes, otherwise, what is 
this:
"var blah = new Foo();"? Are the properties and methods that are unique 
to
each instance called instance members? Yes. And what about those members
that are shared across instances? What's another word for shared, in 
object
oriented vernacular? Static. And what we're arguing about is the fact 
that
kangax said that a perfectly good design pattern is bad. I said "no, 
that's
wrong and here's why"

If sound OO practice is bad design, than what do you make of the new
features centered around these same concepts, that will be in Javascript 
2?

Concepts of good, bad, right and wrong are purely subjective


That statement is wrong :) (sorry, had to do it)
Posted by kangax (Guest)
on 2008-07-03 23:43
(Received via mailing list)
On Jul 3, 10:34 am, "Ryan Gahl" <ryan.g...@gmail.com> wrote:

> Javascript does not have classes, true. Javascript does have instance
> variables, and does have static members (where in the world are you getting
> this stuff). You're kind of saying "javascript is not object oriented",
> which it is. Does javascript have instances? Yes, otherwise, what is this:
> "var blah = new Foo();"? Are the properties and methods that are unique to
> each instance called instance members? Yes. And what about those members
> that are shared across instances? What's another word for shared, in object
> oriented vernacular? Static. And what we're arguing about is the fact that

Your definition of "static" is what confused me. Why are you calling
shared instance members (where member is property/method) "static"?
Wiki, btw, clearly states that "... a static method cannot refer to a
specific instance of the class (i.e. it cannot refer to this, self,
Me, etc.)..." 
http://en.wikipedia.org/wiki/Method_(computer_scie...
That's pretty much what I wrote earlier about "static" members as
understood by majority - it's a member of constructor, not
constructor's prototype (as you refer to).

// constructor
function Person(name) {
  this.name = name;
  Person.count++;
};

// static property (defined directly on a constructor)
Person.count = 0;

// shared instance method
Person.prototype.say = function(message) {
  return this.name + ' says: ' + message;
}

Same goes for prototype.js

var Person = Class.create({
  // constructor
  initialize: function(name) {
    this.name = name;
    Person.count++;
  },
  // shared instance method
  say: function(message) {
    return this.name + ' says: ' + message;
  }
});

// static property
Person.count = 0;

-- kangax
Posted by Ryan Gahl (Guest)
on 2008-07-04 04:29
(Received via mailing list)
>
> Why are you calling
> shared instance members (where member is property/method) "static"?


Sorry, that's not what I meant to say. If you read my blog post (
http://www.someelement.com/2007/03/multiple-inheri...)
- I explain what I mean by "prototype-static".

Ok, let's look at your example:

// constructor
>  return this.name + ' says: ' + message;
> }


(btw, you forgot a semicolon there  - and yes I'm pedantic when it comes 
to
missing semicolons :))

So... what I mean by "prototype static" is the fact that after that last
line it is now possible to call "Person.prototype.say("blah")" 
statically
(i.e. without having an instance) -- and of course get an error. What I 
mean
by "instance only" members, is any member that is ONLY visible from
instances, period. And of course true private variables and methods is
another thing I was talking about.

meh... nevermind :)
Posted by Jerod Venema (Guest)
on 2008-07-04 04:59
(Received via mailing list)
On Thu, Jul 3, 2008 at 10:28 PM, Ryan Gahl <ryan.gahl@gmail.com> wrote:

> // constructor
>>  return this.name + ' says: ' + message;
>> }
>
>
> (btw, you forgot a semicolon there  - and yes I'm pedantic when it comes to
> missing semicolons :))
>

<sigh> If you only knew HOW pedantic... :-D

>
>
> >
>


--
Jerod Venema
Senior Software Engineer
Nth Penguin, LLC
http://www.nthpenguin.com
(919) 368-5105
---
WebWidgetry.com / MashupStudio.com
Future Home of the World's First Complete Web Platform
This topic is locked and can not be replied to.