Archive for the ‘tutorials’ Category

Linux Screen [session management utility]

Thursday, February 7th, 2013


Screen is a unix/linux application that allows you to run multiple processes from an interactive shell, such as Apple’s Terminal application. This nifty utility also allows you keep processes running when you close out of an interactive shell session (if you have experience working with interactive shells, you know that when you close a shell the processes running in that environment will stop running).

Screen is extremely useful for working with the Raspberry Pi, or any other remote computer to which you connect using ssh. Here are two scenarios that illustrate why I love screen. If you are intrigued, read on to learn how to use screen.

  • You are logged into the Raspberry Pi, using ssh, running an http server that publishes data from a sensor connected to the RPi. All of a sudden you get a “Connection Closed” message. Your session is abruptly closed and your http server gets shutdown because it was linked directly to your session. If you were running your http server using screen, then it would have continued running even when your session ended.
  • Let’s say that you want to run two different node servers on a remote computer. You could open two separate ssh connections to the remote computer, and start-up a node server in each one. In order to keep the servers running you will need to keep both sessions open indefinitely. With screen, you can connect to the remote server and create two separate screens, each one running its own node server. Best of all, you can log out of your session and the screens will continue to run the node servers.

Now that I’ve given you my description of what screen does, and why it rocks, here is a the official description from the man page: “Screen is a full-screen window manager that multiplexes a physical terminal between several processes (typically interactive shells).” Check out the Screen User’s Manual for more details.

Quick Start Guide to Using Screen
I am not a screen (or Unix/Linux) expert. So here is my short cheat sheet with all the screen commands that you will need to get started using this powerful utility.

Find Out What Screens are Running: When you run the command below you will get a list of all screens that are currently running. The name of each screen will be preceded by a process number and followed by the screen’s status. When the status is “attached” that means that a session is currently logged into that screen; “detached” means that the no one is logged into the screen.

$ screen -ls

Create New Screen: In order to create a new screen just run the command below, replacing the screen_name with an alphanumeric identifier. You can create two screens with the same name, though I don’t recommend it. If you do so, you can use the unique process id to differentiate between them.

$ screen -S screen_name

Connect to Existing Screen: To connect (or attach) to an existing screen you need to know it’s name or process id number. Then just run the command below using the appropriate identifier.

$ screen -r screen_name

Detach from Screen: To detach from a screen just use the key stroke combinations described below. Note that to “detach” means to disconnect from a screen without closing it. After detaching from a screen I always confirm that it is still running by using the list screens command described previously.

'ctrl-a' followed by 'd'

Closing a Screen: To close a screen you need to use the key stroke combinations described below. Remember that when you close a screen it will shut down any processes that were running in the screen.

'ctrl-a' followed by ':quit' then 'enter' key

Rotary Encoders [how they work]

Tuesday, January 1st, 2013

Optical Rotary Encoder Wheels

A few months ago a colleague at the LAB asked for my help to develop a simple prototype with a custom-made optical rotary encoder. I was excited to get this opportunity to play around with optical rotary encoders because, even though I had worked with these types of switches in the past, I still did not fully understand how they worked. Helping to build this prototype was a perfect opportunity to bridge my knowledge gap in this area.

Rotary encoders are awesome. Two of my favorite things about encoders is that they provide unlimited rotation and they are surprisingly easy to make. Did I mention that rotary encoders are awesome? Ok, I definitely drank the rotary encoder kool-aid. This post is my attempt to get you hooked on this kool-aid.

With that in mind, I have put together this overview that explains how rotary encoders work. In the coming weeks I will also post a tutorial on designing a custom optical rotary encoder along with code examples for Arduinos. Before I dive, I want to acknowledge the most useful sources of information that I found on the web about rotary encoders. Most the content on this post is distilled from these websites.

Optical Rotary Encoders: An Overview
An optical rotary encoder is a type of rotary switch whose angular position or motion can be detected by optical sensors. These switches provide unlimited rotation, making them unique and ideal for many different applications. There are two main types of encoders: relative (incremental) and absolute. Here is a brief overview of each:

  • Relative encoders provide information about the motion of the shaft that can be used to determine direction and speed. These are the most commonly used type of encoders.
  • Absolute encoders provide feedback regarding the current angular position of the shaft, and are sometimes called angle transducers. The physical position of absolute encoders is always available to the system.

How They Work
Optical rotary encoders feature one or more light sources separated from one or more photo detectors by a surface that modulates light. The photo detectors are configured so that when they are read simultaneously (or at least nearly so), the pattern resulting from their individuals states is used to determine the encoders overall state (or position).

For the sake of clarity, here is a step-by-step description of how encoders work: first, light is emitted by the encoder’s light sources. The light passes through slots in a sensing wheel, or is reflected by light and dark areas on a printed wheel. The resulting light patterns that are captured by the photo detectors are used by the firmware to determine the encoders position or motion.

Designing Encoders
The type and resolution of an encoder are determined by the design of the encoder wheel, and the number and placement of the photo sources and detectors.

Relative Encoders feature two or more photo sources and detectors, coupled with a single-track wheel or two-track quadrature wheel. The configuration of the photo detectors differs depending on the number of tracks on the coded wheel. The photo sensors are offset on one-track wheels, while they are aligned in two-track quadrature wheels. The placement of the sensors is crucial to enabling the rotary encoder to determine the direction of the rotation.

Relative Encoder Wheels

These types of encoders support higher resolution with a smaller number of photo detectors than absolute encoders. Just look at the middle and right coded wheels above to see how it is possible to increase the resolution of relative encoders without changing the number of sensors.

Absolute Encoders feature four or more photo sources and detectors, coupled with an appropriately-designed coded wheel. The resolution on these types of encoders is tightly linked to the number of photo sensors they feature. Each photo detector can hold the equivalent of one bit of data. Therefore, an absolute encoder with four photo detectors is able to support a resolution of 16 different states or positions.

Absolute Encoder Wheels

There are two different encoding patterns used on the coded wheels in absolute rotary encoders: binary and gray encoding. Gray encoding is a binary system where adjacent states/positions differ only by one track. This is the preferred encoding scheme because it is less prone to errors. (please note that the diagram above is labeled incorrectly, sorry!)

Programming Encoders
To parse data from rotary encoders the firmware needs to be able to perform edge detection. Edge detection refers to processes designed to detect sharp changes in state.

In the context of rotary encoders the “edges” refer to the moments when the state of an encoder pin changes from high to low (falling), and vice versa (rising). The detection of an “edge” is then used as a trigger to read the state of all the photo sensors to determine the current motion or position of the encoder.

Edge Detection

The “edges” that serve as triggers will vary depending on the type and resolution of the encoder. For example, on a relative encoder we often use only the rising edge of a single track as a trigger. On an absolute encoder the edges are a bit less important since the encoder’s position is always available.

Another important question to consider is whether to use an interrupt- or polling-based approach for edge detection.

Interrupt-based edge detection is the most effective approach, especially for relative encoders. Interrupts enable a software function to be called in response to changes in the state of a physical pin. The Arduino supports both falling and rising interrupts.

Polling-based edge detection relies on continuous sampling and processing of input from all photo sensors. This approach is more computationally-intensive and less responsive, though it is often a satisfactory solution for absolute encoders.

Switches Library [now fully documented]

Monday, December 31st, 2012


I’m a big fan of switches, and digital inputs of all types. A little over a year ago I published a blog post about the Switches Library for Arduino that I created. This library provides classes for managing the state of switches, buttons, analog switches, and rotary encoders. I developed this library for a project where I neded to connect a large number of switches to multiple different Arduinos.

I never got a chance to fully document how this library works, until now. Earlier today I published an updated version of the library that includes example sketches, a readme file with detailed description of how each switch class works, and source code that is well documented.

The Switches library was designed to enable you to handle input from different types of physical inputs using a consistent code/design pattern. This library is actually a collection of libraries, where each one handles a different type of switch. The switch-specific libraries are refered to as implementation classes in the documentation. These provide helpful features, such as debouncing capabilities for digital switches and smoothing capabilities for analog switches.

Below is an list of the example sketches that have been added to the library. You can access these examples by selecting File -> Examples -> Switches from the top menu bar on the Arduino IDE app.

  • analog_switch demonstrates how the analog switch class can be used to set-up an analog switch. The sketch sends a serial message with the switch’s state whenever its state changes.
  • digital_switch shows how the digital switch class handles a digital switches, when in momentary mode. The example sketch sends a serial message with the switch’s state whenever its state changes.
  • multi_state_rgb_button illustrates how to create a sketch that manages a multi-state button with an rbg led that reflects the button’s current state. The example sketch updates the led color and sends a serial message with the switch’s current state whenever the button’s state changes.
  • rotary_encoder shows how to hook-up a rotary encoder using the switches encoder library. The sketch sends a serial message with the encoder’s current state whenever its state changes.

I had a fun time testing out the digital switch, multi-state rgb button, and analog switch examples on the ProtoSnap Pro Mini kit from Sparkfun. I’ve had this little prototyping kit since I got it from Nathan Seidle at the MakerFaire in San Mateo, so I have to give a shout out to Nathan and Sparkfun.

Please note that I was not able to test the rotary encoder example yet. I will update the code as necessary when I test the code in the coming week.

About the Header Image for This Post I created this image using Creative Commons licensed photos from flickr. To credit the owners of these photos, I put together an annotated version of this image that features links to the original source images.

Proximity Detection [mpr121 capacitive touch sensor]

Saturday, December 29th, 2012

During the past few months at the LAB we have been working with the MPR121 Capacitive Touch Sensor breakout board from Sparkfun. This capacitive sensing controller features touch sensing and proximity detection capabilities, though our work has focused on proximity detection exclusively.

We used the tutorial published by Jim Bloom on bildr as our starting point. This tutorial walks through the process of hooking-up the breakout board to an Arduino, and features a sketch that configures the controller to sense touch events from all 12 electrodes.

Our next step, was to figure out how proximity detection works on the MPR121 and what needs to be done to activate and configure this capability. Here is a brief description of how detection sensing works, taken from one of the application notes on Freescale’s product site:

MPR121 has a unique feature that all the electrode inputs can be internally connected together so that all the surface touch sensing area on the inputs are “summed” together to act as a single large electrode pad. This can effectively increase the total area of the sensing conductor for non-contact near proximity detection for hand approaching.

This means that proximity detection works best when all 12 touch sensing electrodes are connected, and that the MPR121 can sense proximity and touch simultaneously.

After one afternoon of reading through the MPR121 documentation site, and a day of going through the Proximity Detection and Capacitance Sensing Settings application notes and testing different register settings with our prototype, we figured out how to activate the proximity sensing capabilities. In the process, we learned to configure over 15 registers. For the most part, we used the suggested settings from the application notes for these registers.

Check-out the tutorial on github for instructions on how to hook-up an Arduino to an MPR121 breakout board. You can download the Arduino sketch here, or from the github tutorial page. The tutorial is included in the readme file, along with the sketch and a hook-up diagram.

Learning Ruby [IO system]

Sunday, October 9th, 2011

The IO class is the basis for all input and output in Ruby. Objects from this class represent connections to various different input and output devices such as hard drives, keyboards, and screens. All Ruby programs have three standard I/O streams:

  • the input stream, known as STDIN or $stdin, is set to capture data from the keyboard;
  • the output stream, named STDOUT or $stdout, is set to output data to a terminal screen;
  • the error stream, called STDERR or $stderr, also outputs to the terminal screen.

Whenever unadorned IO methods are called (for example puts, prints, and gets) they are routed to and from the standard output and input streams. In order to send output to the error stream STDERR must be explicitly specified, for example STDERR.puts “text”.

To change the routing of any of the standard streams, you can reassign the global variables associated to each one ($stdin, $stdout, $stderr). It is recommended that you leave the constants untouched (STDIN, STDOUT, STDERR), so that you can still access the default input and output devices.

Now let’s discuss how IO objects read data streams. IO objects use iterators to read and write data to IO streams. Iterations in are delineated by the global input record separator, $/. The default global input record separator is a new line character, “\n”, which is why Ruby usually processes data one line at a time. By changing the global input record separator you can change how Ruby iterates through input and output streams.

Before covering how to read and write data to IO objects, let’s take a look at the most common IO object in Ruby: The File object. As the name suggests, the File object is used to represent files within Ruby. This object provides functionality that enables files to be opened up, read from, written to, and closed.

The most common approaches to create a file object is to use the or methods. These method require one parameter along with several optional parameters. The object has two advantages: it also supports an optional code block and it can be called without being preceded by the class name File.

The first parameter is the only one that is mandatory. It accepts a string object that holds the location of the file. The location can be specified using an absolute or relative path. The other parameters can be used to define several options, though the only option I will cover here is the file mode. The file mode determines how a file can be used. The most common file modes are:

  • Read mode is identified by an “r”. This is mode only supports reading from a file. This is the default mode. If a file does not exist then the method will return an exception.
  • Append mode is identified by “a”. This mode supports writing to a file by appending new data to any existing content. If a file does not exist then it will be created.
  • Write mode is identified by “w”. This modes supports writing to a file by overwriting any existing content. If a file does not exist then it will be created. method and the method called without a code block, function in the same way, they return a reference to a file. When using either of these approaches to create a file object it is important to remember to call the close method when you are done.

If the optional code block is created, it will be passed a reference to the file object as an argument. The file object will automatically be closed when the block terminates. In this instance, returns the value of the block.

The open-uri library makes it easy to access remote files from networks using the HTTP and HTTPS protocols. After importing this library using the require keyword you can open remote files using the open method as though they were local files. Files are downloaded and returned as StringIO objects. These objects enable strings to behave like an IO stream, which means that they can be read using the standard IO stream input methods described below.

In Ruby, IO objects feature a suite of standard input and output methods. We’ll take a look at the input methods first. All of these methods can be used with different objects to read input from various sources such as the keyboard, files from a hard-drive, or from a local or remote server.

First let’s take a look at the methods that read input one character at a time. There are four such methods, getc, getbyte, readchar, and readbyte. These can be divided in two different ways based on how they work. First we can group these methods by how they deal with being called to read data after reaching the end of a file. getc, and getbyte return nil, while readchar, and readbyte return a fatal error.

The other, more significant difference relates to the data that is actually returned by these methods. The getc and readchar methods return characters, whereas the getbyte and readbyte methods return individual bytes. Since most characters are encoded in two bytes, these methods return two numbers, each one representing a different byte.

Here are links to two short scripts that let you see how these different methods read data from files and from the keyboard.

Now let’s move on to the methods that read data one line at a time. There are three such methods, gets, readline, and each. The first two function similar to their counterparts. They both read one line at a time, but gets returns nil when it reaches the end of a file; readline returns a fatal error.

The third method functions a bit different. If you recall, each is a standard iterator method. Therefore, it iterates through the entire file (as it would with any other collection), yielding each line to a code block where it can be processed. This approach is ideal if you plan to process all the lines from a file at once. On the other hand, it does not allow you to walk through a file with the same level of control provided by gets, and readline.

Here are links to two short scripts that let you see how these different methods read data from files and from the keyboard.

Lastly, let’s take a look at the two methods that read entire files: read and readlines. These methods are designed to read from files only and are not appropriate for getting input from a keyboard. Usually, these methods are only used to read small files. When reading large files it is best to process them iteratively, as this is a more efficient use of memory and processing power.

Before we cover how to output data, let’s briefly review the methods for navigating within a file. First off, the rewind method enables you to jump back to the beginning of a file. The pos accessor attribute provides getter and setter methods that enable you to check your current location, to move to a new absolute position within the file.

The seek() method can also be used to change your current position within a file. It enables you to move by specifying a position that is either relative to your current position, to the start of the file or to the end of the file. The first argument is an integer that specifies the distance to be moved, while the second parameter is a constant that specifies the point of origin for this movement.

Here are the constants that can be specified for the second argument: IO::SEEK_SET is the default setting and it sets pointer position from the beginning of file; IO::SEEK_CUR sets pointer position from the current location; IO::SEEK_END sets pointer position from end of file).

Here is a link to a short script that illustrates how to read and navigate through a file.

Now let’s take a look at the standard output methods: print, puts, and p. For any of these methods to work the output stream on which they are called must be opened for output. If these methods are called without specifying an object recipient then they will default to the standard output stream,$stdout.

The puts(obj, …) method accepts multiple objects as arguments and writes them to an IO stream. Any objects that are not strings are converted to string using their to_s method. A newline character is appended to each object before it is written to an IO stream (unless the original object already ended with a newline). If method is called with an array argument it writes each element on a newline. If called without any arguments it outputs a newline character. This method also always returns nil.

The print(obj, …) method accepts multiple objects as arguments and writes them to an IO stream. Any objects that are not strings are converted to string using their to_s method. If multiple arguments are provided they are appended to each other using the output field operator, saved in global variable: $,. By default this global variable is empty, which means that strings are appended back to back. If this method is called without any arguments then it returns the last line of input that was read in your program, saved in global variable: $_. This method always returns nil.

The printf(obj, …) method accepts a format string followed by multiple objects. It uses the format string to determine how to integrate the data from the objects into the output string that is sent to the IO stream. The number of objects passed into the method must be consistent with the number and type of objects identified in the format string, otherwise an error exception will be raised.

The IO capabilities used by this method are based on the print method covered above, which is why this method also returns nil. The formatting capabilities embedded in this method are based on Ruby’s format method, which accepts the same parameters and returns a formatted string. For more details on creating format strings check out the documentation here.

The p(obj, …) method accepts multiple objects as arguments and outputs the return value from each object’s inspect method, followed by a newline character. Unlike the other output methods that we just reviewed, this one returns the same string that it outputs to the IO stream.

When you are working with files many of the error exceptions you will encounter are system errors. In these cases, Ruby is just a messenger that is informing you about errors that happened at the operating system level. Several objects have been created to wrap these system errors to enable Ruby to provide intelligible error exception messages. These error exception objects are part of the Errno namespace, that is why all of these errors will be labelled Errno::ERRORNAME.

Learning Ruby [enumerator, enumerable objects]

Wednesday, October 5th, 2011

I did not provide a good description for iterators earlier, so let me do that now before jumping into the concept of enumerators. Iterators are methods that have the ability to iterate through a collection such as an array or hash table, and that yield one or more values to a code block.

Enumerators are objects that are created for doing iterations. These objects contain the standard suite of iterator methods available for all classes that mix-in the Enumerable module. To create an enumerator the logic for the each method needs to be defined. If you recall, the each logic is used to determine how all other iterator methods work in any class with the Enumerable module mixed-in.

Since enumerators are objects they are able to hold information about the current state of their iteration. That means you can step through an iteration little by little. Iterator methods are atomic; once the method call is completed they are not able to save information related to their iteration.

Enumerators can also be used to protect information. By transferring data from a collection to an enumerator object you can iterate through the data without the risk of it being changed.

There are three ways to create enumerators. The most common approach is to use an iterator method from an existing object to define the each logic for the newly minted Enumerator object. Most iterators methods return an enumerator object if they are called without a code block. As you can see in the example below, the each method when called without a code block returns a numerator, which I have assigned to a variable.

You can also call the enum_for method on a collection to create an enumerator. This method takes up to two arguments, the first specifies the iterator method that will be used as the basis of the each logic for new enumerator; the second is an optional initialization argument that is only useful for a limited number of methods, such as inject.

In the example below, the select iterator from ingredients collection is used as the basis of the each logic on this new enumerator object. This makes the each method on the new object function like the select method from the ingredients collection.

You can also use the method to create an enumerator object. In this case you need to define the each logic for this object inside a block of code. Here you need to define the elements that this object will iterate through and the way in which this iteration will happen. This includes identifying the value that should be yielded by the iterator methods from this object.

In the example code below I have created an array of strings, called ingredients. It contains the elements that my enumerator object will iterate through. Then I use the each method from this array to define the way in which the iteration will happen, which is based on each element’s index in the array. Lastly, I use the expression yielder << ingredient to identify the value that should be yielded from this object on each iteration.

This last example is rather silly. I am sharing it to illustrate the point that you can create a new enumerator objects without using an existing iterator as the basis for your new object. The each logic defined below iterates through three different values, yielding each one in turn.

Learning Ruby [the enumerable module]

Wednesday, October 5th, 2011

In order to mix-in the functionality from enumerable module into a Ruby class, the class needs to be a collection and the each method needs to be defined. The each method is responsible for holding the iteration logic for a class. This method defines what value(s) are yielded to the code block during each iteration. The logic encapsulated in this method serves as the basis for all other enumerable module methods, which are briefly described below.

First let’s look at the conditional methods that return boolean values. All of these methods, except include?, will evaluate the return values from the code block to determine whether to return a true or false. The names of these methods make their function pretty self explanatory.

Next let’s look at the methods that return filtered content from a collection. Once again the code blocks play a key role in how these methods work. All of these methods, except grep, use the return value from the code block to select which elements should be returned. The find method returns only first matching element from the original collection, while the find_all and select methods return all matching elements. The reject method, returns all non-matching element.

The grep method works a little bit differently. The filter logic is defined by a RegEx expression that is passed into the method as an argument. The code block is used to process the matching elements before they are added to the array that is returned. In the example below, the results are converted to uppercase.

The group_by and partition methods filter elements by arranging them into separate groups. The group_by method returns a hash table with the elements from the original collection sorted into different groups based on an expression defined in the code block. In the example below the words are grouped based on the length.

The partition array returns elements from the original collection sorted into two groups based on a true/false condition that is applied to each element. In the example below the expression checks whether each word has more than 5 letters.

There are several interesting variations of the each method that are implemented for all classes mixed in with the enumerable module. These are methods designed to provide access to all elements from a collection via the code block. They differ from the examples we covered because they do not provide a useful return value – they return the original collection, unchanged.

The each_with_index method iterates through collection and yields the current element and index to code block. The cycle(n) method iterates through a collection n number of “times”, yielding the current element from the collection to the code block.

The each_slice(size) method iterates through collection a few elements at a time. It yields to the code block an array that contain a non-overlapping slice of the elements from the collection. The each_cons(size) methods also iterates through a collection by looking at several elements at a time. However, the arrays that it yields to the code block are overlapping.

Lastly, let’s look at methods that return content generated during the iteration process. These methods return single objects, or arrays, that have been created through the iteration process.

The inject(init) method loops through a collection and yields to the code block the current element along with an accumulator. The accumulator can be initialized via an argument; otherwise, it is initialized with the first element from the collection. Once finished iterating the method returns the last statement from the code block, which is usually the accumulator. It is important to remember that the accumulator value that is passed from one iteration to the next is always the value from last expression in the code block.

The map method is one of the most powerful methods from the each family. It iterates through a collection and generates a new array that is populated with the return values from the code block. This method returns a new array of the same size as the original collection.

In order to be able to sort custom-created objects in a collection you can take one of three approaches. All approaches require the definition of the logic which governs how a custom-created object should be compared with other objects – from a greater than, equal to, and less than perspective.

The simplest approach is to define a <=> method, also known as a spaceship method. This method accepts an object as an argument. It needs to be defined so that it returns -1 if the self object i less than, 1 if the self object is greater than, and 0 if both objects are equal. Once this method is defined for a given class then Ruby will know how to sort a collection of objects from that class.

The next approach is to use a code block that tells the array how to sort the objects. This approach can be very useful when you have an array of objects that needs to be sorted in many different ways. The sort method passes two different objects to the code block; by defining how to compare two objects the collection is able to sort the entire collection.

The last, and most robust approach, is to define the spaceship method and mix-in the Comparable module into the new class. Beyond array sorting, the Comparable module provides your objects with ability to support comparison operations such as <, >, == and so on.

Learning Ruby [sets]

Monday, October 3rd, 2011

Sets are a special type of collection that contain elements with unique content. A set can contain any type of object. However, it makes sure that there is only one version of each object in a given set. Sets are created using the method. This method accepts a collection as an argument. It also supports the definition of a code block to process the contents from the collection being passed as an argument.

A new element can be added to a set using the << operator, or the add(item) and add?(item) methods. These approaches are identical for the most part. Except that add? returns nil if the item already exists in the set. The merge(collection) method enables merging new collections into the set; using the add methods adds an entire collection as a single item.

As expected, the delete(item) method deletes objects from a set.

Using the operators +, -, |, & you can check the union (add), difference (subtract), intersection (and and or) between different set objects. You can also use the superset?(set) and subset?(set) methods to compare two sets to determine if they relate to one another in either of these ways.

Learning Ruby [hash tables]

Monday, October 3rd, 2011

Hashes are collections of objects that are primarily organized by sets of key/value pairs. The keys must be unique and they can be any type of object. Most often, strings or symbols are used as keys. Like an Array, Hashes feature all of the collection-related functionality provided by the Enumerable module

In Ruby, hashes are considered ordered because they maintain information about the order in which objects were added. Hashes are said to have a meta-index; each element in a hash features a key, a value, both of which can be any type of object, and an meta-index, which is always an integer.

There are three ways to create hash tables in Ruby. The literal approach is the most common. It uses curly brackets that contains key/value pairs linked by the => operator, and separated from one another by commas. Below is an example where the keys are symbols and the values are strings (hashes support any types of objects for both keys and values).

Learning Ruby [arrays]

Monday, October 3rd, 2011

Arrays in Ruby are similar to arrays in other programming languages. They are collections of objects that are ordered based on a numerical index. This class is mixed with the Enumerable module, which provides a lot of collection-related functionality.

There are several ways to initialize an array: the literal approach; the method; the Array method, and the %w[] (or %W[]) syntax. The literal approach, which is illustrated below, is the most common. In this approach a bare list in square brackets is used to initialize an array. The square brackets can be also be empty, to create an empty array.