atom feed27 messages in com.googlegroups.prototype-coreRe: Suggested addition to Function Me...
FromSent OnAttachments
Rick WaldronJun 23, 2009 8:25 am 
joe t.Jun 24, 2009 5:55 am 
Tobie LangelJun 24, 2009 6:00 am 
Robert KiefferJun 24, 2009 6:55 am 
Rick WaldronJun 24, 2009 7:49 am 
Rick WaldronJun 24, 2009 7:50 am 
Tobie LangelJun 24, 2009 9:53 am 
YaffleJun 24, 2009 10:28 am 
Robert KiefferJun 24, 2009 12:39 pm 
Rick WaldronJun 24, 2009 2:28 pm 
Tobie LangelJun 24, 2009 7:04 pm 
Rick WaldronJun 25, 2009 10:23 am 
Tobie LangelJun 26, 2009 3:02 am 
joe t.Jun 26, 2009 6:46 am 
Samuel LebeauAug 25, 2009 7:33 pm 
T.J. CrowderAug 27, 2009 3:17 am 
Robert KiefferAug 27, 2009 8:13 am 
T.J. CrowderAug 27, 2009 8:29 am 
Tobie LangelAug 27, 2009 8:51 am 
Rick WaldronAug 27, 2009 10:08 am 
T.J. CrowderAug 27, 2009 11:38 am 
Tobie LangelAug 27, 2009 2:49 pm 
T.J. CrowderAug 27, 2009 6:25 pm 
joe t.Aug 28, 2009 7:59 am 
Robert KiefferAug 28, 2009 9:30 am 
T.J. CrowderAug 28, 2009 9:49 am 
Tobie LangelAug 29, 2009 5:05 pm 
Subject:Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])
From:T.J. Crowder ("t.@crowdersoftware.com)
Date:Aug 27, 2009 3:17:07 am
List:com.googlegroups.prototype-core

Hi all,

Weighing in... First off, love the idea of Function#repeat. Wonderfully simple and expressive.

As Tobie says, the goals when doing it should be to handle all of the issues PE already handles, to reuse existing code, and to be consistent with other API functions.

Some notes:

1. I'd avoid requiring #curry or #bind on top of #repeat; #repeat should be able to handle arguments and context itself. Every curry at least doubles the call overhead.

2. Optional context would be helpful:

Function#delay(options[, args...]) -> Number

...with `options` being either a number (frequency) or an object with `context` and `frequency` parameters; the latter allows repeating method calls.

3. #1 suggests that rather than #repeat using PE, the guts of PE should become #repeat and the PE should use it:

var PeriodicalExecuter = Class.create({ initialize: function(callback, frequency) { this.handle = callback.repeat(frequency, this); }, stop: function() { if (this.handle) { clearInterval(this.handle); this.handle = 0; } } });

4. I'd like to be able to repeat functions not explicitly designed to #repeat, which suggests not changing their signature. Perhaps the self- stop mechanism could remain a feature that PE adds on top of #repeat (at the cost that PE functions have to be explicitly intended to be repeated [or must ignore their args], as is currently the case).

5. Like Robert, I prefer the self-repeat over setInterval (that's always how I do it), but unless we've seen significant issues with setInterval we should be wary of changing it, especially in light of how doing so complicates the API (e.g., return value issues). Perhaps this aspect is a separate question entirely.

6. If we do need to use something other than an interval handle as the return value, I'd suggest providing a stop function that works with both interval handles and whatever our new thing is, e.g.:

Function.stop = function(handle) { if (typeof handle == 'number') { clearInterval(handle); } else { /* ...stop it the new way... */ } };

@Rick: All of this discussion probably seems like nit-picking your idea to death. In fact, I think it indicates that there's a lot of support and appreciation for your idea, and we're all (well, nearly all, there's a dissenter) just trying to make it fit in, and make it as cool as the idea warrants.

On Aug 26, 3:33 am, Samuel Lebeau <samu@gmail.com> wrote:

Joe,

Callback function receives PE instance as first argument, so here   would be the self-stop mechanism :

        function(executer) { executer.stop() }.repeat()

Best, Samuel.

On 26 juin 09, at 15:46, joe t. wrote:

Tobie,

Function.prototype.repeat = function(interval) { var fn = this; if (arguments.length > 1) {   // not testsed but you get the idea   fn = fn.curry.apply(fn, Array.prototype.slice.call(arguments, 1)); } return new PeriodicalExecuter(fn, interval);

}

If sticking to the PE approach there's no internal self-stop mechanism (is there?), which i see as a nice touch in the above proposal (for what my opinion is worth). What about (from 1.6.1_rc2):

onTimerEvent: function() {  if (!this.currentlyExecuting) {    try {      this.currentlyExecuting = true;      if (this.execute()===false) // MOD        this.stop();              // NEW    } catch(e) {      /* empty catch for clients that don't support try/finally */    }    finally {      this.currentlyExecuting = false;    }  } }

Just tossing in my 2 cents because i'm intrigued by that feature. -joe t.

On Jun 26, 6:02 am, Tobie Langel <tobi@gmail.com> wrote:

How to stop it? arguments?

Stopping it is as easy as:

pe = foo.repeat(); pe.stop();

Passing arguments would require some simple currying:

Function.prototype.repeat = function(interval) {  var fn = this;  if (arguments.length > 1) {    // not testsed but you get the idea    fn = fn.curry.apply(fn, Array.prototype.slice.call(arguments, 1));  }  return new PeriodicalExecuter(fn, interval);

}

This may come to you twice, but this is slightly updated:

This repeat() method def is 775Bytes, accepts arguments like delay/ defer, uses setTimeout (returns initial setTimeout index) and has a   stopping mechanism.

What's the point in returning setTimeout index? That will set expectations which can't be met: developers will expect to be able to stop the functions calls by clearing it.

Are you sure your proposal fixes all of the small issues PE fixes?   For example, does it guarantee that the function will continue being called if it happens to once throw an error. Does it avoid calling   the function again if a previous function is still executing, etc.?

I understand your eagerness to move away from a model you dislike,   but that shouldn't make you throw away all of the work that's been put into previous solutions.

FWIW, I just noticed a patch wasn't applied to PE in current trunk (it's missing a throw statement).

Best,