J. Gregory Wright
2008-Mar-05 18:12 UTC
Template#evaluate and attributes that resolve to functions?
If I have [admittedly simple] code as follows: MyClass = Class.create({ _a: false, _ b: false, _c: false, initialize: function(a, b, c) { this._a = a; this._b = b; this._c = c; }, first: function(){ return this._a; }, second: function(){ return this._b; }, third: function(){ return this._c; } }); var myObj = new MyClass(''A'',''B'',''C''); var myTmpl = new Template(''First: #{first}, Second: #{second}, Third: #{third}''); var myOut = myTmpl.evaluate(myObj); Then the string value placed in myOut will not be: "First: A, Second: B, Third: C" but rather will be: "First: function(){ return this._a; }, Second: function(){ return this._b; }, Third:function(){ return this._c; }" Based on the code for Template#evaluate, it would seem that the line: return before + String(ctx); could be replaced by: return before + (Object.isFunction(ctx)) ? ctx.apply(object) : String(ctx); and produce [the/my] desired effect of rendering the return value from the function instead of the function literal. Is there a reason why this would not be workable, or should not be done? Thanks in advance, G --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Christophe Porteneuve
2008-Mar-05 19:27 UTC
Re: Template#evaluate and attributes that resolve to functions?
Hey, Check out the following ticket: http://dev.rubyonrails.org/ticket/8166 You''ll find the patch you need. Advanced, function-including evaluation was deemed "too much" for the core trunk, but it can be done (and more, like nesting) :-) -- 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 -~----------~----~----~----~------~----~------~--~---
kangax
2008-Mar-05 19:34 UTC
Re: Template#evaluate and attributes that resolve to functions?
Interesting. Actually String( ) already acts as a sort of a delegator by invoking toString( ) on whatever you pass into it. It''s actually quite flexible - we can *redefine* toString on any object and make it return anything we want. Checking for type (as you propose) just seems a little too limiting to me. Take a look at how easy the implementation is: (by redefining native "toString" on instance methods to return curried versions of themselves) ... var myObj = new MyClass(''A'', ''B'', ''C''); $w('' first second third '').each(function(m) { myObj[m].toString = Prototype.K.curry(myObj[m]()); }) var myOut = ''First: #{first}, Second: #{second}, Third: #{third}''.interpolate(myObj); myOut; // => "First: A, Second: B, Third: C" The only limitatation I see here is that we need to know a list of methods to augment. On the other hand, it is possible to change Class.create to do all of this in a more generic way. Best, kangax On Mar 5, 1:12 pm, "J. Gregory Wright" <daecab...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> If I have [admittedly simple] code as follows: > > MyClass = Class.create({ > _a: false, > > _ b: false, > > _c: false, > > initialize: function(a, b, c) { > this._a = a; > this._b = b; > this._c = c; > }, > > first: function(){ > return this._a; > }, > > second: function(){ > return this._b; > }, > > third: function(){ > return this._c; > } > > }); > > var myObj = new MyClass(''A'',''B'',''C''); > var myTmpl = new Template(''First: #{first}, Second: #{second}, Third: > #{third}''); > var myOut = myTmpl.evaluate(myObj); > > Then the string value placed in myOut will not be: > > "First: A, Second: B, Third: C" > > but rather will be: > > "First: function(){ > return this._a; > }, Second: function(){ > return this._b; > }, Third:function(){ > return this._c; > }" > > Based on the code for Template#evaluate, it would seem that the line: > > return before + String(ctx); > > could be replaced by: > > return before + (Object.isFunction(ctx)) ? ctx.apply(object) : > String(ctx); > > and produce [the/my] desired effect of rendering the return value from > the function instead of the function literal. Is there a reason why > this would not be workable, or should not be done? > > Thanks in advance, > G--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
J. Gregory Wright
2008-Mar-05 21:38 UTC
Re: Template#evaluate and attributes that resolve to functions?
I actually mis-typed the logic from Template#evaluate - what Template#evaluate uses is not: return before + String(ctx); but: return before + String.interpret(ctx); where String.interpret() is simply: return (value == null) ? '''' : String(value); The problem is that the toString() operation called on an object of type Function returns the literal string source of the function. I''m not sure that I see where checking the type is limiting - if it is a function, apply it with the current object; if it is not send it through the usual interpretation. Looking at the patches referred to earlier in the thread, it looks like handling things in that manner is pretty straightforward, and has a fair amount of utility especially when nesting or chaining functions.. On Mar 5, 2:34 pm, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Interesting. > Actually String( ) already acts as a sort of a delegator by invoking > toString( ) on whatever you pass into it. It''s actually quite flexible > - we can *redefine* toString on any object and make it return anything > we want. Checking for type (as you propose) just seems a little too > limiting to me. > > Take a look at how easy the implementation is: > (by redefining native "toString" on instance methods to return curried > versions of themselves) > > ... > var myObj = new MyClass(''A'', ''B'', ''C''); > > $w('' first second third '').each(function(m) { > myObj[m].toString = Prototype.K.curry(myObj[m]()); > > }) > > var myOut = ''First: #{first}, Second: #{second}, Third: > #{third}''.interpolate(myObj); > > myOut; // => "First: A, Second: B, Third: C" > > The only limitatation I see here is that we need to know a list of > methods to augment. On the other hand, it is possible to change > Class.create to do all of this in a more generic way. > > Best, > kangax > > On Mar 5, 1:12 pm, "J. Gregory Wright" <daecab...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > If I have [admittedly simple] code as follows: > > > MyClass = Class.create({ > > _a: false, > > > _ b: false, > > > _c: false, > > > initialize: function(a, b, c) { > > this._a = a; > > this._b = b; > > this._c = c; > > }, > > > first: function(){ > > return this._a; > > }, > > > second: function(){ > > return this._b; > > }, > > > third: function(){ > > return this._c; > > } > > > }); > > > var myObj = new MyClass(''A'',''B'',''C''); > > var myTmpl = new Template(''First: #{first}, Second: #{second}, Third: > > #{third}''); > > var myOut = myTmpl.evaluate(myObj); > > > Then the string value placed in myOut will not be: > > > "First: A, Second: B, Third: C" > > > but rather will be: > > > "First: function(){ > > return this._a; > > }, Second: function(){ > > return this._b; > > }, Third:function(){ > > return this._c; > > }" > > > Based on the code for Template#evaluate, it would seem that the line: > > > return before + String(ctx); > > > could be replaced by: > > > return before + (Object.isFunction(ctx)) ? ctx.apply(object) : > > String(ctx); > > > and produce [the/my] desired effect of rendering the return value from > > the function instead of the function literal. Is there a reason why > > this would not be workable, or should not be done? > > > Thanks in advance, > > G--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
J. Gregory Wright
2008-Mar-05 21:54 UTC
Re: Template#evaluate and attributes that resolve to functions?
Since I''m new to Prototype, am I correct in my assumption that these patches would be applied against a source distribution, and would have to be re-applied with subsequent upgrade builds? On Mar 5, 2:27 pm, Christophe Porteneuve <t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org> wrote:> Hey, > > Check out the following ticket: > > http://dev.rubyonrails.org/ticket/8166 > > You''ll find the patch you need. Advanced, function-including evaluation > was deemed "too much" for the core trunk, but it can be done (and more, > like nesting) :-) > > -- > 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 -~----------~----~----~----~------~----~------~--~---
kangax
2008-Mar-05 22:38 UTC
Re: Template#evaluate and attributes that resolve to functions?
> The problem is that the toString() operation called on an object of > type Function returns the literal string source of the function.Unless we redefine it (which is what the previous example is about)> I''m not sure that I see where checking the type is limiting - if it is > a function, apply it with the current object; if it is not send it > through the usual interpretation.I guess it''s just a matter of taste : ) Cheers, 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 -~----------~----~----~----~------~----~------~--~---
J. Gregory Wright
2008-Mar-05 23:18 UTC
Re: Template#evaluate and attributes that resolve to functions?
On Mar 5, 5:38 pm, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > The problem is that the toString() operation called on an object of > > type Function returns the literal string source of the function. > > Unless we redefine it (which is what the previous example is about)Hmmmm, there''s something to ponder... although the thought of overriding it globally makes me wonder what might break as a result of doing so... with my luck, the answer would be "lotsa stuff". :)> > I''m not sure that I see where checking the type is limiting - if it is > > a function, apply it with the current object; if it is not send it > > through the usual interpretation. > > I guess it''s just a matter of taste : )I''ll buy that... I''m no JavaScript (much less Prototype) expert, so I was concerned that I might be missing something fundamental where manipulating objects was concerned. Gracias, G --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Nicolás Sanguinetti
2008-Mar-06 01:02 UTC
Re: Template#evaluate and attributes that resolve to functions?
Maybe I''m completely off, and I haven''t touched Proto in over a month (!?!!*), But what about declaring a toTemplateReplacements in the object? (the following is untested) MyClass = Class.create({ initialize: function(a, b, c) { this._a = a; this._b = b; this._c = c }, first: function() { return this._a }, second: function() { return this._b }, third: function() { return this._c }, toTemplateReplacements: function() { return { first: this.first(), second: this.second(), third: this.third() } } }); var obj = new MyClass(1, 2, 3); "Hey, I''m #{first}, i''m #{second} and I''m #{third}".interpolate(obj); //=> "Hey, I''m 1, I''m 2 and I''m 3" That''s supposedly the use of toTemplateReplacements :) Best, -Nicolas *PS: my new job working full time with rails is great, though I miss hacking stuff with proto :) On Wed, Mar 5, 2008 at 9:18 PM, J. Gregory Wright <daecabhir-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > On Mar 5, 5:38 pm, kangax <kan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > The problem is that the toString() operation called on an object of > > > type Function returns the literal string source of the function. > > > > Unless we redefine it (which is what the previous example is about) > > Hmmmm, there''s something to ponder... although the thought of > overriding it globally makes me wonder what might break as a result of > doing so... with my luck, the answer would be "lotsa stuff". :) > > > > > I''m not sure that I see where checking the type is limiting - if it is > > > a function, apply it with the current object; if it is not send it > > > through the usual interpretation. > > > > I guess it''s just a matter of taste : ) > > I''ll buy that... I''m no JavaScript (much less Prototype) expert, so I > was concerned that I might be missing something fundamental where > manipulating objects was concerned. > > Gracias, > > > G > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Christophe Porteneuve
2008-Mar-06 07:38 UTC
Re: Template#evaluate and attributes that resolve to functions?
Nicolás Sanguinetti a écrit :> But what about declaring a toTemplateReplacements in the object? (the > following is untested)Yes, that''s the current way to go.> MyClass = Class.create({ > initialize: function(a, b, c) { this._a = a; this._b = b; this._c = c }, > first: function() { return this._a }, > second: function() { return this._b }, > third: function() { return this._c }, > > toTemplateReplacements: function() { > return { first: this.first(), second: this.second(), third: this.third() } > } > }); > > var obj = new MyClass(1, 2, 3); > "Hey, I''m #{first}, i''m #{second} and I''m #{third}".interpolate(obj); > //=> "Hey, I''m 1, I''m 2 and I''m 3" > > That''s supposedly the use of toTemplateReplacements :)Absolutely. I can understand, however, people wanting to squeeze more power out of evaluate/interpolate… -- 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 -~----------~----~----~----~------~----~------~--~---
J. Gregory Wright
2008-Mar-06 15:49 UTC
Re: Template#evaluate and attributes that resolve to functions?
On Mar 6, 2:38 am, Christophe Porteneuve <t...-x+CfDp/qHev2eFz/2MeuCQ@public.gmane.org> wrote:> Nicolás Sanguinetti a écrit : > > > But what about declaring a toTemplateReplacements in the object? (the > > following is untested) > > Yes, that''s the current way to go. >[snipped]> > Absolutely. I can understand, however, people wanting to squeeze more > power out of evaluate/interpolate...I guess what I was looking for was a way to only invoke the methods on an object if they were included in the template. The specific use case I''ve been playing with is a "formatted date" class where each instance has a Date and a Template for rendering the date. Say for the sake of the argument your options for rendering a month in a Template string are: m - Month number, no padding. mm - Two digit month number, zero padded mmm - "Short" name for month (e.g., "Mar" or "Apr") mmmm - "Full" name for month (e.g., "March" or "April") Typically only one of the placeholders for month will appear in such a template, and therefore only one function is invoked. Using the toTemplateReplacement() approach, all four of the functions would be invoked, not knowing which placeholder for month (if any) will be used in the Template. If Template was extended to include a method like getPlaceholders() or something of that nature that returned the placeholder strings, then those in turn could be passed to a toTemplateReplacement() on the object being rendered as a "hint", which the toTemplateReplacement() implementation could choose to apply or not. I''ve seen a couple folks mention a function for retrieving the placeholders, and I think that at least seems like a useful idea. I''ll be working today on a subclass of Template that would provide some of the extended services without having to patch the "core" Template class. I''m just very happy that there is so much that one can do even with this one area of Prototype that it sparks discussion on how to build on it. Cheers, G --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---