PubSub with return value

For this post we use the following implementation of the pubsub pattern: pubsub with a twist

Ok, this one goes against some key benefits of the pubsub pattern. A subscriber is not supposed to return any value because it is breaking the lose coupling feature of the pattern. But lose-coupling is not the only benefit of pubsub. The other benefit is that it provides a framework to link functions at runtime. Let’s consider a class Cat, that publishes the event “signal_presence” and a class “mouse” that subscribes to it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Cat
  comesHome: ->
    pubsub.publish "signal_presence"
    @

class Mouse
  constructor: ->
    pubsub.subscribe "signal_presence", @get_the_f_out_of_here
  get_the_f_out_of_here: ->
    console.log "A mouse runs away..."

jerry = new Mouse
stuart = new Mouse
tom = (new Cat).comesHome()

output:
=======

A mouse runs away...
A mouse runs away...

The 0 to n mouse present in the room will be notified and do what mice do, hide in your toaster…
We can also have the same class subscribing and publishing the event:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Person
  setName: (name) ->
    @name = name
    @
  comesHome: ->
    pubsub.publish "signal_presence", @name
    pubsub.subscribe "signal_presence", @greetings
  leavesHome: ->
    pubsub.unsubscribe "signal_presence", @greetings
  greetings: (name) =>
    console.log "#{@name} says: @{name}!"

Rob = (new Person).setName("Rob").comesHome()
Marta = (new Person).setName("Marta").comeHome()

output:
=======

Rob Says: Marta!

Note that I used the fat arrow here so that the events callback preserve the context of the object and I can call @name.

Ok, so that was pubsub as we know it. Now, what if pubsub could return a value, it would change the implementation of the publish method from pubsub with a twist to:

1
2
3
4
5
6
7
8
9
10
11
  publish = (topic) ->
    event = cache[topic]
    if event and event.length>0
      callbackCount = event.length
      res = []
      while callbackCount--
        if event[callbackCount]
          res.push event[callbackCount].apply {}, Array.prototype.slice.call(arguments, 1)
      # some pubsub enhancement: see http://html5stars.com/blog/2012/10/20/pubsub-with-a-twist/
      publish topic+"_done"
      res

The variable “res” has been added. So now we could have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Person
  setName: (name) ->
    @name = name
    @
  comesHome: ->
    res = pubsub.publish "signal_presence", @name
    if res
      @answer(res.name) for person in res
    pubsub.subscribe "signal_presence", @howareyou
  leavesHome: ->
    pubsub.unsubscribe "signal_presence", @howareyou
  howareyou: (name) =>
    console.log "#{@name} says: @{name}, how are you?"
  answer: (name) =>
    console.log "#{@name} says: Doing well. thank you #{@name}"

Rob = (new Person).setName("Rob").comesHome()
Marta = (new Person).setName("Marta").comeHome()
Paul = (new Person).setName("Paul").comeHome()

output:
=======

Rob Says: Marta, how are you?
Marta Says: Doing well, thank you Rob
Rob Says: Paul, how are you?
Paul Says: Doing well, thank you Rob
Marta Says: Paul, how are you?
Paul Says: Doing well, thank you Marta

I have added that because I had a specific need where I wanted to know if an object had certain feature, but did not want to know how many instances of this object have been created and look through them. For this kind of need we can optimize the enhancement described here and let “res” be a variable, not an array. So that it would return only the return value of the last subscriber. Since I am using pubsub a lot in this program, saving the time used to instanciate an array and GCing every time seemed significant.

Includes and fat arrows

I have been using the module that adds extend and include capabilities to coffeescript classes, this module can be found here: The Little Book on CoffeeScript

Here is the implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Module
  moduleKeywords = ['extended', 'included']
  @extend: (obj) ->
    for key, value of obj when key not in moduleKeywords
      @[key] = value

    obj.extended?.apply(@)
    this

  @include: (obj) ->
    for key, value of obj when key not in moduleKeywords
      # Assign properties to the prototype
      @::[key] = value

    obj.included?.apply(@)
    this

It is very useful and you can now have an object and include it in any class. The example at the end of the article in The Little Book on CoffeeScript is probably the best:

1
2
3
4
5
6
7
8
9
ORM =
  find: (id) ->
  create: (attrs) ->
  extended: ->
    @include
      save: ->

class User extends Module
  @extend ORM

The micro template function is to handlebarjs what this is to backbonejs.

Anyway… there is one pitfall I wanted to point out, that I have not seen documented. You cannot use the fat arrow inside the ORM module. Which is as disapointing as understandable. For example, my class including the ORM module might want to save a user on click on a button (with the id “save”, for example):

1
2
3
4
class User extends Module
  @extend ORM
  constructor: ->
    document.getElementById("save").addEventListener "mousedown", @save

The solution to make this work is not:

1
2
3
4
5
6
7
ORM =
  find: (id) ->
  create: (attrs) ->
  extended: ->
    @include
      save: =>
        #@ referes to the window object... cannot save the user instance

You actually can’t use the fat arrow. The solution is to the module as is (ORM in this example) and changes the context before calling the module’s function (@save).

1
2
3
4
class User extends Module
  @extend ORM
  constructor: ->
    document.getElementById("save").addEventListener "mousedown", => @save()

The lightest javascript framework in the world

A little break from coffeescript. I wanted to write the smallest js framework possible, my aim was to make it shorter than a tweet. And it would be cheating to make it have dependencies. So, no coffeescript, no jQuery, no bullshit. It’s called the j-framework and here is the code (135 chars).

1
window.onload=function(){var a=document.getElementsByTagName('*'),m,l=a.length;while(l--) if(m=a[l].getAttribute("data-j")) j[m](a[l])}

The only concession I had to make, that bothers me, is that I have to use window.onload, instead of the better form window.addEventListener(“load”,…). So you can’t have any other listener on the window’s load event. Pretty sad. But otherwise, it’s actually a very useful little framework, a simplified version of theBeast (see heroku.theBeast.com). It leverages the declarative power of HTML and attaches javascript features to HTML element, making the whole thing more readable and maintainable.

Here is a short example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<script>
window.onload=function(){var a=document.getElementsByTagName('*'),m,l=a.length;while(l--) if(m=a[l].getAttribute("data-j")) j[m](a[l])}
window.j = {
  test: function(el){
    el.innerHTML = "the j framework rocks";
  }
}
</script>
<div data-j="test"></div>
<div data-j="test"></div>
<div data-j="test"></div>
<div data-j="test"></div>
</html>

All you need is to include the j-framework, declare a global j object (I put window.j to make it explicitely global, but window. is not necessary here) where your modules are keys. On load, the j-framework looks for element with attribute “data-j” and try to execute the correponding function.

OUTPUT:

1
2
3
4
the j framework rocks
the j framework rocks
the j framework rocks
the j framework rocks

A simple cross-browser profiler for your javascript code

Here is the code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
profiler = do ->
  debug = true # turn this to false if you don't want the profiler to run
  count = 0
  profiles = {}
  start: (name) ->
    if debug
      profiles[name] = [] if not profiles[name]
      profile =
        startTime: +new Date
        stop: -> this.stopTime = +new Date
      profiles[name].push profile
      profile
  show: ->
    for profileName of profiles
      console.log "------------------ #{profileName} ------------------"
      profile = profiles[profileName]
      totalTime = 0
      totalTime += iteration.stopTime - iteration.startTime for iteration in profile when iteration.stopTime
      console.log "Total time: #{totalTime}ms"
      console.log "Number of iterations: #{profile.length}"
      console.log "Average time: #{Math.roundHack((10*totalTime)/profile.length)/10}ms"
    null

And here, is how to use it

1
2
3
  profile = profiler.start "performance of doSomething()"
  doSomething()
  profile.stop()

Now go in the inspector and type

1
  profiler.show()

You will see how many time the function doSomething has been called, the average time/run, and the total time.
You can add as many profiles as you want they will all be listed by the command profiler.show()

Simple and useful? Hopefully…

Writing good code: 7 is the magic number

  • 7 lines of code in a function
  • 7 functions in a file
  • 7 files in a directory



That is as simplistic as unrealistic. Nevertheless I always keep that in mind when I write code. There are many other rules you can apply, but this is just my guideline.


Now, what about functions arguments? Well, we can put value to it and we’ll find that 7 still comes in handy.


Property of a parameter:

  • Type: integer, string, object…
  • Concept: dimension, UID, name…



So, count the number of arguments + number of concepts + number of types and try to keep it under 7


Example:

1
ctx.drawImage img, x, y


  • img is an object, the concept is an image
  • x is an integer, the concept is a dimension
  • y is an integer, the concept is a dimension



So, we have:

  • number of arguments: 3
  • number of concept: 2
  • number of types: 2



The arguments of drawImage has a weight of 7, which makes it easy to read.

pubsub with a twist

Here is a standard pubsub implementation in coffeescript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
window.pubsub = do ->
  "use strict"
  cache = {}

  publish: (topic) ->
    event = cache[topic]
    if event
      callbackCount = event.length
      while callbackCount--
        event[callbackCount].apply {}, Array.prototype.slice.call(arguments, 1)

  subscribe: (topic, callback) ->
    cache[topic] = [] unless cache[topic]
    cache[topic].push callback
    [ topic, callback ]

  unsubscribe: (topic, callback) ->
    if cache[topic]
      callbackCount = cache[topic].length
      while callbackCount--
        if cache[topic][callbackCount] is callback
          cache[topic].splice callbackCount, 1

  isSubscribed: (topic, callback) ->
    res = false
    if cache[topic]
      callbackCount = cache[topic].length
      while callbackCount--
        if cache[topic][callbackCount] is callback
          res = true
    res

On my last project I realized that I was missing a piece of functionality that is similar to jQuery deferred action (see here for more on the subject).

Well, it turned out to be really easy to add what I need, only 1 line of code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
window.pubsub = do ->
  "use strict"
  cache = {}

  publish: (topic) ->
    event = cache[topic]
    if event
      callbackCount = event.length
      while callbackCount--
        event[callbackCount].apply {}, Array.prototype.slice.call(arguments, 1)
      # some pubsub enhancement: we can get notified when everything
      # has been published by registering to topic+"_done"
      @publish topic+"_done"

  subscribe: (topic, callback) ->
    cache[topic] = [] unless cache[topic]
    cache[topic].push callback
    [ topic, callback ]

  unsubscribe: (topic, callback) ->
    if cache[topic]
      callbackCount = cache[topic].length
      while callbackCount--
        if cache[topic][callbackCount] is callback
          cache[topic].splice callbackCount, 1

  isSubscribed: (topic, callback) ->
    res = false
    if cache[topic]
      callbackCount = cache[topic].length
      while callbackCount--
        if cache[topic][callbackCount] is callback
          res = true
    res

Everything happens on line 13!

So, let’s say on window.onload you publish the topic “init”:

1
window.onload = ->pubsub.publish "init"

Some init module can now all the initializations:

1
2
3
4
5
6
7
8
9
10
initModule1 = do ->
  pubsub.subscribe "init", ->
    initModule1.foo1 = "bar1"
    # more init...
  {}
initModule2 = do ->
  pubsub.subscribe "init", ->
    initModule2.foo2 = "bar2"
    # more init...
  {}

Then, the other modules can access be triggered after init is completed:

1
2
3
4
myModule = do ->
  pubsub.subscribe "init_done", ->
     myModule.allFoo = "#{initModule1.foo1} and #{initModule2.foo2}"
  {}

You can also go deeper, if a module need to access myModule.allFoo, you can do

1
2
3
4
myDeepModule = do ->
  pubsub.subscribe "init_done_done" ->
    myDeepModule.allFoo2 = "#{myModule.allFoo}2"
  {}

Of course you would generally not want to make something so tricky, but in some cases it comes in handy, it is simple, and you really don’t need to write much code. So I like to think that it’s pretty clean…

Modulo

Short note on the modulo operator, let’s say you have the following:

1
2
myArray = ["el1", "el2", "el3", "el4"]
cursorInMyArray = 0

and you want to implement the function shiftIndex that increment or decrement cursorInMyArray in a cyclic manner. You have 2 possibilities

1
2
3
4
shiftIndex = (shift) ->
  cursorInMyArray += shift;
  cursorInMyArray = myArray.length-1 if cursorInMyArray<0
  cursorInMyArray = 0 if cursorInMyArray === myArray.length

or

1
2
shiftIndex = (shift) ->
  cursorInMyArray = (cursorInMyArray+shift+myArray.length) % myArray.length

More readable, less readable? Geschmacksache

A bon entendeur, salut!

Coffescript instance variable

I have been using coffeescript for a while, on my last project (a personal project), I encountered an issue that first freaked me out, but now I calmed down…

Take the following class:

1
2
3
4
5
6
class Animal
  name: ""
  power: []
  constructor: (n, p) ->
    @name = n
    @power.push(p) if p

Now take the following instances

1
2
monkey = new Animal("super monkey", "lightning")
mydog = new Animal("dog")

Well, now guess what? My dog has the lightning super power!
This is because it shares the same initialized value for the power instance variable: [], which is short for new Array[]. So, to avoid this issues, we should avoid initializing object at the class level, this should be done in the constructor:

1
2
3
4
5
6
7
class Animal
  name: ""
  power: null
  constructor: (n, p) ->
    @power = []
    @name = n
    @power.push(p) if p

Here you go, now mydog does not have any super power anymore!

theBeast.js

I have been working at Huge as a lead front end developer for almost a year now. From the first project I started, I have tried to find a way to organize code that gives a maximum freedom to the developer and which can be adopted fairly easily. It is somewhere between a full fledged MVC front-end, and plain old procedural JS coding.

I used this on 4 project, 3 of which or live and on production. This mini-framework has evolved it now has unit test and all the features that are required to be used as is, that is why it is now a V1.0. Since I coded this framework while working on real projects, the features are there to solve real life problems of mid-size projects. Bigger projects would probably need something more advanced like spine.js or backbone.js.

But enough said, There is a well documented tutorial: http://theBeast.heroku.com. And you can find the source code with the unit tests at https://github.com/standup75/theBeast

JS PubSub enhanced

This is not exactly HTML5 related, but it’s what I call the bof (backend of the frontend), and helped me a lot getting things clean and organized.

I was working on a project which had a very heavy front-end. It was relying on several back-ends I was taking information from and consolidating on the front-end. The front-end has several modules, and one or more needed to be updated every time I receive data. I can imagine a HTML5 game having the same kind of problematic where modules need to communicate but stay independent

Here is my (jQuery) solution, a small piece of js that I call eventer

Let’s take an example.



The game is handled in game.js which has a function that scores points:

1
2
3
4
5
6
7
8
var game = game || Eventer.extend({
scorePoints: function(score) {
$.publish("SCORE_UPDATED", score);
},
init: function() {
// the game here
}
});

You add the Event at the beginning of eventer.js

1
var customEventList = ["SCORE_UPDATED"];

now you can just create a function onScoreUpdated in a class called (for example) userInfo:

1
2
3
4
5
6
7
8
9
var userInfo = userInfo || Eventer.extend({
onScoreUpdated: function(score) {
  // code to update the DOM with the new score like:
  $("#score").text(score);
},
init: function() {
// the user info module here
}
});

So you don’t need to explicitly link the event with the onScoreUpdated function, eventer is doing that for you, camelize the name of the event, add on, and look for a function with that name

Your modules become very independant and easy to handle

Hope that can help