Marcus McDuffie

Marcus McDuffie is a hobbyist programmer from the Traverse City region who hacks on Ruby, Rails, Haskell, Lua, Lisp, C and whatever else he feels like.

The Coffeescript Fat Arrow and Classes
April 19th, 2012 15:56

Like my previous post on the fat arrow in Coffeescript, Coffeescript Fat Arrow: Step-By-Step for this one we are going to slowly step through how classes work in Coffeescript and then introduce how the fat arrow interacts with them so that we can get a complete picture of how this works. You are going to learn this concept the way I did. That means you’re going to learn it step-by-step through observing simple examples of what Coffeescript compiled output looks like.

So, without further delay, here is step one. Let’s see what happens when we just use the ‘class’ keyword in Coffeescript:

class Car

Compiles to this:

(function() {
  var Car;

  Car = (function() {

    function Car() {}

    return Car;

  })();

}).call(this);

Lets pick this apart. On the first line, we can see the Coffee compiler has created a function which ends on the last line and then is called. This is standard for all compiled Coffeescript, so we can safely ignore the first and last lines. On the second line, we see "var Car;". This is Coffeescript’s way of creating a global variable to identify our class. This isn’t really too different from the way that many programming languages work, it’s just that usually the interpreter in most languages with classes creates a variable to represent the class automatically when the class is defined. With JavaScript, which doesn’t natively support classes, the Coffee compiler has to do this on its own. That way we have a way to refer to the class after we’ve created it.

On the third line (or fourth, if you count that blank line), we can see that a function is being assigned to the ‘Car’ variable. But why is there a parenthesis in front of it? Even weirder, f you look three lines down, we can see that the closing parenthesis after the end of the function’s body and then another set of parentheses immediately after. This is called a "self-executing anonymous function" and is the kind of syntactic garbage that only JavaScript could bring us. Basically, the Coffee compiler is wrapping the entire function that represents our class in a closed scope and then executing it right away. This really serves (as my understanding goes) to keep the class definition from polluting the global namespace. So, in simple terms this mess of parentheses is just part of Coffeescript trying to get as close as possible to classes as they work in other languages.

Also worth noting is that Coffeescript isn’t just creating a self-executing anonymous function. It’s creating a self-executing anonymous function that returns another function. I’m not 100% certain, but I would speculate that this is so that our class can be referred to and called in different ways and still have a consistent response (like "Car" does the same thing as "Car()"). If someone knows more about this, I would love for them to let me know!

Ok, enough of that. Let’s add some stuff to our class. First, I add an attribute to our Car class. Then I create a new instance of the class. Finally, I call a method on the class:

class Car
  honk: -> "Beep!"

honda = new Car
alert honda.honk()

That Coffeescript code compiles to this JavaScript:

(function() {
  var Car, honda;

  Car = (function() {

    function Car() {}

    Car.prototype.honk = function() {
      return "Beep!";
    };

    return Car;

  })();

  honda = new Car;

  alert(honda.honk());

}).call(this);

What can we learn from this code? Well, we can see that Coffeescript adds methods to classes by adding them to the class’s prototype (or since the class is really a function, the function’s prototype). This is part of the way that Coffeescript uses JavaScript’s prototype-based inheritance goodness to emulate the classes that JavaScript doesn’t really have.

Wonderful. Let’s fatten up our skinny arrow and see what happens:

class Car
  honk: => "Beep!"

honda = new Car
alert honda.honk()

And here is the changed JavaScript :

(function() {
  var Car, honda,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  Car = (function() {

    function Car() {
      this.honk = __bind(this.honk, this);
    }

    Car.prototype.honk = function() {
      return "Beep!";
    };

    return Car;

  })();

  honda = new Car;

  alert(honda.honk());

}).call(this);

Has anything changed? Well, our car still honks. And it’s still a Honda. Now, however, there is a bunch of this weird "__bind" stuff all over.

At the top, we can see if creates a function called "__bind" that takes two arguments. The first argument is a function object, and the second is the current value of "this". With these, the "__bind" function returns a function that calls "apply()" on the provided function and passes the current value of "this". The "apply" function is a built-in JavaScript function that allows us to call a function with a specific value for "this" (the object that owns the function or that the function is a method of). So, really all we need to know about what Coffeescript is doing here is this: Coffeescript takes our function and makes it into a function that always executes with "this" being what "this" meant inside our class definition.

I must admit, it was kind of hard for me to come up with a generic example for the fat arrow in a class that showed its usefulness without being too complicated or contrived. In fact, I didn’t succeed at all. But here is as close as I could get:

class Car
  constructor: (@wheels,@doors) ->
  features: -> "I have #{@wheels} wheels and #{@doors} doors."
honda = new Car(4,2)
functionThatTakesCallback = (callback) -> callback()
alert functionThatTakesCallback(honda.features) 

When this code is run, it alerts: “I have undefined wheels and undefined doors." Why? Well, that is because when we call the "features" function, the value of "this" is the function object that we passed the "honda.features" function to, not the current instance of the "Car" class, "honda."

Now, if we use a fat arrow:

class Car
  constructor: (@wheels,@doors) ->
  features: => "I have #{@wheels} wheels and #{@doors} doors."
honda = new Car(4,2)
functionThatTakesCallback = (callback) -> callback()
alert functionThatTakesCallback(honda.features)

Our page will alert: "I have 4 wheels and 2 doors." This is because the compiled JavaScript was like this:

(function() {
  var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  $(function() {
    var Car, functionThatTakesCallback, honda;
    Car = (function() {

      function Car(wheels, doors) {
        this.wheels = wheels;
        this.doors = doors;
        this.features = __bind(this.features, this);
      }

      Car.prototype.features = function() {
        return "I have " + this.wheels + " wheels and " + this.doors + " doors.";
      };

      return Car;

    })();
    honda = new Car(4, 2);
    functionThatTakesCallback = function(callback) {
      return callback();
    };
    return alert(functionThatTakesCallback(honda.features));
  });

}).call(this);

And in the code, our features function was bound to the value of "this" as it was in the class definition.

That example seems contrived, so I will tell you this. The common practical use for the fat arrow is demonstrated well in The Little Book on CoffeeScript chapter on classes. Their example looks like this:

class Animal
  price: 5

  sell: =>
    alert "Give me #{@price} shillings!"

animal = new Animal
$("#sell").click(animal.sell)

So, you can see that a common practical use for the fat arrow is when you expect to pass your class method (function) to JQuery to use as a callback. Then, we can make sure that we are asking the value of "price" on the animal object, and not on the "sell" HTML element.

Show Comments
Comments:
Viagra overnight posted on May 20th, 2012 23:12:
, Cheap cialis, 446, Cialis, 572811, Cialis online, 5862, Buy levitra, 345, Viagra, 1067, Buy viagra canada, %OOO, Buy viagra, 438, Cheap viagra overnight, ufenb, Viagra online, :[,
Stypewape posted on May 20th, 2012 23:08:
viagra $0.9 pill cheap discount pill sale viagra <a href="http://vi-edu.us/ ">buying viagra with no prescription </a> , gtsnj , buy cheap viagra in estonia buy now viagra
Generic viagra overnight posted on May 20th, 2012 19:27:
, Cheap cialis professional, %-], Cialis, :-[[, Cialis, 0420, Buy levitra, 832266, Viagra, 4970, Buy viagra canada, %)), Buy viagra, 629210, Viagra overnight, 469, Viagra, frdm,
Cheap viagra posted on May 20th, 2012 18:23:
, Viagra online, 8-D, Cheap cialis, nccz, Discount viagra online, byskit, Discount viagra, 199038, Viagra, 8-PPP, Buy viagra cheap, kzmf, Viagra online, 0998, Viagra, 562352, Buy cialis, lxzimx,
brgwth posted on May 20th, 2012 16:53:
6jh2vF <a href="http://skwllwtghazr.com/">skwllwtghazr</a>, [url=http://esfkmfbgstas.com/]esfkmfbgstas[/url], [link=http://eipingtrpecu.com/]eipingtrpecu[/link], http://vmcrnwcbwwhz.com/
Engiquani posted on May 20th, 2012 08:10:
http://fectpporaram.lxb.ir http://ninggallphoman.MahTarin.Com http://buycurtstakgor.bloghi.com http://obciogace.MahTarin.Com http://axglaztarrde.unblog.fr http://nowslanpiefi.MahTarin.Com http://tieklezifop.unblog.fr http://handbaljala.unblog.fr http://unnadcoffwa.bloghi.com http://commuscbarna.unblog.fr http://buweramre.unblog.fr http://hiefrennozzbi.MahTarin.Com http://vabyvpsvho.freeblog.hu http://telrollthema.unblog.fr http://qmatjaojmw.freeblog.hu http://vorresadi.GLXBlog.Comhttp://nopmucentemp.bloghi.comhttp://steepopifus.MahTarin.Comhttp://sentdewcmarbprof.LoxBlog.Comhttp://frugbaddbeport.LoxBlog.Comhttp://mwdvvbwndl.freeblog.huhttp://supphadoubli.bloghi.comhttp://sorowacip.unblog.frhttp://ligxihumo.MahTarin.Comhttp://nioreestomi.LoxTarin.Comhttp://siobonsobcba.bloghi.comhttp://grasetaplai.LoxTarin.Comhttp://quepidiscnibb.LoxTarin.Comhttp://staractechsa.bloghi.comhttp://choibicosen.LoxTarin.Com http://ilheumicha.lxb.ir http://scarerhiger.bloghi.com http://dlpyhibknc.freeblog.hu http://nauflumveschie.LoxBlog.Com http://giaflipearti.bloghi.com http://logmildpeara.bloghi.com http://bloodinusjo.MahTarin.Com http://tiasaboulsou.bloghi.com http://esigorpar.GLXBlog.Com http://paycremonso.MahTarin.Com http://maibaroson.bloghi.com http://bootcilehe.GLXBlog.Com http://xdsizotxkv.freeblog.hu http://absecilreck.bloghi.com http://ziethematmi.bloghi.com
free_cialis posted on May 19th, 2012 05:40:
Engiquani posted on May 19th, 2012 13:58:
http://rhaborunfres.unblog.fr http://intatali.GLXBlog.Com http://sirangambcor.bloghi.com http://cesslastreadscud.bloghi.com http://potyjasu.bloghi.com http://thudipostfi.bloghi.com http://tatmegeli.bloghi.com http://matahorla.bloghi.com http://ressimeando.unblog.fr http://thizliamisscon.lxb.ir http://lendplifgiacomp.unblog.fr http://colsanimo.lxb.ir http://aruanrefti.lxb.ir http://privinhansi.bloghi.com http://houbugnymos.MahTarin.Com http://mutoconpozd.LoxTarin.Comhttp://ligxihumo.LoxTarin.Comhttp://wrathtogbeta.bloghi.comhttp://ziethematmi.bloghi.comhttp://anassiri.GLXBlog.Comhttp://syouririre.bloghi.comhttp://maicarstralcor.bloghi.comhttp://evllsfevot.freeblog.huhttp://cayrawathe.bloghi.comhttp://distdilade.bloghi.comhttp://gtkmkohtzm.freeblog.huhttp://jcjqfmuqjy.freeblog.huhttp://odjwzwnxfc.freeblog.huhttp://pertisesu.bloghi.comhttp://creatovbranma.bloghi.com http://ratuttlingvent.bloghi.com http://percirotta.bloghi.com http://alariner.bloghi.com http://tusumriwad.bloghi.com http://raritote.bloghi.com http://fahrmulala.bloghi.com http://quepidiscnibb.lxb.ir http://lendplifgiacomp.unblog.fr http://betingprogpor.unblog.fr http://thochespholsre.bloghi.com http://bogglocksizzre.bloghi.com http://axcripanib.bloghi.com http://postresttempbo.bloghi.com http://cesslastreadscud.bloghi.com http://vajmusspelde.bloghi.com
free_cialis posted on May 19th, 2012 02:02:
Viagra posted on May 18th, 2012 16:18:
, Cheap cialis, >:DD, Viagra, =-]], Cheap cialis, fqexv, Viagra oral jelly, 559, Viagra, sfps, Generic viagra, >:-PP, Generic viagra online, ujh, Viagra, 261, Viagra price, pakio,
viagra_price posted on May 18th, 2012 07:25:
Viagra online posted on May 18th, 2012 10:33:
, Cheap viagra, 716, Cheap viagra 100mg, nmnj, Viagra for sale, pqs, Viagra online, 44245, Online cialis, 6559, Generic viagra online, >:))), Viagra, vqcn, Generic viagra online, dlc, Generic viagra online, 25107,
cheap_cialis posted on May 18th, 2012 05:41:
Viagra online posted on May 18th, 2012 00:45:
, Viagra online without prescription, =[[, Cialis generic, 8773, Online viagra, %-D, Cheap viagra online, fbi, Buy generic viagra, 686, Viagra, 601277, Viagra price, 1505, Viagra, 821386, Cheap cialis, kyp,
Buy cialis no prescription posted on May 17th, 2012 15:59:
, Cheap cialis generic online, uvrfw, Buy cialis, 8-), Cialis, 650325, Levitra vs viagra, 8-[[, Viagra, >:]], Viagra, scllw, Order viagra online, >:))), Viagra alternative, 8139, Viagra online canadian pharmacy, slizjk,
side posted on May 17th, 2012 03:49:
discount_cialis posted on May 17th, 2012 04:11:
Cialis online posted on May 16th, 2012 21:40:
, Viagra online without prescription, 217974, Generic cialis online, syql, Viagra sales, %-PPP, Discount viagra, :-O, Viagra, uxcj, Viagra price, ptxqwj, Discount viagra, 8[[, Viagra, wzi, Generic cialis, 330701,
Generic viagra posted on May 16th, 2012 13:07:
, Cheap viagra, 7183, Cheap viagra, 5666, Viagra online, eoeuly, Viagra, 8-PPP, Cialis online, txvnqk, Cheap viagra, %))), Generic viagra online, 175, Viagra, nsk, Generic viagra online, 3864,
Generic viagra posted on May 16th, 2012 07:37:
, Levitra online pharmacy, 05684, Viagra, >:-DDD, Viagra online, 343, Buy viagra online, 36174, Buy levitra, 624449, Generic viagra pharmacy, utzvjk, Generic viagra online, 8339, Viagra online, cfoapa, Viagra, :]],
Viagra posted on May 15th, 2012 23:20:
, Viagra online, esk, Generic cialis online, yhtwf, Viagra, 309584, Buy cheap viagra, 597598, Buy viagra online, :]], Viagra viagra, fjgmo, Buy viagra cheap, 642, Buy discount viagra, >:-(((, Cialis online without prescription, 03954,
Viagra posted on May 16th, 2012 00:20:
, Levitra, =(((, Viagra online, :)), Buy viagra, %DDD, Buy viagra, =-]]], Levitra online, bqeyv, Viagra, 889902, Viagra, :), Viagra, 395537, Viagra, :-((,
viagra_cost posted on May 16th, 2012 04:41:
Backlinks posted on May 16th, 2012 07:35:
Check out this crazy service that sends thousands of visitors to your web page automatically! Hey www.marcusmcduffie.com admin I wanted to tell you about this website I used with great results, that drives thousands of targeted visitors to your site who are dying to spend money! You’ve probably already know that creating great content is only half the battle when it comes to running a successful website. The second half of the equation is DRIVING TRAFFIC! With this service, you can forget about the tedious process of posting backlinks because they do everything for you so you can focus on more important things, like dealing with the flood of traffic to your site! And that’s not all! this service is SUPER AFFORDABLE and will direct thousands of new visitors to your site in just hours, GUARANTEED! This is the only service that can skyrocket your page to the top of the search engines! You can check it out here: <a href=http://xrumerservice.org>backlink service</a> Best, Jason



Coffeescript Fat Arrow: Step-By-Step
April 10th, 2012 09:46

For those of you who may be kind of slow, like me, I figured I would share the step-by-step procedure I went through to understand the 'fat arrow' ('=>') in Coffeescript and how it works. I think that something like the fat arrow is probably easy to understand if you’re a long-time JavaScript hacker that uses JQuery a lot (not that the fat arrow is only useful to JQuery users, just that it is commonly used to solve a problem JQuery users often face). For the rest of us, the fat arrow is something that pretty much every time we see it described on the web is described poorly. Or, to be fairer, described in a confusing way.

Slightly Off-Topic: Is that a Hash Rocket?

Being a Ruby fan, the first thing I thought when I saw that fat arrow is 'that’s a hash rocket!' In Ruby, the assignment operator within a hash (associative array) that binds a key to a value looks like this:

{ 'cars' => 20, 'parking_spaces' => 10 }

With 'cars', for example, being a key and 20 being a value. Just in case you might be tempted to think so, the fat arrow is not a hash rocket.

Learn by doing

To figure this out, I started writing some Coffeescript and observed what the compiled JavaScript looked like. Let’s start with this nonsensical statement (which kind of seems like it should be illegal):

=>

This compiles to:

(function() {
  var _this = this;

  (function() {});

}).call(this);

So here we can see the basic building blocks of how the fat arrow is going to work. First, as all Coffeescript is, our code is wrapped in a function that is then called (the first line and last line). Then, Coffeescript declares any variables that are going to be needed in the script. This is also standard behavior for the Coffee compiler with or without the fat arrow being involved. The difference you should notice though is that the only variable being defined is called "_this". And it’s being set equal to "this". Why?

Well, basically, Coffeescript is creating an alias for "this". The "this" keyword refers to the current object (the object that any methods will be called on), kind of like the "self" keyword in Ruby. It is important to note that this variable is effectively global. So, what Coffeescript has really done is create a variable that represents the current value of 'this', which in this example script would be the window object, that we can refer to from anywhere. Even if the value of 'this' changes while we’re inside another object, when we refer to '_this' it will still mean that 'this' was where we used the fat arrow. This will be an important thing to remember as we go along.

Lastly, we can see that using the fat arrow has created an anonymous function with an empty body. This should be obvious because the fat arrow’s skinny cousin ('->') does basically the same thing, which is create a function. In fact, if you do the same thing with a skinny arrow (that is, create a script that only says '->' inside), you’ll notice that the only difference is that the Coffee compiler does not add the 'var _this = this;' line. So the important thing to observe at this point is that the fat arrow is really just like the skinny arrow and when used in the same way will work basically the same way. That extra 'this' alias is really only used if you choose to use it. Otherwise, the skinny arrow is no different from the fat arrow at this point.

The function that ('=>') created is anonymous because we didn’t put anything on the left side of the fat arrow and its body is empty because we didn’t put anything on the right. So let’s do that in the next example, which builds on the last one:

foo => "bar"

This compiles to:

(function() {
  var _this = this;

  foo(function() {
    return "bar";
  });

}).call(this);

What has changed? Well, we can see that the function (the one that starts on the fourth line) created by the fat arrow has a name now, because we put 'foo' on the left side of the arrow. We can also see that the function is no longer empty and returns 'bar' because that’s what we typed on the right-hand side of our fat arrow, and Coffeescript functions always return the value of the last statement evaluated in the function, just like Ruby does. Notice that so far, we still haven’t used the "_this" variable yet, so this function isn’t really different from a regular Coffeescript function.

Enter the 'At' Sign

Ok, now let’s bring something else into the mix that will finally make the fat arrow make sense: the 'At' sign. In Coffeescript, the 'at' sign ('@') literally means 'this'. So, wherever you type the 'at' sign in your source, the compiler puts the word this in the JavaScript output. So, if you typed '@foo' in the source you get 'this.foo' in the compiled script. Likewise, if we just put a '@' anywhere in the code, we can see what Coffeescript thinks 'this' is anywhere in the code. So, let’s do that. Here is a modified version of our code:

@
foo => @

This compiles to:

(function() {
  this;
  var _this = this;

  foo(function() {
    return _this;
  });

}).call(this);

If you look closely at the output, it should suddenly become apparent what the real purpose of the fat arrow is. Notice that outside of our fat arrow function, when we used '@' we got 'this'. However, and this is the important part, inside the function '@' compiled to '_this'. And, since using the fat arrow to define our function created the line that says 'var _this = this;' outside of that function, the value of 'this' we are using is the function where our function is defined and not the value of 'this' inside the function we defined. Whew, that was a long sentence. What I’m trying to say is, we grab the value of 'this' before we go into the function and use that instead. Now, the example they give on the Coffeescript homepage should make more sense:

Account = (customer, cart) ->
  @customer = customer
  @cart = cart

  $('.shopping_cart').bind 'click', (event) =>
    @customer.purchase @cart

This compiles to:

var Account;

Account = function(customer, cart) {
  var _this = this;
  this.customer = customer;
  this.cart = cart;
  return $('.shopping_cart').bind('click', function(event) {
    return _this.customer.purchase(_this.cart);
  });
};

Notice that everywhere inside the function we defined with the fat arrow where we put an '@' sign, it is using '_this' instead of 'this' so that we use the value of 'this' in the 'Account' function and not the value of 'this' in the function that is being bound the 'shopping_cart'.

This example from the Coffeescript homepage demonstrates one of the big reasons (I think) behind the fat arrow being part of Coffeescript: defining a callback function within another function and still being able to use the parent function’s scope.

For another big reason, and one of the coolest reasons to use the fat arrow, read my next post on using the fat arrow with classes.

Show Comments
Comments:
Jose E posted on April 19th, 2012 20:27:
Hi! Good to see yet another article on this topic. I for one, can't get enough of them since, like you, Took me a lot to understand how the fat arrow works. May I suggest you point out something very important, In the last example I think it's very important to emphasize that the: _this is used instead of this Because this points to DOM element selected using jQuery. Another thing, I believe you could even extend your article by mentioning all the ways (Contexts) in which this changes its meaning in JavaScript. Good job, I'm you've made this article.
Anon posted on April 20th, 2012 04:49:
Sorry dude, this article just made me confused.
Viagra price posted on May 17th, 2012 08:30:
, Cialis vs viagra, php, Cialis, >:OO, Discount viagra online, ydg, Cheap viagra online, mfir, Buy viagra without prescription, inm, Viagra, 8-)), Viagra, >:-PP, Buy viagra on line, mnugw, Cialis online without prescription, 117,



I Give Up
April 4th, 2012 14:18

Sometimes, you have what seems like a brilliant idea, you think to yourself "how come nobody else has ever thought of this before?" and then, after toying around with the idea for awhile, you discover why. Here is one of those stories. I share it here with the hopes that if anyone else has this idea and stumbles across my blog they will be more aware of the limitations of this idea.

What I wanted to do

The experiment I wanted to setup was to test the viability of this idea: Use HTML5 web sockets and canvas to implement a server-driven GUI in the browser that would allow web application developers to bypass the limitations of the browser all together. So, essentially the web page, once downloaded, would have some JavaScript on it that would open a web socket to the server. The moment the socket opened, the server would start sending binary messages back to the browser. In those binary messages would be all of the data for the pixel colors for an entire canvas area in the page. Then, the browser would use that data to render the canvas area. On the server side, there would be a buffer that all this pixel data would be dumped into whenever the server side GUI wanted to update the screen. That way, I could write an entire server-side GUI framework in a language of my choice (Ruby) and have complete control over what the user sees on their screen without the browser interfering. The server would just continually send out screens on the web socket in an endless loop (or perhaps only when the server redrew the screen?), and the browser would draw them as fast as it could. The only thing being sent back to the server would be mouse clicks and keyboard input.

In my research into this idea I discovered noVNC, which uses web sockets with binary pushes and HTML5 canvas to basically do a very similar thing for the purpose of getting a remote screen session in the browser. So, the idea didn’t seem impossible as it has (mostly) been done before.

Why this is a bad idea

First, the obvious problem. Sending entire screens over the wire, even in compressed binary, is going to take a lot of bandwidth. Even if you only send a screen when the server changes something you still are going to have a lot of data to move. While apparently many canvas implementations are fast enough to draw the canvas with reasonable speed (I know from a previous experiment that the DOM is definitely not fast enough), it still seems like a lot to make our single-threaded web browsers do.

Then, there are other challenges. Most server implementations of web sockets are event-driven (like Node.js or Eventmachine). So, you can’t block your entire event loop while the server is in an endless loop sending out screens. Maybe you could have the event loop check a shared variable from another thread that said if the screen had been updated and then push out a new screen if it was? I’m not sure if that is a good idea, either. I’m sure there is a way to write this without multiple threads but it would be tricky. I thought about building my own web sockets server, too, but that would be re-inventing the wheel.

Also, to make a canvas-based GUI, you need to re-implement or sacrifice all of the things that users are used to like cut and paste, keyboard input and tabbing through fields, drag-and-drop, and the list goes on. And what if the user wants to print? How is that going to work?

I think I’m rambling at this point, and I’m not saying these aren’t all impossible hurdles to overcome, but maybe we just have to accept that web applications are written in JavaScript. After all, JavaScript development is getting easier all the time.

Show Comments
Comments:
poupyiscuice posted on May 16th, 2012 02:16:
I want to set up you a immense show. Fail debate it. Discovery it on <a href=http://camera-tv.com>show page</a>.



Eventmachine, Websockets, and push updates
March 29th, 2012 08:09

I’ve been playing around with Eventmachine and the em-websocket gem for doing WebSockets stuff the past few days. I’ve seen examples of web apps that can continually push messages to the browser. You know, for something like a stock ticker. Usually, though, these seem to be coded in something like Node.js, which I’ve experimented with before. However, I like Ruby so I want to use Eventmachine.

I was inspired by Jesse Dearing’s post where he essentially assigns the websocket object to something outside of the eventmachine loop and then sends stuff to it from another thread.

I like that approach, but I wanted to wait until a socket was opened from the browser and then start pushing stuff to the browser. So, this convoluted mess is the closest I could get :

require 'rubygems'
require 'eventmachine'
require 'em-websocket'

socket = nil

Thread.new do
  EventMachine::WebSocket.start(:host => 'localhost', :port => 8080) do |ws|
    ws.onopen do
      socket = ws
    end
  end
end

Thread.new do
  until socket != nil
    sleep(0.1)
  end
  loop do
    sleep(0.5)
    socket.send "#{rand(8900) + 1000}"
  end
end

sleep

This looks like crazy person scrawling I’m sure, but allow me to explain. I wanted an endless loop running after the socket is opened that pushes stuff out. In my experiments, though, I found that if you put an endless loop in the Eventmachine event loop, it will block the whole thing from working. That makes sense when you think about how an event loop is supposed to work. I thought that maybe I should put a Node.js style callback in the ws.onopen block, but I wasn’t sure if that would work either (I’m pretty sure Node.js does some magic in the background that makes things in callbacks not block the event loop). So, you can see that as soon as we create the socket, we assign it to a placeholder outside of the thread.

Then, we have another thread that is possibly already running and waiting until the socket exists. I tried just putting sleep in that until block with no arguments, but then the loop never loops. So, it waits 0.1 seconds (should I go lower than that?) on each iteration. Once the socket exists, we break out of that loop and start our endless loop of pushes to the browser. In this example I’m just sending random junk. At the end of the whole script there is another sleep, because apparently you need that there to keep the program from exiting after spawning the threads.

I’ve heard that sometimes in programming when you feel the pain of something being not quite right or too complex, you should listen to that pain. Perhaps this solution feels convoluted because there is an easier way that I haven’t seen yet. Perhaps this solution betrays my lack of experience in event driven and/or multithreaded programming. In the coming weeks as I learn more about Eventmachine it might suddenly become obvious that I’m doing this all wrong. If anyone out there knows of a better way to do this let me know!

Show Comments
Comments:



Rails Reads routes.rb from Top to Bottom!
March 27th, 2012 09:05

I should have known this, and I feel stupid for not knowing it. But maybe one more post out in the blogosphere that mentions this will somehow save someone else from falling into this same trap. If you are reading the Rails Guide Rails Routing from the Outside In you’ll see a yellow box a little ways down the page that says:

"Rails routes are matched in the order they are specified, so if you have a resources :photos above a get 'photos/poll' the show action’s route for the resources line will be matched before the get line. To fix this, move the get line above the resources line so that it is matched first."

The only problem is, that I (unlike the rails router) do not read things from top-to-bottom. So, I skipped right over that part and started trying to add routes for my RESTful resources at the bottom of the file. So, for example, I was adding something like this to my routes.rb file:

  resources :customers do
    collection do
      get 'search'
    end
  end

Then, when I would try to go to /customers/search it was saying that it couldn’t find a customer with the ID "search". Basically, this is because the first route it matches is something like /customers/:id to customers#show and that trumps the route I was adding later. Also, at the top of my file I had "resources :customers" and then I was trying to re-declare the route at the bottom. I could not figure out what the cause of this was for the longest time! Finally, in the middle of the night my brain somehow suddenly remembered that Rails matches routes in the order that they are declared. One might think that you would make your routes file more general at the top and then more specific at the bottom. However, what is really happening is once the router matches a request to a route, it doesn't need to go down farther in the file. Don’t be a Marcus, kids. Remember to always declare your routes in the right order!

Show Comments
Comments:



Favicons and Rails 3.1
March 23rd, 2012 11:01

For anyone who might be trying to use the favicon_link_tag helper in Rails 3.1, you may have noticed that it doesn’t really work very well. I personally think this may get fixed at some point in the future, or the helper may just be removed altogether. I’m still a little cloudy on the details, but here is what I’ve figured out so far. When you put the favicon_link_tag helper in your view, it’s going to render this:


The problem with this path is that depending on how you’re setup, it may not work. I think that in older versions of Rails, it was safe to assume that a request to "/favicon.ico" would be a routable request that may very well find a file with this name. After all, usually this file would be served up from the public directory and there is even an empty favicon.ico file that comes with Rails. With 3.1 and the asset pipeline, this might not be the case. In deployment, I think most setups will have:

config.serve_static_assets = false

Set in their config/environments/production.rb file. So, they might not even be serving anything from the public folder. Also, I noticed that in development mode sometimes if I tried to open the favicon.ico file from my assets directory I would get an error like "No route matches for [GET] /assets/favicon.ico" even though an identical path would work to open an image file. I’m guessing this had to do with the way the asset pipeline figures out which directory ("images", "stylesheets", or "javascripts") to serve assets from based on their file extension. Either way, I don’t think we’re supposed to put something like a favicon in the assets folder, but I figured I would try it.

In the end, I just hand-coded the link tag for my favicon in the template:


This approach works, but seems sloppy somehow. I’m sure there is probably some way to force everything in Rails to work with the code that favicon_link_tag outputs, but it didn’t seem worth it.

I guess the reason I bring this all up is that I hope that someday in the future, Rails will have a way of magically including a favicon on your page without having to monkey around too much.

- UPDATE -

Turns out, I’m an idiot. My PassengerAppRoot directive in my .htaccess file was set to the root of my Rails app’s folder, but my DocumentRoot for Apache was set to the same folder. That means that Passenger was trying to serve up the favicon file from the root of my Rails app, not from the public folder, as it should be. Once I changed that, everything was fine. So, just so we’re all clear, do use the favicon_link_tag with Rails 3.1. Just don’t be an idiot like me and configure your production server wrong.

Show Comments
Comments:



Stating the obvious
March 22nd, 2012 15:32
I may be stating the obvious here, but for anyone who is new to Rails, it might be helpful to point out why:
@invoice.customer.id
Is different from:
@invoice.customer_id
I just tripped over this one myself. When you use the first form, notice what the error looks like when you try it in the Rails Console:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: customers.invoice_id: SELECT “customers”.* 
FROM “customers” WHERE “customers”.”invoice_id” = 2 LIMIT 1
Notice that it is looking for a field in “customers” called “invoice_id”. This is because Rails (ActiveRecord, really) is assuming that we have a has_many or has_one association where a customer has_one invoice or has_many invoices. What I really had was an invoice that has_one customer, so we wanted the second form:
@invoice.customer_id
Because our invoice has a customer, which we find via their customer_id. Really, it would also help to look at our schema.rb file, where we would see:
  create_table "invoices", :force => true do |t|
    t.datetime "created_at",  :null => false
    t.datetime "updated_at",  :null => false
    t.integer  "customer_id"
  end
Show Comments
Comments:



First Post on a New Blog
March 21st, 2012 15:31
I’ve had a blog at this address before, but this is a fresh start. The usual topic of my blog will be programming, programming languages, and other tech-related things. The blog page itself is of my own design. I wrote the backend in Rails 3.1 and it uses a little bit of jQuery/Coffeescript. The source for this blog page is available at https://github.com/mmcduffie/marcus_blog if you’re interested.
Show Comments
Comments: