It would be great if I could accomplish the following (I understand it may involve changing parts of protoype.js to achieve this). Any help appreciated as always. I want to be able to hook and event that get fired whenever a method on a class gets called (before or after the method is called, doesn''t matter which). something like: Event.observe("class:method", function(event) { // do something }); Now I understand that you can fire ''custom'' events: window.fire("class:method", { blah: 0 }); what I''m looking for is where in prototype.js I could a hook that would fire such an event passing the class and method as above whenever a method on one of my classes is called. Make sense? No idea if it''s even possible but would be great for what I''m doing... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
It would be great if I could accomplish the following (I understand it may involve changing parts of protoype.js to achieve this). Any help appreciated as always. I want to be able to hook an event that gets fired whenever a method on a class gets called (before or after the method is called, doesn''t matter which). something like: Event.observe("class:method", function(event) { // do something }); Now I understand that you can fire ''custom'' events: window.fire("class:method", { blah: 0 }); what I''m looking for is where in prototype.js I could insert a hook that would fire such an event passing the class and method as in the code above, whenever a method on one of my classes is called. Make sense? No idea if it''s even possible but would be great for what I''m doing... --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
GarethAtFlignet a écrit :> Event.observe("class:method", function(event) { > // do something > });Yes, except you need to observe on a DOM node, so you''d insert, say, document as a first argument.> Now I understand that you can fire ''custom'' events: > window.fire("class:method", { blah: 0 });Almost. "fire" exists only on DOM elements and the document node, so "document" instead of "window." The trick here is to take an existing method and turn it into the same method that also fires a custom event. That''s AOP, and in Prototype you can achieve that with the wrap method. Consider this: YourClass.prototype.yourMethod = YourClass.prototype.yourMethod.wrap( function(proceed, arg1, arg2) { document.fire(''your:event''); proceed(arg1, arg2); } ); Then whenever one of your instances of YourClass gets its yourMethod called (assuming here it takes two arguments, but customize for your case), it''ll delegate tot he original implementation and fire the ''your:event'' custom event on the document node. To trigger the event before the original behavior, just switch lines in the new function. You can also pass extra data as an additional object in 2nd argument to document.fire, which will be accessible through the event''s memo property. To listen for the event: document.observe(''your:event'', function(event) { ... }); ''HTH -- Christophe Porteneuve aka TDD tdd-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
WOW thanks looks like oyu''ve given me just what I wanted. On Jan 20, 10:51 am, Christophe Porteneuve <t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org> wrote:> GarethAtFlignet a écrit : > > > Event.observe("class:method", function(event) { > > // do something > > }); > > Yes, except you need to observe on a DOM node, so you''d insert, say, > document as a first argument. > > > Now I understand that you can fire ''custom'' events: > > window.fire("class:method", { blah: 0 }); > > Almost. "fire" exists only on DOM elements and the document node, so > "document" instead of "window." > > The trick here is to take an existing method and turn it into the same > method that also fires a custom event. That''s AOP, and in Prototype you > can achieve that with the wrap method. Consider this: > > YourClass.prototype.yourMethod = YourClass.prototype.yourMethod.wrap( > function(proceed, arg1, arg2) { > document.fire(''your:event''); > proceed(arg1, arg2); > } > ); > > Then whenever one of your instances of YourClass gets its yourMethod > called (assuming here it takes two arguments, but customize for your > case), it''ll delegate tot he original implementation and fire the > ''your:event'' custom event on the document node. To trigger the event > before the original behavior, just switch lines in the new function. > > You can also pass extra data as an additional object in 2nd argument to > document.fire, which will be accessible through the event''s memo property. > > To listen for the event: > > document.observe(''your:event'', function(event) { ... }); > > ''HTH > > -- > Christophe Porteneuve aka TDD > t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
On Sunday 20 January 2008, Christophe Porteneuve wrote:> The trick here is to take an existing method and turn it into the > same method that also fires a custom event. That''s AOP, and in > Prototype you can achieve that with the wrap method.No, it''s not. Function#wrap is very convenient, but it is not AOP. If anything, it is method combination[1], a forerunner of AOP that predates it by some 10 or 20 years. An essential part of AOP is quantification over join points, meaning you can express things like this - Wrap a function around (or before, after) *all* functions (methods) of a parcticular class. - Execute a function around (or before, after) any call to a specific function that happens within a particular module. - Execute a function around (or before, after) any call to a specific function that is called within or somewhere below another given function. My purpose here is twofold. For one thing, I detest the dilution of terminology. More importantly, I thing it''s doing people a disservice telling them that Function#wrap (around method combination) is all there is to AOP; there is more to be had, indeed, more to be wanted, and good reason not to be content with just #wrap. Michael [1] http://www.lisp.org/HyperSpec/Body/glo_m.html#method_combination [2] http://en.wikipedia.org/wiki/Aspect-oriented_programming -- Michael Schuerig mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org http://www.schuerig.de/michael/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Michael Schuerig a écrit :>> same method that also fires a custom event. That''s AOP, and in >> Prototype you can achieve that with the wrap method. > > No, it''s not. Function#wrap is very convenient, but it is not AOP. If > anything, it is method combination[1], a forerunner of AOP that > predates it by some 10 or 20 years.Agreed, but what''s with the cavalry charge? Doesn''t sound like your usual self, Michael… We''re not on an AOP list, and I therefore believe I don''t cause much harm nor should expect flames when I simplify and just don''t bother prefixing "AOP" with "akin to." We certainly have quite a few people on the list pretty keen on AOP (including members of Prototype Core), but there''s accurate and "accurate enough." So yes, okay, method wrapping (or combination, as you''ll have it) is but a part of what AOP can do, and does not defined AOP all by itself, to be sure. Still, it''s essential to it. At any rate, hey, relax Michael! I''m not all that sure that this flame added pragmatic value for the OP… Best, -- Christophe Porteneuve aka TDD tdd-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
AOP or not, grateful for the help as it solves out problem with regards client->server proeprty sync for our PHP widget framework. Thanks again Chris, and Michael many thanks for the AOP links. Looks like I could do with looking into AOP in more detail as "- Wrap a function around (or before, after) *all* functions (methods) of a parcticular class. " is exactly what we''re doing in this instance. Cheers Gareth On Jan 20, 5:30 pm, Christophe Porteneuve <t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org> wrote:> Michael Schuerig a écrit : > > >> same method that also fires a custom event. That''s AOP, and in > >> Prototype you can achieve that with the wrap method. > > > No, it''s not. Function#wrap is very convenient, but it is not AOP. If > > anything, it is method combination[1], a forerunner of AOP that > > predates it by some 10 or 20 years. > > Agreed, but what''s with the cavalry charge? Doesn''t sound like your > usual self, Michael... We''re not on an AOP list, and I therefore believe > I don''t cause much harm nor should expect flames when I simplify and > just don''t bother prefixing "AOP" with "akin to." > > We certainly have quite a few people on the list pretty keen on AOP > (including members of Prototype Core), but there''s accurate and > "accurate enough." > > So yes, okay, method wrapping (or combination, as you''ll have it) is but > a part of what AOP can do, and does not defined AOP all by itself, to be > sure. Still, it''s essential to it. At any rate, hey, relax Michael! > I''m not all that sure that this flame added pragmatic value for the OP... > > Best, > > -- > Christophe Porteneuve aka TDD > t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
On Sunday 20 January 2008, Christophe Porteneuve wrote:> Michael Schuerig a écrit : > >> same method that also fires a custom event. That''s AOP, and in > >> Prototype you can achieve that with the wrap method. > > > > No, it''s not. Function#wrap is very convenient, but it is not AOP. > > If anything, it is method combination[1], a forerunner of AOP that > > predates it by some 10 or 20 years. > > Agreed, but what''s with the cavalry charge? Doesn''t sound like your > usual self, Michael…Oh, you need an update on my usual self. I''ve recently been called intimidating on ror-talk. In that spirit, I really have to defend my new-won reputation. Fear me! Would it help if I grew a beard like Ze^H^H Emperor Ming''s?> We certainly have quite a few people on the list pretty keen on AOP > (including members of Prototype Core), but there''s accurate and > "accurate enough."First of all, even if I have send the cavalry (yes, admittedly I have), it''s not stampeding at you or anyone else personally.> So yes, okay, method wrapping (or combination, as you''ll have it) is > but a part of what AOP can do, and does not defined AOP all by > itself, to be sure. Still, it''s essential to it. At any rate, hey, > relax Michael! I''m not all that sure that this flame added pragmatic > value for the OP…Well, if the OP remembers that there''s more to AOP than what wrap does, I consider myself successful. In the best of all possible worlds, someone, possibly even from Prototoype Core, would come forth with a full-blown, Prototype-based AOP implementation. Michael -- Michael Schuerig mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org http://www.schuerig.de/michael/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Michael Schuerig a écrit :> Well, if the OP remembers that there''s more to AOP than what wrap does, > I consider myself successful. In the best of all possible worlds, > someone, possibly even from Prototoype Core, would come forth with a > full-blown, Prototype-based AOP implementation.Perhaps you''d care to build one up and put it in Scripteka? :-) I''m sure Tobie would love to discuss the innards and philosophy of it with you :-) -- Christophe Porteneuve aka TDD tdd-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
On Sunday 20 January 2008, Christophe Porteneuve wrote:> Michael Schuerig a écrit : > > Well, if the OP remembers that there''s more to AOP than what wrap > > does, I consider myself successful. In the best of all possible > > worlds, someone, possibly even from Prototoype Core, would come > > forth with a full-blown, Prototype-based AOP implementation. > > Perhaps you''d care to build one up and put it in Scripteka? :-) I''m > sure Tobie would love to discuss the innards and philosophy of it > with you :-)I bet, but I think I pass on that opportunity. First and foremost because I don''t have a practical need for AOP in JavaScript right now. My client-side code is architecturally too simple to warrant using AOP. I tend to implement things just for the fun of it, but it is not the best recipe to come up with a robust and maintained library. Michael -- Michael Schuerig mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org http://www.schuerig.de/michael/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
We are using a very simple AOP implementation (that Samuel Lebeau has come up with) in Prototype UI. http://i.gotfresh.info/2007/12/7/advised-methods-for-javascript-with-prototype One relevant problem we are facing is how inconvenient it is to fire certain framework-level events. In the following example, we can''t fire custom event (''component:initialized'') from within parent constructor as it would lose all the semantic in a subclass. Letting subclasses fire events on their own (as an alternative solution) just doesn''t feel quite right. I''m guessing the best way would be to augment Class.create to "wrap" constructors, yet handle $super calls properly. UI.Component = Class.create(UI.Observable, { initialize: function(element) { this.element = element; // ... do some initialization this.fire(this.componentId + '':initialized''); } }) UI.Menu = Class.create(UI.Component, { initialize: function($super, element) { $super(element); // <= event is fired from within parent, royally messing things up ... // <= need to be fired in the end of execution } }) Best, kangax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
many thanks for that kangax, will definitely look at your AOP stuff. On Jan 21, 1:34 am, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> We are using a very simple AOP implementation (that Samuel Lebeau has > come up with) in Prototype UI.http://i.gotfresh.info/2007/12/7/advised-methods-for-javascript-with-... > > One relevant problem we are facing is how inconvenient it is to fire > certain framework-level events. In the following example, we can''t > fire custom event (''component:initialized'') from within parent > constructor as it would lose all the semantic in a subclass. Letting > subclasses fire events on their own (as an alternative solution) just > doesn''t feel quite right. I''m guessing the best way would be to > augment Class.create to "wrap" constructors, yet handle $super calls > properly. > > UI.Component = Class.create(UI.Observable, { > initialize: function(element) { > this.element = element; > // ... do some initialization > this.fire(this.componentId + '':initialized''); > } > > }) > > UI.Menu = Class.create(UI.Component, { > initialize: function($super, element) { > $super(element); // <= event is fired from within parent, royally > messing things up > ... > // <= need to be fired in the end of execution > } > > }) > > Best, > kangax--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Do you think that prototype''s custom event handling mechanism is suitable for handling an entire event-driven application? I have a large number of events which are fired by class methods. Currently I have some auxillary functions which all classes inherit that enable them to subscribe to and notify others about important events. I considered porting this functionality to make use of prototype 1.6''s custom event functionality, but I have run into some barriers and am wondering if it is even a good idea. Basically I want to have some methods fire events, and pass a reference to the parent class along. document.fire(''custom:event'', {firingWidget:widget}); An observer would then catch the custom event and respond, treating the event as if it were fired by the referenced class, and not by document, something like: document.observe(''custom:event'', onCustomEvent.bindAsEventListener(event.memo.firingWidget)); Does this look do-able? Furthermore, would it make sense to switch to using prototype''s custom events? The system works fine at the moment using it''s own observer-like event system, however, if prototype can fully support custom events now, it doesn''t seem like it is necessary to have a superclass just for event-handling functionality. Any advice or thoughts on the subject would be very much appreciated. :) Thanks! Keith On Jan 20, 5:51 am, Christophe Porteneuve <t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org> wrote:> GarethAtFlignet a écrit : > > > Event.observe("class:method", function(event) { > > // do something > > }); > > Yes, except you need to observe on a DOM node, so you''d insert, say, > document as a first argument. > > > Now I understand that you can fire ''custom'' events: > > window.fire("class:method", { blah: 0 }); > > Almost. "fire" exists only on DOM elements and the document node, so > "document" instead of "window." > > The trick here is to take an existing method and turn it into the same > method that also fires acustomevent. That''s AOP, and in Prototype you > can achieve that with the wrap method. Consider this: > > YourClass.prototype.yourMethod = YourClass.prototype.yourMethod.wrap( > function(proceed, arg1, arg2) { > document.fire(''your:event''); > proceed(arg1, arg2); > } > ); > > Then whenever one of your instances of YourClass gets its yourMethod > called (assuming here it takes two arguments, but customize for your > case), it''ll delegate tot he original implementation and fire the > ''your:event''customevent on the document node. To trigger the event > before the original behavior, just switch lines in the new function. > > You can also pass extra data as an additional object in 2nd argument to > document.fire, which will be accessible through the event''s memo property. > > To listen for the event: > > document.observe(''your:event'', function(event) { ... }); > > ''HTH > > -- > Christophe Porteneuve aka TDD > t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
#wrap is simply amazing. We can easily augment Class.create to make all of instance methods fire proper events ( e.g. "Class:method" ) Class.create = Class.create.wrap(function() { var args = $A(arguments), proceed = args.shift(), methods = args.last(), className = methods[''className''] || ''Klass''; for (var m in methods) { if (/initialize|className/.test(m)) continue; methods[m] = methods[m].wrap(function() { var _args = $A(arguments), _proceed = _args.shift(); console.log(className + '':'' + m); return _proceed.apply(_proceed, _args); }) } return proceed.apply(proceed, args); }) var Class1 = Class.create({ initialize: function() { }, className: ''Class1'', bar: function() { } }); var Class2 = Class.create({ initialize: function() { }, className: ''Class2'', baz: function() { } }); new Class1().bar(); // fires "Class1:bar" new Class2().baz(); // fires "Class2:baz" P.S. This is by no means a thorough solution, but rather a proof of concept... Best, kangax --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks for the reply. That looks like an interesting route of handling events, but not exactly what I had in mind. Ideally I would like to be able to just use Event#observe and Event#fire. It might be workable using wrap, but that would add a whole other layer of complexity that I hope to avoid. Thanks, Keith On Mar 2, 5:16 am, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> #wrap is simply amazing. We can easily augment Class.create to make > all of instance methods fire proper events ( e.g. "Class:method" ) > > Class.create = Class.create.wrap(function() { > var args = $A(arguments), > proceed = args.shift(), > methods = args.last(), > className = methods[''className''] || ''Klass''; > for (var m in methods) { > if (/initialize|className/.test(m)) continue; > methods[m] = methods[m].wrap(function() { > var _args = $A(arguments), _proceed = _args.shift(); > console.log(className + '':'' + m); > return _proceed.apply(_proceed, _args); > }) > } > return proceed.apply(proceed, args); > > }) > > var Class1 = Class.create({ > initialize: function() { }, > className: ''Class1'', > bar: function() { } > > }); > > var Class2 = Class.create({ > initialize: function() { }, > className: ''Class2'', > baz: function() { } > > }); > > new Class1().bar(); // fires "Class1:bar" > new Class2().baz(); // fires "Class2:baz" > > P.S. This is by no means a thorough solution, but rather a proof of > concept... > > Best, > kangax--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
To give another example of what I was thinking, using YUI''s custom event object (just an example..) you can do: // Begin Code... var Puppy = Class.create(); //Create and a custom event document.barkEvent = new YAHOO.util.CustomEvent("puppyBark", this); Puppy.prototype = { initialize: function (name) { this.name = name; }, bark: function () { console.log(this.name + ": Woof!"); //Fire event document.barkEvent.fire(this); } } var Kitten = Class.create(); Kitten.prototype = { initialize: function (name) { this.name = name; //Subscripe to bark event document.barkEvent.subscribe(this.onBark, this); }, onBark: function (type, args, me) { console.log(me.name + ": Why hello der" + args[0].name + " !"); } } //Test: var otis = new Puppy("Otis"); var milo = new Kitten("Milo"); otis.bark(); // End Code... ---------- OUTPUT ------------ Otis: Woof! Milo: Why hello der Otis! -------------------------------------- -Keith On Mar 4, 2:07 pm, Keith <keith.hugh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Thanks for the reply. That looks like an interesting route of handling > events, but > not exactly what I had in mind. Ideally I would like to be able to > just use Event#observe > and Event#fire. It might be workable using wrap, but that would add a > whole other > layer of complexity that I hope to avoid. > > Thanks, > Keith > > On Mar 2, 5:16 am, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > #wrap is simply amazing. We can easily augment Class.create to make > > all of instance methods fire proper events ( e.g. "Class:method" ) > > > Class.create = Class.create.wrap(function() { > > var args = $A(arguments), > > proceed = args.shift(), > > methods = args.last(), > > className = methods[''className''] || ''Klass''; > > for (var m in methods) { > > if (/initialize|className/.test(m)) continue; > > methods[m] = methods[m].wrap(function() { > > var _args = $A(arguments), _proceed = _args.shift(); > > console.log(className + '':'' + m); > > return _proceed.apply(_proceed, _args); > > }) > > } > > return proceed.apply(proceed, args); > > > }) > > > var Class1 = Class.create({ > > initialize: function() { }, > > className: ''Class1'', > > bar: function() { } > > > }); > > > var Class2 = Class.create({ > > initialize: function() { }, > > className: ''Class2'', > > baz: function() { } > > > }); > > > new Class1().bar(); // fires "Class1:bar" > > new Class2().baz(); // fires "Class2:baz" > > > P.S. This is by no means a thorough solution, but rather a proof of > > concept... > > > Best, > > kangax--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Keith, that''s very simple: var Puppy = Class.create({ initialize: function(name) { this.name = name; }, bark: function () { console.log(this.name + ": Woof!"); document.fire(''puppy:bark'', { name: this.name }); } }); var Kitten = Class.create({ initialize: function (name) { this.name = name; document.observe(''puppy:bark'', this.onBark.bindAsEventListener(this)); }, onBark: function (e) { console.log(this.name + ": Why hello der " + e.memo.name + " !"); } }); var otis = new Puppy("Otis"); var milo = new Kitten("Milo"); otis.bark(); /* Otis: Woof! Milo: Why hello der Otis ! */ Best, kangax On Mar 4, 4:36 pm, Keith <keith.hugh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> To give another example of what I was thinking, using YUI''s custom > event object (just an example..) you can do: > > // Begin Code... > > var Puppy = Class.create(); > > //Create and a custom event > document.barkEvent = new YAHOO.util.CustomEvent("puppyBark", this); > > Puppy.prototype = { > initialize: function (name) { > this.name = name; > }, > bark: function () { > console.log(this.name + ": Woof!"); > > //Fire event > document.barkEvent.fire(this); > } > } > > var Kitten = Class.create(); > > Kitten.prototype = { > initialize: function (name) { > this.name = name; > > //Subscripe to bark event > document.barkEvent.subscribe(this.onBark, this); > }, > > onBark: function (type, args, me) { > console.log(me.name + ": Why hello der" + args[0].name + " !"); > } > } > > //Test: > var otis = new Puppy("Otis"); > var milo = new Kitten("Milo"); > > otis.bark(); > > // End Code... > > ---------- OUTPUT ------------ > Otis: Woof! > Milo: Why hello der Otis! > -------------------------------------- > > -Keith > > On Mar 4, 2:07 pm, Keith <keith.hugh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Thanks for the reply. That looks like an interesting route of handling > > events, but > > not exactly what I had in mind. Ideally I would like to be able to > > just use Event#observe > > and Event#fire. It might be workable using wrap, but that would add a > > whole other > > layer of complexity that I hope to avoid. > > > Thanks, > > Keith > > > On Mar 2, 5:16 am, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > #wrap is simply amazing. We can easily augment Class.create to make > > > all of instance methods fire proper events ( e.g. "Class:method" ) > > > > Class.create = Class.create.wrap(function() { > > > var args = $A(arguments), > > > proceed = args.shift(), > > > methods = args.last(), > > > className = methods[''className''] || ''Klass''; > > > for (var m in methods) { > > > if (/initialize|className/.test(m)) continue; > > > methods[m] = methods[m].wrap(function() { > > > var _args = $A(arguments), _proceed = _args.shift(); > > > console.log(className + '':'' + m); > > > return _proceed.apply(_proceed, _args); > > > }) > > > } > > > return proceed.apply(proceed, args); > > > > }) > > > > var Class1 = Class.create({ > > > initialize: function() { }, > > > className: ''Class1'', > > > bar: function() { } > > > > }); > > > > var Class2 = Class.create({ > > > initialize: function() { }, > > > className: ''Class2'', > > > baz: function() { } > > > > }); > > > > new Class1().bar(); // fires "Class1:bar" > > > new Class2().baz(); // fires "Class2:baz" > > > > P.S. This is by no means a thorough solution, but rather a proof of > > > concept... > > > > Best, > > > kangax--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Yes, all this is do-able. The only part that seems unusual to me is this: document.observe(''custom:event'', onCustomEvent.bindAsEventListener(event.memo.firingWidget)); If you want the scope correction to happen "automatically," this won''t do it -- the "event" variable you''re trying to read from doesn''t exist except within the scope of the handling function. If you want to extract the general pattern of firing an event handler in the scope of a custom property set on the event, you can do something like this: Function.customEventScope = function(fn) { return function() { return fn.apply(arguments[0].memo.firingWidget, arguments); }; }; Then, in your class... document.observe(''custom:event'', Function.customEventScope(onCustomEvent)); Now, this is all do-able, but I wonder if it''s necessary, since you say you''ve got a solution already working. If you were building it from scratch, this is a great way to get extra mileage out of the custom event system. But it is somewhat awkward nonetheless. Cheers, Andrew On Feb 29, 8:33 am, Keith Hughitt <keith.hugh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Do you think that prototype''s custom event handling mechanism is > suitable for handling an > entire event-driven application? > > I have a large number of events which are fired by class methods. > Currently I have > some auxillary functions which all classes inherit that enable them to > subscribe to > and notify others about important events. > > I considered porting this functionality to make use of prototype 1.6''s > custom event functionality, > but I have run into some barriers and am wondering if it is even a > good idea. > > Basically I want to have some methods fire events, and pass a > reference to the parent class along. > > document.fire(''custom:event'', {firingWidget:widget}); > > An observer would then catch the custom event and respond, treating > the event as if it > were fired by the referenced class, and not by document, something > like: > > document.observe(''custom:event'', > onCustomEvent.bindAsEventListener(event.memo.firingWidget)); > > Does this look do-able? Furthermore, would it make sense to switch to > using prototype''s custom events? > The system works fine at the moment using it''s own observer-like event > system, however, if prototype > can fully support custom events now, it doesn''t seem like it is > necessary to have a superclass just for event-handling > functionality. > > Any advice or thoughts on the subject would be very much > appreciated. :) > > Thanks! > Keith > > On Jan 20, 5:51 am, Christophe Porteneuve <t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org> wrote: > > > GarethAtFlignet a écrit : > > > > Event.observe("class:method", function(event) { > > > // do something > > > }); > > > Yes, except you need to observe on a DOM node, so you''d insert, say, > > document as a first argument. > > > > Now I understand that you can fire ''custom'' events: > > > window.fire("class:method", { blah: 0 }); > > > Almost. "fire" exists only on DOM elements and the document node, so > > "document" instead of "window." > > > The trick here is to take an existing method and turn it into the same > > method that also fires acustomevent. That''s AOP, and in Prototype you > > can achieve that with the wrap method. Consider this: > > > YourClass.prototype.yourMethod = YourClass.prototype.yourMethod.wrap( > > function(proceed, arg1, arg2) { > > document.fire(''your:event''); > > proceed(arg1, arg2); > > } > > ); > > > Then whenever one of your instances of YourClass gets its yourMethod > > called (assuming here it takes two arguments, but customize for your > > case), it''ll delegate tot he original implementation and fire the > > ''your:event''customevent on the document node. To trigger the event > > before the original behavior, just switch lines in the new function. > > > You can also pass extra data as an additional object in 2nd argument to > > document.fire, which will be accessible through the event''s memo property. > > > To listen for the event: > > > document.observe(''your:event'', function(event) { ... }); > > > ''HTH > > > -- > > Christophe Porteneuve aka TDD > > t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Thank you kangax and Andrew for the responses. I now have a much better grasp of the custom events system in Prototype 1.6. I think that for the time being the best route is to stick with the current Event- handling system. To make use of prototype''s custom events is do-able, but would indeed add another level of complexity, which defeats my original intentions for using them. Thanks for all of your help and patience. Take care, Keith On Mar 4, 11:08 pm, Andrew Dupont <goo...-TiabPMV39B5K4mp1Ns0Z8Q@public.gmane.org> wrote:> Yes, all this is do-able. The only part that seems unusual to me is > this: > > document.observe(''custom:event'', > onCustomEvent.bindAsEventListener(event.memo.firingWidget)); > > If you want the scope correction to happen "automatically," this won''t > do it -- the "event" variable you''re trying to read from doesn''t exist > except within the scope of the handling function. > > If you want to extract the general pattern of firing an event handler > in the scope of a custom property set on the event, you can do > something like this: > > Function.customEventScope = function(fn) { > return function() { > return fn.apply(arguments[0].memo.firingWidget, arguments); > }; > > }; > > Then, in your class... > > document.observe(''custom:event'', > Function.customEventScope(onCustomEvent)); > > Now, this is all do-able, but I wonder if it''s necessary, since you > say you''ve got a solution already working. If you were building it > from scratch, this is a great way to get extra mileage out of the > custom event system. But it is somewhat awkward nonetheless. > > Cheers, > Andrew > > On Feb 29, 8:33 am, Keith Hughitt <keith.hugh...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Do you think that prototype''s custom event handling mechanism is > > suitable for handling an > > entire event-driven application? > > > I have a large number of events which are fired by class methods. > > Currently I have > > some auxillary functions which all classes inherit that enable them to > > subscribe to > > and notify others about important events. > > > I considered porting this functionality to make use of prototype 1.6''s > > custom event functionality, > > but I have run into some barriers and am wondering if it is even a > > good idea. > > > Basically I want to have some methods fire events, and pass a > > reference to the parent class along. > > > document.fire(''custom:event'', {firingWidget:widget}); > > > An observer would then catch the custom event and respond, treating > > the event as if it > > were fired by the referenced class, and not by document, something > > like: > > > document.observe(''custom:event'', > > onCustomEvent.bindAsEventListener(event.memo.firingWidget)); > > > Does this look do-able? Furthermore, would it make sense to switch to > > using prototype''s custom events? > > The system works fine at the moment using it''s own observer-like event > > system, however, if prototype > > can fully support custom events now, it doesn''t seem like it is > > necessary to have a superclass just for event-handling > > functionality. > > > Any advice or thoughts on the subject would be very much > > appreciated. :) > > > Thanks! > > Keith > > > On Jan 20, 5:51 am, Christophe Porteneuve <t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org> wrote: > > > > GarethAtFlignet a écrit : > > > > > Event.observe("class:method", function(event) { > > > > // do something > > > > }); > > > > Yes, except you need to observe on a DOM node, so you''d insert, say, > > > document as a first argument. > > > > > Now I understand that you can fire ''custom'' events: > > > > window.fire("class:method", { blah: 0 }); > > > > Almost. "fire" exists only on DOM elements and the document node, so > > > "document" instead of "window." > > > > The trick here is to take an existing method and turn it into the same > > > method that also fires acustomevent. That''s AOP, and in Prototype you > > > can achieve that with the wrap method. Consider this: > > > > YourClass.prototype.yourMethod = YourClass.prototype.yourMethod.wrap( > > > function(proceed, arg1, arg2) { > > > document.fire(''your:event''); > > > proceed(arg1, arg2); > > > } > > > ); > > > > Then whenever one of your instances of YourClass gets its yourMethod > > > called (assuming here it takes two arguments, but customize for your > > > case), it''ll delegate tot he original implementation and fire the > > > ''your:event''customevent on the document node. To trigger the event > > > before the original behavior, just switch lines in the new function. > > > > You can also pass extra data as an additional object in 2nd argument to > > > document.fire, which will be accessible through the event''s memo property. > > > > To listen for the event: > > > > document.observe(''your:event'', function(event) { ... }); > > > > ''HTH > > > > -- > > > Christophe Porteneuve aka TDD > > > t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---