Programming Language Peculiarities


So lets talk about Ruby WAT!

In this article I'm going to talk about a few constructs of the Ruby programming language that can make the code unclear / unreadable. The examples I will give are fairly edge cases but I use them purely to demonstrate the concept.

In the past I was asked to write a parser for Ruby, after having written it I decided Ruby is not the language for me.

First of all I want to give you some examples of valid ruby constructs before going on to explain what is wrong with the fact that these constructs are valid.

The if-modifier statement if-modifier-statement :: statement [ no line-terminator here ] if expression

The above definition means that instead of a normal if statement e.g.

if y == 3 thenstatement1end

also this equivalent form would be valid:

statement1 if y == 3

This form is known as the if-modifier.

Method calls

Method arguments do not have to be wrapped in parentheses:

method-invocation-expression ::= primary-method-invocation| method-invocation-without-parentheses| local-variable-identifier

In line 2 we see a reference to the method-invocation-without-parenthesesconstruct below.

method-invocation-without-parentheses :: command| chained-command-with-do-block| chained-command-with-do-block ( . | :: ) method-name| argument-without-parentheses | return-with-argument| break-with-argument| next-with-argument

In line 4 we can see a reference to the argument-without-parenthesesconstruct below:

argument-without-parentheses ::[ lookahead ∈/ { { } ] [ no line-terminator here ] argument-list

Statements are not required to be terminated with a semicolon unless on a single line. However an if statement can be written all on one line and begin can be substituted with a separator as the following grammar snippet shows:

if-expression ::if expression then-clause elsif-clause∗ else-clause? end

The elseif-clauseand the else-clauseare not obligatory.

then-clause ::separator compound-statement | separator ? then compound-statement

A then-clausemay or may not include a then.

separator :: ; | [line-terminator here]

A separator is defined as either a new line or a semicolon.

Given the above information, how would you interpret the following given that examplePrint is the name of a method as is isFalse:

print "foo"; if isTrue; print "bar" end

This is a valid line of code but it is very unclear here what the expected behaviour is for someone reading the code. Obviously this would print either foo, bar or both.

So lets look at it in detail:

print "foo"

is a statement, as mentioned previously

if isTrue

could apply to this statement. However in this case

if isTrue

applies to

print "bar"


print "bar"

is followed by


Another example where the language may be misunderstood, is when a variable and a function have the same name but the method takes no arguments. An example of this would be:

number = 3sum = 0def number()return 6endsum = numberprint sumprint number()print number

The output when the code is run is as follows: 363

In line 8 it is not clear if we are referring to number the variable or number the function.In this case it is virtually impossible to understand what the identifier is referring to because a method or function call does not requires the parenthesis to be present. Obviously this makes the code very difficult to read and maintain.

Here I have just outlined two of the cases I found while writing a parser for Ruby.Obviously it would not be a best practice to program in this way, so it is unlikely to be a problem.None the less, these issues make it very difficult to understand and maintain these languages. If the language treated whitespace as important as Python does this would be less of an issue.

Call me old fashioned but an if belongs before the statements it affects. I also think some form of statement terminator should always be used and only used, to terminate statements. These small things make a language much cleaner and clearer.

Next week I'll cover another language.