[Prototype-core] Re: Class.create() and method binding

2007-05-11 Thread Ryan Gahl
Dan, check out my blog: http://www.someelement.com - I have only 2 relevant
posts, but in both of them I discuss some things that you may find
interesting about implementing a classical model in javascript, without
sacrificing the power of being able to "do what you want when you want" that
javascript gives. Namely, using a true private/public method model...

You're right though, experienced js programmers expect to have to track and
correct scope issues manually, and IMHO it's not that hard... and if this
starts being handled automatically you lose flexibility, as mentioned, for
edge cases.

On 5/11/07, Dan Webb <[EMAIL PROTECTED]> wrote:
>
>
> > > I wasn't being very clear -- sorry.  Those first two examples
> > > illustrate what would happen if we implemented *both* the stuff in the
> > > events branch as it is now *and* Dan's proposal to bind class methods
> > > automatically.
> >
> > Right! It is exactly where the magic bites.
>
> Heh, maybe your right.  I think, as a JS programmer, that having to
> bind functions manually is what you expect to do but as a beginner it
> isn't but I suppose there's no point in confusing matters for
> experienced JS programmers.  In the example here (where this is
> normally the element but if you pass in the a Class instance its bound
> to the object) I quite like how it works actually but each to their
> own.  I still think it would be nicer if Class.create() actually
> created something that acted like a class from a class based language
> rather than just being a normal contructor.
>
> On that point about base: base.js doesn't bind methods but it does
> wrap every method to allow access to its super classes version of the
> method which is going to introduce even more of a performance overhead
> but hasn't been a problem in my experience.
>
> >
>


-- 
Ryan Gahl
Principal, Manager
Nth Penguin, LLC - Consulting
http://www.nthpenguin.com
--
Software Architect
WebWidgetry.com / MashupStudio.com
Future Home of the World's First Complete Web Platform
--
Inquire: 1-262-951-6727
Blog: http://www.someElement.com

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-11 Thread Dan Webb

> > I wasn't being very clear -- sorry.  Those first two examples
> > illustrate what would happen if we implemented *both* the stuff in the
> > events branch as it is now *and* Dan's proposal to bind class methods
> > automatically.
>
> Right! It is exactly where the magic bites.

Heh, maybe your right.  I think, as a JS programmer, that having to
bind functions manually is what you expect to do but as a beginner it
isn't but I suppose there's no point in confusing matters for
experienced JS programmers.  In the example here (where this is
normally the element but if you pass in the a Class instance its bound
to the object) I quite like how it works actually but each to their
own.  I still think it would be nicer if Class.create() actually
created something that acted like a class from a class based language
rather than just being a normal contructor.

On that point about base: base.js doesn't bind methods but it does
wrap every method to allow access to its super classes version of the
method which is going to introduce even more of a performance overhead
but hasn't been a problem in my experience.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-11 Thread Mislav Marohnić
On 5/10/07, Andrew Dupont <[EMAIL PROTECTED]> wrote:
>
>
> > The new Event code binds whatever it gets in IE to someElement. It
> doesn't
> > know anything about Foo.
>
> I wasn't being very clear -- sorry.  Those first two examples
> illustrate what would happen if we implemented *both* the stuff in the
> events branch as it is now *and* Dan's proposal to bind class methods
> automatically.


Right! It is exactly where the magic bites.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-11 Thread Ryan Gahl

It's definitely not being cast off... Just scrutinized :-)

-Original Message-
From: "Dan Webb" <[EMAIL PROTECTED]>
To: prototype-core@googlegroups.com
Sent: 5/10/2007 11:52 AM
Subject: [Prototype-core] Re: Class.create() and method binding


> No, seriously - how often do people copy instance methods around? Is the
> minority really enough to justify the mass binding on each instance
> creation? How about solving the problem in a real way, by realizing what
> you're doing an compensating for that:
>
> func = a.showA.bind(a)

People do copy methods around without knowing it all the time: when
assigning event handlers and using the enumerable methods most notably
and this always causes confusion.  Perhaps I didn't give real enough
examples.  MANY people try to do things like this and get very
confused:

var w = new MyWidget();

$('my_el').observe('click', w.someMethod);

then find that this has changed in the context of the event handler.
This is by no means an edge case: It happens all the time.  Even when
you know that this is the case and know about bind() it get really
ugly as you find lots of places where you need bind and this would
clean up a lot of those.

My main point is that Class.create() does not create what anyone
thinks of as a class.  It's sort of looks like one but doesn't do
anything that classes do.  Why not make it behave more like a class?
In Java, Ruby and just about all class-based languages methods have a
binding to their instance.  This would be mimicking that behavior.

Plus, if you want the unbound version of the method you can get it
from the prototype.

I really don't think it's such a bad idea and I'm slightly surprised
that you immediately cast it off.




--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Andrew Dupont

> Would it? ;)
>
> The new Event code binds whatever it gets in IE to someElement. It doesn't
> know anything about Foo.

I wasn't being very clear -- sorry.  Those first two examples
illustrate what would happen if we implemented *both* the stuff in the
events branch as it is now *and* Dan's proposal to bind class methods
automatically.


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Mislav Marohnić
On 5/10/07, Andrew Dupont <[EMAIL PROTECTED]> wrote:
>
>
> ...but calling
>
>   Event.observe(someElement, 'click', Foo.bar);
>
> (where bar is a function) would fire the event in Foo's scope.


Would it? ;)

The new Event code binds whatever it gets in IE to someElement. It doesn't
know anything about Foo.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Andrew Dupont


Dan Webb wrote:
> > It's not a bad cause, I just think the solution is a performance eater.
> > Imagine: the loop runs on every object instantiation. It wraps every
> > function inside another and it needs $A for that. After that, every function
> > call internally calls another, triggering $A one more time. To me it's a
> > terrible waste considering the total number of objects and their respective
> > instance method calls. And for what, solving event handling gotchas? Surely
> > we could do some implicit binding only in places where it makes sense (for
> > instance in the Event or Ajax modules for some operations).
>
> Yeah, your right on that point.  It was my main concern.  It could be
> streamlined a fair bit though (getting rid of $A would be fine) and I
> wondered how many classes that are created with Class.create() really
> get instantiated in a typical project.  I'm interested to see the
> impact it does have...I'll write some tests.  I think you're right
> though, it's probably not going to be worth the performance hit.
> Saying that, I use base.js quite a bit which wraps functions in quite
> a bit of code and I've not noticed the performance hit.

My objection is not the performance hit -- it's violation of POLS.
(Even though I do feel the pain this is meant to address.)

The refurbished system in the events branch corrects scope
automatically in IE, so that "this" refers to the element that
received the action. This means that calling

  Event.observe(someElement, 'click', foo);

(where foo is a function) would fire the event in someElement's scope,
but calling

  Event.observe(someElement, 'click', Foo.bar);

(where bar is a function) would fire the event in Foo's scope.

I think that events firing in class scope should remain opt-in,
whether through the existing `bind`:

  Event.observe(someElement, 'click', Foo.bar.bind(Foo));

or through an extra argument:

  Event.observe(someElement, 'click', Foo.bar, Foo);

I prefer the latter, since it'd deprecate the useCapture argument
(which won't work in IE, so we shouldn't expose it).

In JavaScript, context binds in execution scope, not definition scope
(though this will change for classes in ES4). I think we'd be stepping
into a minefield if we introduced new "magic" conventions for what
"this" means on any given line of code. It's hard enough to keep track
of already.

Cheers,
Andrew


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Mislav Marohnić
On 5/10/07, Dan Webb <[EMAIL PROTECTED]> wrote:
>
>
> Yeah, your right on that point.  It was my main concern.  It could be
> streamlined a fair bit though (getting rid of $A would be fine)


Of course. $As aren't needed in this case.

Saying that, I use base.js quite a bit which wraps functions in quite
> a bit of code and I've not noticed the performance hit.


Base *does* this?

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Dan Webb

> It's not a bad cause, I just think the solution is a performance eater.
> Imagine: the loop runs on every object instantiation. It wraps every
> function inside another and it needs $A for that. After that, every function
> call internally calls another, triggering $A one more time. To me it's a
> terrible waste considering the total number of objects and their respective
> instance method calls. And for what, solving event handling gotchas? Surely
> we could do some implicit binding only in places where it makes sense (for
> instance in the Event or Ajax modules for some operations).

Yeah, your right on that point.  It was my main concern.  It could be
streamlined a fair bit though (getting rid of $A would be fine) and I
wondered how many classes that are created with Class.create() really
get instantiated in a typical project.  I'm interested to see the
impact it does have...I'll write some tests.  I think you're right
though, it's probably not going to be worth the performance hit.
Saying that, I use base.js quite a bit which wraps functions in quite
a bit of code and I've not noticed the performance hit.

Having scope stuff in observe is a very worthwhile and for the sake of
compatibility with new versions of JS you should be able to pass an
optional scope as the final argument to all of the enumerable
functions.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Mislav Marohnić
On 5/10/07, Dan Webb <[EMAIL PROTECTED]> wrote:
>
>
> People do copy methods around without knowing it all the time: when
> assigning event handlers and using the enumerable methods most notably
> and this always causes confusion.


Well, that's why we have bindAsEventListener(). I know it's a bit verbose -
YUI does it internally, depending on an optional boolean attribute. Maybe we
should do something like this in new Event stuff.

I really don't think it's such a bad idea and I'm slightly surprised
> that you immediately cast it off.


It's not a bad cause, I just think the solution is a performance eater.
Imagine: the loop runs on every object instantiation. It wraps
everyfunction inside another and it needs $A for that. After that,
every function
call internally calls another, triggering $A one more time. To me it's a
terrible waste considering the total number of objects and their respective
instance method calls. And for what, solving event handling gotchas? Surely
we could do some implicit binding only in places where it makes sense (for
instance in the Event or Ajax modules for some operations).

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Dan Webb

> No, seriously - how often do people copy instance methods around? Is the
> minority really enough to justify the mass binding on each instance
> creation? How about solving the problem in a real way, by realizing what
> you're doing an compensating for that:
>
> func = a.showA.bind(a)

People do copy methods around without knowing it all the time: when
assigning event handlers and using the enumerable methods most notably
and this always causes confusion.  Perhaps I didn't give real enough
examples.  MANY people try to do things like this and get very
confused:

var w = new MyWidget();

$('my_el').observe('click', w.someMethod);

then find that this has changed in the context of the event handler.
This is by no means an edge case: It happens all the time.  Even when
you know that this is the case and know about bind() it get really
ugly as you find lots of places where you need bind and this would
clean up a lot of those.

My main point is that Class.create() does not create what anyone
thinks of as a class.  It's sort of looks like one but doesn't do
anything that classes do.  Why not make it behave more like a class?
In Java, Ruby and just about all class-based languages methods have a
binding to their instance.  This would be mimicking that behavior.

Plus, if you want the unbound version of the method you can get it
from the prototype.

I really don't think it's such a bad idea and I'm slightly surprised
that you immediately cast it off.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Mislav Marohnić
On 5/10/07, Ryan Gahl <[EMAIL PROTECTED]> wrote:
>
> Yeah. What if I want to copy the instance method somewhere else, but I
> > want it to change scope? If it was bound that I can't bind it to anything
> > else. So it's a potential blocker in some cases.
>
>
> Just what I was saying...
>

Mine had less underscores and uppercase :)

I'm kidding - I just realized that you've said the same, when you pointed it
out ...

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Ryan Gahl
>
> Yeah. What if I want to copy the instance method somewhere else, but I
> want it to change scope? If it was bound that I can't bind it to anything
> else. So it's a potential blocker in some cases.


Just what I was saying...

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Mislav Marohnić
On 5/10/07, Dan Webb <[EMAIL PROTECTED]> wrote:
>
>
> Any good?
>

It's awful :P

No, seriously - how often do people copy instance methods around? Is the
minority really enough to justify the mass binding on each instance
creation? How about solving the problem in a real way, by realizing what
you're doing an compensating for that:

func = a.showA.bind(a)

In my opinion, if you're doing something weird then go ahead, just be aware
of the scope change and know how to handle it.

Any problems Im not thinking of?


Yeah. What if I want to copy the instance method somewhere else, but I want
it to change scope? If it was bound that I can't bind it to anything else.
So it's a potential blocker in some cases.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Class.create() and method binding

2007-05-10 Thread Ryan Gahl
Interesting idea, and I'd have to really reflect on this... but my initial
reaction is that it is actually somewhat limiting. Here's what I mean...

In some edge cases it may desirable to use an instance method and bind it to
_some_other_ object. This would certainly be considered "clever" and I can't
think of any concrete cases right now, but I know with the way things are
now it _possible_ if needed. Under this system you would be limiting the
scope binding to only a single instance. I know what you're saying, in that
that IS how traditional classes should be. HOWEVER, one of the things that
makes js development so powerful is this dynamic nature, and the ability to
do things like that when you need to. If this ability starts getting removed
in a core layer of a major abstraction library like prototype, I think it
may have potential to be a "bad thing".

...but that's just my initial reaction. Definitely seems like a reasonable
thing for someone to propose though. I'll be interested to see how this one
plays out...



On 5/10/07, Dan Webb <[EMAIL PROTECTED]> wrote:
>
>
> Hello Everyone,
>
> Just had an idea for a possible enhancement to Class.create() that I
> wanted to float with y'all.   Here's the preamble:
>
> From knocking around on mailing lists / IRC etc it seems that by far
> the most irritating problem for most new JS library users is the idea
> that, in JS, methods of objects have no inherent binding to the object
> they are attached to so if you do something like this:
>
> Car = Class.create();
> Object.extend(Car.prototype, {
> initialize : function(a) {
>this.a = a;
> },
> showA : function() {
>console.log(this.a);
> }
> });
>
> This gives the 'expected' result:
>
> a = new Car(7);
> a.showA(); //=> 7
>
> But this doesn't:
>
> func = a.showA
> func(); //=> undefined
>
> This is always a problem inside event handlers and the enumerable
> functions and of course the way to stop it is to use bind().  But I
> think possibly that a point of confusion in Prototype particularly
> that if you use Class.create() you expect a thing that acts like a
> class which it of course doesn't.  So
>
> How about this:
>
> Class = {};
> Class.create = function() {
> return function() {
>this.initialize.apply(this, arguments);
>
>for (var prop in this)
>  if (typeof this[prop] == 'function')
>this[prop] = this[prop].bind(this);
> };
> }
>
> Which also binds methods of the object to the object itself
> automatically so you can point event handlers etc straight to methods
> of objects and they remain bound?
>
> Any good?  Any problems Im not thinking of?
>
>
>
> --
> Dan Webb
> http://www.danwebb.net
>
> Event Wax (http://www.eventwax.com)
>
> >
>


-- 
Ryan Gahl
Principal, Manager
Nth Penguin, LLC - Consulting
http://www.nthpenguin.com
--
Software Architect
WebWidgetry.com / MashupStudio.com
Future Home of the World's First Complete Web Platform
--
Inquire: 1-262-951-6727
Blog: http://www.someElement.com

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---