Using Many Objects at Once

Posted by Berin Loritsch Wed, 06 Aug 2008 11:53:00 GMT

Last article was meant to introduce you to the terminology that is common to object oriented languages. You should have a clear idea of what an Object is and what a Method is. Today, we are going to learn about how to use more than one object at a time. We’ll start with simple variables, which are simply names for objects you are using so you can get to them again. Then we’ll talk about some special objects called containers, whose sole purpose is to organize a group of objects for you.

A container is an object that holds a bunch of other objects

Variables

So there’s a little more terminology here. We can assign objects to individual variables fairly easily just by giving a name, using the equals sign, and the value. For example:

my_variable = 12345

As long as the first character of the variable name starts with a letter or an underscore “” character, the rest of the characters can be letters, numbers, and underscores. Almost all languages have this requirement, so that the computer doesn’t get confused between what is supposed to be a number and what is supposed to be a variable. Just a little helpful advice from someone with experience here, use variable names that make sense. It is better to type a few extra keys than wonder whether _cntr meant counter or center later on. It’s also better to use names that reflect the variable’s purpose rather than what it is made of.

array = ['cero', 'uno', 'dos', 'tres']
ones_column = ['cero', 'uno', 'dos', 'tres']

The variable named ‘array’ is kind of silly. It describes what kind of object is assigned to the variable rather than what we are using the variable for. The variable named ‘ones_column’ describes the purpose for the variable better. We are using an array of names to write out the ones column of a number.

Variables let us hold on to objects with a user friendly name so we can use them later

Arrays

Since we already introduced how to create an array above, let’s talk about how they are used. Arrays hold a bunch of related values together so that we can use them in interesting ways. Using the ‘ones_column’ example above, we can use any single digit number to get the name of that number.

Arrays are lists of information

puts ones_column[2]

# prints 'dos'

Remember in the last lesson, when we had a number do something using the times method? The number passed back to our code started at zero. The number inside the square brackets is an index number that starts at zero. So the first element in the array is always 0, not 1. That’s why we started the array with ‘cero’ (Spanish for zero) instead of ‘uno’ (Spanish for one).

An Array is a Collection, so like all collections it has an each method. The each method works just like the times method on the number objects. The method will pass back the elements (the objects) of the array one at a time in order. So, if we wanted to count in Spanish, we would use our ones_column array like this:

ones_column.each do |number|
  puts number
end

Hash

A Hash allows you to map one object as a key and another object as the value. Other languages will call the Hash a Map or a Dictionary, essentially letting you look up one object (a definition) using another object (the word to look up). Think of the word key in the terms of a map key. A symbol represents a concept, so to speak.

Hash lets you associate key objects with value objects

In Ruby, Hashes are created using the curly braces, and the key/value pairs are marked with the phrase: key => value . They can be quite handy when you have a lot of information to pass from one place to the next. One variable would take all the name/value pairs. If it helps, think of it as a collection of variables. It is most common to see string names be the key, but in Ruby we also have something called a symbol. Strings are surrounded by quotes, and they can change. Symbols have a colon in front and they never change.

my_map = {'string' => 'surrounded by quotes',
          :symbol => 'starts with colon',
          :string => 'not the same as a string'}

puts my_map['string'] # shows 'surrounded by quotes'
puts my_map[:symbol]  # shows 'starts with colon'
puts my_map[:string]  # shows 'not the same as a string'
puts my_map[:string.to_s] # shows 'surrounded by quotes'

In the above code, we set up a map of keys to string values. Just so you know, the objects don’t have to be the same type. In fact you’ll see that we used one string and two symbols for keys. You’ll also see that the Hash object treats them differently. The last lookup call might cause a little confusion, so look at the method being called on the symbol. The to_s method is on every Ruby object, and it is a convenient way to get a string out of the object. For a symbol, the to_s returns the name of the symbol (everything except for the colon). Because that happens to be the same name as a string key that is already in the map, it returns the value that belongs to the string.

This brings up a very important point, particularly for newbies. Save yourself a lot of headaches, and only use keys of the same type until you know exactly what you are doing. If you ever use many types of objects for different keys make sure you document your code with your comments. You don’t want to run the chance of spending hours tracking down a bug only to find it is the same thing I showed here. Talk about your ‘Doh!’ moments.

Strings

Ok, the Array and Map are good enough to get you going—there are more collection types and more things you can do with these collections, but strings are pretty important in programming. The string is your best tool for communicating with the user. On web forms, your values are all strings, and when you add content onto a page, they are strings. There are three ways of working with strings in Ruby, depending on how much power you need. We will introduce them from the simplest to the most complex.

Strings hold text

simple_string = 'single quotes and no processing'

The above string is rather simple. The single quotes mean to take the text AS IS, no escaped characters, no single quotes, and no formatting. You’d be surprised by how much you can use this simple declaration. If we ever needed to stick two strings together, we can use the plus sign (’+’).

hello = 'Hello'
world = 'World'

puts hello + ' ' + world

#shows 'Hello World'

Things can get messy when you have to show information your program has back to the user. The ’+’ concatenation only works for strings, so each object that is not a string needs to call the to_s method to be concatenated. Oh, and then you still have the problem of formatting the text to be pretty. There is a more powerful way to declare and use strings, and that is to use double quotes:

number = 4

puts "Number:\t#{number}" 

In the string we sent directly to the puts method, we see a bunch of stuff that might look confusing at first. The first funny looking characters would be the ”\t”. The backslash (’\’) is an escape character, so you can access more special characters with it. You can embed double quotes by adding a backslash in front, or in this case you can embed a tab character. Essentially, we told the string to embed some white space. The next set of funny looking characters would be ”#{number}”, but when you realize that the number inside the curly braces is the same name as the variable we defined before, it suddenly becomes a little less confusing. Basically anything between the ’#{’ and ‘}’ will be treated like regular ruby. You can even do math in there if you really wanted. It’s best to keep it simple and only use it to display the value of variables in your string.

That’s all well and good, but what if I have a lot of text, I only need to embed a little bit of Ruby variables, and I want to do all the spacing and carriage returns myself? There is a way to define a big string by providing your own “terminator”. The terminator is just so that Ruby can know when the string is done and it can go back to normal Ruby processing.

really_big = <<-END
This string will keep going and going
on and on until I use the terminator
to make it end.
END

puts really_big

You can embed variables just like before using the ’#{}’ construct, but there really isn’t a whole lot of need for escape characters and such. When you have a big message you want to give to the user, this is usually the best way to get it done. The important thing is that you choose the terminator so it will never be text in your block. The characters ‘<<-’ basically tell ruby to keep adding lines to the string until we reach X where X is the terminator. In my example, I chose the word END in all capital letters, but you could just as well use TERMINAR or BATTLE_FLAG or any other gibberish you want. The string will start on the following line and continue until it hits the terminator you set up. Just make sure it is clear what you are doing so that when you come back to the code later you aren’t thinking What in the world did I do?

How to Aproach a New Language

Posted by Berin Loritsch Wed, 05 Sep 2007 11:54:00 GMT

Whether you are new to a spoken language or a computer language, the principles are similar. There is so much to learn and it can seem so foreign to you that you can easily get overwhelmed. You can always start with survival phrases: little conversation swiss army knives that can get you a long way. They are really designed to get you to a point where you can find someone who speaks your language to finish the conversation, so it’s not like you are going to understand what many people are saying back to you most of the time. There are three major parts to understand a language: the vocabulary, the grammar, and the writing system.

Programming languages are usually easier to learn than spoken languages primarily because the vocabulary is intentionally kept small. The grammar is also kept consistent and simple to keep the parsers sane and predictability high. The writing system usually entails what can be typed from a keyboard and a few rules for mathematic symbols. There is some punctuation that you have to worry about, but not that much. So what makes a language so difficult? In my short experience, it has to do with translating the simple rules into something useful. You need to learn the libraries that come with the language to help you get something done with the operating system. A more subtle problem is more akin to dialects in spoken language, which is finding the standard idioms for doing things.

Spoken languages are usually tougher to learn because of the volume of the vocabulary and the different grammar rules you have to learn. Sure there is a basic grammar that is consistent throughout a language, but there are always exceptions you have to learn. After all that, you’ll invariably get stumped at some phrases and slang. For example if you translate the Arabic phrase for “How are you?” literally into English you would get “What color are you?” For someone who has grown up using the language its as natural as breathing, but for someone else it’s not that intuitive. How should you take it if someone wishes you to “be enlarged with fatness”? Should you be insulted or flattered? In many languages and cultures it’s a compliment.

Even though the two types of languages have very different challenges and end goals, there are a few strategies to help you in the process. Surprisingly, these strategies are the same for both endeavors. As someone who has learned Spanish and Classical Greek in a classroom environment, and everything else by self-study and pestering people, I can say that the classroom only gets you so far. This is what I’ve found to be helpful to me:

  1. Use it. What good will a language do you if you don’t use it for something? Even if you don’t know a lot, use what you know. You’ll find out more about what you need to know by stealing Nike’s advertising slogan and Just Do It.
  2. Develop a system or schedule for how you are going to expand your vocabulary. You can only take information in so fast before your brain overloads. It needs time to process what you’ve learned so far.
  3. Review constantly. You’re making mistakes, you just don’t know it yet. Go back over what you’ve done in the past in light of what you know now.
  4. Immerse yourself in the language. Do what you need to do to see and hear the language used properly. Watch shows, listen to podcasts, get involved in an open source project, read books, whatever you can do, do it. You’ll eventually find a good support group that will help you with the difficult stuff, and find new friends in the process.
  5. Learn the slang. Textbooks and classrooms teach you the “correct” way to do things, from an academic standpoint. That might be all well and good for some situations, but the real world is different than the classroom.
  6. Don’t strive for mastery. Strive to be better than you are. Mastery comes with a large amount of personal investment in the process. You’ll get overwhelmed if you try to master what you are studying. Just try to make incremental improvements and you’ll be more productive and happy with the progress.

Ok, so considering everything, how can I make these general guidelines? After all, what have I taken the time to learn, and how good am I with it? Even I’m surprised when I look at the list:

  • English—fluent, my natural language, 14 years of classroom (grade school and college) plus being competent in the idioms and slang.
  • Spanish—somewhat conversant, my second language, 2 years of classroom and a few years of talking to Spanish speaking people. I can speak, read, and write, but I’m still really slow listening. My vocabulary has wained a bit from lack of use.
  • Classic Greek—1 year of classroom, some self study using the Bible and study helps. It’s no longer a spoken language, but I can read and write the characters and I know where to look for answers that I need.
  • Japanese—I just started learning this language mostly out of curiosity. I’ve got some cultural ties to Japan both from my wife’s family and from mine. I’ve got martial arts, culinary, and cultural interests. Imagine my delight to find Japanese Pod 101.com to aid in my endeavors here.
  • There are some languages I just picked up a smattering of phrases, words, etc. Hardly useful more than to break the ice: Arabic, Punjabi, French, German, Russian, Swahili, Finnish.
  • BASIC—My first computer was a Commodore 64, which came with BASIC and some other language options. I learned BASIC well enough to work on some toy programs. I also learned the IBM and TRS-80 variants.
  • LOGO—I didn’t do more than turtle graphics with this one, but I’m dating myself aren’t I?
  • 6502 Assembly Language—BASIC was too slow, so I figured out how to make things happen at a lower level. Graphics were the same either way, so I found Assembly much more powerful and even expressive than the limited BASIC that was native to the Commodore machine. BTW geoProgrammer was excellent (more later).
  • GameMaker—Game making infrastructure, including sprite editors and rule editors.
  • COMAL—I had a class at school with this one. I never used it for anything more the classroom. However I did learn some cool tricks to use the modulus operator to handle certain corner cases with leap year handling.
  • C++—I skipped C because I believed that C++ had more of a future. By this time I left my C64 behind, and I was working with PCs. I first learned with GCC, and then with Microsoft Visual C++. When I started, neither were standards compliant (although I don’t think any where). One of my first personal projects involved CORBA. I’m very well conversant in this language, and if I need to I can get right back into it.
  • ColdFusion—I try to block this experience from my mind, but it did drive home the need for a good MVC architecture.
  • Java—I started by developing a data migration tool, which was actually well constructed even for a first project. I then got into Cocoon and Avalon as an answer to the ColdFusion fiasco. I’m fluent and still using this today.
  • D—The first of the languages I explored for sheer curiosity. It touted itself as a successor to C++ , having enough influence from Java to correct some memory handling snafus and binary compatibility across machines, yet enough C++ to be able to use local libraries natively. Obviously, binary compatibility has to do with how the methods are bound together, which is something that was left undefined in C++. That means it doesn’t matter which compiler is used or what machine the binary was compiled on, it will work if all the supporting libraries are present.
  • C#—While I was never really sold on anything that is born from Microsoft, ignoring it completely is more of a mistake. I wanted to find out where the utility began and the hype ended. Sadly, it was nothing more than a language very similar to Java. Sure it had some nice conveniences which were adopted fairly quickly in Java, so as an evolution it had some value. Nevertheless, I can’t entirely trust a culture which does nothing more than to parrot one voice. Java at least has a diverse world of opinions which provides a healthy base to gain experience from. It’s probably because of my firm cultural bias from C++ and Java aesthetics that make me think that C# code looks ugly. C++ had some tools that would extract specially formatted comments into docs, a system that Java took wholesale and extended into the JavaDoc system. C# ignored the precedence and decided to do things different from Java just to be different.
  • Lisp/JESS—I had to introduce myself for a project where we were using the Java Expert System Shell for a part of it. It’s based on a dialect of Lisp, so it took a lot of getting used to for me. I barely developed a working understanding of the tool.
  • Smalltalk—The second of the languages I explored for sheer curiosity. I wanted to get back to the roots of object oriented programming, and see how these guys did things. It had a profound influence on me, even though I don’t use it everyday. I highly recommend introducing yourself to the language even if you have no intentions of using it.
  • Ruby—I’ve heard so much about how nice this language is to use, and I have to say it is a shear pleasure to use once you’ve caught on to the Ruby culture. Remember how one of the keys to learning a language is to immerse yourself in it? You’ll be rewarded. Of course, now I love Ruby on Rails which has greatly influenced how I think web applications should be developed.
  • Perl—I can’t say I’m fluent, but I am conversant enough. I was hired to migrate an application to a more modern architecture (with newer versions of Perl and DBI libraries).

That’s a lot of stuff. I’ve got all these languages, both spoken and programming, rummaging around my head with different levels of proficiency. However, by the time you’ve learned your third language it becomes easier. You start to see similarities between them, and you start thinking about them abstractly. Those notions help you learn the new languages more quickly. When you realize that Greek adjectives are positioned grammatically like Spanish, and that Japanese sentence structure is somewhat like Greek (with the verb at the end) you’re building on concepts you’ve already learned.

I’m not finished yet. There will be new languages I have interest in the future. They’ll likely be programming languages, but I’m not ruling out learning another spoken language—or even expanding my knowledge in one of the ones I barely know. Constant learning keeps you sharp, and the good thing is that you can do it a little bit at a time. I don’t have the time, spare money, or the inkling to sit down in a classroom these days. However, if I can fit a little study in here and there, I’m happy. I’ve learned that there are more similarities than differences in all these languages and cultures.