Today I Learned

3 posts by jasonkurian

FactoryGirl identifiers as symbols not strings

Why is FactoryGirl.create(:my_object) better than FactoryGirl.create("my_object")?

Symbols are immutable objects that are stored by the Ruby interpreter as a numeric ID (an implementation detail, the design of Ruby is flexible for different storage mechanisms).

Strings, on the other hand, take up a memory footprint as large as the number of characters in the string. Using symbols will thus take up less memory and potentially be faster because the same address in memory will be used.

If you have n instances of the same string in your code, Ruby will use O(n) memory to store all those strings, however, if you have n instances of the same symbol in your code, Ruby will use O(1) memory to do the same lookup.

Further reading: https://bugs.ruby-lang.org/issues/7792#note-58

This TIL came courtesy of a discussion with Evan and later on Arturo about best practices in writing test code, but shared here because it's broadly applicable and the FactoryGirl example is just one use case.

the .then(onSuccess, onError) anti-pattern

Before:

somePromise().then(
  function onSuccess (res) {
    // stuff happens, but oh no!
    // an error is thrown in here!
  },
  function onError (err) {
    // request-only error handler
  }
);

After:

somePromise()
  .then(function onSuccess (res) {
    // stuff happens, but oh no!
    // an error is thrown in here!
  })
  .catch(function onError (err) {
    // yay! The error thrown in the function above
    // can be handled here or rethrown to be handled elsewhere.
  });

More details here.

ES2015 Arrow fns do not have the arguments object

const myFn = (/*unknown arity*/) => {
  console.log(arguments); //EMPTY ARRAY!
};
function myFn(/*unknown arity*/) {
  console.log(arguments); //returns what you expect!
}

My takeaway: only use arrow functions when they're necessary, which actually isn't that often! Plain old named JS functions are still powerful and if necessary can still easily be bound with .bind(this).

Related reading: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments