No CoffeeScript for Beginners

CoffeeScript is growing in popularity. Taking a tour around the recent web repositories on Github, you'll notice a lot of CoffeeScript being used instead of our good old Javascript. There was a heated debate on whether CoffeeScript is worth it, and the best answer is "You either hate it or love it". However, I think CoffeeScript is designed for programmers who already know Javascript well. For beginners, it actually makes their Javascript learning journey quite a lot harder. CoffeeScript has too much behind-the-scene magic that makes some of the essential Javascript behaviors not very obvious. Let's take a look at 2 of the most important Javascript features, execution context and prototypal inheritance and why CoffeeScript is not a good learning tool in those cases.

Execution context

Execution context is basically the environment the current code is being evaluated in. It is the reason for some prominent Javascript features that are well-beautified by CoffeeScript to the point that they are almost hidden to beginners.

Global context

At the bottom of the execution stack is always the global context which can be accessed by all. The language's dependence on a global context is the ugliest thing about Javascript and should be used with caution. CoffeeScript tries to avoid accidentally adding things to the global context by automatically wrapping all the code in a function call:

(function() {
  // Your code...
}).call(this);

as well as automatically adding var to every variable declaration. They are good practices every Javascript programmers should follow, but have become a behind-the-scene magic in CoffeeScript. Lots of beginners don't understand why global context is bad and why CoffeeScript does it that way. I often see people who are too used to CoffeeScript struggle with when and where to use global context when switching back to Javascript. Some of them even forget to use var most of the time. The result is very nasty.

Scope chain and this

The this keyword in Javascript is one of the most confusing things in the language, and most people learn it the hard way. In a nutshell, the value of this is determined during the creation stage of the execution context and refers to the context in which the function is called. It gets more and more confusing in the case of event handler. For example:

var Foo = function() {
  this.handler = function() {
    console.log(this);
  }
}
var foo = new Foo();
button.onclick = foo.handler;

this in this case is the button element, not the foo instance. For the handler function to get access to foo`, we can make use of scope chain:

var Foo = function() {
  var _this = this;
  this.handler = function() {
    console.log(_this);
  }
}
var foo = new Foo();
button.onclick = foo.handler;

Now handler has access to _this which is a reference to foo. CoffeeScript adds some syntactic sugar to this technique by using arrow function:

Foo = ->
  this.handler = =>
    console.log(this)

It hides away scope chain and closure, which is bad for beginners who haven't fully understood the concepts. I've seen a lot of my friends do this:

foo = 
  handler: =>
    console.log(this)

button.onclick = foo.handler

Guess what? this now refers to the global context because we cannot define _this in object literal! So It's better to learn the real thing before trying to be smart.

Notes: ES6 is going to introduce built-in arrow function which will not have its this defined in execution context. It allows this to be lexically picked up from the outer context where the function is defined.

Variable hoisting

Another effect of execution context is variable hoisting. Most experienced Javascript programmers are aware that all variables declarations are hoisted to the top of the function. So this behavior is expected:

var foo = "Hello";
(function() {
  console.log(foo);  // undefined because declaration of `foo` is hoisted to the top
  var foo = "Hello World";
})();

CoffeeScript makes this a little easier by automatically taking care of variable duplication:

foo = "Hello"
( ->
  console.log(foo)
  foo = "Hello World"
  bar = "Test"
)()

This translates to:

var foo = "Hello";
(function() {
  var bar;
  console.log(foo);  // "Hello"
  foo = "Hello World";
  return bar = "Test";
})();

Again, this is good for those who already know about variable hoisting. For beginners, having too much magic behind the scene almost makes them blind to this essential Javascript behavior. I can imagine a lot of "WTFs" given when they face unexpected behaviors working on projects without CoffeeScript support.

Prototypal Inheritance

Understanding prototypal inheritance is the gateway to mastering Javascript. The CoffeeScript way of writing classes and inheritances is a double-edge sword for beginners. On one hand, it makes it easier for them to write functional object hierarchy. On the other hand, it deprives them from fully understanding the language's prototypal core. For example:

class Person
  money: 0
tom = new Person()
tom.hasOwnProperty('money')  // false

This looks pretty much like Java, except the fact that tom actually doesn't have money as its own property. Some of my friends with Java background had a very hard time understanding this behavior when looking at the code above. Compared to this native Javascript code:

var Person = function() { };
Person.prototype.money = 0;
tom = new Person();

It's much clearer now that money is added to the prototype of Person, not directly to tom. Every Javascript programmer must know that the language doesn't have the concept of classes. But CoffeeScript makes this really confusing by adding a too convenient class declaration syntax. The transition from classical to prototypal way of thinking is not going to be easy if inexperienced programmers keep using classes in CoffeeScript like that.

I've been advising my beginner friends to learn as much as possible about Javascript before writing anything in CoffeeScript (unless they don't care about Javascript and only want the shortcut). Even better, they should learn all of Javascript "the good parts" and how to write good Javascript code. After all, CoffeeScript is just the good parts of Javascript with some syntactic sugar. If we already write good Javascript code, CoffeeScript is just a matter of preference.

Summary of ECMAScript 6 Major Features

ECMAScript 6, the new Javascript standard, is going to be released by the end of 2014. Dr. Axel Rauschmayer gave a presentation about its features at the O'Reilly Fluent Conference 2013 in San Francisco. The presentation slides can be found here. Here is my summary of what I think are the most major features of ES6 that benefit the majority of Javascript developers:

Blocked-scope variables

let is going to be included in ES6 which allows blocked-scope variable declaration. So no more "declaring your variables at the top of the function".

Lexical this

ES6 introduces "arrow function", which is a borrowed concept from CoffeeScript. Arrow functions don't have their owned this defined at the point they're called, so this refers to the context in which the functions are defined. For example:

function UiComponent {
  var button = document.getElementById(!#myButton!);
  button.addEventListener(!click!, => () {
    console.log(this);
  });
}

this in this case refers to the UIComponent object where the event handler is defined, not the global window object or any arbitrary object that calls the event handler.

Parameter default values

Setting default values for function parameters is now possible:

function(x, y = 3) { ... }

Defining prototypal inheritance in object literal

__proto__ is being included in ES6, making it possible to define prototypal inheritance in object literal:

var obj = {
  __proto__: someOtherObj,
  method: function() { ... }
}

So no more having to use the long form Object.create() as well as the weird confusing constructor and new pattern.

Introduction of Symbols

symbol is a new kind of primitive value, and each symbol is unique. This allows enum-style values, which have been a major deficiency in the language:

let red = Symbol();
let green = Symbol();
let blue = Symbol();
function handleColor(color) {
  switch (color) {
    case red:
      ...
    case green:
      ...
    case blue:
      ...
  }
} 

Given their uniqueness, symbols can be used as identifiers, such as object property keys:

let specialMethod = Symbol();
let obj = {
  [specialMethod]: function (arg) {
    ...
  }
};
obj[specialMethod](123);

This guarantees no name clashes among object properties that are symbols as well as enables computed property name.

Introduction of Classes

I'm not sure whether it's a good thing to include classes in the Javascript standard, since Javascript is not a "classical" language. But in ES6, it's now possible to do this:

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  toString() {
    return !(!+this.x+!, !+this.y+!)!;
  }
}

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // same as super.constructor(x, y)
    this.color = color;
  }
  toString() {
    return this.color+! !+super();
  }
}

This seems to me like Javascript is going back to the conventional classical object oriented way of doing things. Classes hide the language's prototypal core, which makes it more confusing for beginners. It's just my opinion, of course the ECMA committee has a good reason to do so.

Modules

This is to me the biggest improvement of the language. ES6 now supports exporting and importing modules across different files. Once the standard is implemented, it's possible to write modular Javascript code without having to use external libraries.

Multiple-line Strings

No need to say more, a major pain is relieved:

var str = raw"This is a text
                    with multiple lines.
                    Escapes are not interpreted,
                    \n is not a newline."; 

Above is my personal take on what's going to be the most major features in ES6 from a developer's point of view. ES6 is still in draft phase, and won't be completed until late 2014 according to the timeline. Its specification can and will change, but the preliminary features are very much worth looking forward to. For a complete list of new features, please refer to Dr. Rauschmayer's presentation.

EmberJS: How to Use Ember within a Rails page

I have been working extensively with EmberJS recently and loving every bit of it. Ember can make things happen out of the box, very well suited for single-page applications. However, a lot of times I find myself writing semi-single page websites, i.e. only some portions of the site require Ember, the rest are handled by Rails. This guide shows my current approach of embedding Ember code inside a Rails application.

Use ember-rails

First of all, I highly recommend using the ember-rails gem to manage Ember assets. The gem precompiles Handlebars template and add Ember assets to assets pipeline. It also provides some useful Rails generators that generate code templates for controller, model, store...To use ember-rails, just add to your Gemfile:

gem "ember-rails"

Also, don't forget to set up Ember variant in Rails initializer in order for it to work:

config.ember.variant = :develop # or :production    

Shared templates

This is the tricky part. Ember's approach is to render everything with Handlebars templating system. However, for some cases you may want to add Rails related content. The best way to do it is to share templates between Rails and Handlebars. For example in your Rails view:

<!--example_user_show.html.rb-->
<head> 
  <title>Example shared template</title>
  <script src="example_user_show.js"></script>
</head>

<body>
  <%= current_user.name %>
  <script type="text/x-handlebars" data-template-name="application">
    {{user.email}}
  </script>
</body>

Where {{user.email}} comes from the user model stored in ApplicationController:

// example_user_show.js
MyApp = Ember.Application.create();

MyApp.User = DS.Model.extend({
  email: DS.attr('string'),
  name: DS.attr('string')
})

MyApp.ApplicationController = Ember.Controller.extend({
  user: Ember.K

  init: function() {
    this.set('user', MyApp.User.find(userID));
  }
})

Notice that MyApp.User.find(userID) fires an Ajax request to obtain the user data. It results in data duplication when the same user model is loaded twice in Rails and Ember. We can solve this problem by preloading Ember data which will be discussed in next section.

Also note that an Ember application is associated to only one root element. To use Ember for different parts of the page, you can create multiple Ember applications. For example in Rails view:

<!--example.html.erb-->
<head> 
  <title>Example shared template</title>
  <script src="example_calendar.js"></script>
  <script src="example_map.js"></script>
</head>

<body>
  <div id="calendar">
    <!--Display a dynamic calendar with a lot of interactions. Perfect use case for Ember-->
    <script type="text/x-handlebars" data-template-name="calendar"></script>
  </div>

  <div id="map">
    <!--Display a map with a lot of interactions. We can also use Ember for that-->
    <script type="text/x-handlebars" data-template-name="map"></script>
  </div>

  <div id="other-stuff">
    <!--Some other stuff that should be handled by Rails-->
  </div>   
</body>

JS:

// example_calendar.js
Calendar = Ember.Application.create({
  rootElement: '#calendar'
})

Calendar.ApplicationView = Ember.View.extend({
  templateName: 'calendar'
})

Calendar.ApplicationController = Ember.Controller.extend({
  init: function() {
    // Do stuff
  }
})

// example_map.js
Map = Ember.Application.create({
  rootElement: '#map'
})

Map.ApplicationView = Ember.View.extend({
  templateName: 'map'
})

Map.ApplicationController = Ember.Controller.extend({
  init: function() {
    // Do stuff
 }
})

Since we're using Ember for only one page of the Rails application, Ember router becomes unnecessary. Therefore I prefer doing setup (getting model, setting up bindings...) in the init function of the ApplicationController. In theory, one Ember application is enough for one page (make the root element body or parent container), but in many cases I find myself using Ember for only a small portion of the site. Therefore, it doesn't make much sense to wrap the entire template in Handlebars just for a small Ember code to work. Plus, separating different portions into different applications makes the code more modular and easier to maintain.

Preload Ember data

As mentioned above, there is a data duplication issue when the same record being fetched twice by both Rails and Ember. To avoid this, we can preload Ember data using a preload store. The PreloadStore used for Discourse is a great example of a simple and powerful preload store. So now in the Rails template we can do:

<!--example_user_show.html.erb-->
<head> 
  <title>Example shared template</title>
  <script src="preload_store.js"><script>
  <script src="example_user_show.js"></script>
</head>

<body>
  <script>
    PreloadStore.store('currentUser', JSON.parse(<%= current_user.as_json() %>)); 
  </script>

  <%= current_user.name %>
  <script type="text/x-handlebars" data-template-name="application">
    {{user.email}}
  </script>
</body>

and JS:

// example_user_show.js
MyApp = EmberApplication.create();

MyApp.User = DS.Model.extend({
  email: DS.attr('string'),
  name: DS.attr('string')
})

MyApp.ApplicationController = Ember.Controller.extend({
  user: Ember.K

  init: function() {
    // Retrieve current user data from PreloadStore
    // the record will be automatically deleted from the store after retrieval
    var currentUser = PreloadStore.getAndRemove('currentUser');  
    if (currentUser) {
      this.set('user', currentUser);
    } else {
      // Cannot retrieve from preload store, fallback to Ajax request
      this.set('user', MyApp.User.find(userID)); 
    }
  }
})

This is a very clean way of injecting static data into Ember without setting global variables and sending unnecessary Ajax requests. You can also take a look at Discourse to see how they use PreloadStore consistently throughout their site.

Conclusion

Ember is probably the most powerful MVC framework out there for single-page application. However, using Ember for font-end rendering means that much of the Rails magic becomes useless. Incorporating Ember in Rails template is a good choice if you only want Ember to handle some portions of the web page. The above is my preferred approach and not a standard guideline from the Ember community. It's been working very well for me. If you have any comments or suggestions, feel free to drop me a note.

Mac Development: Get Highlighted Text on Key Press

Not long ago I wrote this little Mac hack called InstantGSearch out of my burning desire for the quickest way to search Google for any highlighted text from any application (Chrome, IDE, PDF, Console... you name it!). How it works:

  1. Highlight text

  2. Hit Option+G

It's really simple, but I faced a challenge of how to get the highlighted text from all applications. My first option was to use Accessibility API to do UI inspection on the currently running app, but quickly found out that the number of fully accessible apps are very limited. And since there's no access to the OS-level API, I opted for a dirty but powerful hack: Simulate the Copy action and get the text from Pasteboard.

This is how to simulate the Copy action by simulating the Command+C key combination:

- (void)simulateCopy {
  CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
  CGEventRef copyCommandDown = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, YES);
  CGEventSetFlags(copyCommandDown, kCGEventFlagMaskCommand);
  CGEventRef copyCommandUp = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, NO);

  CGEventPost(kCGAnnotatedSessionEventTap, copyCommandDown);
  CGEventPost(kCGAnnotatedSessionEventTap, copyCommandUp);

  CFRelease(copyCommandUp);
  CFRelease(copyCommandDown);
  CFRelease(source);

}

Read from Pasteboard:

- (NSString *)getSelectedText {
  NSPasteboard *pb = [NSPasteboard generalPasteboard];

  // Simulate the copy action
  NSInteger currentChangeCount = [pb changeCount];
  [self simulateCopy];

  // Poll the pasteboard for whether our text has been put there
  NSDate *startTime = [NSDate date];
  while (true) {
    if (currentChangeCount != [pb changeCount]) {
      while (true) {
        // Another polling since the text might not be written in Pasteboard yet
        NSString *selectedText = [pb stringForType:NSStringPboardType];
        if (selectedText != nil) {
          return selectedText;
        }
      }
    } else {
      NSDate *endTime = [NSDate date];
      if ([endTime timeIntervalSinceDate:startTime] - 0.1 > 0) {
        return nil;
      }
    }
  }
}

Works like a charm! Full code is available on GitHub.

Get Your Ass Back to School

Degrees don't matter. They really don't. But it doesn't mean school is a total waste of time. I used to be a school hater, and at some point last year I even thought of dropping out. I went as far as taking a one year off school for an internship in the software industry, expecting to tell my parents "See, I don't need to go to school to do all these things". Turned out it was quite the opposite. I'm now more than half way through the internship and finding myself wanting to get back to school. Here's why:

I realize that school only sucks when you don't know what to study. What happened to me during my first two years of college was that I had no clue what the stuff taught in school was for. I had never imagined that I would use MergeSort and BinarySearch in a software project, or how useful it would be to understand SSL/TLS when setting up the company server. Being in the industry helps me know what technologies are being used by the real people and what not. For the first time in my college life I realize how relevant school knowledge is and how to apply it appropriately. There're things I wish I could have paid more attention to in school and things I know I need to delve into the moment I get back.

School is about experience, not knowledge. Knowledge has become much more accessible with all the people offering it for free (Coursera, Udacity, Stanford Online Courses, you name it). The role of physical universities have now shifted to providing more than just content. You can find plenty of good experiences like internships, exchange studies, entrepreneurship, etc that your school may offer. Those are the things that can shape who you are, what you care about, and what you want to achieve. There are also similar experiences in the outside world, but it is much easier to make use of the available school resources (my internship is also a part of my school training and exchange program). So please get out there and do real stuff. Don't just sit around attending boring classes and complain you don't learn enough.

So to all the ambitious dropouts out there, unless you're geniuses, get your ass back to school. I'm pretty sure there would be 1 or 2 courses that can help you earn big bucks in the future. Learn to appreciate what school can do for you and study what really matters. If you really can't learn anything, at least know your classmates who do and network with them well. They may end up being your employer, co-founder, life partner, etc that your future success depends on. There should be something your school can offer you. Keep searching for it!