Rodrigo Alves Vieira

Having fun with Ruby Arrays and Hashes

There’s often the need – in our projects – to convert data from a structure to another. In some languages, when it comes to array/{hashes/maps/tuples} that may be tricky when there’s no built-in mechanisms for converting those datatypes. Ruby offers ways to convert them, merge, organize them in the way you need to.

Arrays

Consider this hypothetical scenario: you have two arrays, the first one contains a set of songs, and the second a set of albums of a rock band. And then you want to merge them into on array of arrays, being each individual array a set of an album and its song.

songs = %w(scar_tissue give_it_away cant_stop)

albums = %w(californication blood_sugar by_the_way)

songs.zip(albums) 
# => [["scar_tissue", "californication"], ["give_it_away", "blood_sugar"],
# ["cant_stop", "by_the_way"]]

Amazing, eh? Way better than having to implement the algorithm yourself in your production code.

Ruby Array#zip takes any number of arguments (arrays), and zip them within the receiver object:

songs = %w(scar_tissue give_it_away cant_stop)

albums = %w(californication blood_sugar by_the_way)

awards = %w(grammy echo billboard)

albums.zip(songs, years, awards) 

# => [["californication", "scar_tissue", 1999, "grammy"], 
# ["blood_sugar", "give_it_away", 1991, "echo"], 
# ["by_the_way", "cant_stop", 2003, "billboard"]]

Turning into Hashes

You can also convert your zipped arrays to hashes, by passing them to the Hash constructor:

Hash[albums.zip(years)]
# => {"californication"=>1999, "blood_sugar"=>1991, 
# "by_the_way"=>2003}

Hash[albums.zip(songs)]
# => {"californication"=>"scar_tissue", "blood_sugar"=>"give_it_away", 
# "by_the_way"=>"cant_stop"}

That’s it, hope this helps you.

Caching JavaScript loops

Loops – don’t matter what code you’re writing – may be an expensive task. They can also be performing critical blocking operations in your code, slowing it down. When possible (and/or needed), it is useful to cache your loops.

JavaScript lets you cache for loops in a simple way.

Let’s think of a scenario, in which we have a great many <li> tags representing car models in our documents. Each of these elements have a HTML5 data attribute called name that contains the model name of the vehicle. In the following algorithm we iterate over all <li> on the document, fetching their model names and storing it in an array of names, defined blank, before the loop:

var modelNames = [];

var modelListings = document.getElementsByTagName("li");

for (var i=0; i < modelListings.length; i++) {
  var listing = modelListings[i];
  modelNames.push(listing.getAttribute("data-name"));
}

The problem with the approach in the algorithm above is that JavaScript will keep querying the modelListings length while it is greater than i. We can prevent that from happening by querying the modelListings length only once and storing it in a variable, which would then serve the running loop:

for (var i=0; size = modelListings.length; i < size; i++) {
  var listing = modelListings[i];
  modelNames.push(listing.getAttribute("data-name"));
}

Depending on the task you’re performing, you may notice significative performance improvements by using this method. Additionally, this method does not leave the code less readable and perhaps should always be used.

Controlling access to your JavaScript Objects properties

JavaScript objects are awesome for dealing with data into the language, parsing JSON, quick prototyping and creating your own objects that behave like a datatype on their own. When the case is the last one, you may want to define in your objects properties that may not be changed, or you may want to lock that object in order to prevent any further addition to it, etc. As any good Object Oriented programming language, JavaScript (since ECMAScript 5) defines methods for specifying object visibility.

Let’s start by creating a sample, ordinary JS object to be used throughout this post:

function User(name, location, username) {
  this.name = name;
  this.location = location;
  this.username = username;
  this.constructor = User
}

var user = new User(
  "Don Quixote", "La Mancha", "don"
);

All objects in JavaScript have an inner object containing the properties which characterize the access to it. These properties are enumerable, configurable and writable.

Now have a glance at the following snippet:

Object.isExtensible(user); // true

By default, all objects in JavaScript are fully modifiable. We can add, alter and remove any of its properties:

  
  user.name = 1;
  
  user.name; // 1, name was set to 1
  

You can specify the access to the object’s attributes individually, using the static Object.defineProperty method:

Object.defineProperty(user,
    "username", {writable: false}
) // Object may not have the username attribute changed.

user.propertyIsEnumerable("username");

Similarly, you can define settings for several attributes at once using the Object.defineProperties method, passing the given object as first argument, and a the set of attributes as second:

Object.defineProperties(user, {  
    "name": {  
      writable: true 
    },
    "username": {  
      configurable: false  
    }  
});

Persistence

In OO, we’re used to create objects that have a given behavior, and we further create other objects that inherit behavior/state from that original one.

All object properties access definitions are persistent across that object prototypes. It means that if object Apartment is prototype of object House, and the latter has a protected maxAvailableSize property, that property won’t be alterable from the Apartment object.

Be aware that none of these methods operate on inherited properties. They’re all based on the hasOwnProperty() method, for security – or sanity – reasons.

You may observed that, till now, we’ve been only controlling access to specific attributes of our objects, but what if we really want to lock them up?

Meet preventExtensions()

Object.preventExtensions() does exactly what its name suggests: it locks an object so it becomes impossible to add new properties to it:

Object.preventExtensions(user);

user.bio = "An user";

user.bio // undefined

NOTE: if you’re adding a new property to an object, you may – in our code – be relying upon that property. If the object is locked for extensions, you’d be badly surprised! The Object.preventExtensions() method reveals whether a given object may be extended or not:

Object.preventExtensions(user);
Object.isExtensible(user); // false

Meet seal()

You may want to create a class, an object and prevent any deletion and/or addition of properties, there is the static seal() for that:

function Car(name, year) {  
  this.year = year;
  this.name = name;
}

var prius = new Car("Prius", 2010);

prius.name // Prius

prius.name = "Prius C"

prius.name // Prius C

// Mark that Car object as sealed
// preventing property addition and remotion

Object.seal(prius);

prius.seats = 5;

prius.seats // undefined

You may have already observed that all unsuccessful assignments fail silently. No JS exception is thrown at you. In the sealing case, you can use Object.isSealed() to find out if the object is sealed.

Meet freeze()

Finally, you can also lock the object entirely, preventing any further change to it, using Object.freeze() and Object.isFrozen() for checking if an object is frozen.

That’s it for today, I hope this post was clear enough. I plan to go on writing about JavaScript. Leave your comments!

Add require_relative to IRB

Ruby 1.9 brought require_relative to the rubyists' life and it’s a nice thing. If you like it, you probably would like to use it in the interactive console.

For some reason I don’t yet know for sure, require_relative does not work on IRB:

>> require_relative "doom" 
LoadError: cannot infer basepath
    from (irb):2:in `require_relative'
   from (irb):2
   from /Users/rodrigovieira/.rbenv/versions/1.9.3-p125/bin/irb:12:in `<main>'
>>

So, I needed this an implemented this method and added it to the .irbrc file, nothing complex, but I found it useful still:

module Kernel
  def require_relative(file)
    $:.push Dir.pwd
    require file
  end  
end

Hope it is as helpful to you as it is to me, I’ll update this post whenever I found why this beloved method does not work in the console.

Deploying Noir to Heroku

I’ve been writing small apps with Noir for a while and, being Noir a web framework, deploying it is a step in the development flow.

In this post I’m going to guide you through deploying Noir apps to Heroku.

First, cd into the project and run

  $ heroku create --stack cedar

This will create the app on Heroku for you and also add this remote repo to your Git config for your use, later.

Note: if it doesn’t work, then that’s probably because you don’t have the Heroku gem/toolbelt.

You should now create a file called Procfileyes, I know, this is for telling Heroku how to run the server for your app:

web: lein run -m my-noir-app.server

Remember that you should replace my-noir-app.server with the actual namespace of your app.

The Actual Deploy

Heroku – adorably – uses Git for deployment. So the following commands should to this job for us:

  $ git add .
  $ git commit -m "First deploy."
  $ git push heroku master

This will send the code to Heroku and manage the app’s dependencies via Leiningen as well ;)

Now you must specify on which port your app will run:

  $ heroku config:add PORT=8080

Note: Use 8080 or whatever, notice that Noir defines the in src/my-noir-app/server.clj file.)

Then, ask Heroku to launch your app:

  $ heroku restart

And that’s it!

Unix Goodies Part 4 - xargs

Terminal

Often, in the command-line, we need to pass the output of a program as arguments to another. Pipe (|) may do the trick, but pipe alone passes only one argument. When you need to pass multiple items, you can use pipe with xargs, which solves your problems.

To illustrate xargs in action, I show you the following command:

  $ pidof emacs | xargs kill

Suppose your computer is got two running instances of Emacs, pidof will list them and xargs will handle the passing properly to kill.

This very command makes kill raise a “not enough arguments” exception if you omit xargs.

Favorite Snippet

There is this one command that I find very useful and use in a regular basis in my Git workflow.

  $ git ls-files --deleted | xargs git rm

This passes all deleted files from the current repo to git rm thus letting you avoid removing each file individually from the Git index. We could call it git rm ..

That’s it, hope I have clearly showed you how xargs can help you during your day-to-day tasks in the console. For more info on the program, consult its manual page.