[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-08-27 Thread T.J. Crowder

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.
--
T.J. Crowder
tj / crowder software / com

On Aug 26, 3:33 am, Samuel Lebeau samuel.leb...@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 tobie.lan...@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:

 http://jsbin.com/opimu

  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 

[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-08-27 Thread Robert Kieffer
@TJ...

Your goals sound about right.  Implicit in there, I think, is make it easy
to deprecate PE at some later date.  At least, that's how I read it. :)

Re: #2 - Why not just use bind() to provide context?   I've never been a fan
of overloading arguments with multiple interpretations.   'Gets too
confusing, and makes the implementation that much uglier.

Re: #4 - I feel the ability to self-stop is more important than being able
to repeat() functions that aren't designed for it.  I _really_ feel that
making the self-stop behavior an optional add-on feature of PE is a bad
idea.  self-stop is an elegant pattern (IMHO) so forcing users to go through
the awkward PE API to get at it doesn't make sense.  Also, it makes
deprecating PE harder.

***Hmm...*** How about this as a solution:  Instead of having a function
return false to stop, have it throw $break!  I think that addresses your
concern, and is consistent with how Prototype does this sort of thing
elsewhere (in Enumerable).

--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-08-27 Thread T.J. Crowder

Hey Robert,

It's true, I was thinking in terms of deprecating PE at some
stage... :-)

Re #2: Using #bind at least doubles the call overhead, which I'm not a
fan of generally.

 ...have it throw $break!

Now that is a very smart idea.
--
T.J. Crowder
tj / crowder software / com


On Aug 27, 4:13 pm, Robert Kieffer bro...@gmail.com wrote:
 @TJ...

 Your goals sound about right.  Implicit in there, I think, is make it easy
 to deprecate PE at some later date.  At least, that's how I read it. :)

 Re: #2 - Why not just use bind() to provide context?   I've never been a fan
 of overloading arguments with multiple interpretations.   'Gets too
 confusing, and makes the implementation that much uglier.

 Re: #4 - I feel the ability to self-stop is more important than being able
 to repeat() functions that aren't designed for it.  I _really_ feel that
 making the self-stop behavior an optional add-on feature of PE is a bad
 idea.  self-stop is an elegant pattern (IMHO) so forcing users to go through
 the awkward PE API to get at it doesn't make sense.  Also, it makes
 deprecating PE harder.

 ***Hmm...*** How about this as a solution:  Instead of having a function
 return false to stop, have it throw $break!  I think that addresses your
 concern, and is consistent with how Prototype does this sort of thing
 elsewhere (in Enumerable).
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-08-27 Thread Tobie Langel

Food for thought:

1. We would like to completely decouple native and host objects in the
LANG section for version 1.7.

`setTimeout` and `setInterval` are host objects...

2. We're planning strict ES 5 compliance of enumerables for 1.7. that
implies removing $break.

Best,

Tobie

On Aug 27, 5:29 pm, T.J. Crowder t...@crowdersoftware.com wrote:
 Hey Robert,

 It's true, I was thinking in terms of deprecating PE at some
 stage... :-)

 Re #2: Using #bind at least doubles the call overhead, which I'm not a
 fan of generally.

  ...have it throw $break!

 Now that is a very smart idea.
 --
 T.J. Crowder
 tj / crowder software / com

 On Aug 27, 4:13 pm, Robert Kieffer bro...@gmail.com wrote:



  @TJ...

  Your goals sound about right.  Implicit in there, I think, is make it easy
  to deprecate PE at some later date.  At least, that's how I read it. :)

  Re: #2 - Why not just use bind() to provide context?   I've never been a fan
  of overloading arguments with multiple interpretations.   'Gets too
  confusing, and makes the implementation that much uglier.

  Re: #4 - I feel the ability to self-stop is more important than being able
  to repeat() functions that aren't designed for it.  I _really_ feel that
  making the self-stop behavior an optional add-on feature of PE is a bad
  idea.  self-stop is an elegant pattern (IMHO) so forcing users to go through
  the awkward PE API to get at it doesn't make sense.  Also, it makes
  deprecating PE harder.

  ***Hmm...*** How about this as a solution:  Instead of having a function
  return false to stop, have it throw $break!  I think that addresses your
  concern, and is consistent with how Prototype does this sort of thing
  elsewhere (in Enumerable).
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-08-27 Thread Tobie Langel

 *blech* to ES5's enumerable stuff not having $break or similar
 functionality.  I've just read the forEach section of the draft spec
 from a while back, and I'm not seeing a discussion of exception
 handling.  I haven't delved deep, though -- do you know offhand how
 exceptions in the callback function are handled?  E.g, can one
 implement one's own $break handling, or are exceptions eaten?

Exceptions aren't eaten.

 Re setInterval and setTimeout, how do you see implementing #delay or
 similar without using them?

You can't.

 Or do you not see it, e.g., a pure LANG
 version of Prototype wouldn't have Function#defer.

Maybe Function#defer would be defined only if window.setTimeout was
present.
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-08-27 Thread T.J. Crowder

 Exceptions aren't eaten.

Good, so a $break-like mechanism is possible then, just moved out a
level.

-- T.J.

On Aug 27, 10:49 pm, Tobie Langel tobie.lan...@gmail.com wrote:
  *blech* to ES5's enumerable stuff not having $break or similar
  functionality.  I've just read the forEach section of the draft spec
  from a while back, and I'm not seeing a discussion of exception
  handling.  I haven't delved deep, though -- do you know offhand how
  exceptions in the callback function are handled?  E.g, can one
  implement one's own $break handling, or are exceptions eaten?

 Exceptions aren't eaten.

  Re setInterval and setTimeout, how do you see implementing #delay or
  similar without using them?

 You can't.

  Or do you not see it, e.g., a pure LANG
  version of Prototype wouldn't have Function#defer.

 Maybe Function#defer would be defined only if window.setTimeout was
 present.
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-26 Thread Tobie Langel

 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:

 http://jsbin.com/opimu

 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,

Tobie


--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-26 Thread joe t.

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 tobie.lan...@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:

 http://jsbin.com/opimu

  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,

 Tobie
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...]) -- Revised from Robert's version

2009-06-25 Thread joe t.

Rick,
Maybe i'm missing how that revision works, but it appears to me that
your stop property doesn't actually stop the repeater. Your stop
returns before further execution happens, but the timeout ID for the
window still exists.

What am i missing?
-joe t.


On Jun 24, 12:20 pm, Rick Waldron waldron.r...@gmail.com wrote:
 I made a few modifications to your version, allowing repeat() to behave like
 delay() with regard to arguments

 I've posted a demo here:

 http://jsbin.com/ekone

 All the output is to the firebug console... i've included fbug lite just in
 case

 Rick

 On Wed, Jun 24, 2009 at 10:50 AM, Rick Waldron waldron.r...@gmail.comwrote:

  I've subbed my implementation with your to do some use-case testing. I'll
  report back anything of interest as I go along.

  Rick

  On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron 
  waldron.r...@gmail.comwrote:

  This is fantastic feedback - thanks!

  On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com wrote:

  I can't say I'm a big fan of this.  For several reasons.

  First, it's just a cosmetic replacement for setInterval(myfunction
  (...).bind(), ...) which simply isn't all that bad.

  Second, I'm not a fan of setInterval in general.  I've seen some
  rather nasty behavior with calls queuing up if the invoked function
  takes longer than the delay to execute.  In particular, this seems to
  be an issue if you do something like put a laptop to sleep.  (But
  maybe others haven't seen this problem???)  Thus, I prefer to use a
  self-invoking timeout like so:

  function myFunction() {
     // do stuff ...
     // call ourselves again
     if (/*we want to continue?*/) setTimeout(myFunction, 1000)
  }

  This doesn't call the function at exactly one second intervals, but
  that type of accuracy is rarely important.  Instead, it guarantees you
  have at least one second of delay between invocations, which for
  distributing cpu load or polling (the more common cases where
  setInterval might be used), is more desireable.

  Finally, as Joe T. points out, there should be a way of cancelling the
  interval that doesn't require the user to store the returned value
  (*that* is what I find most annoying, not the syntax of
  setInterval).

  Thus, I'd suggest this instead:

   Object.extend(Function.prototype, {
     repeat: function(delay) {
       // Reset state
       if (this._repeater) delete this._repeater;
       this._repeatTimeout = clearTimeout(this._repeatTimeout);

       if (!delay) return; // (stop repeating if no args or delay==0)

       // Create setTimeout-based invoker
       var _method = this;
       if (!this._repeater) this._repeater = function() {
         // Let _method cancel repeat by doing return false;
         if (_method() !== false) setTimeout(_method._repeater, delay);
       }

       // Start repeating
       this._repeatTimeout = setTimeout(this._repeater, delay);
     },

     stopRepeating: function() {
       this.repeat();
     }
   });

  For example:

   var count = 0;
   function foo() {
     console.log(count++);
     return count  10;  // Return false when count = 10 to cancel
  the repeat
   }

   // Start repeating 1/sec
   foo.repeat(1000);
   //... some time later change interval to 2/sec
   foo.repeat(500);
   // ... later still stop repeating.
   foo.stopRepeating();

  As you can see, this implementation of repeat() does a lot more for
  you than simply alias'ing setInterval:
   - It guarantees your function is only invoked by one interval
   - It makes changing the interval or cancelling it altogether
  trivial.
   - It allows you to conditionally cancel the repeat from w/in the
  function itself.

  The only thing missing is the bind() behavior but, well, that's what
  bind is for.   If you need to bind arguments, just bind() your
  arguments first.

  On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
   I detest the way setInterval() looks, so I came up with this... have
  been
   using it my personal JS for some time.

   Object.extend(Function.prototype, {
     repeat: function() {
       var __method = this, args = $A(arguments), interval = args.shift()
  *
   1000;
       return window.setInterval(function() {
         return __method.apply(__method, args);
       }, interval );
     }

   });

   // usage:
   var _pollInt = 0;
   function repetiousPollFn() {
    console.log(_pollInt++);

   }

   repetiousPollFn.repeat(.5);

   Will, of course, repeat repetiousPollFn() every half second.

   Almost identical to .delay(), except that it returns setInterval
  instead of
   setTimeout. One thing I intend to add is support for clearInterval,
  however
   I figured I'd at least bring it up here first. I've never
   proposed/contributed here before (i'm a lurker of the list :D ) - any
   guidance is appreciated.

   Rick


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To 

[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...]) -- Revised from Robert's version

2009-06-25 Thread Rick Waldron
Note this last revision brings back a bit more of Robert's version, it's
more 50/50 now.


Rick



On Thu, Jun 25, 2009 at 12:53 PM, Rick Waldron waldron.r...@gmail.comwrote:

 You're right... It appears i copied the source in a bit hastily. After
 re-examining, I've revised again...

 http://jsbin.com/ajoqu

 Rick




 On Thu, Jun 25, 2009 at 9:37 AM, joe t. thooke...@gmail.com wrote:


 Rick,
 Maybe i'm missing how that revision works, but it appears to me that
 your stop property doesn't actually stop the repeater. Your stop
 returns before further execution happens, but the timeout ID for the
 window still exists.

 What am i missing?
 -joe t.


 On Jun 24, 12:20 pm, Rick Waldron waldron.r...@gmail.com wrote:
  I made a few modifications to your version, allowing repeat() to behave
 like
  delay() with regard to arguments
 
  I've posted a demo here:
 
  http://jsbin.com/ekone
 
  All the output is to the firebug console... i've included fbug lite just
 in
  case
 
  Rick
 
  On Wed, Jun 24, 2009 at 10:50 AM, Rick Waldron waldron.r...@gmail.com
 wrote:
 
   I've subbed my implementation with your to do some use-case testing.
 I'll
   report back anything of interest as I go along.
 
   Rick
 
   On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron 
 waldron.r...@gmail.comwrote:
 
   This is fantastic feedback - thanks!
 
   On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com
 wrote:
 
   I can't say I'm a big fan of this.  For several reasons.
 
   First, it's just a cosmetic replacement for setInterval(myfunction
   (...).bind(), ...) which simply isn't all that bad.
 
   Second, I'm not a fan of setInterval in general.  I've seen some
   rather nasty behavior with calls queuing up if the invoked function
   takes longer than the delay to execute.  In particular, this seems
 to
   be an issue if you do something like put a laptop to sleep.  (But
   maybe others haven't seen this problem???)  Thus, I prefer to use a
   self-invoking timeout like so:
 
   function myFunction() {
  // do stuff ...
  // call ourselves again
  if (/*we want to continue?*/) setTimeout(myFunction, 1000)
   }
 
   This doesn't call the function at exactly one second intervals, but
   that type of accuracy is rarely important.  Instead, it guarantees
 you
   have at least one second of delay between invocations, which for
   distributing cpu load or polling (the more common cases where
   setInterval might be used), is more desireable.
 
   Finally, as Joe T. points out, there should be a way of cancelling
 the
   interval that doesn't require the user to store the returned value
   (*that* is what I find most annoying, not the syntax of
   setInterval).
 
   Thus, I'd suggest this instead:
 
Object.extend(Function.prototype, {
  repeat: function(delay) {
// Reset state
if (this._repeater) delete this._repeater;
this._repeatTimeout = clearTimeout(this._repeatTimeout);
 
if (!delay) return; // (stop repeating if no args or delay==0)
 
// Create setTimeout-based invoker
var _method = this;
if (!this._repeater) this._repeater = function() {
  // Let _method cancel repeat by doing return false;
  if (_method() !== false) setTimeout(_method._repeater,
 delay);
}
 
// Start repeating
this._repeatTimeout = setTimeout(this._repeater, delay);
  },
 
  stopRepeating: function() {
this.repeat();
  }
});
 
   For example:
 
var count = 0;
function foo() {
  console.log(count++);
  return count  10;  // Return false when count = 10 to cancel
   the repeat
}
 
// Start repeating 1/sec
foo.repeat(1000);
//... some time later change interval to 2/sec
foo.repeat(500);
// ... later still stop repeating.
foo.stopRepeating();
 
   As you can see, this implementation of repeat() does a lot more for
   you than simply alias'ing setInterval:
- It guarantees your function is only invoked by one interval
- It makes changing the interval or cancelling it altogether
   trivial.
- It allows you to conditionally cancel the repeat from w/in the
   function itself.
 
   The only thing missing is the bind() behavior but, well, that's what
   bind is for.   If you need to bind arguments, just bind() your
   arguments first.
 
   On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
I detest the way setInterval() looks, so I came up with this...
 have
   been
using it my personal JS for some time.
 
Object.extend(Function.prototype, {
  repeat: function() {
var __method = this, args = $A(arguments), interval =
 args.shift()
   *
1000;
return window.setInterval(function() {
  return __method.apply(__method, args);
}, interval );
  }
 
});
 
// usage:
var _pollInt = 0;
function repetiousPollFn() {
 console.log(_pollInt++);
 
}
 
repetiousPollFn.repeat(.5);
 
Will, of 

[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...]) -- Revised from Robert's version

2009-06-25 Thread Rick Waldron
You're right... It appears i copied the source in a bit hastily. After
re-examining, I've revised again...

http://jsbin.com/ajoqu

Rick



On Thu, Jun 25, 2009 at 9:37 AM, joe t. thooke...@gmail.com wrote:


 Rick,
 Maybe i'm missing how that revision works, but it appears to me that
 your stop property doesn't actually stop the repeater. Your stop
 returns before further execution happens, but the timeout ID for the
 window still exists.

 What am i missing?
 -joe t.


 On Jun 24, 12:20 pm, Rick Waldron waldron.r...@gmail.com wrote:
  I made a few modifications to your version, allowing repeat() to behave
 like
  delay() with regard to arguments
 
  I've posted a demo here:
 
  http://jsbin.com/ekone
 
  All the output is to the firebug console... i've included fbug lite just
 in
  case
 
  Rick
 
  On Wed, Jun 24, 2009 at 10:50 AM, Rick Waldron waldron.r...@gmail.com
 wrote:
 
   I've subbed my implementation with your to do some use-case testing.
 I'll
   report back anything of interest as I go along.
 
   Rick
 
   On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron waldron.r...@gmail.com
 wrote:
 
   This is fantastic feedback - thanks!
 
   On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com
 wrote:
 
   I can't say I'm a big fan of this.  For several reasons.
 
   First, it's just a cosmetic replacement for setInterval(myfunction
   (...).bind(), ...) which simply isn't all that bad.
 
   Second, I'm not a fan of setInterval in general.  I've seen some
   rather nasty behavior with calls queuing up if the invoked function
   takes longer than the delay to execute.  In particular, this seems to
   be an issue if you do something like put a laptop to sleep.  (But
   maybe others haven't seen this problem???)  Thus, I prefer to use a
   self-invoking timeout like so:
 
   function myFunction() {
  // do stuff ...
  // call ourselves again
  if (/*we want to continue?*/) setTimeout(myFunction, 1000)
   }
 
   This doesn't call the function at exactly one second intervals, but
   that type of accuracy is rarely important.  Instead, it guarantees
 you
   have at least one second of delay between invocations, which for
   distributing cpu load or polling (the more common cases where
   setInterval might be used), is more desireable.
 
   Finally, as Joe T. points out, there should be a way of cancelling
 the
   interval that doesn't require the user to store the returned value
   (*that* is what I find most annoying, not the syntax of
   setInterval).
 
   Thus, I'd suggest this instead:
 
Object.extend(Function.prototype, {
  repeat: function(delay) {
// Reset state
if (this._repeater) delete this._repeater;
this._repeatTimeout = clearTimeout(this._repeatTimeout);
 
if (!delay) return; // (stop repeating if no args or delay==0)
 
// Create setTimeout-based invoker
var _method = this;
if (!this._repeater) this._repeater = function() {
  // Let _method cancel repeat by doing return false;
  if (_method() !== false) setTimeout(_method._repeater, delay);
}
 
// Start repeating
this._repeatTimeout = setTimeout(this._repeater, delay);
  },
 
  stopRepeating: function() {
this.repeat();
  }
});
 
   For example:
 
var count = 0;
function foo() {
  console.log(count++);
  return count  10;  // Return false when count = 10 to cancel
   the repeat
}
 
// Start repeating 1/sec
foo.repeat(1000);
//... some time later change interval to 2/sec
foo.repeat(500);
// ... later still stop repeating.
foo.stopRepeating();
 
   As you can see, this implementation of repeat() does a lot more for
   you than simply alias'ing setInterval:
- It guarantees your function is only invoked by one interval
- It makes changing the interval or cancelling it altogether
   trivial.
- It allows you to conditionally cancel the repeat from w/in the
   function itself.
 
   The only thing missing is the bind() behavior but, well, that's what
   bind is for.   If you need to bind arguments, just bind() your
   arguments first.
 
   On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
I detest the way setInterval() looks, so I came up with this...
 have
   been
using it my personal JS for some time.
 
Object.extend(Function.prototype, {
  repeat: function() {
var __method = this, args = $A(arguments), interval =
 args.shift()
   *
1000;
return window.setInterval(function() {
  return __method.apply(__method, args);
}, interval );
  }
 
});
 
// usage:
var _pollInt = 0;
function repetiousPollFn() {
 console.log(_pollInt++);
 
}
 
repetiousPollFn.repeat(.5);
 
Will, of course, repeat repetiousPollFn() every half second.
 
Almost identical to .delay(), except that it returns setInterval
   instead of
setTimeout. One thing I intend to add is 

[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-25 Thread Rick Waldron
Thanks for the insight Tobie, definitely appreciated.


Function.prototype.repeat = function(interval) {
 return new PeriodicalExecuter(this, interval);
}

How to stop it? arguments?


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

http://jsbin.com/opimu


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


Rick












On Wed, Jun 24, 2009 at 10:04 PM, Tobie Langel tobie.lan...@gmail.comwrote:


 Hi Rick, hi Robert.

 Fully agree regarding PE. It does however handle issues a regular
 setInterval doesn't (as you mentioned).

 It's clearly an area which would need refinement, but that's better
 done in a backwards compatible way.

 Personally, I'd love to see PE implemented as a method of Function
 instances.

 So since this is the core mailing list, I'm trying to give directions
 on how it could be best implemented given legacy constraints and
 consistency with the rest of the API.

 Clearly, consistency with Function#defer and Function#delay would
 imply returning a setInterval index. Unfortunately, since setTimeout
 is used instead of setInterval, this isn't possible.

 Maybe the simplest solution would be to make Function#repeat return an
 instance of PE. Implementation would then be roughly:

 Function.prototype.repeat = function(interval) {
  return new PeriodicalExecuter(this, interval);
 }

 Note that in that case, modifying Function#delay and Function#defer to
 return a PE-like object instance with a stop method would make more
 sense API wise, but at the expense of a larger memory footprint and
 backwards compatibility.

 As you can see, making the right choice isn't simple.

 Best,

 Tobie

 On Jun 24, 11:28 pm, Rick Waldron waldron.r...@gmail.com wrote:
  Tobie,
 
  I had in fact looked into PeriodicalExecuter and to be perfectly honest,
  with no offense intended, i think it's usage syntax is hideous which is
 what
  led me to writing my own Function.prototype method instead, taking
  inspiration from .delay()
 
  It doesnt matter to me whether or not .repeat() makes it into the
 prototype
  core - I will always have it at my disposal, I simply wanted to share the
  concept with the group.
 
  I think everything I've said sounds like I'm in a bad mood, sorry about
  that! :D
 
  Rick
 
  On Wed, Jun 24, 2009 at 12:53 PM, Tobie Langel tobie.lan...@gmail.com
 wrote:
 
 
 
 
 
   Just to clarify the above: Prototype Core already contains a similar
   functionality: PeriodicalExecuter. The API is different but the
   functionality is the same.
 
   I'd strongly suggest looking into combining both approaches if you
   want your suggestion to be included in core and not just stay a thread
   in the mailing list. :)
 
   Best,
 
   Tobie
 
   On Jun 24, 4:50 pm, Rick Waldron waldron.r...@gmail.com wrote:
I've subbed my implementation with your to do some use-case testing.
 I'll
report back anything of interest as I go along.
 
Rick
 
On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron 
 waldron.r...@gmail.com
   wrote:
 
 This is fantastic feedback - thanks!
 
 On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com
   wrote:
 
 I can't say I'm a big fan of this.  For several reasons.
 
 First, it's just a cosmetic replacement for setInterval(myfunction
 (...).bind(), ...) which simply isn't all that bad.
 
 Second, I'm not a fan of setInterval in general.  I've seen some
 rather nasty behavior with calls queuing up if the invoked
 function
 takes longer than the delay to execute.  In particular, this seems
 to
 be an issue if you do something like put a laptop to sleep.  (But
 maybe others haven't seen this problem???)  Thus, I prefer to use
 a
 self-invoking timeout like so:
 
 function myFunction() {
// do stuff ...
// call ourselves again
if (/*we want to continue?*/) setTimeout(myFunction, 1000)
 }
 
 This doesn't call the function at exactly one second intervals,
 but
 that type of accuracy is rarely important.  Instead, it guarantees
 you
 have at least one second of delay between invocations, which for
 distributing cpu load or polling (the more common cases where
 setInterval might be used), is more desireable.
 
 Finally, as Joe T. points out, there should be a way of cancelling
 the
 interval that doesn't require the user to store the returned value
 (*that* is what I find most annoying, not the syntax of
 setInterval).
 
 Thus, I'd suggest this instead:
 
  Object.extend(Function.prototype, {
repeat: function(delay) {
  // Reset state
  if (this._repeater) delete this._repeater;
  this._repeatTimeout = clearTimeout(this._repeatTimeout);
 
  if (!delay) return; // (stop repeating if no args or
 delay==0)
 
  // Create setTimeout-based invoker
  var _method = this;
  if 

[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-24 Thread Tobie Langel

You might also want to look at the already existing
PeriodicalExecuter.

Any implementation of a Function#repeat API should take this in
account.

On Jun 24, 2:55 pm, joe t. thooke...@gmail.com wrote:
 Only suggestion i can think of is that your method strongly implies a
 requirement that repetitionsPollFn.repeat() get assigned to a
 variable so it can be cleared later:

 var interval = repetitiousPollFn.repeat(0.5);
 // interval is the setInterval ID

 then later
 window.clearInterval(interval);

 i could also see potential for more scheduling options
 (repeatUntilTime, repeatXTimes, etc) built into your #repeat idea, but
 don't really have the time to flesh them out.

 i find it an interesting idea though. :)
 -joe t.

 On Jun 23, 11:25 am, Rick Waldron waldron.r...@gmail.com wrote:



  I detest the way setInterval() looks, so I came up with this... have been
  using it my personal JS for some time.

  Object.extend(Function.prototype, {
    repeat: function() {
      var __method = this, args = $A(arguments), interval = args.shift() *
  1000;
      return window.setInterval(function() {
        return __method.apply(__method, args);
      }, interval );
    }

  });

  // usage:
  var _pollInt = 0;
  function repetiousPollFn() {
   console.log(_pollInt++);

  }

  repetiousPollFn.repeat(.5);

  Will, of course, repeat repetiousPollFn() every half second.

  Almost identical to .delay(), except that it returns setInterval instead of
  setTimeout. One thing I intend to add is support for clearInterval, however
  I figured I'd at least bring it up here first. I've never
  proposed/contributed here before (i'm a lurker of the list :D ) - any
  guidance is appreciated.

  Rick
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-24 Thread Robert Kieffer

I can't say I'm a big fan of this.  For several reasons.

First, it's just a cosmetic replacement for setInterval(myfunction
(...).bind(), ...) which simply isn't all that bad.

Second, I'm not a fan of setInterval in general.  I've seen some
rather nasty behavior with calls queuing up if the invoked function
takes longer than the delay to execute.  In particular, this seems to
be an issue if you do something like put a laptop to sleep.  (But
maybe others haven't seen this problem???)  Thus, I prefer to use a
self-invoking timeout like so:

function myFunction() {
// do stuff ...
// call ourselves again
if (/*we want to continue?*/) setTimeout(myFunction, 1000)
}

This doesn't call the function at exactly one second intervals, but
that type of accuracy is rarely important.  Instead, it guarantees you
have at least one second of delay between invocations, which for
distributing cpu load or polling (the more common cases where
setInterval might be used), is more desireable.

Finally, as Joe T. points out, there should be a way of cancelling the
interval that doesn't require the user to store the returned value
(*that* is what I find most annoying, not the syntax of
setInterval).

Thus, I'd suggest this instead:

  Object.extend(Function.prototype, {
repeat: function(delay) {
  // Reset state
  if (this._repeater) delete this._repeater;
  this._repeatTimeout = clearTimeout(this._repeatTimeout);

  if (!delay) return; // (stop repeating if no args or delay==0)

  // Create setTimeout-based invoker
  var _method = this;
  if (!this._repeater) this._repeater = function() {
// Let _method cancel repeat by doing return false;
if (_method() !== false) setTimeout(_method._repeater, delay);
  }

  // Start repeating
  this._repeatTimeout = setTimeout(this._repeater, delay);
},

stopRepeating: function() {
  this.repeat();
}
  });

For example:

  var count = 0;
  function foo() {
console.log(count++);
return count  10;  // Return false when count = 10 to cancel
the repeat
  }

  // Start repeating 1/sec
  foo.repeat(1000);
  //... some time later change interval to 2/sec
  foo.repeat(500);
  // ... later still stop repeating.
  foo.stopRepeating();


As you can see, this implementation of repeat() does a lot more for
you than simply alias'ing setInterval:
  - It guarantees your function is only invoked by one interval
  - It makes changing the interval or cancelling it altogether
trivial.
  - It allows you to conditionally cancel the repeat from w/in the
function itself.

The only thing missing is the bind() behavior but, well, that's what
bind is for.   If you need to bind arguments, just bind() your
arguments first.

On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
 I detest the way setInterval() looks, so I came up with this... have been
 using it my personal JS for some time.

 Object.extend(Function.prototype, {
   repeat: function() {
     var __method = this, args = $A(arguments), interval = args.shift() *
 1000;
     return window.setInterval(function() {
       return __method.apply(__method, args);
     }, interval );
   }

 });

 // usage:
 var _pollInt = 0;
 function repetiousPollFn() {
  console.log(_pollInt++);

 }

 repetiousPollFn.repeat(.5);

 Will, of course, repeat repetiousPollFn() every half second.

 Almost identical to .delay(), except that it returns setInterval instead of
 setTimeout. One thing I intend to add is support for clearInterval, however
 I figured I'd at least bring it up here first. I've never
 proposed/contributed here before (i'm a lurker of the list :D ) - any
 guidance is appreciated.

 Rick
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-24 Thread Rick Waldron
This is fantastic feedback - thanks!





On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com wrote:


 I can't say I'm a big fan of this.  For several reasons.

 First, it's just a cosmetic replacement for setInterval(myfunction
 (...).bind(), ...) which simply isn't all that bad.

 Second, I'm not a fan of setInterval in general.  I've seen some
 rather nasty behavior with calls queuing up if the invoked function
 takes longer than the delay to execute.  In particular, this seems to
 be an issue if you do something like put a laptop to sleep.  (But
 maybe others haven't seen this problem???)  Thus, I prefer to use a
 self-invoking timeout like so:

 function myFunction() {
// do stuff ...
// call ourselves again
if (/*we want to continue?*/) setTimeout(myFunction, 1000)
 }

 This doesn't call the function at exactly one second intervals, but
 that type of accuracy is rarely important.  Instead, it guarantees you
 have at least one second of delay between invocations, which for
 distributing cpu load or polling (the more common cases where
 setInterval might be used), is more desireable.

 Finally, as Joe T. points out, there should be a way of cancelling the
 interval that doesn't require the user to store the returned value
 (*that* is what I find most annoying, not the syntax of
 setInterval).

 Thus, I'd suggest this instead:

  Object.extend(Function.prototype, {
repeat: function(delay) {
  // Reset state
  if (this._repeater) delete this._repeater;
  this._repeatTimeout = clearTimeout(this._repeatTimeout);

  if (!delay) return; // (stop repeating if no args or delay==0)

  // Create setTimeout-based invoker
  var _method = this;
  if (!this._repeater) this._repeater = function() {
// Let _method cancel repeat by doing return false;
if (_method() !== false) setTimeout(_method._repeater, delay);
  }

  // Start repeating
  this._repeatTimeout = setTimeout(this._repeater, delay);
},

stopRepeating: function() {
  this.repeat();
}
  });

 For example:

  var count = 0;
  function foo() {
console.log(count++);
return count  10;  // Return false when count = 10 to cancel
 the repeat
  }

  // Start repeating 1/sec
  foo.repeat(1000);
  //... some time later change interval to 2/sec
  foo.repeat(500);
  // ... later still stop repeating.
  foo.stopRepeating();


 As you can see, this implementation of repeat() does a lot more for
 you than simply alias'ing setInterval:
  - It guarantees your function is only invoked by one interval
  - It makes changing the interval or cancelling it altogether
 trivial.
  - It allows you to conditionally cancel the repeat from w/in the
 function itself.

 The only thing missing is the bind() behavior but, well, that's what
 bind is for.   If you need to bind arguments, just bind() your
 arguments first.

 On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
  I detest the way setInterval() looks, so I came up with this... have been
  using it my personal JS for some time.
 
  Object.extend(Function.prototype, {
repeat: function() {
  var __method = this, args = $A(arguments), interval = args.shift() *
  1000;
  return window.setInterval(function() {
return __method.apply(__method, args);
  }, interval );
}
 
  });
 
  // usage:
  var _pollInt = 0;
  function repetiousPollFn() {
   console.log(_pollInt++);
 
  }
 
  repetiousPollFn.repeat(.5);
 
  Will, of course, repeat repetiousPollFn() every half second.
 
  Almost identical to .delay(), except that it returns setInterval instead
 of
  setTimeout. One thing I intend to add is support for clearInterval,
 however
  I figured I'd at least bring it up here first. I've never
  proposed/contributed here before (i'm a lurker of the list :D ) - any
  guidance is appreciated.
 
  Rick
 


--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-24 Thread Rick Waldron
I've subbed my implementation with your to do some use-case testing. I'll
report back anything of interest as I go along.

Rick

On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron waldron.r...@gmail.comwrote:

 This is fantastic feedback - thanks!






 On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com wrote:


 I can't say I'm a big fan of this.  For several reasons.

 First, it's just a cosmetic replacement for setInterval(myfunction
 (...).bind(), ...) which simply isn't all that bad.

 Second, I'm not a fan of setInterval in general.  I've seen some
 rather nasty behavior with calls queuing up if the invoked function
 takes longer than the delay to execute.  In particular, this seems to
 be an issue if you do something like put a laptop to sleep.  (But
 maybe others haven't seen this problem???)  Thus, I prefer to use a
 self-invoking timeout like so:

 function myFunction() {
// do stuff ...
// call ourselves again
if (/*we want to continue?*/) setTimeout(myFunction, 1000)
 }

 This doesn't call the function at exactly one second intervals, but
 that type of accuracy is rarely important.  Instead, it guarantees you
 have at least one second of delay between invocations, which for
 distributing cpu load or polling (the more common cases where
 setInterval might be used), is more desireable.

 Finally, as Joe T. points out, there should be a way of cancelling the
 interval that doesn't require the user to store the returned value
 (*that* is what I find most annoying, not the syntax of
 setInterval).

 Thus, I'd suggest this instead:

  Object.extend(Function.prototype, {
repeat: function(delay) {
  // Reset state
  if (this._repeater) delete this._repeater;
  this._repeatTimeout = clearTimeout(this._repeatTimeout);

  if (!delay) return; // (stop repeating if no args or delay==0)

  // Create setTimeout-based invoker
  var _method = this;
  if (!this._repeater) this._repeater = function() {
// Let _method cancel repeat by doing return false;
if (_method() !== false) setTimeout(_method._repeater, delay);
  }

  // Start repeating
  this._repeatTimeout = setTimeout(this._repeater, delay);
},

stopRepeating: function() {
  this.repeat();
}
  });

 For example:

  var count = 0;
  function foo() {
console.log(count++);
return count  10;  // Return false when count = 10 to cancel
 the repeat
  }

  // Start repeating 1/sec
  foo.repeat(1000);
  //... some time later change interval to 2/sec
  foo.repeat(500);
  // ... later still stop repeating.
  foo.stopRepeating();


 As you can see, this implementation of repeat() does a lot more for
 you than simply alias'ing setInterval:
  - It guarantees your function is only invoked by one interval
  - It makes changing the interval or cancelling it altogether
 trivial.
  - It allows you to conditionally cancel the repeat from w/in the
 function itself.

 The only thing missing is the bind() behavior but, well, that's what
 bind is for.   If you need to bind arguments, just bind() your
 arguments first.

 On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
  I detest the way setInterval() looks, so I came up with this... have
 been
  using it my personal JS for some time.
 
  Object.extend(Function.prototype, {
repeat: function() {
  var __method = this, args = $A(arguments), interval = args.shift() *
  1000;
  return window.setInterval(function() {
return __method.apply(__method, args);
  }, interval );
}
 
  });
 
  // usage:
  var _pollInt = 0;
  function repetiousPollFn() {
   console.log(_pollInt++);
 
  }
 
  repetiousPollFn.repeat(.5);
 
  Will, of course, repeat repetiousPollFn() every half second.
 
  Almost identical to .delay(), except that it returns setInterval instead
 of
  setTimeout. One thing I intend to add is support for clearInterval,
 however
  I figured I'd at least bring it up here first. I've never
  proposed/contributed here before (i'm a lurker of the list :D ) - any
  guidance is appreciated.
 
  Rick
 



--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...]) -- Revised from Robert's version

2009-06-24 Thread Rick Waldron
I made a few modifications to your version, allowing repeat() to behave like
delay() with regard to arguments

I've posted a demo here:

http://jsbin.com/ekone


All the output is to the firebug console... i've included fbug lite just in
case



Rick




On Wed, Jun 24, 2009 at 10:50 AM, Rick Waldron waldron.r...@gmail.comwrote:

 I've subbed my implementation with your to do some use-case testing. I'll
 report back anything of interest as I go along.

 Rick


 On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron waldron.r...@gmail.comwrote:

 This is fantastic feedback - thanks!






 On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com wrote:


 I can't say I'm a big fan of this.  For several reasons.

 First, it's just a cosmetic replacement for setInterval(myfunction
 (...).bind(), ...) which simply isn't all that bad.

 Second, I'm not a fan of setInterval in general.  I've seen some
 rather nasty behavior with calls queuing up if the invoked function
 takes longer than the delay to execute.  In particular, this seems to
 be an issue if you do something like put a laptop to sleep.  (But
 maybe others haven't seen this problem???)  Thus, I prefer to use a
 self-invoking timeout like so:

 function myFunction() {
// do stuff ...
// call ourselves again
if (/*we want to continue?*/) setTimeout(myFunction, 1000)
 }

 This doesn't call the function at exactly one second intervals, but
 that type of accuracy is rarely important.  Instead, it guarantees you
 have at least one second of delay between invocations, which for
 distributing cpu load or polling (the more common cases where
 setInterval might be used), is more desireable.

 Finally, as Joe T. points out, there should be a way of cancelling the
 interval that doesn't require the user to store the returned value
 (*that* is what I find most annoying, not the syntax of
 setInterval).

 Thus, I'd suggest this instead:

  Object.extend(Function.prototype, {
repeat: function(delay) {
  // Reset state
  if (this._repeater) delete this._repeater;
  this._repeatTimeout = clearTimeout(this._repeatTimeout);

  if (!delay) return; // (stop repeating if no args or delay==0)

  // Create setTimeout-based invoker
  var _method = this;
  if (!this._repeater) this._repeater = function() {
// Let _method cancel repeat by doing return false;
if (_method() !== false) setTimeout(_method._repeater, delay);
  }

  // Start repeating
  this._repeatTimeout = setTimeout(this._repeater, delay);
},

stopRepeating: function() {
  this.repeat();
}
  });

 For example:

  var count = 0;
  function foo() {
console.log(count++);
return count  10;  // Return false when count = 10 to cancel
 the repeat
  }

  // Start repeating 1/sec
  foo.repeat(1000);
  //... some time later change interval to 2/sec
  foo.repeat(500);
  // ... later still stop repeating.
  foo.stopRepeating();


 As you can see, this implementation of repeat() does a lot more for
 you than simply alias'ing setInterval:
  - It guarantees your function is only invoked by one interval
  - It makes changing the interval or cancelling it altogether
 trivial.
  - It allows you to conditionally cancel the repeat from w/in the
 function itself.

 The only thing missing is the bind() behavior but, well, that's what
 bind is for.   If you need to bind arguments, just bind() your
 arguments first.

 On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
  I detest the way setInterval() looks, so I came up with this... have
 been
  using it my personal JS for some time.
 
  Object.extend(Function.prototype, {
repeat: function() {
  var __method = this, args = $A(arguments), interval = args.shift()
 *
  1000;
  return window.setInterval(function() {
return __method.apply(__method, args);
  }, interval );
}
 
  });
 
  // usage:
  var _pollInt = 0;
  function repetiousPollFn() {
   console.log(_pollInt++);
 
  }
 
  repetiousPollFn.repeat(.5);
 
  Will, of course, repeat repetiousPollFn() every half second.
 
  Almost identical to .delay(), except that it returns setInterval
 instead of
  setTimeout. One thing I intend to add is support for clearInterval,
 however
  I figured I'd at least bring it up here first. I've never
  proposed/contributed here before (i'm a lurker of the list :D ) - any
  guidance is appreciated.
 
  Rick
 




--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-24 Thread Tobie Langel

Just to clarify the above: Prototype Core already contains a similar
functionality: PeriodicalExecuter. The API is different but the
functionality is the same.

I'd strongly suggest looking into combining both approaches if you
want your suggestion to be included in core and not just stay a thread
in the mailing list. :)

Best,

Tobie

On Jun 24, 4:50 pm, Rick Waldron waldron.r...@gmail.com wrote:
 I've subbed my implementation with your to do some use-case testing. I'll
 report back anything of interest as I go along.

 Rick

 On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron waldron.r...@gmail.comwrote:



  This is fantastic feedback - thanks!

  On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com wrote:

  I can't say I'm a big fan of this.  For several reasons.

  First, it's just a cosmetic replacement for setInterval(myfunction
  (...).bind(), ...) which simply isn't all that bad.

  Second, I'm not a fan of setInterval in general.  I've seen some
  rather nasty behavior with calls queuing up if the invoked function
  takes longer than the delay to execute.  In particular, this seems to
  be an issue if you do something like put a laptop to sleep.  (But
  maybe others haven't seen this problem???)  Thus, I prefer to use a
  self-invoking timeout like so:

  function myFunction() {
     // do stuff ...
     // call ourselves again
     if (/*we want to continue?*/) setTimeout(myFunction, 1000)
  }

  This doesn't call the function at exactly one second intervals, but
  that type of accuracy is rarely important.  Instead, it guarantees you
  have at least one second of delay between invocations, which for
  distributing cpu load or polling (the more common cases where
  setInterval might be used), is more desireable.

  Finally, as Joe T. points out, there should be a way of cancelling the
  interval that doesn't require the user to store the returned value
  (*that* is what I find most annoying, not the syntax of
  setInterval).

  Thus, I'd suggest this instead:

   Object.extend(Function.prototype, {
     repeat: function(delay) {
       // Reset state
       if (this._repeater) delete this._repeater;
       this._repeatTimeout = clearTimeout(this._repeatTimeout);

       if (!delay) return; // (stop repeating if no args or delay==0)

       // Create setTimeout-based invoker
       var _method = this;
       if (!this._repeater) this._repeater = function() {
         // Let _method cancel repeat by doing return false;
         if (_method() !== false) setTimeout(_method._repeater, delay);
       }

       // Start repeating
       this._repeatTimeout = setTimeout(this._repeater, delay);
     },

     stopRepeating: function() {
       this.repeat();
     }
   });

  For example:

   var count = 0;
   function foo() {
     console.log(count++);
     return count  10;  // Return false when count = 10 to cancel
  the repeat
   }

   // Start repeating 1/sec
   foo.repeat(1000);
   //... some time later change interval to 2/sec
   foo.repeat(500);
   // ... later still stop repeating.
   foo.stopRepeating();

  As you can see, this implementation of repeat() does a lot more for
  you than simply alias'ing setInterval:
   - It guarantees your function is only invoked by one interval
   - It makes changing the interval or cancelling it altogether
  trivial.
   - It allows you to conditionally cancel the repeat from w/in the
  function itself.

  The only thing missing is the bind() behavior but, well, that's what
  bind is for.   If you need to bind arguments, just bind() your
  arguments first.

  On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
   I detest the way setInterval() looks, so I came up with this... have
  been
   using it my personal JS for some time.

   Object.extend(Function.prototype, {
     repeat: function() {
       var __method = this, args = $A(arguments), interval = args.shift() *
   1000;
       return window.setInterval(function() {
         return __method.apply(__method, args);
       }, interval );
     }

   });

   // usage:
   var _pollInt = 0;
   function repetiousPollFn() {
    console.log(_pollInt++);

   }

   repetiousPollFn.repeat(.5);

   Will, of course, repeat repetiousPollFn() every half second.

   Almost identical to .delay(), except that it returns setInterval instead
  of
   setTimeout. One thing I intend to add is support for clearInterval,
  however
   I figured I'd at least bring it up here first. I've never
   proposed/contributed here before (i'm a lurker of the list :D ) - any
   guidance is appreciated.

   Rick
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en

[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-24 Thread Robert Kieffer

FWIW, PeriodicalExecuter has always struck me as a bit of a wart on
the Prototype API. The name and usage are awkward, and it's
functionality really feels like something that should just be a
Function extension, as we're seeing in this thread.  I'm assuming it's
presence is mostly a legacy thing.

But... I'm not really arguing for it's removal.  Just pissing into the
wind.  :-)

On Jun 24, 9:53 am, Tobie Langel tobie.lan...@gmail.com wrote:
 Just to clarify the above: Prototype Core already contains a similar
 functionality: PeriodicalExecuter. The API is different but the
 functionality is the same.

 I'd strongly suggest looking into combining both approaches if you
 want your suggestion to be included in core and not just stay a thread
 in the mailing list. :)

 Best,

 Tobie
--~--~-~--~~~---~--~~
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 
prototype-core-unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-24 Thread Rick Waldron
Tobie,

I had in fact looked into PeriodicalExecuter and to be perfectly honest,
with no offense intended, i think it's usage syntax is hideous which is what
led me to writing my own Function.prototype method instead, taking
inspiration from .delay()

It doesnt matter to me whether or not .repeat() makes it into the prototype
core - I will always have it at my disposal, I simply wanted to share the
concept with the group.

I think everything I've said sounds like I'm in a bad mood, sorry about
that! :D


Rick


On Wed, Jun 24, 2009 at 12:53 PM, Tobie Langel tobie.lan...@gmail.comwrote:


 Just to clarify the above: Prototype Core already contains a similar
 functionality: PeriodicalExecuter. The API is different but the
 functionality is the same.

 I'd strongly suggest looking into combining both approaches if you
 want your suggestion to be included in core and not just stay a thread
 in the mailing list. :)

 Best,

 Tobie

 On Jun 24, 4:50 pm, Rick Waldron waldron.r...@gmail.com wrote:
  I've subbed my implementation with your to do some use-case testing. I'll
  report back anything of interest as I go along.
 
  Rick
 
  On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron waldron.r...@gmail.com
 wrote:
 
 
 
   This is fantastic feedback - thanks!
 
   On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com
 wrote:
 
   I can't say I'm a big fan of this.  For several reasons.
 
   First, it's just a cosmetic replacement for setInterval(myfunction
   (...).bind(), ...) which simply isn't all that bad.
 
   Second, I'm not a fan of setInterval in general.  I've seen some
   rather nasty behavior with calls queuing up if the invoked function
   takes longer than the delay to execute.  In particular, this seems to
   be an issue if you do something like put a laptop to sleep.  (But
   maybe others haven't seen this problem???)  Thus, I prefer to use a
   self-invoking timeout like so:
 
   function myFunction() {
  // do stuff ...
  // call ourselves again
  if (/*we want to continue?*/) setTimeout(myFunction, 1000)
   }
 
   This doesn't call the function at exactly one second intervals, but
   that type of accuracy is rarely important.  Instead, it guarantees you
   have at least one second of delay between invocations, which for
   distributing cpu load or polling (the more common cases where
   setInterval might be used), is more desireable.
 
   Finally, as Joe T. points out, there should be a way of cancelling the
   interval that doesn't require the user to store the returned value
   (*that* is what I find most annoying, not the syntax of
   setInterval).
 
   Thus, I'd suggest this instead:
 
Object.extend(Function.prototype, {
  repeat: function(delay) {
// Reset state
if (this._repeater) delete this._repeater;
this._repeatTimeout = clearTimeout(this._repeatTimeout);
 
if (!delay) return; // (stop repeating if no args or delay==0)
 
// Create setTimeout-based invoker
var _method = this;
if (!this._repeater) this._repeater = function() {
  // Let _method cancel repeat by doing return false;
  if (_method() !== false) setTimeout(_method._repeater, delay);
}
 
// Start repeating
this._repeatTimeout = setTimeout(this._repeater, delay);
  },
 
  stopRepeating: function() {
this.repeat();
  }
});
 
   For example:
 
var count = 0;
function foo() {
  console.log(count++);
  return count  10;  // Return false when count = 10 to cancel
   the repeat
}
 
// Start repeating 1/sec
foo.repeat(1000);
//... some time later change interval to 2/sec
foo.repeat(500);
// ... later still stop repeating.
foo.stopRepeating();
 
   As you can see, this implementation of repeat() does a lot more for
   you than simply alias'ing setInterval:
- It guarantees your function is only invoked by one interval
- It makes changing the interval or cancelling it altogether
   trivial.
- It allows you to conditionally cancel the repeat from w/in the
   function itself.
 
   The only thing missing is the bind() behavior but, well, that's what
   bind is for.   If you need to bind arguments, just bind() your
   arguments first.
 
   On Jun 23, 8:25 am, Rick Waldron waldron.r...@gmail.com wrote:
I detest the way setInterval() looks, so I came up with this... have
   been
using it my personal JS for some time.
 
Object.extend(Function.prototype, {
  repeat: function() {
var __method = this, args = $A(arguments), interval =
 args.shift() *
1000;
return window.setInterval(function() {
  return __method.apply(__method, args);
}, interval );
  }
 
});
 
// usage:
var _pollInt = 0;
function repetiousPollFn() {
 console.log(_pollInt++);
 
}
 
repetiousPollFn.repeat(.5);
 
Will, of course, repeat repetiousPollFn() every half second.
 
Almost identical to 

[Prototype-core] Re: Suggested addition to Function Methods: .repeat(seconds[, arg...])

2009-06-24 Thread Tobie Langel

Hi Rick, hi Robert.

Fully agree regarding PE. It does however handle issues a regular
setInterval doesn't (as you mentioned).

It's clearly an area which would need refinement, but that's better
done in a backwards compatible way.

Personally, I'd love to see PE implemented as a method of Function
instances.

So since this is the core mailing list, I'm trying to give directions
on how it could be best implemented given legacy constraints and
consistency with the rest of the API.

Clearly, consistency with Function#defer and Function#delay would
imply returning a setInterval index. Unfortunately, since setTimeout
is used instead of setInterval, this isn't possible.

Maybe the simplest solution would be to make Function#repeat return an
instance of PE. Implementation would then be roughly:

Function.prototype.repeat = function(interval) {
  return new PeriodicalExecuter(this, interval);
}

Note that in that case, modifying Function#delay and Function#defer to
return a PE-like object instance with a stop method would make more
sense API wise, but at the expense of a larger memory footprint and
backwards compatibility.

As you can see, making the right choice isn't simple.

Best,

Tobie

On Jun 24, 11:28 pm, Rick Waldron waldron.r...@gmail.com wrote:
 Tobie,

 I had in fact looked into PeriodicalExecuter and to be perfectly honest,
 with no offense intended, i think it's usage syntax is hideous which is what
 led me to writing my own Function.prototype method instead, taking
 inspiration from .delay()

 It doesnt matter to me whether or not .repeat() makes it into the prototype
 core - I will always have it at my disposal, I simply wanted to share the
 concept with the group.

 I think everything I've said sounds like I'm in a bad mood, sorry about
 that! :D

 Rick

 On Wed, Jun 24, 2009 at 12:53 PM, Tobie Langel tobie.lan...@gmail.comwrote:





  Just to clarify the above: Prototype Core already contains a similar
  functionality: PeriodicalExecuter. The API is different but the
  functionality is the same.

  I'd strongly suggest looking into combining both approaches if you
  want your suggestion to be included in core and not just stay a thread
  in the mailing list. :)

  Best,

  Tobie

  On Jun 24, 4:50 pm, Rick Waldron waldron.r...@gmail.com wrote:
   I've subbed my implementation with your to do some use-case testing. I'll
   report back anything of interest as I go along.

   Rick

   On Wed, Jun 24, 2009 at 10:49 AM, Rick Waldron waldron.r...@gmail.com
  wrote:

This is fantastic feedback - thanks!

On Wed, Jun 24, 2009 at 9:55 AM, Robert Kieffer bro...@gmail.com
  wrote:

I can't say I'm a big fan of this.  For several reasons.

First, it's just a cosmetic replacement for setInterval(myfunction
(...).bind(), ...) which simply isn't all that bad.

Second, I'm not a fan of setInterval in general.  I've seen some
rather nasty behavior with calls queuing up if the invoked function
takes longer than the delay to execute.  In particular, this seems to
be an issue if you do something like put a laptop to sleep.  (But
maybe others haven't seen this problem???)  Thus, I prefer to use a
self-invoking timeout like so:

function myFunction() {
   // do stuff ...
   // call ourselves again
   if (/*we want to continue?*/) setTimeout(myFunction, 1000)
}

This doesn't call the function at exactly one second intervals, but
that type of accuracy is rarely important.  Instead, it guarantees you
have at least one second of delay between invocations, which for
distributing cpu load or polling (the more common cases where
setInterval might be used), is more desireable.

Finally, as Joe T. points out, there should be a way of cancelling the
interval that doesn't require the user to store the returned value
(*that* is what I find most annoying, not the syntax of
setInterval).

Thus, I'd suggest this instead:

 Object.extend(Function.prototype, {
   repeat: function(delay) {
     // Reset state
     if (this._repeater) delete this._repeater;
     this._repeatTimeout = clearTimeout(this._repeatTimeout);

     if (!delay) return; // (stop repeating if no args or delay==0)

     // Create setTimeout-based invoker
     var _method = this;
     if (!this._repeater) this._repeater = function() {
       // Let _method cancel repeat by doing return false;
       if (_method() !== false) setTimeout(_method._repeater, delay);
     }

     // Start repeating
     this._repeatTimeout = setTimeout(this._repeater, delay);
   },

   stopRepeating: function() {
     this.repeat();
   }
 });

For example:

 var count = 0;
 function foo() {
   console.log(count++);
   return count  10;  // Return false when count = 10 to cancel
the repeat
 }

 // Start repeating 1/sec
 foo.repeat(1000);
 //... some time later change