Nerd Talk

My CoffeeScript Enlightenment: Class Variables

For the longest time, I have used JavaScript without any classes. I never even once thought that classes were possible in JavaScript. That is, until I discovered JavaScript’s secret feature, Ruby mode. I think some people call it CoffeeScript, but whatever, JavaScript’s Ruby mode is one of the absolute BEST abstractions that I have ever used. That’s coming from someone who has never used a language abstraction before, but enough of the small talk. Moving on, I want to share a little about classes in JavaScript’s Ruby mode and explain how it works.

In the following example here, we have a class in CoffeeScript. For most object orientated programmers, this is pretty straight forward and it shouldn’t be a surprise to anyone.

class HelloWorld
  personsName = null
  greeting = null

  setName: (name) ->
    personsName = name

  setGreeting: (greet) ->
    greeting = greet

  greet: () ->
      console.log greeting, personsName

Just to go over the class briefly:

  • We have a class named HelloWorld.
  • We have 2 class variables that are initialised to null.
  • We have 2 mutator methods, 1 for each variable.
  • We have a greet method that prints these 2 variables to screen.

Let’s instantiate it, and say hello!

JapanesePerson = new HelloWorld()
JapanesePerson.setGreeting "こにちは"
JapanesePerson.setName "あさみ"
JapanesePerson.greet()
# こにちは あさみ

As expected, the JapanesePerson greeted us in Japanese with こにちは あさみ. So far so good, grrreat!

tonythetiger

Let’s have the EnglishPerson greet us now!

EnglishPerson = new HelloWorld()
EnglishPerson.greet()

Oh whoops, I forgot to set the variables, but that’s not problem since the variables are initialised to null anyways.

YEAH FUCKING RIGHT BECAUSE RUBY MODE COMES WITH RUBY MAGIC.

If you ask the EnglishPerson to greet you here, she would actually speak Japanese and say こにちは あさみ.

So what the fuck CoffeeScript? Why you many unpredictable? Let’s take a deeper look into the compiled JavaScript and see what is actually happening.

var EnglishPerson, HelloWorld, JapanesePerson;

HelloWorld = (function() {
 var greeting, personsName;

 function HelloWorld() {}

 personsName = null;

 greeting = null;

 HelloWorld.prototype.setName = function(name) {
 return personsName = name;
 };

 HelloWorld.prototype.setGreeting = function(greet) {
 return greeting = greet;
 };

 HelloWorld.prototype.greet = function() {
 return console.log(greeting, personsName);
 };

 return HelloWorld;

})();

JapanesePerson = new HelloWorld();
JapanesePerson.setGreeting("こにちは");
JapanesePerson.setName("あさみ");
JapanesePerson.greet();

EnglishPerson = new HelloWorld();
EnglishPerson.greet();

In this JavaScript example, we have a variable with an anonymous function that is evaluated right away (self-invoking as some say), and inside that, we have a HelloWorld prototype setup and then we return the prototype.

As you see here the two variables, greeting and personsName, are outside of the object constructor. Instantiating HelloWorld is as expected, you get a new object. But the interesting part here is the two variables. The reason why the EnglishPerson was greeting in Japanese was because of closures. Closures remember the outer scope variables that it was created in, so since HelloWorld was created within the self-invoking anonymous function already, creating a new object from the returned object constructor allowed the EnglishPerson and the JapanesePerson to speak the same language.

All in all, the nuances of Ruby mode is a small price to pay for the amount of value you get if you ignore debugging the abstraction part. I did have different expectations of behaviors between the CoffeeScript code and the JavaScript code, but this shouldn’t serve as a deterrent for using Ruby mode.  Different expectations, more disappointment.

 

Don’t get fancy with JavaScript

Today, I thought it would be a good idea to finally apply all the JavaScript knowledge  that I have accumulated in the past few months. While I was at it, I thought it would be a good idea to review all the Computer Sciencey stuff like design patterns, and sorting algorithms. For design patterns, I decided to use the command pattern, the strategy pattern, and the factory method pattern. For the sorting, I used merge sort, selection sort, and insertion sort. I implemented the merge sort, and it sorted 1,000 numbers perfectly; But 1,000 numbers is nothing, so I bumped it up to a million to see how fast it could sort 1,000,000 numbers, but it started hanging and performed like shit.

At first, I thought it might have been my number generator taking too long to generate my array of random numbers. A console.log later, and I quickly found out that the counter in my for-loop would hang at 99,999. No biggie there, I rewrote it with a while-loop and just counted down to 0. Time to start sailing.

     function TopDownSplitMerge(arrayOfNumbers) {
            var length = arrayOfNumbers.length
            var middleIndex = parseInt(length/2);

            if(length <= 1) {
                return arrayOfNumbers;
            }

            // Split left side
            var left = TopDownSplitMerge(arrayOfNumbers.slice(0, middleIndex));

            // Split right side
            var right = TopDownSplitMerge(arrayOfNumbers.slice(middleIndex, length-1));

            // Merge every back together
            return TopDownMerge(left, right);
        }

        function TopDownMerge(left, right) {
            var results = []

            while(left.length || right.length) {
                // Check if both sides are NOT empty, if so, then just finish shifting the non-empty side
                if(left.length && right.length) {
                    if(left[0] <= right[0]) {
                       results.push(left.shift())
                    } else {
                       results.push(right.shift())
                    }
                } else if(left.length) {
                   results.push(left.shift())
                } else {
                   results.push(right.shift())
                }

            }

What do you think? It shouldn’t be a problem right? And look at all the fancy JavaScript array functions that I am using. Gotta drink that Kool-aid!

kool-aid-man

10 minutes later. My terminal explodes and gives me this:

FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory

I knew that there was no way merge sort would take this long since I implemented it in Java before. Upon closer observation, my next culprit was the slice() function because I thought it would have to use some kind of loop in order for it to copy the elements in order to return a new array. I did some Googling and found this StackOverflow post saying:

… all JavaScript objects (including Array instances) are maps…

Well, that explains a lot. That means, not only is the slice() hurting my performance, but the shift() is as well. For each recursion, I was running a bajillion slices times a bajillion shifts resulting in O(bajillion²). I ended up keeping track of indexes and just directly accessing the element in the array, and I was able to sort 10,000,000,000 numbers in 14360 milliseconds. The lesson here is to stick with the proven algorithm, and to not get fancy with JavaScript.

You can find the rest of my code here: JavaScript Sorting Algorithms

Debugging CSS and JavaScript Hovers

The other day I had to debug a mouse hover tooltip at work and the problem was that the hover element was appearing in the wrong position; It was supposed to appear directly above the link, but it was completely offset to the left side.

For this post, I will be using Chrome’s Developer Tools and I will be using Bootstrap’s tooltips as an example. The first image is an example of how the tooltip should appear, and the second picture is an example of how the hover was offset.

Bootstrap Tooltip Hover

Bootstrap Tooltip Hover (Expected Behavior)

Bootstrap Tooltip Offset (Unexpected Behavior)

Bootstrap Tooltip Offset (Unexpected Behavior)

 

Debugging CSS Hovers

If this was just a pure CSS hover, you could force the CSS :hover state by right clicking on the element Force Element State > :hover. After forcing the hover state, you can proceed to debug normally.

Debugging a CSS hover state with Chrome

Debugging a CSS hover state with Chrome

 

Using this method, you will be able to see all the CSS changes in the hover state as seen in the following picture.

Forcing the hover state in Chrome

Forcing the hover state in Chrome

Notice that the only change in the hover state is the color of the link and the underline; It is also missing the actual tooltip. If this is the case, this is usually an indicator that there is JavaScript involved and that there is a mouseover event attached to the element; You will need to force the hover state in JavaScript.

Debugging JavaScript Hovers

When debugging JavaScript, it is pretty similar to debugging in Java. You can set breakpoints for where the execution would stop. However, it’s a little different in JavaScript since it is an event based language; There is a different concept of breakpoints called “Event Listener Breakpoints” which means the program would pause after a certain event is triggered.  In this scenario, I wanted the program to Pause after I clicked on something, so I went ahead and set a breakpoint for a mouse click event.

Adding a Even Listener mouse click break pointer

Adding a Event Listener mouse click break pointer

 

Next, I would hover over the tooltip and then click to trigger the breakpoint. Afterwards, you will see something similar to the following screenshot. The browser will go dim and you will see a message telling you that it is Paused and you will see the hover.

Paused after mouse click breakpoint

Paused after mouse click breakpoint

 

If you accidentally clicked somewhere else and triggered the breakpoint by mistake, you can always unpause the state by clicking the play button.

After hitting a break point, it will say "Paused" on the right

After hitting a break point, it will say “Paused” on the right

When Paused, you can always click the play icon to resume the normal flow

When Paused, you can always click the play icon to resume the normal flow

 

When you’re in the pause state, you can start debugging the element and see what CSS styles are being applied to the hover element. I noticed you cannot just use the selector and visually select your element, so the next best option is to just search for the element; I searched for “Tooltip on top”.

Now you can see the styles that are offsetting the tooltip and adjust the CSS styles as needed.

After pausing, you can now debug the CSS as normal

After pausing, you can now debug the CSS

After pausing, you can now fix the CSS

After pausing, you can now fix the CSS

 

I was always able to get away with just looking for the :hover style. Other times, I would be able to apply the display: block; style to the hidden element to reveal the hover element. This was one of the first times where those techniques were not applicable because the element was being injected into the DOM via JavaScript; In turn, this forced me to discover and adopt a better practice which I hope would be useful to you as well.

Thanks for reading!