As a "language lawyer", it's fun to learn new languages and see how they differ in subtle ways. Here are some of the many ways Ruby is different from Python, etc. Most of these aren't necessarily good or bad, they're just different. Looking at the differences, it's fun to try to peek into the design decisions behind the languages. If you've noticed more interesting differences, post them below as comments!

In Ruby, Classes, modules, and constants must begin with an upper case letter. Actually, this reminds me of Haskell.



Ruby uses "end" instead of indentation. That's fine unless you're a Python programmer like me who keeps forgetting to type "end" ;)



Ruby doesn't have true keyword arguments like Python. Instead, if you pass ":symbol => value" pairs to a function, they get put into a single hash. Python can act like Ruby using the "**kargs" syntax, but Ruby cannot act like Python; it cannot explicitly declare which keyword arguments are acceptable in the function signature.



Ruby is like Perl in that the last value of a function is its implicit return value. In Python, if there isn't an explicit return statement, the return value is implicitly None.



Ruby does not make a distinction between expressions and statements like Python does. Hence, you can do:

a = if 5 > 6

7

else

puts "hi"

end

This is like Scheme and ML.

Ruby is much more clever than Python at figuring out how to translate end of lines into statements. For instance, the following works in Ruby, but not in Python.

a = 2 +

2

Python would require parenthesis.

I'm still trying to figure out the proper style for when you should use parenthesis in function calls and when you should leave them out in Ruby. The distinction is idiomatic.



Ruby's string interpolation syntax is '"foo #{2 + 2}"'. Python uses '"foo %s" % (2 + 2,)'.



The syntax for declaring a class method (what Java calls a static method) is strange, since Python uses "self" for something very different:

def self.my_class_method

puts "hi"

end

I must admit that "@a" is easier to type than Python's "self.a" without any significant loss in readability.

Single quoted strings in Ruby are like single quoted strings in Perl or like raw strings in Python. They get less interpretation.



Instance variables are never directly accessible outside the class in Ruby, unlike in Python or even Java.



In Python, you may use a publically accessible member on day one and change it to a property on day two behind everyone else's back. In Ruby, you use an attribute on day one. Fortunately, the syntax is very convenient, "attr_accessor :name". This is much more succinct that explicit getters and setters in Java.



Ruby has protected and private members, which Python and Perl purposely chose to leave out. A private member in Ruby is even more private that a private member in Java. If you have two instances of the same class, in Java one instance can access the other instance's private members, but that's not true in Ruby.



Ruby uses modules as mixins instead of using multiple inheritance to support mixins.



Ruby embraces what Python calls "monkey patching".



Python programmers generally try to avoid using eval, but I don't think that's the case in Ruby.



Ruby uses to "items << item" to append to a list. Python uses "items.append(item). PHP uses "items[] = item". This is one place where every language does it differently.



Ruby has "%w { foo bar bat }", which is like Perl's "q( foo bar bat )". Python doesn't have a construct for this, but you can use "'foo bar bat'.split()".



Ruby makes heavy use of symbols, like Scheme and Erlang (which calls them atoms). Python doesn't have symbols, so strings are used instead.



Ruby uses "elsif", whereas Python uses "elif".



Ruby doesn't need a colon in control structures, but it does require an end of line or a semicolon. Hence, to do a one liner in Python, it's:

if 11 > 10: print "yep"

if 11 > 10; puts "yep"; end

whereas in Ruby it's:As everyone knows, Ruby supports blocks. Personally the use of "|a, b|" to denote arguments to the block seems really strange to me. Who uses's pipes for arguments? They don't even pair like parenthesis do!

In Python, there's a much stronger emphasis on passing functions. I'm sure that it's possible in Ruby, but it's more natural to pass a block instead.



Ruby has a very different syntax for exceptions handling than most languages:

begin

a = some_func

rescue FuncFailed

puts "I'm hosed!"

end

When you unmarshal an object in Ruby, all the class definitions have to be loaded already. Python will import them for you, assuming they can be imported.

Ruby allows function names like "empty!" and "empty?" which is clearly a matter of taste, but I like it. This is probably inspired by Scheme.



For some reason, it seems like using "help(String)" in Ruby is pretty slow, whereas using "help(str)" is pretty fast. I wonder if Ruby doesn't have the docstrings attached to the object at runtime like Python does. In Python, this stuff is always loaded unless you use "-00" for optimization.



The rest of these comments are inspired by: http://books.rubyveil.com/books/ThingsNewcomersShouldKnow



What Ruby calls "'foo'[0]", Python calls "ord('foo'[0])". What Python calls "'foo'[0]", Ruby calls "'foo'[0,1]" or "'foo'[0].chr".



In Ruby, a failed lookup in a hash returns a default value, which is usually nil. You can set a different default if you want. Python will raise an exception if you try to access a key that doesn't exist. However, in Python 2.5, you can now set a default value for the dict. Now I know where they got that idea from ;)



In Ruby, you say "(hash[key] ||= []) << value", whereas in Python, you say "hash.setdefault(key, []).append(value)."



In Python, it's "len(obj)" (i.e. len is a generic function). In Ruby, it's "obj.length" (i.e. polymorphism is used). This difference seems to happen a lot.



In Ruby, strings are mutable. Hence, "s.upcase" returns a upcase version of s, whereas "s.upcase!" actually modifies s. Python strings are immutable.



Ruby doesn't have tuples (i.e. immutable arrays).



Because Ruby doesn't have as strong a notion of immutable objects as Python does. For instance, you may use mutable objects as hash keys in Ruby. Python forbids this. If you do change the value of a key in Ruby, you may want to let the hash recalculate the hash values for all the keys via "my_hash.rehash".



Ruby will let you assign a new value to a variable defined outside your scope:

i = 0

(0..2).each do |i|

puts "inside block: i = #{i}"

end

puts "outside block: i = #{i}" # -> 'outside block: i = 2'

This was not previously possible in Python without using a workaround. However, Python is gaining this feature with the use of a keyword similar to the "global" keyword.

Coming at it from a different angle, in Java, you use explicit variable declarations to assign scope. This is true too in Perl when you use "my". In Python, an assignment automatically sets scope. Hence, you can shadow variables in Java, Python, and Perl. Ruby tries really hard to avoid shadowing. Hence, whoever assigns to the variable first sets the scope. Shadowing can still happen in rare cases (see here), but it's a lot less likely.



Ruby assignments are expressions. Hence, you can do:

while line = gets

puts line

end

for line in sys.stdin:

print line

Python purposely left this out because it's too easy to confuse "=" and "==". Hence, in Python you would write:Ruby has two sets of logical operators. They have different precedences. Hence, "a = b && c" means "a = (b && c)", whereas "a = b and c" means "(a = b) and c". I'm going to agree with Guido on this one and say this is just too confusing.

Ruby has an === operator and case statements. This feature is a lot closer to the match feature in ML languages than anything in Python:

case my_var

when MyClass

puts "my_var is an instance of MyClass"

when /foo/

puts "my_var matches the regex"

end

This is really neat. Notice that, thankfully, Ruby doesn't require "break" like all the C inspired languages.

In Ruby, only false and nil are considered as false in a Boolean expression. In particular, 0 (zero), "" or '' (empty string), [] (empty array), and {} (empty hash) are all considered as true.



In Python, 0, "", '', [], and {} are all considered False. In general, Python has a very rich notion of "truthiness", and you can define the "truthiness" of your own objects.



In Ruby, if s is a string, you may write "s += 'a'" or "s << 'a'". The first creates a new object. The second modifies s. If you modify s, that may "surprise" other pieces of code that also have a reference to s. Python strings are simply immutable so this can't happen.

Ok, that's all for now! In my opinion, they're both great languages. If you know about more fun differences, post them below!