![]() |
Ruby is an object-oriented language. What does that even mean? It has unique quirks and characteristics that we’ll explain clearly. This article assumes that you have no programming experience, not even HTML.
An important skill to have when creating a program is translating — translating the desires of the user into the output they are looking for. In order to do that, you have to be able to think like a developer so that you can take what you know instinctively (as a user) and morph it into what the computer needs to be able to do what you want. So, we’ll help you start thinking like a developer. When you are done, you should have a mental model of how Ruby works and be on your way to becoming a successful Rubyista.
We’ll take you through a variety of the fundamental elements of the Ruby language and explain the whys behind the hows.
For all the code samples we go over, you can test them out on Try Ruby (without having to install anything on your computer). You can follow Try Ruby’s tutorial if you want, but you don’t need to in order to understand what we’ll outline below. It’s just a quick way to get your feet wet without the headache of installing anything.
The interpreter for Ruby — basically, the main brain of the programming language that makes sense of the code you write — reads the code from top to bottom and left to right; meaning, it starts at line 1, character 1, literally, and first reads across line 1 to the last character, then goes down to the next line, and repeats this process until it reaches the last line of your program. If you have any syntax errors — i.e. errors in your code, such as misspelled variable names, improper use of constants (we’ll get to constants in a bit), etc. — it will halt execution and show you an error message, usually with a line number corresponding to the code. Remembering this is important because if you encounter an error report while coding, you will need to know how to decipher it. Figuring this out isn’t always straightforward for beginners.

Fictitious code from The Matrix. (Image: Absolute Chaos)
This top-down parsing also affects the control of the flow of logic in your program. Say you want to calculate the balance of someone’s account before showing it to them. You would have to make sure that you put the method and function that does the calculation before the output of the balance; that is, if you are outputting the balance at line 10, then you would have to do the calculations somewhere between line 1 and 9. We’ll dive into this later.
An object is a thing. It is at the heart of Ruby. Going back to our earlier statement about Ruby being an object-oriented language, that means that Ruby manipulates all data on the assumption that the data is an object. There are many object-oriented languages, but very few put the object at the center of their universe like Ruby does. In Ruby, everything is an object. I mean everything: every variable, every operation. Every object has different characteristics; that’s what makes them different. A string is an object that has built-in characteristics that make it suitable for handling text. For a more technical definition, check out the article “Object” on Wikipedia.
A method is simply a definition of an action that can be
performed on an object. Ruby has built-in object definitions and
methods. One such method is capitalize for the Ruby
class strings (we will dive into strings later).
string1 = "this string is awesome"
If you wrote string1.capitalize, the
output would look something like this:
"This string is awesome".
All that the capitalize method tells the Ruby
interpreter to do is convert the first character of the string
from lowercase to uppercase. Check out an
example directly from the Ruby documentation. As you can see
from the documentation, the string object in Ruby
has a ton of methods that you can use right out of the box.
Another thing you should have noticed is the way to call a
method, string1.capitalize, which is basically
. .
In this case, the object is a string variable. If you tried to do
capitalize on an object that is not a string, Ruby
would throw an error.
You can create any method for any of your objects. Here is the way to do that:
def method_name
#Enter code here
end
The # basically tells the Ruby interpreter that
this is a comment for another human and to ignore it. So, the
Ruby interpreter skips lines that begin with a #.
A class is like a blueprint that allows you to create objects of a particular type and to create methods that relate to those objects. But classes have a special property called “inheritance.” Inheritance means just what you would think. When you inherit something from someone, it likely means a few things:

Classes are like a blueprint for objects. (Image: Todd
Ehlers)
Those principles are the same in Ruby. There are parent, grandparent and children classes. As a general rule, children classes inherit all of the attributes of a parent or grandparent class.
In Ruby, an object’s grandparent class is known as
its “superclass.” In other words, if you have an object
that is a string — meaning that your object inherits the
properties of the String class — then the parent
class of String is String’s superclass.
Be careful not to miss an important distinction here: the
superclass of String (which is a class that tells
Ruby how to treat strings) is not the same
as the superclass of a String object. Here is a
demonstration:
> num1 = "this is a string" => "this is a string" > num1.class => String > String.superclass => Object > Object.superclass => BasicObject > BasicObject.superclass => nil
What we have done is set the local
variables num1 to be a string. When we
check the class of num1, by calling
the .class method, it tells us that the
class of num1 is String.
Then, when we checked the superclass of String, it
tells us Object, and so on.
Look at what would happen if we
tried num1.superclass:
> num1 = "this is a string" => "this is a string" > num1.superclass => #
The reason this doesn’t work is
because num1 is an object (a local
variable) that has inherited the properties of the class
String. And num1 is
not a class, so it has no superclass.
Here is another way to do what we did earlier:
> num1 = "this is a string" => "this is a string" > num1.class => String > num1.class.superclass => Object > num1.class.superclass.superclass => BasicObject > num1.class.superclass.superclass.superclass => nil
The reason the last value is nil is because
BasicObject has no parent. It inherits nothing from
another class, so it stops there.
One key thing we have done here that is different from before is we have “chained” methods, meaning we have continued applying a method to the current statement. That’s another beautiful thing about Ruby: every time it evaluates something, it returns a copy and allows you to continue evaluating it.
Take the last line:
> num1.class.superclass.superclass.superclass => nil
Basically, Ruby did this:
num1? It’s a string, so
return String.
String?
String is a child class of Object, so
return Object.
Object?
Object is a child class of BasicObject,
so return BasicObject.
BasicObject?
BasicObject is not a child class of anything, so
return nil.
All on one line, all in one command. Simple, neat, elegant.
The structure of classes and superclasses is the hierarchy of class inheritance.
Now the question is, how do you define a class and use one? Glad you asked.
class MyClass # some code logic end
That’s it.
Basically, you just have the opening
keyword, class, followed by the name of
your class (MyClass, in this case). Then you have
some code. And when you are done, you close it with the
keyword end. Make sure that class
and end are always all lowercase (i.e. don’t write
Class or End or you might get errors).
That’s all there is to it.
If you have a parent class that you want this new class to inherit stuff from, you would define it like this:
class MyChildClass < MyClass # some code that is specific to the child class end
Ruby interprets the <</code> operator to mean that
the class name on the right side is the parent and the class name
on the left is the child (therefore, the child should inherit
methods and such from the parent).
Also, remember that class names usually start with an
uppercase letter; and if their name has multiple words, you do
what is called “CamelCasing” — i.e. instead of using a space or
underscore or hyphen, you just start the new word with an
uppercase letter.
Class Instances
Now we know how to create a class, which we know is the
blueprint of an object type. So, if you think of baking, a class
is like a recipe (which contains a list of ingredients and
instructions for creating something). But once you create
something — say, blueberry muffins — then each muffin may be
considered an “instance” of that class.
So, each instance or muffin is an object.
The way to create an instance is like this:
muffin = BlueberryMuffin.new
That’s it.
To be technical, the only part of the statement above that
actually creates an instance of the
BlueberryMuffin
class is BlueberryMuffin.new. In order to use
the object, you have to store it somewhere, so we’ve stored it in
the local variable muffin so that we can reuse
this specific instance (or muffin).
You will need to do more technical things with a class, like set up an initialization method so that whenever you create an object of the class, Ruby knows how to do that exactly. That is a bit beyond the scope of this article — just understand what a class is, how it relates to objects, how to create new objects, etc.
To read up on classes, check out the article about them on Learn Ruby The Hard Way.
How is data structured?
At the core of programming is the manipulation of data. Computer scientists have come up with a way to manipulate data in a structured way by inventing things called “data structures.” A data structure is simply a container for a particular type of data. Words are handled differently than formulas; likewise, characters and letters are handled differently than numbers — in most cases.
What’s a variable?
A variable is the name of the most basic type of container that you will store data in. Each variable name has to be unique to its scope (i.e. the area in which the variable is allowed to exist). Think of it as a Venn diagram, in which each variable is only valuable in the circle or square within which it is contained.
Say you wanted to create a program (or a part of a program) that is responsible for adding two numbers. From the coder’s point of view, you would need to set up a container for each of those numbers, and then set up the mathematical function between the containers. The reason to do this is because you don’t want the user to have to edit the source code every single time they want to calculate the sum. Although you could do that, the solution is neither practical nor efficient. Most users know what a calculator looks like, so they can just press the buttons or enter the numbers. But editing source code is a no-no.
In Ruby, each of those containers is a variable. So, you would do something like this:
sum = num1 + num2
As opposed to something like this:
sum = 19 + 20
Ruby and many other languages have many types of variables. We’ll go over just a few to be brief and not confuse you too much.
num1 — that is used in three
different ways in each of those methods and that stores three
different values. Going back to the Venn diagram, suppose there
are three shapes within the diagram: Circle 1, Circle 2,
Square. Also suppose that Circle 1 and Circle 2 are not
connected, but both are within Square. A local variable would
be confined to its respective circle and would not be able to
affect anything outside of its circle. The way to use these
variables is to just use them. If you want to use a local
variable called sum that stores the sum of the
values of num1 and num2, you would
simply write sum = num1 + num2.
$ before the name. So,
suppose you want to calculate multiple dimensions of a circle,
and you want to define the radius beforehand. You would do
something like this: $ radius = 20. Then, at any
other time throughout the program, regardless of whether you
are in a subcircle of the square or in the square alone, you
can reference $ radius. Now, using global
variables has a good side and bad side. The good side is that
you can read the value of a global variable in any method or
function within your program. The bad side is that you can also
write to a global variable in any method or function within
your program. If you change the value, forgetting that another
method or function depends on the previous value could really
screw things up. As a rule, then, stay away from global
variables unless you are confident that you know where they
will be used and how changes would affect the rest of the
program.
PI =
3.14. Constants have to begin with an uppercase letter,
and more often than not they are all uppercase, but they don’t
have to be. Note that I said that the values of constants are
supposed to be constant throughout your entire
program, but they can be changed. Ruby doesn’t forbid you from
changing the value, but when you do, it gives you a warning
because it doesn’t like it. Going back to the Venn diagram,
think of PI as being set outside of the square,
and it can be used anywhere within the square and anywhere
within the circles within the square.
@@ at the beginning of the name of the variable.
@ at
the beginning of the name of the variable.
Here’s a recap on how to use the variable types:
sum = num1 + num2$ radius = 20$ .
PI = 3.14@@length = 10 #Square, and
defined the length of each side for demonstration purposes.
What’s important to note here is that all “squares” would have
a “length” of 10 by default.
@length = 5 #5 instead of the default 10. You
could use this instance variable to specify the length of this
particular square, your “Red Square.”
Note that these rules are by no means comprehensive. Some words you can’t use as variable names. They are called “reserved words,” which Ruby uses internally to identify various elements of the language.
To find out more about variables and other do’s and don’ts, check out the following resources:
What is a string?
A string is a series or sequence of characters — i.e. a “word” or sequence of words. You might say a sentence, but a string is not just a sentence. For instance:
string1 = 'a' string2 = 'This is a string'
Two things are happening here. The first is that we are using
local variables, and the second thing is that we are using single
quotes to define the content of the variable. Even though
string1 contains just one letter, it is still a
string because it is declared in single quotes. Ruby knows how to
treat a variable by the way it is declared. You can use double
quotes, but you have to be consistent. You can’t start the
string’s declaration with a double quote and end with a single
quote, like this: string1 = "This is a string'. But
you can do this: string1 = "This is a string", or
string2 = 'This too is a string'. Both are valid,
and it’s just a matter of taste.
num1 = 9
This sets num1 to the numerical value of 9. So, if
you did num1 + 1, the result would be
10.
But if you used single quotes around the 9, like
this…
num1 = '9'
… then that would say that 9 is actually a string,
not a number. So, if you wrote num1 + 1, it would
throw an error along the lines of: => #. The
Ruby interpreter is basically saying that you have given it a
number and a string and that it doesn’t know how to add them.
To take that one step further, if you did this…
num1 = '9' num2 = '1' num1 + num2
… the result would be this:
"91"
Because Ruby would take the two strings and literally squish them
together. When you specify a value in quotes (either single and
double quotes), you are telling the Ruby interpreter, “Don’t
translate this. Just take the exact content between the beginning
and end quotes.” It treats the 9 like any other
letter. So, as far as Ruby is concerned…
num1 = '9'
… is more or less the same as this:
num2 = 'a'
As a matter of fact, if you did num1 + num2, the
result would be 9a.
In summary, a string is just a combination of letters, numbers and special characters.
So far, we have covered individual pieces of data, such as one or a handful of items that can be stored in a local variable, or a single object created as an instance of a class.
But what happens if we want to work with many pieces of data — that is, a collection, such as a series of numbers that we need to put in ascending order, or a list of names sorted alphabetically. How does Ruby manage that?
Ruby gives us two tools: hashes and arrays.
The easiest way to explain an array is to show an image of what a “typical” one looks like.
Rather than having six different variables for the six food
types, we have just one food array that stores each food item in
its own container or element. The numbers to the right of the
diagram above are the “index” or “keys” (i.e. addresses) of each
element ([0] = chicken, [1] = rice,
etc). Note that the keys are always integers (whole numbers) and
always start at 0 and go up from there. So, the first element is
always [0], and [1] is always the
second element, etc. So, you will know that the range of keys of
any array is always [0] to (length-1) —
meaning that the last element is always total length of the array
minus 1, because we started at [0].
To create the above in Ruby, we would do something like this:
food = ['chicken', 'rice', 'steak', 'fish', 'shrimp', 'beef'] => ['chicken', 'rice', 'steak', 'fish', 'shrimp', 'beef'] > food.count => 6
Notice that for each element, we use single quotes (we could have
used double quotes instead) because we are storing strings in
each element. Ruby’s array class has some methods
that we can use right out of the box, such as count,
as used above. It simply counts the total number of elements in
the array and outputs that value. Thus, even though the index
goes up to 5, there are 6 elements because the index started at
0.
Now that we have created a food array, we can access each item by invoking the name of the array that we created, followed by the index number.
> food[0] => "chicken" > food[1] => "rice" > food[2] => "steak" > food[6] => nil
The reason we get nil at food[6] is
because there is no [6] — or, rather, nothing is
stored in food[6], so Ruby automagically sets
food[6], food[7], food[8]
and so on to nil. To add another food item to this
array, all you would have to do is set the next element to
whatever value you wanted, like so:
> food[6] = 'carrots' => "carrots" > food => ["chicken", "rice", "steak", "fish", "shrimp", "beef", "carrots"] > food.count => 7
There is another way to add elements to your array in Ruby. You
use the append operator, <<, which basically
sticks something at the end of the array. The difference
here is that we don’t have to specify an index position when
using the append operator. We just do this:
> food food < ["chicken", "rice", "steak", "fish", "shrimp", "beef", "carrots", "irish potato", 42]
Everything that comes after the << is added to
the array. This is pretty convenient because you can append
variables and other objects to an array without worrying about
the content itself. For instance:
> sum = 10 + 23 => 33 > food < ["chicken", "rice", "steak", "fish", "shrimp", "beef", "carrots", "irish potato", 42, 33]
All we did here was create a local variable named
sum, and then push the value of sum to
the end of the array. We can even add arrays to the end of other
arrays:
> name_and_age = ["Marc", "Gayle", 28] => ["Marc", "Gayle", 28] > food => ["chicken", "rice", "steak", "fish", "shrimp", "beef", "carrots", "irish potato", 42, 33] > food.count => 10 > food food.last => ["Marc", "Gayle", 28] > food.count => 11
Even though the last element is an array with three elements —
Marc, Gayle, 28 — it still
counts as just one element (i.e. one array) inside the food
array. So, the count figure goes from 10 (before
name_and_age is added) to 11.
If we wanted to find out how many elements were inside the last element of the food array, we could do something like this:
> food.last.count => 3
A few other interesting methods that Ruby allows us to use right
out of the box are first, last,
length, include? (followed by the
object you want to check for), empty?,
eql? and sort.
> food
=> ["chicken", "rice", "steak", "fish", "shrimp", "beef", "carrots"]
> food.first
=> "chicken"
> food.last
=> "carrots"
> food.length
=> 7
> food.count
=> 7
> food.include?("chicken")
=> true
> food.include?("filet mignon")
=> false
> food.empty?
=> false
> food[0]
=> "chicken"
> food[0].eql?("chicken")
=> true
> food[0].eql?("beef")
=> false
> food.sort
=> ["beef", "carrots", "chicken", "fish", "rice", "shrimp", "steak"]
In the brackets right after eql?, we put the string
in double quotes because we are dealing with a string. Also,
sort arranges alphabetically on strings and from
lowest to highest for numbers.
We can store anything in each element, not just strings. We can even mix; some elements can be strings, others can be numbers.
Say we wanted an array of numbers. We would do something like this:
numbers = [1, 2, 3, 4, 5, 6] => [1, 2, 3, 4, 5, 6]
Remember what we said earlier about always starting the index at
0. You can see here why that is so important. In
order to reference the number 1 in this array, the
array reference has to be [0] because that is the
first element in the array.
> numbers[0] => 1 > numbers[1] => 2 > numbers[6] => nil > numbers.first => 1 > numbers.last => 6 > numbers.count => 6 > numbers.length => 6 > numbers.include?(3) => true > numbers.include?(10) => false > numbers.empty? => false > numbers[1] => 2 > numbers[1].eql?(1) => false > numbers[1].eql?(2) => true
Because we are evaluating numbers, the objects in the brackets should not be wrapped in double quotes. In fact, if we did use double quotes, Ruby wouldn’t find the items because it would be looking for a string and not a number. Be careful with those quotes!
> numbers.include?("3")
=> false
> numbers[1].eql?("2")
=> false
To see what other Ruby methods are included in the
array class, check the documentation on
“Array.”
Everything we’ve just discussed covers one-dimensional arrays (i.e. arrays with just one column). These are best used to store lists of items.
As you can imagine, there are multi-dimensional arrays. We’ll just touch on a 2-D array. Once you understand how to use them, you can then extrapolate to 3-D and beyond (if you ever want to go there).
A 2-D array looks like this:
We are storing two things: the name of the dish, along with a price related to that item.
As the diagram suggests, in order to access each element, you would use both keys.
This is how we would declare this array:
> food2 = [["chicken", 10], ["rice", 5], ["steak", 20], ["fish", 15], ["shrimp", 18], ["beef", 9]] => [["chicken", 10], ["rice", 5], ["steak", 20], ["fish", 15], ["shrimp", 18], ["beef", 9]]
A few key differences should jump out at you. Essentially,
food2 is an array of arrays (meaning that it is an
array whose elements are themselves arrays). Huh? Well, look at
each element.
> food2[0] => ["chicken", 10] > food2[1] => ["rice", 5] > food2[2] => ["steak", 20] > food2[3] => ["fish", 15]
When you access each “single” element, you notice that each has
an array inside of it; ["chicken", 10] is an array
that has a string (chicken) in the first element and
a number (10) in the second element.
So, to access each individual element, we would do something like this:
> food2[0] => ["chicken", 10] > food2[0][0] => "chicken" > food2[0][1] => 10
First, food2[0][0] is saying, “Show me the first
element of the first element of the array food2.”
And food2[0][1] is saying, “Show me the second
element of the first element of the array food2.”
You can also use the same methods of the Ruby class
array on subarrays.
> food2 => [["chicken", 10], ["rice", 5], ["steak", 20], ["fish", 15], ["shrimp", 18], ["beef", 9]] > food2.count => 6 > food2[0] => ["chicken", 10] > food2[0].count => 2 > food2.last => ["beef", 9] > food2.first => ["chicken", 10]
Keep in mind one important distinction for multi-dimensional arrays: Ruby will check whatever you call the method on.
For instance, if you wanted to check whether chicken
is in the food2 array, you could not do this:
> food2.include?("chicken")
=> false
The reason is that food2 is just an array of arrays.
So, you would have to do something like this:
> food2
=> [["chicken", 10], ["rice", 5], ["steak", 20], ["fish", 15], ["shrimp", 18], ["beef", 9]]
> food2[0].include?("chicken")
=> true
We had to specify the particular element ([0]) that
we wanted to check for the string chicken.
In this case, we knew that the string chicken was
stored in food2[0] because we put it there. How
would we find it if we didn’t know? We’d have to use an iterator.
An iterator is a mechanism in Ruby that enables you to cycle
through data structures that store multiple elements (such as an
array) and examine each element. One of the most commonly used
methods is named each. Each is a method in the array
class that comes with Ruby.
Let’s start simple. Suppose we wanted to print a list of all of
our food items stored in the food array. How would
we do this?
> food => ["chicken", "rice", "steak", "fish", "beef"] food.each do |x| puts x end chicken rice steak fish beef
A few things to be aware of here:
each on a collection of data.
each, you have to pass a block to
it. A block is just a contained bit of code. Basically, you are
saying to apply the code contained within the block to
each element that you look at.
There are two ways to use a block. The first is similar to the example above, where you just do this:
do |variable| #some code end
Note that you have to use a block with an iterator. You can
define a block outside of an iterator, but in order to execute
the block, you have to use it in conjunction with an iterator.
That’s why we called do |x| after
food.each earlier.
You can use one or more variables in your block. Those variables
are local to the block alone, so they will be destroyed once you
leave. Thus, if you had two blocks, you could use the variable
x in both, and one wouldn’t affect the other.
In the example above about food, we have said, for each element
in the array food, print it to the screen.
Another way to use a block is on one line, like this:
food.each { |x| puts x }
In this case, the opening curly brace ({) replaces
the do, and the closing curly brace replaces the
end. If your operation is just one line, then this
way is convenient, although I have found that rereading such code
in future is sometimes harder; so, I usually just use
do and end, but that’s a personal
preference. Do whatever makes you most comfortable.
The reason that blocks use variables is because the elements of
the collection are actually not modified — unless you
specifically chose to do so. Basically, what happens is that for
every single iteration through the array, a copy of the new
element is stored in x, and then x is
used in the block.
Going through the food array, the local block
variable x would look something like the following.
First iteration:
food[0] = 'chicken' x = food[0] x = 'chicken'
Second iteration:
food[1] = 'rice' x = food[1] x = 'rice'
Third iteration:
food[2] = 'steak' x = food[2] x = 'steak'
Using numbers would more clearly illustrate that the values aren’t changed in the original array:
> numbers = [1, 2, 3, 4, 5] => [1, 2, 3, 4, 5] > numbers.each do |x| … x = x + 2 … puts x … end 3 4 5 6 7 > numbers => [1, 2, 3, 4, 5]
Here we’ve printed out the numbers 3, 4, 5, 6, 7
(i.e. 1+2, 2+2, 3+2, etc.); but at the end, the
numbers array is the same.
A hash is another collection type. It is a collection of “key-value” pairs. A key-value pair is a combination of the name of a container (i.e. the key) and the contents of the container (i.e. the value).
a => "Marc"
In the key-value pair above, the key is a, and the
value is Marc.
A hash, then, is basically a list of these key-value pairs, separated by commas. A hash looks like this:
a =>"Marc", b => "Cheyenne", c => "Alexander", d=> "Mia"
Hashes and arrays have some key differences, though, and some things to note:
a is “first” or that it “comes before”
b in the example above, because Ruby does not look
at the order of keys in hashes.
Marc, Cheyenne, etc. But don’t confuse
this with the way in which array keys are ordered.
There are multiple ways to initialize (or initially create) a hash, but the most popular ways look something like the following.
To create an empty hash (i.e. a hash with no values):
> day = Hash.new
=> {}
To create a hash with particular values:
> names = Hash["a" => "Marc", "b" => "Cheyenne", "c" => "Alexander", "d" => "Mia"]
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia"}
> names2 = {"a" => "Marc", "b" => "Cheyenne"}
=> {"a" => "Marc", "b" =>"Cheyenne"}
You will notice that to create the hash, you don’t have to use
the keyword Hash or square brackets
([]). You can use them if you like, or you can just
use = { }.
For the keys and values, you also don’t need to put the keys in
quotes. You need to do that only if you want to use strings
as the key. Ruby also requires a =>
(pronounced “rocket”) to assign the value on the right side of
the rocket to the key on the left side.
If you tried to do names2 without the quotes around
the keys, you would likely get an error like this:
> names2 = { a => "Marc", b => "Cheyenne"}
=> #
To access values within the hash, you have to specify the name of the hash, along with the key for the value you are trying to access.
> names
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia"}
> names["a"]
=> "Marc"
> names["c"]
=> "Alexander"
> names[a]
=> #
Because we didn’t use quotes for names[a], the Ruby
interpreter thinks that a is a local variable or a
method and so can’t find a value for it, thus throwing an error.
If you tried to access a seemingly legitimate value via a
legitimate key that has not been assigned a value, then Ruby
would usually return nil.
> day["a"] => nil > day[9] => nil #For you Day9 fans, don't worry… I am a fan too![]()
Suppose you wanted to create a hash in which every value has a “default” value. You could do something like this:
> year = Hash.new("2012")
=> {}
> year[0]
=> "2012"
> year[12]
=> "2012"
All we’ve done was call the method new on the Ruby
class Hash and pass the default value of
2012 into that method. So, when trying to access a
value that doesn’t exist, instead of returning nil,
Ruby would return the default value (2012).
You can use a number of methods with hashes:
> names.keys => ["a", "b", "c", "d", "e"] > names.values => ["Marc", "Cheyenne", "Alexander", "Mia", "Christopher"]
As you can guess, the keys just returns all of the
keys in the hash, and the values returns all of the
values.
> names.length
=> 5
> names.has_key?("a")
=> true
> names.has_key?("z")
=> false
> names.has_key("a")
=> #
Note that the name of the has_key method is actually
has_key?. If you left out the ?, it
would throw an error like the one above.
All that has_key? is doing is checking the hash to
see whether any key matches whatever is in the brackets. If it
finds a match, then it returns true; if it
doesn’t, it returns false.
> f_names = names
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia", "e"=>"Christopher"}
> l_names = {"g" => "Gayle", "h" => "Gayle", "j" => "Jackson", "m" => "Brown"}
=> {"g"=>"Gayle", "h"=>"Gayle", "j"=>"Jackson", "m"=>"Brown"}
> f_names.merge(l_names)
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia", "e"=>"Christopher", "g"=>"Gayle", "h"=>"Gayle","j"=>"Jackson", "m"=>"Brown"}
> f_names
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia", "e"=>"Christopher"}
> l_names
=> {"g"=>"Gayle", "h"=>"Gayle", "j"=>"Jackson", "m"=>"Brown"}
All we’ve done above was create a new hash, f_names,
by assigning it the existing names hash. Then, we
created another hash, l_names, that has a few last
names. Then, we just merged the two hashes to create a master
hash. However, because we just ran the merge method
without assigning the result to any variable, it wasn’t stored.
If you check the values of f_names and
l_names after, you will see that they look exactly
the same as before we ran merge.
If we wanted to store the value of the merge, we would have had to do something like this:
> master_hash = f_names.merge(l_names)
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia", "e"=>"Christopher", "g"=>"Gayle", "h"=>"Gayle", "j"=>"Jackson", "m"=>"Brown"}
Another approach is to do a “destructive” merge. This is an interesting feature of Ruby. For many (perhaps most) methods, if you add an exclamation point to the end of the method’s call, you actually replace the value of the method’s caller with the returned value. For example:
> f_names
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia", "e"=>"Christopher"}
> l_names
=> {"g"=>"Gayle", "h"=>"Gayle", "j"=>"Jackson", "m"=>"Brown"}
> f_names.merge!(l_names)
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia", "e"=>"Christopher", "g"=>"Gayle", "h"=>"Gayle", "j"=>"Jackson", "m"=>"Brown"}
> f_names
=> {"a"=>"Marc", "b"=>"Cheyenne", "c"=>"Alexander", "d"=>"Mia", "e"=>"Christopher", "g"=>"Gayle", "h"=>"Gayle", "j"=>"Jackson", "m"=>"Brown"}
As you can see, the f_names value after we ran the
destructive merge method (merge!) is now the same
value as the merged hash.
Another method that you can use with hashes is each.
But it is slightly different. With arrays, you just have to pass
in one variable to the block (which essentially represents the
index of the array). With hashes, you have to pass in two
variables: one that represents the key, and another that
represents the value.
> f_names.each do |key, value|
.. puts "#{key} is #{value}"
.. end
=> "a is Marcb is Cheyennec is Alexanderd is Miae is Christopherg is Gayleh is Gaylej is Jacksonm is Brown"
This looks a little messy. Here is what’s happening:
key and value. So, after the first
iteration, key would be a, and
value would be Marc.
puts, followed by a string. In
other words, it will print everything in quotes to the screen.
puts? That’s called “string interpolation.” It
basically says, stick the value of this variable into my string
at this exact position. Thus, after the first iteration,
puts would do this:
a).
is).
is).
Marc). (The
entire string, after the first iteration, would be a is
Marc.)
puts
command is done.
end, so goes back to the beginning of
the block to see whether any more elements are in this hash
object.
puts line (and we didn’t put a space after
the first quote on the puts line), no space will be
between the last character of the first iteration and the first
character of the second iteration.
puts looks like puts "
#{key} is #{value}", then the resulting string might make
more sense: a is Marc b is Cheyenne c is Alexander
etc.
I intended for the output to make sense, but when I saw the result, I realized that this has tripped me up many times in my career, so I figured to highlight it.
You can use a lot more methods on hashes, many of which you
should be familiar with because they look like others we have
covered here, such as value? (note the
? — I’m not asking a question here), and they look
similar to the methods we went over in the arrays section, such
as include?, empty?, eql?,
size, etc.
The last element of Ruby that you should be familiar with is an object type called a symbol.
A symbol is an object type that resembles a string, but is not
quite one. The major difference between a symbol and a string is
that a symbol always begins with a colon (like
:name). (For more information, see the “Symbol”
article in the Ruby documentation and “The Ruby_Newbie Guide
to Symbols” on Troubleshooters.com)
Symbols work nicely with hashes because you can use them as the keys instead of strings.
> f_names
=> {:a =>"Marc", :b =>"Cheyenne", :c =>"Alexander", :d =>"Mia", :e =>"Christopher"}
> f_names[:a]
=> "Marc"
The good thing about this is that you no longer have to worry about all of those quotes for both the keys and the values… but you can still remember the words for the keys.
> pets = {:dog => "Cookie", :cat => "Snowy", :fish => "Goldie"}
=> {:dog=>"Cookie", :cat=>"Snowy", :fish=>"Goldie"}
> pets[:dog]
=> "Cookie"
> pets[:fish]
=> "Goldie"
Symbols make dealing with hashes much simpler than using strings as keys. You can, of course, use hashes for anything else in the Ruby language; their main function is to store values and make retrieval easier on the interpreter (since handling strings has many rules).
I hope you have learned a lot here. Remember that this guide to Ruby is not comprehensive, but simply an introduction tailored to those with little or no programming experience. It’s not written in the typical programming tutorial style because I’ve always found that to be a bit difficult. I need to understand the whys behind the whats, so I’ve taken that approach here. I also don’t profess to be a Ruby ninja; I just wanted to learn how to build Web products myself, so I taught myself Ruby and Rails.
You now have the foundation to play with Try Ruby some more or to install Ruby on your system and get started (Google it).
Good luck, and remember that true learning often happens when you are struggling with a problem. When you spend one week stuck on a “very simple” problem and you eventually figure it out, you are guaranteed not to make that mistake again. And when you get stuck, don’t panic. Just take a break; maybe Google it and see what solutions others have had. But don’t just copy and paste code. Figure out why it does what it does and how it can help you. That’s how you learn.
If I was unclear with anything, please let me know in the comments.
There are fabulous books on Ruby to help get you started. Here are some of my favorites.
(al) (km)
© Marc Gayle for Smashing Magazine, 2012.
當年任職榮華集團Creative Director 的其中於1999年所創作的作品榮華月餅TVC 1999《新型象》
Video Rating: 0 / 5
Welcome To Today’s JVNP 2.0 Weekend Update Featuring A JV
Offer
Courtesy Of Fellow JVNP 2.0 Partner Mindvalley (Christie
Marie’s
Unlimited Abundance JV Invite), Buzz Builders + More … in
Today’s
Make More Money Mindset Edition.
A Salute To Those That Gave All … Happy Memorial Day Weekend!
- Mike Merz Sr
Mindvalley – Christie Marie – Unlimited Abundance JV Invite
Pre-Launch Begins: Friday, June 22nd 2012
Launch Day: Thursday, June 28th 2012 @ 9PM EST
Source: v3.jvnotifypro.com via Mike on Pinterest
Have you heard of Mindvalley? You have now.
Dearest Fellow JVNP 2.0 Partner,
It’s not every day you get to dip your mitts into an estimated $
70
billion industry.
And today is still not that day.
Today, my Internet-savvy amigo, you get to dip your toe.
But it is still a great day nonetheless. Today you get to be a
part of
something that might change someone’s life.
Today you will have some fun in what you do oh-so-well. You
get
to say “I was there!” when hopefully a new crest rose from the
wave
that crashed down on the Internet marketing ways of old and
we
boldly entered a shiny new era.
>>> We’re Mindvalley …
http://JV-Invite.Com/Mindvalley-Chri…ited_Abundance
And we are fast becoming the biggest name in the online
personal
growth industry.
Over the past 5 years we have been behind some of the biggest
launches in the industry, and we want to try and bring back
some
Silicon Valley style credibility to Internet marketing. We want
to
evolve, create and innovate – and we want you to be on the
frontline
with us.
As of 22nd June, we will be offering our best performing product
of
last year, Christie Marie’s Unlimited Abundance, to ClickBank.
But we go beyond just trying to make pretty websites,
transparent
processes and forming impromptu drum circles. Wayyyyyy beyond.
With all the perks and side benefits we are trying to not only
break
the mold of Internet marketing, but smash that mold back into
an
atom-like existence, and here’s how:
- GetSatisfaction ranks us in the top 3% for customer service in
the
education industry.
- Our best performing affiliates are invited to private
mastermind
sessions around the world – with last year’s hosted on the
pacific
island of Maui as part of our own festival Awesomeness Fest.
- In the next few months we will be launching the iTunes of
the
personal growth market – the Mindvalley Academy.
- We are one of the first companies in the world to open-source
our
marketing strategies and give them away to our affiliates
(and
competitors) for FREE in Mindvalley Insights.
- Our current workforce is made up of over 100 employees from
35
countries, all working hard to provide one of the highest
performing
back end sales rates of any publisher out there and backed up
by
world class customer support.
So if we sound like the kind of people you would like to work
with -
or believe that your words and your reach can change lives –
then
you’re only a few clicks away, friend.
>>> Here’s to you, Affiliate Marketer …
http://JV-Invite.Com/Mindvalley-Chri…ited_Abundance
Mindvalley
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Above. *VIP Review Access Will Be
Made
Available To VIP Partners That Register To Support This Launch
No
Later Than 7 Days Prior To Prelaunch/Launch)
#####
*** If You Have Trouble Accessing Any Link On This Page,
Please Make Sure You Are Logged Into www.JVNotifyPro.com
+ www.JVNewsWatch.com … First. If The Problems Persist,
Please Reply Directly To The Newsletter With The Issue, And
We’ll Do Our Best To Respond + Resolve The Problem … ASAP.***
*** If You’re Having Trouble Logging In, Please Use The
Account
Management Center***
http://v3.jvnotifypro.com/account/management_center/
***All Other Issues, Please Use The Support Helpdesk***
http://support.jvnotifypro.com/
#####
Editor’s Note: For those JVNP 2.0 Partners that don’t read
the
legal stuff at the bottom of every mailing …
This mailing contains (a) JV connection request(s) from (a)
fellow
JVNP 2.0 Partner(s) that either by themselves, or working
with
a fellow partner that has, earned the spot due to content
contribution +/or support of fellow JVNP 2.0 Partners over time.
The JV request is being made by the merchant(s) (or official
representative(s)), NOT JVNotifyPro.com, to you … the JVNP
2.0
Partner.
It is expected and recommended that you perform due
diligence when getting involved in any venture that may
affect you, your business, it’s prospects and customers.
It’s also assumed that, as an Online Business Owner, you’re
capable of running your own business using common sense,
logic + exercising personal responsibility.
#####
———-
Buzz Builders
Winter Valko + Corey Lewis – Rip Curl Commissions JV Invite
Launched Just This Past Monday, May 21st 2012
Mark May 21st down on your calendar because a new EPC Tsunami
is about to make a big splash in the marketplace.
Rip Curl Commissions will flood your bank account with massive
cash
… you wont ever want to stop mailing.
Tons of prizes for JVs and other fun stuff during the launch.
Register now as an Elite JV …
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Is
Available
To VIP Partners That Register To Support This Launch)
http://Buzz-Builders.Net/Winter_Valk…rl_Commissions
Chad Mureta + Jonathan Cronstedt (JV Manager) – App Empire JV
Invite
Pre-Launch Commenced Thursday, May 24th 2012
Launch Day: Friday, June 1st 2012
You may think you have seen app launches, but not like this.
You’re going to finally meet the man that has taught the
industry
gurus, and he’s not pulling any punches.
Your people are going to get a ton of immediately actionable
training
from the source, while you have the opportunity to earn $ 998.50
for
every sale …
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Is
Available
To VIP Partners That Register To Support This Launch)
http://Buzz-Builders.Net/Chad_Mureta…edt-App_Empire
Mark Ling – AffiloBlueprint Version 3.0 JV Invite
Pre-Launch Commenced Tuesday, May 15th 2012
Launch Day: Tuesday, May 29th 2012
AffiloBlueprint v3.0 is a comprehensive step-by-step course
that
shows customers exactly how to set up a money-making
affiliate
website in only 12 weeks.
You get paid anywhere from $ 35 to $ 229 per sale, there’s
over
$ 10k in Launch prizes and during pre-launch I’m putting up $
2
cash per lead for top promoters.
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Is
Available
To VIP Partners That Register To Support This Launch)
http://Buzz-Builders.Net/Mark_Ling-A…rint_Version_3
Matt + Bryan Green, Ken McArthur + Ken Lovett – Power SEO Ranker
JV
Pre-Launch Commenced Thursday, May 24th 2012
Launch Day: Thursday, May 31st 2012
Get on board … Powerful Backlinking tool + very profitable
Aged
Domain Tool!
This is not another get and forget software for your clients
…
No trickery here.
This is one of the few ways left to get your website ranked
high
in the search engines today!
Make 50% per sale and recurring income on both up and down sells …
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Is
Available
To VIP Partners That Register To Support This Launch)
http://Buzz-Builders.Net/Bryan_Green…wer_SEO_Ranker
Eric Roberts, Chris Jones + Cindy Battye – The Intervestor JV
Invite
Launch Day: Tuesday, June 5th 2012
^^Notice Launch Date Change^^
Huge Payouts $ 475.50 Per Sales + Residuals.
We show customers how to “inter-vest” and buy, sell, and hold
websites and earn instant cash in 30 days or less!
This will be a monster …
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Will Be
Made
Available To VIP Partners That Register To Support This Launch
No
Later Than 7 Days Prior To Prelaunch/Launch)
http://Buzz-Builders.Net/Eric_Robert…he_Intervestor
Michael Beeson + Bobby B – Affiliate Overthrow JV Invite
Launch Day: Thursday, June 7th 2012 @ 8AM EST
Win a Bentley Continental GT in the Affiliate Overthrow
Launch
June 7th!
Overthrow the Super Affiliate Team of Michael Beeson & Bobby
B
and win the Bentley! Sign up and check out the unique team
concept that can have you winning the Bentley or $ 70,000
cash
even if you’re not a Super Affiliate …
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Will Be
Made
Available To VIP Partners That Register To Support This Launch
No
Later Than 7 Days Prior To Prelaunch/Launch)
http://Buzz-Builders.Net/Michael_Bee…iate_Overthrow
Steve Olsher – Internet Prophets Live! JV Invite
Affiliate Program Announced Tuesday, May 8th 2012
Date + Location Of Live Event: June 8 – 10 – Chicago, IL USA
Promote this Summer’s largest Internet and Mobile marketing
conference and exhibition focused specifically on teaching
small
business owners and solopreneurs how to profit online,
Internet
Prophet’s LIVE!, and earn 50% on each ticket sold.
27 leading experts including Jay Conrad Levinson, Larry
Winget,
Janet Bray Attwood, Armand Morin, Mike Filsaime and many others.
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Is Not
Available,
As This Is A Live Event … However, Steve Will Provide You With 5
Free
Tickets To The Event As A Bonus For Registering + Mailing.)
http://Buzz-Builders.Net/Steve_Olshe…_Prophets_Live
Paul Clifford – PageOne Curator JV Invite
Pre-Launch Begins: Tuesday, June 5th 2012
Launch Day: Tuesday, June 12th 2012
Make up to $ 441 a sale with a PROVEN affiliate EPC of $ 3.36
across
3,500 front end units sold in just our test WSO week
promoting
PageOne Curator – the whitehat Google ranking training and
software.
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Will Be
Made
Available To VIP Partners That Register To Support This Launch
No
Later Than 7 Days Prior To Prelaunch/Launch)
http://Buzz-Builders.Net/Paul_Clifford-PageOne_Curator
Marc Milburn – List Profit Sniper JV Invite
Launch Day: Monday, July 9th 2012
Six-Figure Marketer Marc Milburn invites you to partner with
him
and grab $ 318.60 per sale (60% commissions) and over $
10,000
in JV prizes! EPCs $ 2+
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Will Be
Made
Available To VIP Partners That Register To Support This Launch
No
Later Than 7 Days Prior To Prelaunch/Launch)
http://Buzz-Builders.Net/Marc_Milbur…_Profit_Sniper
Jacobo Benitez + Michael Carlin – SEO Fight Back JV Invite
Launch Day: Thursday, July 12th 2012
Rake In $ 375 Per Sale With A Revolutionary Penguin & Panda
Proof
Google Ranking System – SEO Fight Back by Michael Carlin and
Jacobo Benitez – The untraceable… undefeatable… impenetrable…
linking network to rule them ALL – Launches July 12th @ 12:00 PM
EST
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Will Be
Made
Available To VIP Partners That Register To Support This Launch
No
Later Than 7 Days Prior To Prelaunch/Launch)
http://Buzz-Builders.Net/Jacobo_Beni…SEO_Fight_Back
Jimmy D. Brown – Membership To Go JV Invite
Launch Postponed – Please Register To Be Notified Of New Launch
Date.
Jimmy D. Brown, the guy who basically started the PLR
industry,
has released a “ready-to-go” PLR package to an entire
membership
site!
This has never been offered before and it includes EVERYTHING
you need to get started, including PLR to the membership
content,
sales letter, presell report, and articles …
(To Access The Merchant’s JV Page, A Link To The Forum
Archive
Of The Mailing For Discussion, VIP Review Access (When
Available*)
+ More … Click The Link Below. *VIP Review Access Is
Available
To VIP Partners That Register To Support This Launch)
http://Buzz-Builders.Net/Jimmy_D_Brown-Membership_To_Go
———-
Bill McIntosh + Stephen Renton, Chad Hamzeh + Matt O’Connor,
Harrison Klein, Jason Westwick, Pawan Agrawal and other
fellow
JVNotifyPro 2.0 partners are waiting in the wings … keep your
eyes
on your Inbox, and follow the action in the JVNP 2.0 Premium
VIP
JV Announcement archives:
http://jv-forum.com/JVNP-2.0-Premium…-Announcements
Question:
“Hey, Mike … I really appreciate the combination of Fellow
Partner + Popular JV Invites you offer in the JVNP 2.0
Update,
but how can I get on board Popular JV launches that are
available to get on board but didn’t make the latest mailing
like the highly anticipated offerings from Chris R, Steven
Lee
Jones + Ben S, Melford and Concetta Bibens + John Hayward,
Andrew X + Steven Johnson, Asher, Ciel + Folusho, John
Racine,
Matt + Phil Benwell, Eva Bright, Imran S, Simon W + Salman S,
Raam Anand, Rob Stafford, Bercaru Viktor, Jason Keith + Jason
Zimmerman, Matt Alexander, Brian Koz + Shawn Casey, Andrew
Gotti + Josh M, Anthony La Rocca and others?
Answer: The JVNewsWatch JV Product Launch Calendar +
Affiliate Program Directory
http://www.jvnewswatch.com/
———-
Popular JVNotifyPro 2.0 Links
What Is JVNotifyPro 2.0/JVNewsWatch? (Start Here …)
http://jv-forum.com/START-HERE-Welco….0-JVNewsWatch
JVNP 2.0 Featured Announcements
http://jv-forum.com/JVNP-2.0-Featured-Announcements
JVNP 2.0 VIP Partner Private Area
http://jv-forum.com/JVNP-2.0-VIP-Partner-Private-Area
New JV Product Launch Announcements
http://jv-forum.com/New-JV-Product-Launch-Announcements
JVNP 2.0 Joint Venture Marketing Discussion Forums
http://jv-forum.com/JVNotifyPro-2.0-…cussion-Forums
JVNP 2.0 Job Board – Need/Provide JV Related Services
http://jv-forum.com/JVNP-2.0-Job-Boa…lated-Services
JVNP 2.0 My JV Circle Social Network – My JV Buzz
http://v3.jvnotifypro.com/my_jv_buzz
JVNP 2.0 Affiliate Program
http://v3.jvnotifypro.com/account/affiliate/
JVNewsWatch JV Product Launch Calendar + Affiliate Program Directory
http://www.jvnewswatch.com/
———-
That’s All, Folks!
To OUR Success,
Mike Merz
http://www.JVNotifyPro.Com
http://www.JVNewsWatch.com
http://www.JVListPro.Com
http://www.facebook.com/jvnotifypro.fan.page
http://www.twitter.com/jvnotifypro
The reason you are receiving this mailing is because
you requested to be on this email list by opting in.
Please use the unsubscribe link below if you no longer
wish to be a JVNP 2.0 Partner, not the Spam button.
The JV offers run in this newsletter and archived on
JVNotifyPro.Com express the opinions of the partners
that have presented them to us … and are not those
of Mike Merz, nor Internet Marketing For Newbies LLC.
Participate at your own risk.
The publicly accessible version of the JVNotifyPro Update
posted on JVNotifyPro.com may include affiliate links that
could result when purchased through in compensation
for either Mike Merz or Internet Marketing For Newbies LLC
for the sale as an affiliate partner … with no further
association to the merchant existing unless otherwise
mentioned.
JVNotifyPro 2.0 Updates are generally mailed twice a week
… on Monday/Tuesday and Thursday/Friday, with an
occasional Saturday edition when either there is a back
log, I screw up … or both. It is done this way to satisfy
the many premium mailing requests, while still respecting
your Inboxes by not over doing it. Thanks for your support.
Powered By http://www.JVListPro.Com
![]() |
There is an aspect to Web design that no one likes to talk about: spec’ing. We all do it, we all hate it, but we also understand that specs are vital to both designers and developers.
For those who aren’t familiar with the term in this context, “specs” is short for specifications — in the case of design, they are instructions that specify colors, fonts, sizes, spacing and so on, just like a blueprint. Specs are a crucial part of the design and development process for companies with big teams and for small companies that have to outsource some of their development. Specs function not only as instructions to developers, but also as a reference point to make sure the whole team is on the same page.
However, the process of producing specs is repetitive and time-consuming, especially for creatives. But now this can all change: Specctr, together with Adobe Fireworks, offers a quick and easy way to generate this important information automatically.
My idea to make Specctr came from my personal experience working on a design team at a large corporation. Spec’ing was part of my routine. One day, after hours of spec’ing, my eyes hurt and I was bored and frustrated. Suddenly, I realized that this kind of intensive work should be automated, and that a designer’s time is much better spent designing rather than spec’ing.
Specctr is more than a tool: it is a business solution for any company whose designers must generate specs for developers. Specctr facilitates this communication and leaves designers and developers happier and more productive. Making this process quicker frees up the business to focus more intently on its core mission.

Possible time saved using Specctr for Adobe Fireworks.
Time saved using Fireworks and Specctr Pro.
In the process of creating Specctr, I brought my design background and practical experience in spec’ing to bear on the issues and opportunities in automating the process. Meanwhile, my colleague, Dmitriy Fabrikant, engineered the software from the ground up. Working in tandem at On Pixel, we released Specctr Pro in January 2012. Since then, it has received many favorable reviews.
In addition to the commercial version of the tool, we’re happy to release a free version called Specctr Lite as a contribution to the community. We chose to highlight width and height as well as text spec’ing abilities, because they are most common to a designer’s workflow. These two feature sets alone will save a lot of valuable time.
The Lite version includes:
Specctr Lite can be downloaded for free from our website, and we’re happy to say that it was created and released as a result of the involvement of Smashing Magazine!

Pro and Lite: a quick comparison
The Lite version is as easy to use as the Pro version, and its features work the same way.
To use Specctr (Pro or Lite), you need:
The installation process is pretty straightforward:
Window → Specctr to open the
Specctr panel.
Please note: If you are using Windows Vista or 7, you might need to launch the Adobe Extension Manager as Administrator, otherwise the extension could fail to install.
If you still have questions, don’t hesitate to consult our online tutorial (PDF, 1.9 MB) or contact us directly!
Once you install Specctr through the Adobe Extension Manager,
restart Fireworks, and then open Specctr from the
Window menu. Now that Specctr is open, you can spec
a document in a few easy steps.
First, prepare your document by making room for your specs. Select the size of your design’s border, and click on the “Expand Canvas” button.
Select which details to display by toggling them on or off from the panel’s menu.
Now Specctr Pro will automatically display your spec with a click of the button.
To spec a shape (shape, line, dot, etc.) or a text object, select the object (or multiple objects), and click on the “Spec Object” button. The specs will be outputted to the nearest edge of the canvas.

Properties of objects in a spec
You can also spec the spacing between two objects by selecting them and then clicking the “Spacing” button. If you select only one object, Specctr will measure the object’s distance to the edges of the canvas.

Measuring the space between objects
Finally, you can also spec the width and height of any object.
The process of developing Fireworks extensions consists of the following steps:
Because the development process is spread over three separate environments, integrating the different pieces of the application and debugging the application present some challenges. But in the end, it’s well worth the positive response from our users.
In the next couple of weeks, Dmitriy will release on GitHub a few ActionScript libraries that he has built during the process of developing Specctr. These libraries will hopefully reduce some of the pain points of the tiered development process. We might also write another article that highlights in more detail the development process for building a Fireworks extension.
One of Fireworks’ strengths is its potential as a development platform that leverages the creativity and innovation of its community. We would love to help this process and show that Fireworks is a powerful tool for Web design.
Here are a few useful resources related to extending Adobe Fireworks:
(al) (mb)
© Chen Blume for Smashing Magazine, 2012.
AWeber’s support offices will be closed on Monday, May 28 as we observe Memorial Day.
As always, we will monitor the AWeber system and the support inbox to address any critical issues.
We’ll be back at 8:00 a.m. ET on Tuesday, May 29 to answer your questions by phone, email and live online chat.
Thanks, and have a great holiday!
In the hustle and hubbub of running an eatery, you’d think no one would have time to sit down at a computer and put together an email marketing campaign.
That’s almost true. But Bill Pavlou, owner of Super Duper Deli in Edison, New Jersey, has found a way to market in just (a very few) minutes a day.
He gets his marketing message out and brings the business in using three main steps.
Without extra time to spend collecting subscribers, the deli just lets it happen through the natural course of the day.
“Due to the nature of our business, we still collect email addresses the old-fashioned way – in store,” says Bill. “By signing up for our email list by leaving a business card, customers can win a free lunch.”
For people searching for local delis online, Bill has opportunities set up for them to subscribe. “We have a web form on our website and also have taken advantage of AWeber’s Facebook web form which allows us to capture subscribers there as well,” he says.
Super Duper Deli sends out an email every morning with their daily specials so subscribers keep them in mind when considering their options for lunch.
This is exactly the kind of email hungry locals want to see mid-morning. “We have a message that we want to communicate, and there’s an audience that wants to receive this information,” Bill explains.
Plus, the deli’s creating a comfortable routine for subscribers by sending them consistent content every day. Readers can come to expect and welcome the daily emails as the clock ticks closer to lunchtime.
Bill sends the deli’s emails at around 10 a.m. every weekday. He finds the most valuable AWeber feature to be broadcast scheduling – he can put the day’s email together whenever he has a few seconds, and count on the system to send it at just the right time.
“Obviously in small business things can get hectic and certain things need to get taken care of when they can get taken care of,” Bill says. “With AWeber I can walk through those doors at 4:00 a.m., brew the coffee and cook some bacon, then login to AWeber to schedule my daily email broadcast to be sent.
“Or I can do it in the evening after I close down shop for the day. It’s intuitive and it’s flexible – two things that are an absolute must when you are balancing many responsibilities.”
Traditionally, delis have faxed their daily specials to local businesses to bring in the lunch crowd. The deli still does this, but replicates the specials with email.
“We realize that not all of our customers are working an office job where a receptionist might receive our fax and post it on a bulletin board,” Bill says. “With the popularity of smartphones, we can let an attorney walking out of a court room what his lunch options are just as easily as we can let a contractor installing cable know the daily soups are.”
The reason AWeber exists is to help busy business owners automate their marketing, so when their day’s crammed full of one task after another, they don’t have to worry about their marketing – the message is still going out.
As Bill puts it, “[Email marketing]‘s an absolute necessity to effectively communicate what you do with the people who want to know what you do. In 2012 we have plans to expand our email marketing outreach, but it’s already important enough that it’s a top priority everyday.”
Do you have any tips or techniques to help Bill and others like him market in minutes a day?
![]() |
“Mobile Web design.” Unless you’ve been hiding under a bush for the last 18 months, you’ll know that it’s one of the hottest topics in the industry at the moment. Barely a week goes by without new tips being unveiled to help us hone our skills in making websites work as well — and as fast — as possible on mobile devices.
If you own or have designed a WordPress website for the desktop and are considering going mobile, the process can be fairly daunting. You probably know of responsive design and might have heard of the mobile-first approach developed by Luke Wroblewski, which entails planning the content and design for mobile devices first and then desktops second, rather than the other way round.
But if your WordPress website has a desktop theme in which everything is set in pixels, then the thought of adopting a responsive design might have you running for the hills.
It doesn’t have to be that way.
Here are four ways to make your WordPress blog or website mobile-friendly, ranging from the quick and dirty to the complex but potentially very beautiful. As well as outlining the pros and cons of these methods, we’ll include information on plugins that will help without actually doing all the work for you, and we’ll provide some code that you can use for a responsive design.
Designing for content is increasingly becoming more common than squeezing content into a pixel-perfect design, as documented here on Smashing Magazine.
If your website is more about content than design (say you run a blog that is content-heavy and designed for reading), then you won’t be too fussed about what your website looks like on mobile devices. You just want people to be able to read it without having to zoom in, move the viewport around or generally tie themselves up in knots until they decide to leave.
If this is the case, then a simple plugin might do the trick. Below are some plugins to consider.
WPtouch, which comes in free and premium versions, strips out your existing theme and displays your content and not much else, but the result is user-friendly, robust and easy to read.
WPtouch is widely used on websites, including Stephen Fry’s blog and Social Media Examiner. You can see below how the plugin renders those two websites. The premium version has options to modify the colors and some styles, including a bespoke menu at the bottom of the screen, as seen on Social Media Examiner.

Social Media Examiner desktop design

Social Media Examiner mobile design, using WPtouch
The WordPress Mobile Pack has some color options and can be used as a mobile switcher if you want a completely different theme for mobile devices. It also has a mobile interface for editing posts, although this has been superseded to some extent by the WordPress apps for iOS and Android.

WordPress Mobile Pack screenshots
If your website runs BuddyPress, then you’ll need a plugin to ensure that none of its functionality is lost on mobile devices. BuddyPress Mobile has theming options, and you can edit the style sheet to make the mobile design your own.

BuddyPress Mobile
If you want a consistent design across desktop and mobile, but you don’t yet have a theme or you want to develop one, then a mobile theme might be the answer.
More and more mobile themes have sprung up over the last year. In particular, Twenty Eleven, WordPress’ default theme since version 3.0, is responsive enough for many websites.

Twenty Eleven on the desktop

Twenty Eleven on mobile
Below are some other themes that include a mobile or responsive style sheet.
The Carrington family of themes can be used as parent themes. You can edit the CSS and functions to suit your needs, and it has a mobile version.

Carrington on desktop

Carrington on mobile
Scherzo is clean and minimalist and would be great to use as a parent theme. It uses a mobile-first responsive design.

Scherzo on desktop

Scherzo on mobile
E-commerce websites are trickier to make mobile-friendly, but Jigoshop can help. It’s a full e-commerce plugin and theme, with a responsive layout that can be tweaked to suit your design.

Jigoshop on desktop

Jigoshop on mobile
In the days before responsive design gained traction, websites
commonly had two versions: desktop and mobile. The mobile version
might have been on an m. subdomain or have a
.mobi extension. Some websites out there still do
this, mainly huge news websites that serve different content
depending on the device.
Fewer WordPress administrators are choosing to do this now, but if you do want to go down this route, then serving two versions of your website from the same database is possible, by using a mobile switcher.
Here are two plugins that make this possible:
Using one of these plugins enables you to develop a completely separate theme for mobile devices, with its own layout, navigation and content structure.
If you don’t want to throw out your existing theme, then the best way to give mobile users an experience that is at least visually similar to the desktop version is to build responsiveness into your theme.
A responsive theme contains media queries in the theme’s style sheet to define CSS that applies only to devices of a specified maximum or minimum width. A truly responsive theme has a fluid layout that adapts to mobile devices and larger screens to some extent already, but with some extra styling to make the layout optimal for mobile devices.
To get started, you will need to define media queries in the style sheet. Most of the styles already in your style sheet apply to desktop and mobile, so you only need to add CSS that is different for mobile devices. This will go at the end of your theme’s style sheet.
Start by defining the screen width you are developing for. There are two main approaches to this:
A media query consists of three main parts:
@media rule;
print and
screen — we’ll use screen);
You could have a media query to target mobile phones (and other small devices such as the iPod Touch) in portrait orientation that have a width of 320 pixels:
@media screen and (max-width: 320px) {
}
The CSS to be applied to that screen width and any screen narrower than it would be written between the braces.
An alternative to the @media rule would be to create
a linked style sheet with the CSS for each screen width. But I
don’t do that because it adds another server request with the
potential to slow the website down; and managing all of the
styles becomes harder if they’re in more than one place.
Here are other media queries for commonly targeted screen sizes:
(max-width: 480px)(max-width: 780px)(max-width: 1024px)You can run one media query after another so that each change you make applies to the screen size you’re querying, plus any widths queried further down in the style sheet. In this case, you would work with wider screens first. For example:
@media screen and (max-width: 480px) {
}
If you are ignoring tablets, you would include this media query first and add any CSS for mobile phones in both portrait and landscape modes (for example, any changes to graphics or text size). You would then follow it with this:
@media screen and (max-width: 320px) {
}
Here, we’re adding any styles that apply only to phones in portrait mode (such as layout changes). You don’t need to repeat the CSS that applies to both landscape and portrait modes because this will still apply. In the same way, you don’t need to repeat any styles that will stay the same for desktop views because they will cascade down from the earlier parts of the style sheet.
Phew! So, now we’ve defined media queries, and we’re ready to
roll with some mobile-friendly CSS. Below are the main things you
will need to work on for a standard WordPress website. Let’s
assume your website’s markup is similar to that of the Twenty
Eleven theme (i.e. html → body →
header (or div #header) →
#main → #content →
#primary → #secondary →
footer (or div #footer). You might need
to substitute your own elements and IDs for the ones in the
examples below.
Overall width of website
You’ll need to change this so that it displays correctly. Add the
following code between the braces of your first media query:
body {
width: 100%;
float: none;
}
This ensures that the website’s body fills the width
of the device and removes any floats. At this point, you might
also want to change the background image if there is one (more on
that shortly).
You will now have the following code at the bottom of your style sheet:
@media screen and (max-width: 480px) {
body {
width: 100%;
float: none;
}
}
Width of content and sidebar
In portrait mode in particular, there isn’t room for a sidebar to
the right of the main content. Add the following code to the
media query relating to devices with a maximum width of 320
pixels:
#content, #primary, #secondary {
width: 100%;
float: none;
margin: 10px 0;
}
Footer content, especially widgets
If your footer has widget areas or other elements with floats
applied, you will need to override them for mobile devices in
portrait mode.
If you want the footer widgets to be full width in both landscape
and portrait modes, then simply add
footer.widget-area to the CSS for the sidebars and
content.
However, you might want the widget areas to be laid out side by side in landscape mode, depending on how many you have. In that case, you’ll need to do the following:
footer .widget-area {
width: 100%;
float: none;
margin: 10px 0;
}
You might also need to adjust the text alignment and borders and padding, depending on your existing theme. Margins should be set to 0 on the left and right; suit them to your theme at the top and bottom, but generally they should be smaller than in the desktop version.
Image sizes
The images in your design might still break the layout or break
out of their containing elements, making your website shrink when
viewed on a mobile device. There is an easy fix for this:
body img {
max-width: 100%;
}
This will ensure that images are never wider than their containing element. You might need to tweak the CSS if images sized further up in the style sheet have greater specificity.
However, this solution isn’t ideal. The images might look smaller, but mobile devices will still have to download their full sizes, which will slow down response times and possibly lose visitors, as well as annoy users on expensive data plans (more of them are out there than you might think). There a number of solutions to this, some of which you will find in this roundup of articles on responsive images. You may recall the mobile-first approach mentioned earlier; one benefit of this approach is that it serves different-sized image files to devices based on screen width.
Text size
So, our layout is working, and everything displays nicely. But
now that the website is narrower, the text might appear huge.
We’ll need to adjust the text’s size with the following code:
body {
font-size: 60%;
line-height: 1.4em;
}
This sets the font size as a percentage of the size set for it further up in the style sheet.
Sometimes mobile users will want to access specific content; for example, visitors to a store’s website will want to find the store’s location easily, and visitors to an e-commerce website will want to shop with a minimum of clicks (or taps). Sometimes you might want to adjust the navigation to make the website look more like an app.
Here are some methods you can follow to do this:




The possibilities are limited only by your imagination and creativity!
You’ve added the media queries above, but your smartphone still
displays the desktop version. Don’t worry! This is because many
smartphones use a virtual viewport that is equal to the width of
a small desktop, which prevents desktop-designed websites from
breaking when rendered in the browser. This can be easily fixed
by placing the following code in
the head of each page. Because yours is a
WordPress website, you need to add it only once, to the
header.php theme file:
What this does is tell the phone to treat the size of the screen as its actual size, not the virtual size… if that makes sense.
Here’s what we’ve looked at in this article:
As you can see, no one option is necessarily the best; it will depend on the website, on the budget and on the time and capability of those involved. Over time, most mobile-friendly WordPress websites will have responsiveness built into them, instead of using a separate theme, mobile website or plugin.
Hopefully this article has given you a starting point to make your WordPress website mobile-friendly. This is just the beginning of the possibilities. To further develop your mobile website, you might want to consider a mobile content strategy; a mobile-first design; APIs and native device functionality to create an even more app-like experience; and more.
Enjoy!
(al)
© Rachel McCollin for Smashing Magazine, 2012.
![]() |
Probably the most remarkable characteristic of our Web design community is that we care about our craft. We care about best practices, about our work, about learning, sharing and improving our skills. This very spirit is the driving force behind our daily work at Smashing Magazine, and this spirit is what has prompted us to organize the very first Smashing Conference: a friendly, valuable and inspiring community event that will help us all become better at what we do.
Whether you are a designer, developer, content strategist or business owner, at the Smashing Conference you’ll explore insights hands on and gain practical tips and new perspectives on our craft. We are very happy to provide an opportunity for you to share and gain practical knowledge in an intimate, informal atmosphere — right in our beautiful home town of Freiburg, Germany, at the foot of the legendary Black Forest.

The legendary Historical Merchants Hall, a late-Gothic
building built between 1520 and 1530. Its façade is decorated
with statues and the coat of arms of four Habsburg emperors. An
exquisite location for the very first Smashing Conference. Image
credit.
We’re delighted to invite you to come together for this inspiring, forward-thinking event on 17 to 19 September 2012. The conference will host a two-day single-track conference on September 17th and 18th, as well as four workshops on September 19th. By “we,” we mean Vitaly Friedman, editor-in-chief of Smashing Magazine, and Marc Thiele, who has been running community events such as beyond tellerrand for over 12 years.
The aim of the event is to deliver the same high-quality content that we deliver on Smashing Magazine, in the familiar atmosphere that beyond tellerrand events are known for. This will be a high-caliber yet friendly event that brings great value to everyone involved, and we’d be honored if you took a part in it.
The conference will take place in Freiburg, Germany at the legendary Historical Merchants Hall at the foot of the Black Forest.

The main hall of the venue. 350 tickets are available in all
for our two-day single-track event. Image credit
Keeping the conference affordable for everyone is important to us. All tickets includes two full single-track conference days, on Monday and Tuesday. Please note that only 350 seats are available.
We are pleased to announce that the first 70 early-bird tickets are on sale for a price of €249. The regular price after that is €349. And all prices include the German VAT of 19% and booking fees! Get your ticket now before it’s too late. We’d be honored to meet you in September!
If you’ve been following Smashing Magazine for a while, then you won’t be surprised by the focus of the Smashing Conference. We’re aiming to cover a wide variety of Web design topics, such as visual design, front- and back-end development, UX design, mobile, responsive design, the business aspects of running a website, as well as the intricate details of the designer and developer’s workflows. We’re encouraging our dear speakers to share details on how they work, what tools they use, and what their design and coding process looks like. We’re aiming for valuable, practical and inspiring talks.
We’ve handpicked all of the speakers to ensure the high quality of the event. So far, 10 out of 15 speakers are officially confirmed. Please note that the topics presented here are subject to change. More details on the conference, speakers, talks and workshops are available on the conference’s official website.
| Speaker | Talk | Details |
| Aarron Walter | The Real Me | |
Aarron Walter is the lead user
experience designer for MailChimp, where he socializes with
primates and ponders ways to make interfaces more human.
Aarron is the author of Designing for Emotion, the
purple stripe in the rainbow of knowledge from A Book Apart.
He lives with his wife and son in Athens, Georgia, and is a
wannabe barista. He tweets about design under the moniker
@aarron.
|
||
| Chris Heilmann | To be announced | |
Chris Heilmann has dedicated a lot
of his time to making the Web better. Originally from a radio
journalism background, he built his first website from
scratch in around 1997, and he spent the following years
working on a lot of large international websites, and a few
years at Yahoo building products and training people; he is
now at Mozilla. Chris has written and contributed to four
books on Web development and has written many articles and
hundreds of blog posts for Ajaxian, Smashing Magazine, Yahoo,
Mozilla, ScriptJunkie and many more.
|
||
| Jeremy Keith | The Spirit of the Web | |
Jeremy Keith makes websites. He is
responsible for the death of the trees used to print the
books DOM Scripting, Bulletproof Ajax and,
most recently, HTML5 for Web Designers. He also shot
a man in Reno just to watch him die. Originally from Ireland,
Jeremy now lives in Brighton, England where he pretends to
work with Clearleft. Peas grow there.
|
||
| Jonathan Snook | Your CSS Is a Mess | |
Jonathan Snook writes about tips,
tricks and bookmarks on his blog. He has also written for A
List Apart, 24ways, and .net magazine, and he has coauthored
two books, The Art and Science of CSS and
Accelerated DOM Scripting. Most recently, Snook has
written the eBook SMACSS, sharing his experience and
best practices on CSS architecture. Snook also works on the
design team at Shopify.
|
||
| Josh Brewer | Responsive Is as Responsive Does | |
Josh spends his time thinking about,
designing and building things that live at the intersection
of form, function and aesthetic. He is principal designer at
Twitter and is the co-creator of 52 Weeks of UX, Ffffallback
and Shares. He is also an advisor and mentor at The Designer
Fund.
|
||
| Lea Verou | To be announced | |
Lea has a long-standing passion for open Web
standards and has been often called a CSS guru. She loves
researching new ways to take advantage of modern Web
technologies, and she shares her findings on her blog. Lea
also makes popular tools and libraries that help Web
developers learn and use these standards. She speaks at a
number of well-known international Web development
conferences and writes for leading industry publications. Lea
also co-organized and occasionally lectures in the Web
development course at the Athens University of Economics and
Business.
|
||
| Paul Boag | Better Websites, Happier Clients and Improved Job Satisfaction | |
Paul Boag has been working on the Web since
1993. He is Web Strategist at Headscape Ltd, a Web design
agency that he cofounded back in 2002. Paul also produces and
hosts the longest-running and award-winning Web design
podcast at boagworld. He is a regular speaker at conferences
and author of Client-Centric Web Design.
|
||
| Rachel Andrew | The Future of Content Management | |
Rachel Andrew is a front- and back-end
Web developer, author and speaker. Her books include the
bestselling CSS Anthology for SitePoint, and she is
a regular contributor to a number of publications both online
and off, including Smashing Magazine. She writes about
business and technology on her own website.
|
||
| Stephen Hay | To be announced | |
Stephen has been designing and developing for the Web since 1995. He currently helps clients with front-end design and development, multi-platform strategy and accessibility through his consultancy, Zero Interface. Aside from his client work, he can be found speaking at industry events about Web design-related topics such as CSS layout and responsive design workflow. Stephen is co-organizer of Mobilism, one of the world’s leading mobile Web development conferences. He is also co-creator of Grip Workshops, a series of two-day intensive workshops for Web project managers on the client side. Stephen has written for publications including A List Apart and .net Magazine. He also coauthored the Smashing Book 3 with a host of super-talented folks. When he makes the time for it, he publishes his thoughts on The Haystack. |
||
| Tim Ahrens | Web Fonts Backstage and On Stage | |
![]() Tim Ahrens is a type designer based in Berlin, where he runs Just Another Foundry with Shoko Mugikura. As a former architect, he is interested in the interplay between technology and design. He develops design software such as the Font Remix Tools and Web applications such as the FontFonter. Since 2010, he has been working as a consultant for Typekit. |
||










Gallery of the speakers at the Smashing Conference.
| Trainer | Workshop | Details |
| Aarron Walter | Interface Design Bootcamp | |
Whether you are designing a Web app or
website, following best practices and standard design
methodologies will help ensure that your interfaces are
usable and engaging. In this workshop, we’ll explore the
design process in detail, including user research,
wireframing, prototyping and visual design. Through
real-world examples, you’ll see how an idea can evolve into
an interface.
|
||
| Andy Clarke | Fashionably Flexible Responsive Web Design | |
Responsive design has made designing
flexible websites fashionable again, but there is more to
being fashionably flexible than technology or using CSS3
media queries. So, this unique workshop — hosted by Andy
Clarke, designer, author and speaker — puts the design back
into responsive design. Andy will teach you how to design
from the “content out,” instead of from the “canvas in.”
He’ll demonstrate how to separate design from layout; and if
you work with designs made in Photoshop, he’ll show how to
deconstruct a design into its components (color, texture and
typography) before reassembling it for a fluid continuum of
devices, from phones to desktops and everything in between.
|
||
| Jonathan Snook | SMACSS: Scalable and Modular Architecture for CSS | |
The SMACSS workshop is a full day of
instruction and exercises on writing HTML and CSS using a
flexible and modular approach that will improve team
efficiency and minimize problems with growing projects. It
brings the eBook to life with practical examples and in-depth
discussion.
|
||



Gallery of the workshop experts at the Smashing
Conference.
As we finalize some major details of organization, we are working hard on a plethora of small details to make the event as valuable and memorable as possible. Please expect more speakers to be confirmed soon and more topics to be announced.
Also, we are looking for sponsors of the event, so if you are interested, please get in touch with us. More details on the location, hotels, speakers, talks, workshops and after party are presented on the official Smashing Conference website.

One of the workshop rooms, with medieval decoration and
statues of medieval knights. 30 seats are available for each
workshop. Image credit.

“Zum Roten Bären“, one of the locations for the conference’s
workshops. Large view.
We’re very excited about the Smashing Conference, and we’ll do our best to make it a valuable, memorable and useful event. We can’t wait to meet you, and please feel free to contact us if you have any questions about participation or sponsorship.
© Vitaly Friedman for Smashing Magazine, 2012.
Is outing & writing polarizing drivel hate baiting or a service to the community?
It is all a matter of perspective, isn’t it?
Some people would like to claim that it is one thing when they do it & something else when somebody else does it.
Unfortunately for those who want to have their cake & eat it too, consistency matters.
Even these guys know that.


If you brand those who fall outside the guidelines or get hit by updates as scammers to be avoided, then when your company gets caught working an angle & “scamming” (based on your own past sermons) your own judgement gets cast against yourself.
Is that fair?
In a word: yes.
Any belief system that is imposed onto others, but unacceptable when imposed upon the person who states it, isn’t a belief system at all. It’s duplicitous hackery at best – possibly much worse.
If your own company doesn’t follow your own advice, then what does that say about your value systems? How many people have had their potential held back by listening to your misinformation & making the unfortunate mistake of trusting you? What does that sort of behavior do to the reputation of the industry? Now everyone else is suspect because you pitched bogus pablum at newbies.
To speak publicly about the pitfalls of doing “blackhat” techniques and then turn around and be caught red-handed for the same just gives credibility to the naysayers claiming our industry is filled with slime balls.
If you want to be a polarizing asshat, then don’t be
surprised when you eat your own cooking. To expect anything
less is an open expression of ignorance of the field of
inbound marketing marketing.
![]() |
What is it that makes a typeface into a text font, instead of a font for larger sizes? The answer differs slightly, depending on whether one aims for print or Web-based environments.
Nevertheless, there are certain features that most good text faces have in common. Familiarity with these helps to select the right fonts for a given project. This article presents a few criteria to help the process along.
Some of today’s most successful typefaces were designed to excel in very specific areas of use: Frutiger grew out of airport signage, Georgia and Verdana were among the first mass-market fonts created for on screen reading, FF Meta was conceived as a telephone book face, and even the Stalwart Times New Roman was tailored for the pages of the London Newspaper The Times. Many typefaces are also often fine-tuned for using in certain sizes.
It should be noted that in this article, when “text” is mentioned, it is in discussion of body text, or running text (in other words, text at a similar size to what you are probably reading right now, rather than much larger sized words).
The features outlined in this article are those that type designers keep in mind while developing new typefaces. It’s important to realize that these aspects of typeface design are different from the text treatment a graphic designer employs while laying out a book page or website—no matter what a typeface’s inherent rhythm and niceties are, setting a text is still something that must be done with great care in respect to readability. There are problems that good fonts themselves cannot solve—whether or not a text sings on the page or screen depends on factors like the width of the column, the amount of space between each line, the contrast between the foreground/background and a number of other factors.

Above, Bembo over the years: this typeface was a favorite of
many book designers throughout the 20th century. At the top of
the image is a scan of the original Bembo typeface, printed with
letterpress. The digital version of the typeface—Bembo, seen in
the middle, is too light for ideal text in print. A newer
digitization was published in 2002—Bembo Book, seen at the
bottom. This font is much darker, and is a better representation
of the original Bembo idea. However, the middle version is still
very elegant, and may still be used well in sub-headlines.
Every typeface has its own inherent rhythm, created by the designer who made the font. With typefaces that are intended for use in body text, it is primarily this rhythm that will make the typeface readable. But there are additional factors that go into the making of a good text face: the space between the letters, the degree of contrast in the letters’ strokes, as well as the x-height and relative size of the whitespace inside of the letters. Not every typeface that works well in text will apply all of these factors in the same way, but all good ones will have many of these features in common.
When it comes to typefaces, the term “monolinear” is used to describe letters that appear to be designed with a consistent stroke thickness. Monolinear typefaces are low-contrast typefaces. Stroke contrast can be a helpful feature in small text sizes, but it is not paramount that a text face appears to be monolinear. Indeed, many newspapers employ high-contrast fonts; the question that must be considered is just how thick the thin strokes in high-contrast typefaces are.
The images in this section show different ends of the contrast spectrum: the Cycles types shown above are serifed, with a good deal of contrast. Sumner Stone’s Cycles typeface is an excellent choice for book design as its letter forms combine clarity with a rather high degree of stroke contrast and an almost timeless appearance. Five separate “versions” of Cycles are used in the above image; each block of text is set in its own optically-sized font.
Below, Avenir Next—also a great text face—is from another style of letter, and has very little contrast. I wouldn’t split good typefaces up into good contrast and bad contrast groups. Rather, some typefaces have a degree of contrast—be it too high or too low—that makes them less suitable for use in text. There is no definite rule on how much or how little contrast impacts a text face’s legibility. However, it is clear that both no contrast and excessive contrast can have adverse effects.
Geometric sans serif typefaces often appear to be monolinear stokes; their letters seem not to have any stroke contrast. In order to achieve this effect to the max, type designers have always made slight optical corrections. To look monolinear, a geometric sans needs some degree of thinning. In the image above, Planeta (left) is compared with Avenir Next (right). Both typefaces are more recent additions to the geometric sans category than stalwart faces (like Futura), or classic display designs (like ITC Avant Garde Gothic). Planeta has no visible stroke contrast, which must be a conscious decision on the part of its designer. While this does give it a unique style, it makes the face less suitable for text than Avenir Next, which is actually not as monolinear as it appears at first glance.
The Garamond Premier typeface family features different versions of each font. These variants are tailored for use in a certain size range. Above, the Display font (left) is compared with the Caption font (right). The Display font is optimized for texts that will appear in very large point sizes, while the Caption font has been optimized for very small text.
In her book Thinking with Type, Ellen Lupton writes:
“A type family with optical sizes has different styles for different sizes of output. The graphic designer selects a style based on context. Optical sizes designed for headlines or display tend to have delicate, lyrical forms, while styles created for text and captions are built with heavier strokes.”
The intended size of a text should be considered when selecting the typeface: is the typeface you want to use appropriate for the size in which you need to set it? Does the family include optical sizes (that is, different versions of the typeface that are tailored specifically for use at different sizes)? As with each of the factors mentioned in this article, the size at which a font is set can make or break your text.
In many ways, it is easiest to see the qualities necessary for good text faces by comparing potential selections with “display” faces. Like the term “text,” “display” refers to the size at which a specific font may best be used. In print media, as well as in many screen and mobile-based applications, the term “display” is often analogous with “headlines.” If a typeface that you are considering looks more like something that you might like to use for a headline, it won’t be the best choice for body text.
In the comparison image below, the Garamond Premier Display font has a tighter rhythm than the Caption font—not as much space is necessary between letters when they are set in large point sizes. Why should one consider type families with optical sizes, anyway? Well, as users bump up the point size of digital fonts, the space between letters increases in equal proportion. This inter-letter space slowly becomes too large, and makes a text feel like it is breaking apart. When a proper text font is set large, it may require some tighter tracking. Typeface families that offer optically-sized variants of their styles play a helpful role here.
In the image above, the first line of text—“Stanley Morison”—is set in the Garamond Premier Display font, while the lines of text underneath it are set in Garamond Premier Caption. Each font is balanced for its size, and they also harmonize well with one another. In another image (below), these fonts have been switched: the headline is now set in the Garamond Premier Caption font, and the text in the Garamond Premier Display. The letters in the Caption face look too clumsy when they are set so large, while the Display fonts’ letters appear uncomfortably thin in a “text” setting.
The amount of stroke contrast visible in caption-sized fonts is much lower than in display-sized fonts. If the Garamond Premier Display font (from the above image) was rendered in a smaller point size, its thin strokes would begin to break apart, making the text unreadable. But this would not occur with the Caption version.
Garamond Premier Caption can robustly set real text, even in poor printing conditions. How well a font will render in small sizes on screen depends on the operating system and applications in question. Font formats themselves also play a role; in certain environments, TrueType fonts with “hinting” information may vastly improve on screen display (see the “Hinting” section at the end of this article).
Garamond Premier’s Display face (above left) is shown next to the Caption face (above right). Both fonts are set at the same point size. The Caption face features a much higher x-height than the Display font.
Many successful text faces feature high x-heights; this means that the ratio of the central vertical area of lowercase letters—the height of the letter x, for instance—is large when compared to the length of the ascenders and descenders. Depending on its design, a text face may have a low x-height and still be quite legible. But the benefit of incorporating a large x-height in a design is that it maximizes the area of primary activity.
A high x-height may also prevent some letters, like the a or the s, from appearing to become too dark; these two letters have three horizontal strokes inside the x-height space, which is a very small area in text sizes. In order for letters to maintain clarity and understandability, they must have a consistent rhythm, as well as include large, open forms.
The images below illustrate just a few of the intra-letter spacing elements that should be understood and considered when choosing which typeface to choose for your body text. In order for the white spaces inside of letters to remain visible in small sizes, it is necessary for their counterforms to have a certain minimum mass, proportionally.
Counters
The image above shows text set in two members of the ITC Bodoni
family: ITC Bodoni Seventytwo and ITC Bodoni Six typefaces. In
the first line, “Randgloves” is set in a size mastered for 72pt
display (ITC Bodoni Seventytwo), while “and jam” is in the
Caption size (ITC Bodoni Six). These words are reversed in the
second line. Note how the enclosed white space in the top portion
of the e changes between the display and text
optical sizes.
Apertures
“Apertures” are the gateways that whitespaces use to move in and out of the counterforms of a typeface’s letter. The above image highlights the wide apertures in four letters from Erik Spiekermann’s FF Meta typeface. These allow for the typeface’s letterforms to feel more open. In certain sizes and settings, wide apertures—and the large counterforms that are their result—will make a text more readable.
The top line of the image above is set in Helvetica, and the bottom line in Frutiger. While the counterforms inside the letters of these two typefaces are similar in size, Helvetica’s apertures are much smaller. Because of this, white spaces inside of Helvetica’s letters and between Helvetica’s letters are much more closed off from each other than in a typeface with more open counters—like Frutiger.
Other counterforms and problematic letters worth remembering
include the c; if the apertures of a, e,
s are very open, the c should follow this
same route. Then there are lowercase letters like a, e, g,
s that often have rather complex shapes—specifically, they
each feature several horizontal strokes inside a small amount of
vertical space. How do their forms relate to one another? How
large is the typeface’s x-height? Do the ascenders and descenders
have enough room, particularly f and g?
Do the counterforms inside of roundish letters (e.g., b, d,
p, q, o) have the same optical size and color as those
inside of straight-sided letters like, h, n, m, and
u? How different from one another are the forms of
the capital I, the lowercase i and
l, and the figure 1? Can the
3 and the 8 be quickly differentiated
from each other? How about the 5 and the
6?
In the sample above, kerning has been deactivated for the second
line. The gaps between the letters T y and V
o are too large when compared with the amount of space
between the other letters in the text. The typeface used in the
image is Carter Sans.
Despite the popular misuse of the term in graphic design circles, “kerning” does not refer to the spacing values to the left and right of the letters in a font. Rather, fonts contain a list of kerning pairs to improve the spacing between the most troubling lettering combinations. The importance of kerning in a font is the role it may play in maintaining an optimal rhythm. Just as kerning describes something much more specific than a typeface’s overall spacing—or the tracking that a graphic designer might apply to a text—kerning is not the rhythm of a typeface itself, but an element that may strengthen a typeface’s already existing rhythm. Not every typeface design requires kerning, and there are typefaces on the market that indeed may have too many kerning pairs—a sign that the basic letter spacing in the font could have been too faulty in the beginning.
In the image above, compare the spaces between the letters of the Helvetica typeface (first row) with Frutiger’s (second row). Frutiger is a more humanist design, featuring a slight diagonal axis in its letters; many of them look similar to Helvetica’s, at least at face value. However, the space between Helvetica’s letters is much tighter.
While most of the images in this article feature typeface families that include Optical Size variants, many commonly used typefaces on the market today do not offer these options. This is why it is helpful to be able to identify text typefaces based on their features, rather than just on their names in the font menu. As mentioned earlier, it is primarily the typeface’s rhythm that dictates the readability of a block of text.
Take Frutiger and Helvetica, which are both commonly used in text, especially for corporate communication—Neue Helvetica is even the UI typeface in iOS and MacOS X 10.7. Yet, despite its popularity, Helvetica is not very effective as a text typeface; its rhythm is too tight. By rhythm, I’m not referring to tracking—or any other feature that a designer can employ when typesetting—but the natural flow of space between letters, and within them as well. Frutiger is a much more open typeface—the spaces between its letters are closer in size to the white spaces inside of the letters than in the case of Helvetica. Like all good text typefaces, Frutiger has an even rhythm—space weaves in and out of the letters easily.
To round off my discussion on text typefaces, I’d like to briefly mention some fonts that are often shown in rather large sizes: fonts for signage. Interestingly, many signage typefaces have design features very similar to typefaces created for very small applications. The Frutiger typeface, based on letters that Adrian Frutiger originally developed for the Roissy airport in Paris (now named after Charles De Gaulle), is quite legible in small sizes precisely because it is a good signage typeface. Despite their size, signage fonts serve a rather different purpose than Display fonts.
After considering the criteria mentioned above, the next question that often comes up is, “does this font have oldstyle figures, or small caps and ligatures, etc.?” A font’s letters might look really great in text, but if they do not include additional elements and features, their use is somewhat minimized. I avoid using fonts with small character and feature sets where I can, because I feel that the lack of these “extras” may break the kind of rhythm I aim to achieve.
Once you’ve established a consistent rhythm by setting your text according to the correct size and application, it would be a pity to inadvertently break that flow. Large blocks of tall figures or capital letter combinations do just that.
Even in languages like German, where capital letters appear at
the start of many words, the majority of letters in a text
planned for immersive reading will be lowercase letters. Every
language has its own frequency concerning the ratio of “simple”
lowercase letters like a c e m n o r s u v w x z to
lowercase letters with ascenders or descenders—b d f g h j
k l p q y. In international communication, language
support is a key consideration when choosing a font, and other
character set considerations may especially play a role.
Traditionally, the style of figures used in running text also have ascenders and descenders. These figures—often called oldstyle figures or text figures—harmonize better with text than the “uppercase” lining figures. These so-called lining figures either align with the height of a typeface’s capital letters, or are slightly shorter. It is no surprise that, when shipping the Georgia fonts for use onscreen and online, Matthew Carter and Microsoft made the figures take the oldstyle form. Many other typefaces that have long been popular with graphic designers, like FF Meta (seen above), also use oldstyle figures as the default style. In my opinion, lining figures are best relegated to text set in all-caps.
Long all-caps acronyms—like NAFTA, NATO, or USSR—also create an uncomfortable block in the line for the reader. Setting these letter-strings in small caps helps reestablish a specific typeface’s natural rhythm in reading sizes, as may be seen in the first line of the image below (set in Erik Spiekermann’s FF Meta).
Along with common ligatures like fi ff fl, small
caps and the many figure options are the most common OpenType
features found in quality text fonts. Aside from having both
lining and oldstyle figures, OpenType-functionality can enable a
font to include both tabular and proportionally-spaced figures,
numerators and denominators for fractions, as well as superior
and inferior figures for academic setting. Additional OpenType
features (such as contextual alternates or discretionary
ligatures), are more powerfully noticed in display sizes, and in
some cases can even be distracting in text.
The display of text on screen, particularly on computers running a version of the Windows operating system, may be fine-tuned and improved with the help of size-specific instructions inside of the font file. These instructions are commonly referred to as “hints.” A TrueType font (or a TrueType-flavored OpenType font), is capable of including hinting. However, not every font manufacturer goes to the effort of optimizing the onscreen appearance of its fonts for Windows—even those fonts specially created for use in text sizes.
All of the text in the above image is shown in the same font: Prensa, set at 18 pixels. The lowest row shows this at actual size in three different onscreen rendering environments. In the enlargements, the top row shows a close-up of rendering in Safari on MacOS X, which ignores the hinting data in fonts. The second row shows rendering in Internet Explorer/WindowsXP (Grayscale only, for this sample). The third row is from a ClearType environment—in this case, from Firefox on Windows7. Prensa is a typeface designed by Cyrus Highsmith at the Font Bureau; the Web font is served by the Webtype service.
Aside from the typefaces already mentioned in this article and its images, here is a small selection of faces that I personally enjoy at the moment. Even though lists of “favorite” typefaces are about as useful as lists of favorite songs or favorite colors, I am happy to pass my subjective recommendations along. No doubt that as new projects arise, my list of favorites is likely to change, too. I do think that these typefaces serve as great starting places. Some are also just from cool friends whose work I dig. Alongside each selection, I mention whether this choice is currently available for print only, or if there is a Web font version, as well. Don’t forget: the typefaces that you pick in the end should depend on your projects, their audience, and the content at hand.
Arnhem is a no-nonsense high-contrast oldstyle-serif face. It is a contemporary classic for newspaper and book setting, designed by Fred Smeijers and distributed via OurType. Available for print and Web.
Benton Sans is a Tobias Frere-Jones performance of Morris Fuller Benton’s News Gothic genre. Designed for Font Bureau, it is not only a great typeface for small print in newspapers, but one of the best-rendering text faces for the Web as well. Available for print and Web.
Ibis is another Font Bureau typeface, designed by Cyrus Highsmith. This square serif family is also no stranger to cross-media text-setting. Ibis works just as well whether you use it in print or on screen. Available for print and Web.
Ingeborg is modern serif family from the Viennese type and lettering powerhouse, the Typejockeys. Like any proper family should, Ingeborg has optically-sized variants for text and display settings. The display versions of the typeface can get pretty far out, too! Designer Michael Hochleitner named this typeface after his mother. Available for print and Web.
Fred Smeijer’s work in contempory type design is so significant that he gets two shout-outs in my list. His Ludwig type family takes a nod from 19th century grotesques, but he does not try to sanitize their quirky forms, as so many type designers had tried to do before him. Available for print and Web.
This is one of the typefaces that I’ve designed. I’m somewhat partial to Malabar. Available for print and Web.
Martin Majoor’s FF Scala Sans has been my top go-to typeface for almost 15 years. It mixes well with the serif FF Scala type, but it’s also really great on its own. Available for print and Web.
Of all the typefaces designed by Hermann Zapf over his long career, URW Grotesk is clearly the best. Unfortunately, it has been a little overlooked. URW Grotesk is a geometric sans, with a humanist twist that brings much more life into the letters than this genre usually allows for. Plus, the family is super big. Available for print and Web.
Are you a DIY-fan? Do you like to print with letter press, whether you set your own type by hand, or have polymer plates made? Then check out the typefaces of Emil Rudolf Weiß! His Weiß-Antiqua is an eternal classic. Weiß may have passed away 70 years ago, but his work is still relevant. He was German, so his last name is sort of pronounced like Vice, as in Miami Vice. Available for print and Web.
There are many factors that play a role in typeface selection. Aside from just browsing through the available fonts that they have, or fonts that could be newly licensed for a project, designers regularly spend considerable effort determining the right typeface to complement a project’s content, or the message at hand. Understanding some of the thoughts that go into the making of text typeface—including how a typeface’s letters are fitted to each other to determine a text’s default underlying rhythm—helps lead to better informed decisions regarding what types are indeed apt, and which faces are better suited for other sorts of jobs. After having read this article, I hope you feel more comfortable with this kind of decision making, and that you will know what to look for with a font in the future.
For more information about choosing the right text fonts, you may be interested in the following books and Web resources:
Note: A big thank you to our fabulous Typography editor, Alexander Charchar, for preparing this article.
(jvb) (il)
© Dan Reynolds for Smashing Magazine, 2012.