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.
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:
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:
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.
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:
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:
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:
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:
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:
functionCar(name,year){this.year=year;this.name=name;}varprius=newCar("Prius",2010);prius.name// Priusprius.name="Prius C"prius.name// Prius C// Mark that Car object as sealed// preventing property addition and remotionObject.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!
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:
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.