Showing posts with label quirks. Show all posts
Showing posts with label quirks. Show all posts

Thursday, December 26, 2013

jshint is good, but...

Let's just be upfront here because I don't want to hurt peoples feelings on jshint (which is apparently known for hurting people's feelings.) I can say many things about jshint , and 99% of them are good. In fact, there are a LOT of good practices that jshint enforces that I think are absolutely invaluable. Yet, here I am really just annoyed with a bunch of these "Code errors." Let me give you some examples.

1. I'm a NodeJS developer working on a test suite, using SHOULD and MOCHA, and I use jshint to test and make sure I use good coding practices. Here's what happens:


Well SCREW YOU TOO. Look at all these unmeaningful errors. I mean, require is definitely defined. I shouldn't have to deal with the jshint output like this.

2. I'm working on a token reader for the front end.



What happened here? I expected an assignment and a falsy check to occur during a while loop, and I got this lame output. Sure it's scrutiny and you can easily rewrite it to something like this:


The question is "Why?". So some novice developer can come in and see what your code does faster? Chances are this small obscurity will teach the novice developer about javascript and the things you can do with it. Sure it's "cute" and silly, but is it really worth your time to change your coding style like this? Just document it.


See, that wasn't so hard. I'd rather teach the beginner the "rules" and then break them.

The following example kills me every time:


Expected a 'break' statement before 'default'.

What if I wanted it to bleed over into the cases and use spaghetti code? Apparently novice coders are too dumb to spend time and figure it out for themselves. Chances are if your code is more complicated, you wanted another statement anyway. Yet, what if the offending sample is simple? What if the code happens to be easier to write and read with the switch statement? That's a matter of your opinion and really the decision should be left up to you.

(It also told me console was not defined but that's arbitrary.)

Look, just make a decision for yourself and use jshint to let it find your bugs before you do. Just make sure you read the error and make a determination for yourself if it's worth "fixing."

I probably spend more time sifting through 'console' is not defined more often than I would personally like to.

~function(){console.log("Josh");}();

Friday, November 8, 2013

Defining Plugin Architecture for Constructor Libraries

Even in a hypothetical world where objects are packaged into black boxes it would seem that convention and configuration butt heads repeatedly until developers are quite frustrated with their code. In the real world it's even more difficult to package up black boxes because the language architecture design is fundamentally flawed. (I'm looking at you Javascript global namespaces!)

So, I've personally set out to develop quick easy ways to make boxes that appear to be black boxes, but are highly configurable.

Here were some of the goals I had in mind for designing my personal plugin Architecture.

  1. Had to be easy!
  2. Had to be quick!
  3. Plugin Convention over configuration
  4. Boilerplate-able
  5. Should give access to constructor options to determine where the construction of the object goes
  6. Should provide a local scope for hidden variables relative to each object.

Here's a boilerplate you can use to create something like I'm describing.

I've a feeling we're not in the global namespace anymore.

If some of that code looks confusing to you, I suggest looking at the concept of functional expressions. They give you a "pseudo-blackbox" that can see the global namespace.

If you are good on closures, then we move on to the next step. Actually defining the code to make plugins work. Here's what I personally use:

This code is rather simplistic, but lets take a look a bit deeper to see the real beauty of it.

This little function right here is where ALL the magic happens. Let me show you an example of why this is "magic." Writing a plugin is very easy to do here.

Boom! Now you can call this:

As if that wasn't enough... let's go back and look at another example. A full on event emitter API.

Take some serious time to learn what just happened here. Each one of the functions created in that script are local to the object itself, because the plugin constructor code is called only once. This allows you to enclose private variables into a black box namespace. It's completely abstracted away to the developer behind the curtain.

Please pay no attention to the variables behind the functional expression.

In functional health,
-Josh

Wednesday, October 23, 2013

EMCA Sub Arrays - An Interesting Technique

Dealing with javascript arrays can be a breeze, or it can be bothersome. The array.length property having the ability to change the array is VERY difficult to replicate. You almost cannot make your own typed arrays. At least you can get pretty close. Take the following code snippet I am investigating.

Running this code will make a ZOMBIE array (as I call it.)

(Warning, I am not responsible for unintended "features" your code exhibits.)

function SubArray(length){
   Array.call(this); //"Magic"
   if(typeof length == "number" && length%1==0&&arguments.length==1){
     this.length = length; //Length has to be set manually for some reason.
   }
   else{
     var _len = arguments.length;
     this.length = _len;
     for(var i = 0; i<_len; i++)
        this[i] = arguments[i];
   }
}

SubArray.prototype = [];

var x = new SubArray();

Presto Change-o!

Suddenly you have a strongly typed array, albeit with a few small caveats.

//Evaluate the following
var x = new SubArray();

typeof x; //"object" -- Just like when you declare a new Array....
Object.prototype.toString.call(x); //"[object Object]" -- To be expected
x instanceof Array;//true -- This is the way the Array functionality would be identified

x.push(1); //2
x;//[undefined, 1]
x[2] = "test";

//Drum roll please....
x;//[undefined, 1]

Wait... what? The property wasn't even set! It just disappeared. Or did it? Check console.log(x[2]); . So what really happened is the .length property wasn't set and the array wasn't updated. However, if this particular limitation does not hold you back, it's very easy to work with it because you haven't done ANYTHING to modify a native prototype.

I would probably use this technique for some fun stuff, but what you really wanted was an Array in the first place... so just return an array and add some properties to it instead. It's lame, but it works.

Or you could simply wait for Native Object inheritance in some later version of EMCAscript that is coming down the pipeline.

In functional health, Josh