CSE341 Notes for Friday, 5/22/09
We started our exploration of Ruby. I mentioned that the 341 class usedn to
cover Smalltalk as its
final programming language. I know quite a bit about the language, but I
thought it would be more fun to look at Ruby. Like Smalltalk, it
is a pure object oriented language. And like Smalltalk, it is a dynamically
typed language. This will allow us to complete the language survey I mentioned
in handout #1:
|
Object-oriented
|
Functional
|
Statically typed
|
Java/C++
|
ML
|
Dynamically typed
|
Ruby
|
Scheme
|
I said that I wanted to discuss the question of where innovation comes from in
our field in terms of programming languages. In the 1970's there a lot of
innovation came from
Alan Kay and the people who
worked for him. Alan is one of the pioneers of object-oriented programming and
one of the chief architects of Smalltalk. He worked for Xerox PARC during the
1970's. One of his most famous quotes is that, "The best way to predict the
future is to invent it," which you'll find along with some amusing stores in
Kay's paper on The Early
History of Smalltalk (one of the most interesting papers I have ever read).
Kay and his colleagues invented the future at Xerox Parc in the 1970's: a
computer with a graphical user interface, a mouse, using a desktop metaphor, on
a network with services like email and chat, programmed with object-oriented
techniques. Xerox couldn't figure out how to make money from it. That took
Apple and Steve Jobs. Then Microsoft made it work for IBM PCs and the rest is
history.
The most recent wave of innovation came in the early 1990's. So what happened
in the early 1990's? That's when Tim Berners Lee invented the world wide web
and that changed everything. The big problem with the web was that it had only
one-way communication. You could create web pages that would present data
along with hyperlinks, but the page couldn't interact with the user.
Sun was working on Java at the time, although they were targeting it for
embedded systems (programs running on handheld devices like cell phones). When
the web became popular, they realized that Java would be useful for programming
applets that would run in a browser. Applets have always had some degree of
popularity, but they have generally turned out to be too big of a pain for
people.
The other dominant paradigm that emerged was the idea of running software on a
server that would interact with a user. So the challenge was to program the
server. Suddenly scripting languages
became very important because they allowed programmers to quickly develop code
to be run on the server. This was a very different kind of programming task
than writing a gigantic program like Microsoft Word. Plus, because it was
running on the server, you had a great deal of flexibility about what language
to use (any language that you could put on your server).
Perl was the early favorite scripting language, but many other popular
languages have emerged to fill this niche. Python and Ruby are two such
languages. I gave the analogy that they are to the programming world what indie films are to the
movie industry. Java, C++ and C# are like Hollywood blockbusters that cost
incredible amounts of money to produce. Python and Ruby are like small
independent films that are produced on a tiny budget but are often more
creative and interesting than the films produced by Hollywood.
Ruby is the brainchild of a Yukihiro Matsumoto,
also known as "Matz". He has said that one of his primary goals was to create
a language that programmers would find fun to use. Given what I've seen and
heard about Ruby, my opinion is that he has succeeded.
We spent most of the lecture in irb seeing how Ruby works. I won't try to
recreate that in the notes, but I'll mention some of the key points to
remember:
- I mentioned that the three major types of data I want to look at are
numbers, strings and arrays. Numbers and strings are pretty familiar.
Arrays are specified using square brackets and a comma-separated list of
values, as in [3, 5, 2.8, ["hello", 9], 17]. Notice that we can have
arrays inside of arrays and that like lists in Scheme, arrays in Ruby are
more flexible than what we get in ML in that we can mix different kinds
of data in a single array.
- Ruby is dynamically typed, which means that we don't have to describe
the types of variables, parameters, and method return values. It also
means that a variable can refer to different types of data at different
times. Ruby is still type-safe in that it checks to make sure you don't
combine values in an illegal way, although we found some pretty odd
combinations that Ruby allows, as in "hello" * 3 which returns
"hellohellohello" or [1, 2, 3] * ":" which returns "1:2:3".
- Ruby is a pure object-oriented language. Everything is an object, even
simple numbers. So we found that we could ask the number 3 what its
methods are by saying 3.methods(). We also found we could eliminate the
parentheses and just ask for 3.methods. Even operations like addition
and multiplication are methods that have a shorthand notation. When you
say "3 + 4" you are calling a method + on the object 3 passing it 4 as a
parameter: 3.+(4).
- We were able to ask each object what class it is by saying things like
3.class or "hello".class. This is called
reflection and is an important part of modern programming languages.
The ability to ask for 3.methods is another example of reflection.
Java has a great deal of support for reflection through packages like
java.lang.reflect, although it's much easier to do this in Ruby. We saw
that we could ask any object for its methods, as in 3.methods (methods of
integers) or "hello".methods (methods of strings) or 3.methods.methods
(methods of arrays).
- We saw that we could define new methods with def...end, as in:
def f(n)
return 2 * n
end
This defines a function f that doubles a number (f(8) returns 16). This
looked like a static method in Java, but in fact it is defined in a
default class called "main". We were able to see it by asking for
self.methods ("self" is the Ruby equivalent of Java's "this" keyword).
- Ruby has a much more consistent syntax for structured objects.
structure # elems? elem i?
-------------------------------------------
array a.length a[i]
String a.length() a.charAt(i)
ArrayList a.size() a.get(i)
Ruby (all) x.length x[i]
We also saw that Ruby has two ways to define a "slice":
x[m, n] #n values starting at index m
x[m..n] #values between indexes m and n inclusive
- Ruby also has a type called Hash that is similar to a Java Map. It uses
curly brace notation. You can either call Hash.new to construct one or
refer to {}. Once defined, you use array-like syntax, as in:
x = {}
x["hello"] = 74
Stuart Reges
Last modified: Wed May 27 09:04:11 PDT 2009