Argh! Ruby!

I tried out Ruby, really excited to get to learn a new language. My first impressions were great – I saw convenience everywhere. But the more I tried things out, the more holes I started to see.

First, in Ruby, you don’t do things in a conventional manner. You’ll know what I mean if you ever have a look at some standard code – it just looks weird. That’s because Ruby can’t do things the standard way. It isn’t designed that way. It’s not that you can’t do something – just not the conventional way. Instead, you have multiple other options, multiple other functions even. You’ll find yourself having to manipulate data in all the most peculiar manners to get what you want. There are plenty of nifty functions to do the job, just not always the one that would make the job easiest.

Starting with news you may have heard before, let’s start with the “nil” issue. This is best demonstrated by the output from Interactive Ruby:

# First, I will ask Ruby to convert an undeclared object to string
irb(main):001:0> a.to_s
NameError: undefined local variable or method ‘a’ for main:Object

# Naturally, we got an expected error
# Now let’s try to assign undefined variable “b” to “a”
irb(main):002:0> a = b
NameError: undefined local variable or method ‘a’ for main:Object

# We get the same expected error
# Now let’s try to assign the still-undefined “a” to itself
irb(main):003:0> a = a
=> nil

What? Given the answer for “b”, you’d expect the same thing to result. At the very least, if this is true, you would think that “a=b” should give the same result. The ironic thing is, uninitialized variables are not defaulted to “nil” as they should be. However, doing the above (a=a) guarantees that the variable will now be nil:

irb(main):004:0> a.to_s
=> “”

Moving onto strings…

The biggest problem is string manipulation. It’s easy to convert from numbers to strings and via versa, sometimes unintentionally! Let’s have a look:

Accessing parts of ruby strings can be so entertaining. (ARG@!) For example, suppose you wanted to extract the first character of a string. Seems simple in every other language: simply append to the string some square brackets, inside of which you have a single number that gives the mathematical index (i.e. starting from zero) of the character you want. Can Ruby do this? Sure.

blarg = “Some string”
puts blarg[0]

What is printed to screen isn’t “S” as you might expect. Instead, it’s the number 83. How are we suppose to access the first character? Simple, you have to use two indexes. So we try this:

puts blarg[0,0]

The output? Empty string. I’m not kidding you. To actually access the first character, you need to make the second index one higher than the first. So this works for all of the characters, right? Only in command prompt. It turns out, you can make both indexes the same if you want the last character in a string (when running a Ruby file).

File extraction and string manipulation

Instead of taking out single characters out of files, we can extract each line via the following:

@filetext = IO.readlines( filename.to_s )

where “filename” is a string containing the name of our file. You now have an array of every line in the file in one variable. Now to mess with each word, you’d think it be easy. You’re right – we apply the function “split” to each array in “@filetext”. The result is an array that you must grab from piecemeal, with another index. Sadly, there isn’t a quick way of getting a single word out of the file. You can’t append multiple sets of square brackets onto things (much less some special function name) and extract out single chunks of data from multiply-nested lists like you can in other languages.

Having programmed in Python, I was hoping to compare the two on an even ground. I sighed at some of the lack of conveniences that Python has (like the easy way of making inline lists from functions enclosed in square brackets), but those are language specific. The syntax between the two languages can appear similar at times, but each has its quirks. With Python, I continually forget to precede my class variables with “self.” in order to ensure they were non-local but actually belonged to the class; with Ruby, I primarily had the problem of forgetting to add my “end” after the definitions of things. Most of the time, I didn’t even know when to add it!

Praises and Cons?

For all its funny quirks, some of which I have discovered and many of which I have yet to discover, the makers of Ruby deserve recognition for their efforts in trying to make programming convenient while keeping the language uniquely object-oriented. Consider the various ways you can control internal variables in a class. You can either set them using “getter” and “setter” methods, create special getter and setter methods using the variable names (more on this in a second) or use special keywords.

Getter and setter methods are obvious (they’re just simple functions that either return the value or assign a passed-in value to it). What about these “special” getter and setter methods? Ruby allows you to get your variable’s value by creating a function with the same name and making it like an ordinary getter. Technically the name isn’t the same since the actual variable is preceded by a “@” character. The setter method is the same as any other setter method except that the name is followed by “=” which must be directly connected to the name. Example:

@avar

def avar
return @avar
end

def avar= (val)
@avar = val
end

The advantage this has is that in your code it looks more as those you are directly accessing the object even though its private.

The third method is using a special keyword. “attr_accessors” followed by “:”, which in turn is directly followed by the variable name, will create a variable with that name as well as the getter and setter methods. “attr_reader” and “attr_writer”, having the same syntax, create a variable with that name and the getter and setter methods respectively.

I could also discuss lists at this point and how easy it is to iterate through some of them. The syntax is very short and quick, but it does take some time to get used to the syntax.

The disadvantage to having multiple ways of doing things is that you have to memorize all of them if you want to read someone else’s code. I compared some code of my with my colleagues for doing the same job and it was very apparent that the differences between our code weren’t due solely to coding style but to the different ways of doing the same simple task. Consider for example string creation (oh no, I’m back to strings). As a very simple but radical set of examples, allow me to layout different ways of adding two strings. For simplicity, I’ll apply the same coding style to both strings.

str = item1.to_s + item2.to_s
str = item1.to_s() + item2.to_s()
str = “#{item1.to_s}#{item2.to_s}”
str = “#{item1.to_s}” + “#{item2.to_s}”
str = item1.to_s.concat( item2.to_s )
str = item1.to_s.insert( item1.to_s.size, item2.to_s )
str = item1.to_s.insert( item1.to_s.length, item2.to_s )

Naturally, there are sub-variations of each of these, many of which simply add the parenthesis to the functions. Do note that there are people who might use any one of the above, regardless of how silly or inefficient some of them may seem, but that’s the consequence of being a newbie and finding the first thing that works. I’m not going to spend more time writing out the other variations much less those that use the do-while loops. Just know that I like the convenience, but this built-in convenience (and not just from someone’s library) may be a bit overkill.

I could go on to discuss Ruby on Rails and more positive aspects of Ruby, but that’s for another post. This post is a rant on some of the obvious and annoying disadvantages of the language.

Advertisements

About chronologicaldot

Just a Christ-centered, train-loving, computer geek.
This entry was posted in software and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Enter the space and time of my little world... Welcome Earthling.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s