There is a lot of discussions of Python vs Ruby, and I all find them completely unhelpful, because they all turn around why feature X sucks in language Y, or that claim language Y doesn't have X, although in fact it does. I also know exactly why I prefer Python, but that's also subjective, and wouldn't help anybody choosing, as they might not have the same tastes in development as I do.

It would therefore be interesting to list the differences, objectively. So no "Python's lambdas sucks". Instead explain what Ruby's lambdas can do that Python's can't. No subjectivity. Example code is good!

Don't have several differences in one answer, please. And vote up the ones you know are correct, and down those you know are incorrect (or are subjective). Also, differences in syntax is not interesting. We know Python does with indentation what Ruby does with brackets and ends, and that @ is called self in Python.

UPDATE: This is now a community wiki, so we can add the big differences here.

Ruby has a class reference in the class body

In Ruby you have a reference to the class (self) already in the class body. In Python you don't have a reference to the class until after the class construction is finished.

An example:

class Kaka
puts self
end

self in this case is the class, and this code would print out "Kaka". There is no way to print out the class name or in other ways access the class from the class definition body in Python (outside method definitions).

All classes are mutable in Ruby

This lets you develop extensions to core classes. Here's an example of a rails extension:

class String
def starts_with?(other)
head = self[0, other.length]
head == other
end
end

Python (imagine there were no ''.startswith method):

def starts_with(s, prefix):
return s[:len(prefix)] == prefix

You could use it on any sequence (not just strings). In order to use it you should import it explicitly e.g., from some_module import starts_with.

Ruby has Perl-like scripting features

Ruby has first class regexps, $-variables, the awk/perl line by line input loop and other features that make it more suited to writing small shell scripts that munge text files or act as glue code for other programs.

Ruby has first class continuations

Thanks to the callcc statement. In Python you can create continuations by various techniques, but there is no support built in to the language.

Ruby has blocks

With the "do" statement you can create a multi-line anonymous function in Ruby, which will be passed in as an argument into the method in front of do, and called from there. In Python you would instead do this either by passing a method or with generators.

Ruby:

amethod { |here|
many=lines+of+code
goes(here)
}

Python (Ruby blocks correspond to different constructs in Python):

with amethod() as here: # `amethod() is a context manager
many=lines+of+code
goes(here)

Or

for here in amethod(): # `amethod()` is an iterable
many=lines+of+code
goes(here)

Ruby supports functional style (pipe-like) programming more easily

Python has built-in generators (which are used like Ruby blocks, as noted above)

Python has support for generators in the language. In Ruby 1.8 you can use the generator module which uses continuations to create a generator from a block. Or, you could just use a block/proc/lambda! Moreover, in Ruby 1.9 Fibers are, and can be used as, generators, and the Enumerator class is a built-in generator
4
[1]

Python has flexible name space handling

In Ruby, when you import a file with require, all the things defined in that file will end up in your global namespace. This causes namespace pollution. The solution to that is Rubys modules. But if you create a namespace with a module, then you have to use that namespace to access the contained classes.

In Python, the file is a module, and you can import its contained names with from themodule import *, thereby polluting the namespace if you want. But you can also import just selected names with from themodule import aname, another or you can simply import themodule and then access the names with themodule.aname. If you want more levels in your namespace you can have packages, which are directories with modules and an __init__.py file.

Python has docstrings

Docstrings are strings that are attached to modules, functions and methods and can be
introspected at runtime. This helps for creating such things as the help command and
automatic documentation.

Python has decorators

Things similar to decorators can also be created in Ruby, and it can also be argued that they aren't as necessary as in Python.

Syntax differences

Ruby requires "end" or "}" to close all of its scopes, while Python uses white-space only. There have been recent attempts in Ruby to allow for whitespace only indentation http://github.com/michaeledgar/seamless

Yeah, I thought this was a better idea, but that would have required people to actually read the question first. :-D So I changed it, it's community wiki now. - Lennart Regebro

(2)
With regards to multiple inheritance, saying just "Ruby does not" is disingenuous. I can not think of anything you can do in Python with multiple inheritance that you can't do in ruby with modules/"mixin inheritance". (It's even arguable that including modules just plain is multiple inheritance.) - Logan Capaldo

(2)
That you can do the same thing some other way is an argument that doesn't hold. You can do everything here some other way. And since modules aren't classes, it's not multiple inheritance. You are welcome to contribute code examples of how it's done in Pythons multiple inheritence vs with Rubys modules. - Lennart Regebro

It's worth noting that the lack of parens in Ruby allows for more declarative-looking constructs. For example, Rails declares relationships as has_many :things, which would look more awkward. And things that looks like special syntax, like Ruby's require (equivalent of import) and attr_accessor, are actually just method calls. - Chuck

(1)
@Chuck, good point, and yet another example of the differing attitudes between the languages. Python sees that as implicit magick. If it is a method call, it should look like a method call. But, that's subjective territory again. - Lennart Regebro

Lennart, you would dislike Scala then...Scala has an even more flexible syntax than Ruby :) - horseyguy

(8)
-1 Unfortunately, this question misses its goal and most of the purported differences aren't differences at all and misinformation abounds! - bias

(1)
@bias: Could you provide a couple of examples of "misinformation" in the question? - jfs

Nvm I can't post code in a comment :/ - David

@Davidmoreen I believe you can short code snippets in comments using the backquote character eg this is some code - theycallmemorty

(2)
Module includes are in fact multiple inheritance, not just in concept but in actual implementation in the Ruby interpreter. When a Ruby module is included, it is injected into the inheritance chain exactly the same way that superclasses are. Method resolution is the same. In Ruby multiple module includes are multiple inheritance. Anyone who wants to contest this as semantically "not the same thing" as multiple inheritance is just being pedantic. What's the point of something not being the "same thing" if the effect is identical and just as easily achieved? A distinction without a difference. - Dave Sims

“In Python, the file is a module, and you can import its contained names with from themodule import *” – In fact, you can even tell a module, which properties should be importable and included in *, by specifying a module's __all__ list. - poke

@Close voter: Why the vote to close? - Andrew Grimm

@Andrew: apparently because it's "not a real question" (I didn't vote to close, I just checked why the voter did). I can see why, it is a very broad, potentially subjective, question that's hard to answer succinctly. - user23743

Nowadays there is programmers.SE, but when this question was posed, it was on-topic here. - Lennart Regebro

(1)
It is most definitely neither subjective, nor argumentative. It's an objective list of differences, not a "better or worse". It's also very helpful. The closing is mistaken and it should be reopened. - Lennart Regebro

The popularity of the ruby over python is because of RubyOnRails web framework. The framework is so flexible and easy to learn and it helps you to create running application in just few minutes. - kapser

[+34]
[2009-07-11 12:32:48]
John Feminella

Ruby has the concepts of blocks, which are essentially syntactic sugar around a section of code; they are a way to create closures and pass them to another method which may or may not use the block. A block can be invoked later on through a yield statement.

For example, a simple definition of an each method on Array might be something like:

class Array
def each
for i in self
yield(i) # If a block has been passed, control will be passed here.
end
end
end

Python has anonymous functions/closures/lambdas, but it doesn't quite have blocks since it's missing some of the useful syntactic sugar. However, there's at least one way to get it in an ad-hoc fashion. See, for example,
here
[1].

@Lennart: I'm not sure that that's equivalent to a block. Consider the somewhat more torturous machinations you'd have to go through, for example, if you wanted to replicate not "each" but some other method. Getting "yield" is significantly harder. - John Feminella

To me it looks like you can do the same thing in Python by explicitly passing a callable to the method. Am I wrong? - Bastien Léonard

(2)
@unbeknow: A, right. But if that had been a function instead of a print, it would have worked. In python 3 this works: [print(e+5) for e in [1,2,3,4]] And when it comes to horribleness, I think the ruby code above is horrible, so that's clearly subjective and thereby not a part of this question. @John I'm not saying it's equivalent, I'm saying it's not obvious what the difference is from your example. @Bastien, no, but that you can do similar things doesn't mean they are the same. Differences here should be listed even if there are otehr ways to do it. - Lennart Regebro

(2)
Well, I can't comment on the ruby code, I'm only a Python programmer. But what I want to point out is that even when some things are syntactically allowed you better don't do them (like using a functional construct like a list comprehension for the side effects). The reason may be the community that frowns on it or general software development principles that forbid it. So the OPs question for features that A has and B has not might be a little bit misleading in practice because nobody is using this feature in A either. - unbeknown

Well, they are, but I think that in the Ruby community it's seen as "beautiful" but in the Python community as "ugly". But the point of this is to document the differences. And the current example code really doesn't have any differences, except that Ruby calls it's closures "blocks" and Python doesn't. So I'm still curious about the actual difference. - Lennart Regebro

(22)
I'm a Python Programmer. I would like to see an example of how Ruby blocks help you to write something more concisely or more beautiful than with Python because it has not blocks. Your example could be written: for i in [1, 2, 3, 4]: print(i + 5). It doesn't use blocks, but its concise and beautiful as well as the ruby each example. - Manuel Ceron

Still no example of this. I removed the "block" part as this seems to not be an actual difference, just a concept in Ruby that nobody talks about in Python. - Lennart Regebro

Those are just anonymous functions. Why try to give them another name and pass as something new? - Сыч

@lennart, I'm definitely not a Python programmer, but I've often wondered how things like Sinatra(sinatrarb.com) would be accomplished without blocks. - zgchurch

(10)
@Manuel, procs are useful for attaching functors to non-trivial data structures (trees, graphs...) which can't be 'for-looped' and hence require special iterators to transverse. Blocks, which are anonymous procs, let you implement the functor in one expression (vs. define then implement) which dramatically speeds up the process of coding and clarifies intent. E.g. if you were creating a graph data structure you could define one 'each' iterator and then mixin Enumerable which would instantly give you access to dozens of iterators (sort, all?, any?, grep). Now you call a block ... - bias

(4)
@RommeDeSerieux, because it needs a name in the language! Moreover, it's a function object, not a function. Let's look at the Ruby Docs: "Proc objects are blocks of code that have been bound to a set of local variables" so an anonymous Proc is just the block and it's certainly not just a function! - bias

This is a fundamental feature of modern scripting languages. JavaScript and Lua do this, too. Ruby doesn't treat functions this way; naming a function calls it.

Of course, there are ways to do these things in Ruby, but they're not first-class operations. For example, you can wrap a function with Proc.new to treat it as a variable--but then it's no longer a function; it's an object with a "call" method.

Ruby's functions aren't first-class objects

Ruby functions aren't first-class objects. Functions must be wrapped in an object to pass them around; the resulting object can't be treated like a function. Functions can't be assigned in a first-class manner; instead, a function in its container object must be called to modify them.

@banister: I think it's fair to say that Common Lisp functions aren't quite first-class. Compare Scheme. As for Scala, I think Scala functions are first-class, while methods are not; but it's super easy to wrap a method as a function. - Jason Orendorff

In scala, a function call is just syntactic sugar for the apply method of an object. Any object that defines an apply() method is a "function" and can be called using obj() or obj.apply(). A function def is just a shorthand for defining an object with an apply method. - Alex Neth

(7)
Things defined by def ... end in ruby aren't functions. They're methods (the way you've defined them, of Kernel). Methods can be unbound (using the #method method), which are then objects. The closest thing ruby has to functions are Proc instances, which are also objects, and can be passed around or invoked. It also has a special syntax for passing a single callback Proc to a method, as John Feminella discusses in his answer. - rampion

(2)
@rampion: Functions are blocks of code with a single entry point that can take parameters and return values. Methods are a type of function. Ruby doesn't get to redefine functions in order to pretend it's more special than everyone else, or as an excuse for how poorly it handles them. That's just hand-waving. - Glenn Maynard

(4)
@Glenn: I get what you're saying, but I'd quibble with the assertion that Ruby's redefining functions - methods are a separate semantic concept. If you want to play the definition game, most imperative code is procedures, not functions. I'm not trying to be difficult, it's just that I believe definitions and exactness are important. I'll agree that manipulating an UnboundMethod can be a PITA, tho. - rampion

@rampion: I don't agree, but it's irrelevant: your semantics don't make the end result any prettier. - Glenn Maynard

(5)
@Glenn: Beauty is in the eye of the beholder. Nonetheless, methods are first-class objects by fulfilling the definition (in this case I'm referring to the Wikipedia definition). Maybe, you have some other definition of first-class? Do they need a Platinum Frequent Flier Card to get bumped up to first-class? - bias

(2)
So long as this answer has my name on the front, you will not edit it to say something entirely different than what I said. That's blatent misattribution. Submit your own answer if you like. From your comment you're obviously trolling, so I'm not discussing anything with you. - Glenn Maynard

(4)
@Glenn Check out the SO FAQ section "Other people can edit my stuff?!" - this is a Community Wiki. - bias

(2)
@Glenn I edited the post so that people know what you posted vs. what I posted. I also added a synopsis of the disagreement. This is an objective language issue, let's not turn this subjective and into a flame/rollback war. - bias

(2)
You are editing this to replace a position you don't like with your own; that's inappropriate editing. Again, and for the last time, if you wish to do that, add your own answer. I won't keep repeating myself; repeat this childish edit again and it will be reverted without comment. The "Add another answer" button is right there at the bottom. - Glenn Maynard

(1)
This is a community wiki. I never remove or modified your information. To respect your post I added supplement information (which you have removed and modified). I linked to references and gave a synopsis of our differences (you don't justify your position). You have called me names and have been offensive - I'm reporting your behavior to SO admins. - bias

(4)
You've repeatedly edited my answer to be partial to your pet language, and you've generally acted immature for the sake of continually wasting my time on an answer I supplied months ago and have no desire to repeatedly return to. I suspect the SO admins will appreciate your wasting their time as much as I appreciate you wasting mine. Grow up. - Glenn Maynard

(3)
@bias: Methods are first-class objects, but they are merely wrappers around blocks, which are not first-class objects. Block is the underlying, fundamental concept that represents a function in Ruby. Because it's not an object, you always have to box it and unbox it, by wrapping it in a Proc (lambda or not) or a Method. And then, when you want to pass a Proc or a Method to code that expects a block (either explicitly declared with & or implicitly used with yield), then you have to unbox it by using the & operator. - Vojislav Stojkovic

2

[+26]
[2010-11-05 00:24:23]
Mark Thomas

Ultimately all answers are going to be subjective at some level, and the answers posted so far pretty much prove that you can't point to any one feature that isn't doable in the other language in an equally nice (if not similar) way, since both languages are very concise and expressive.

I like Python's syntax. However, you have to dig a bit deeper than syntax to find the true beauty of Ruby. There is zenlike beauty in Ruby's consistency. While no trivial example can possibly explain this completely, I'll try to come up with one here just to explain what I mean.

Reverse the words in this string:

sentence = "backwards is sentence This"

When you think about how you would do it, you'd do the following:

Split the sentence up into words

Reverse the words

Re-join the words back into a string

In Ruby, you'd do this:

sentence.split.reverse.join ' '

Exactly as you think about it, in the same sequence, one method call after another.

In python, it would look more like this:

" ".join(reversed(sentence.split()))

It's not hard to understand, but it doesn't quite have the same flow. The subject (sentence) is buried in the middle. The operations are a mix of functions and object methods. This is a trivial example, but one discovers many different examples when really working with and understanding Ruby, especially on non-trivial tasks.

(1)
I agree. Ruby seems to flow naturally when I write it, so "zenlike" is a good term. - the Tin Man

3

[+18]
[2009-07-11 14:54:19]
Jason Baker

Python has a "we're all adults here" mentality. Thus, you'll find that Ruby has things like constants while Python doesn't (although Ruby's constants only raise a warning). The Python way of thinking is that if you want to make something constant, you should put the variable names in all caps and not change it.

(4)
Do you like this(python) way of thinking yourself? Just curious. - Dykam

(1)
My subjective opinion on the issue is that I never understood why some languages have lots of features that prevent me from doing things. I love that Python doesn't try to stop me from doing what I need. But again, that's subjective, and hence OT. ;) - Lennart Regebro

(19)
Ha.. this just reminds me that at least in python 2.*, you were able to do "True, False = False, True"... I believe they have correctly fixed that in python 3.0... that's something you should be prevented from doing. - Tom

(11)
Personally, I like strict guidelines enforced by the language because it makes all code written in that language consistent. It forces you to follow the guidelines, and developers reading your code can tell at a glance what's what. While most Python coders use the same general "style", I've seen some pretty big inconsistencies that wouldn't be possible in Ruby. - Sasha Chedygov

(2)
@Tom: Yeah True and False are just builtin bool instances. :) In python 3 they added them to keywords as well, so you can't create new variables with those names. @musicfreak: I don't mind STYLE enforcements. After all, that's what Python indentation is.;-) It's things like private methods and things I don't like. I can often just stop reasonable code reuse, for example. - Lennart Regebro

@Lennart: Ah, I see. Well in that case I see where you're coming from. :) - Sasha Chedygov

What I hate is that you aren't forced to call the super class constructor. Sometimes it results in errors that are difficult to find. - Bastien Léonard

(2)
@Lennart What? You can use private methods in ruby - just use reflection! Private just hides methods from accidental usage (like the cover flap over a trigger on missile launcher - some times it is good to make sure people actually want to do something). Really, all the anti-Ruby arguments seem to stem from a lack of understanding Ruby. - bias

(5)
-1 It seems like adults make judicious decisions that are informed and that only children make changes without concern for the consequences. Ruby informs you that you are doing something weird, and since you are an informed adult it lets you make that change. - bias

(8)
@bias - I'm not sure why you're downvoting me. This answer doesn't agree or disagree with the python way of doing things. It's just a statement of fact. - Jason Baker

(13)
@Jason "we're all adults here" is a statement of a fact? I'd like to call that an opinion wrapped around a feature, hence the down vote. - bias

You can import only specific functions from a module in Python. In Ruby, you import the whole list of methods. You could "unimport" them in Ruby, but it's not what it's all about.

EDIT:

let's take this Ruby module :

module Whatever
def method1
end
def method2
end
end

if you include it in your code :

include Whatever

you'll see that both method1 and method2 have been added to your namespace. You can't import only method1. You either import them both or you don't import them at all. In Python you can import only the methods of your choosing. If this would have a name maybe it would be called selective importing?

(2)
You can import only function a, not all the functions inside. If for example you include a Ruby module that declares 3 non-static functions, you get them all included in your namespace. In python you'd have to write from module import *. - Geo

(6)
Doesn't that lead to a lot of namespace clutter? - Lennart Regebro

Are you referring to Ruby's module importing system? - Geo

@Geo yes, that's what I'm referring to. - Lennart Regebro

(1)
I think it does. That's what I hate about Ruby modules. - Geo

(8)
Ruby doesn't really have a module system in the same sense as python. require works basically as textual inclusion with some checks for dupilicate inclusion baked in. You can (ab)use modules as namespaces but module is actually a bit of a misnomer. Modules are basically classes sans the new, allocate methods. They work best as a way to share code on a per class/object basis, not as mechanism for partitioning libraries, or to share code across programs. - Logan Capaldo

There are also Sets in Ruby that people rarely use, but they are built in. So I can say, stuff_in_backpack = Set.new; stuff_in_backpack << "computer"; stuff_in_backpack << "shoes"; # and the set will hold all the values without guaranteeing order. - zachaysan

6

[+12]
[2009-07-11 13:41:54]
haffax

What Ruby has over Python are its scripting language capabilities. Scripting language in this context meaning to be used for "glue code" in shell scripts and general text manipulation.

Together with its terse yet epxressive syntax it is perfect for these kind of tasks.

Python to me is more of a dynamically typed business language that is very easy to learn and has a neat syntax. Not as "cool" as Ruby but neat.
What Python has over Ruby to me is the vast number of bindings for other libs. Bindings to Qt and other GUI libs, many game support libraries and and and. Ruby has much less. While much used bindings e.g. to Databases are of good quality I found niche libs to be better supported in Python even if for the same library there is also a Ruby binding.

So, I'd say both languages have its use and it is the task that defines which one to use. Both are easy enough to learn. I use them side-by-side. Ruby for scripting and Python for stand-alone apps.

(1)
Question from someone who does not yet know Ruby: What do you mean by "$-Variables"? Do you mean global variables? If so, in Python, a variable defined in a module outside of a class or function is global. If not - what's the distinction? - Anon

(1)
Anon: if you declare a $variable anywhere in the code it is global because of the prefix. Thus, it doesn't matter where it is defined it is always global, and is always known as such. - Robert K

(8)
Not exactly, actually I meant pre-defined variables like $_, $1 etc. These are autmatically filled with values by ruby itself. $_ is the last line read. $1, $2, etc. are the regular expression matches from the last match. See here for a complete list: zenspider.com/Languages/Ruby/QuickRef.html#17 It basically is a hack for compact scripts. You can get all the info via API calls too, but using $ variables it more terse. Such kind of variables just doesn't suit Python's style, they deliberately left them out. - haffax

Thanks for that zenspider link - had been looking for something like that for a quick (non-tutorial) feel for Ruby. - Anon

7

[+12]
[2009-07-11 14:52:21]
Chuck

I don't think "Ruby has X and Python doesn't, while Python has Y and Ruby doesn't" is the most useful way to look at it. They're quite similar languages, with many shared abilities.

To a large degree, the difference is what the language makes elegant and readable. To use an example you brought up, both do theoretically have lambdas, but Python programmers tend to avoid them, and constructs made using them do not look anywhere near as readable or idiomatic as in Ruby. So in Python, a good programmer will want to take a different route to solving the problem than he would in Ruby, just because it actually is the better way to do it.

(5)
I agree that lambdas have limited scope and aren't useful in many cases. However, I don't think it's fair to say that Python programmers avoid them like the plague. - Jason Baker

(1)
I agree that lambdas are used often with Python - like with map, filter, reduce. The big difference seems to be that Python lambdas are limited to expressions whereas Ruby blocks can be multiline and involve statements. My general impression from what I've read about Ruby is that this feature in particular makes Rubyists go for the DSL approach, whereas Pythonistas are more likely to go for creating API's. My info on Ruby is still very superficial though. - Anon

@Anon: I've looked high and low for example of anonymous multiline blocks in Ruby. If you can do them, then nobody (sensibly) seem to actually do it. Any example? - Lennart Regebro

@Chuck: I don't get it. As far as I can tell respond do |format| requires respond to use yield. Is that incorrect? If it uses yield, then that statement is as far as I can see pretty much equivalent to for format in respond_to(): . So again I fail to see what these magick "blocks" do that Python don't. - Lennart Regebro

(1)
@Lennart: No, it does not use yield. (Ruby's yield is completely different from Python's anyway -- it does not return a generator.) It wouldn't be meaningful to write for format in respond_to(). The respond_to method doesn't return anything meaningful -- it simply responds to the current HTTP request. The do in respond_to do is the beginning of a block. In that block, we talk to a temporary object (labeled format in this example) that implements a very basic DSL for responding to an HTTP request. - Chuck

@Chuck, yeah I found the definition of respond_to now, and it actually takes a block argument and calls it. The other examples of blocks have used a yield. The respond_to example makes it clearer how blocks are used as anonymous functions. Yet, I completely fail to see how this can't be implemented just as elegantly with either generators or by simply passing a named function to do_respond. Both those cases are in any case evidently WAY easier to understand. - Lennart Regebro

@Lennart: Um, OK. I just pointed to that as an example of a multiline block. I wasn't trying to prove anything else. (Also, as I said, Ruby's yield is completely unrelated to Python's yield. There's no difference between calling a block and calling yield.) - Chuck

It may be unrelated, but funnily enough, you use it in exactly the same way. :) - Lennart Regebro

In the sense that both are called with an argument, yes, they're used the same way. In the sense that they do completely different things and are used in different cases, I'm not really sure I'd agree. - Chuck

No, really, every example I have seen of using a block can be replaced with a for x in generator(). It would work the same, and if you use yield in Ruby, it would even look the same! It's just a matter of view point. You claim the method calls the code block with parameters. Python claims the code block calls the method and gets parameters back. The actual differences are miniscule. - Lennart Regebro

OK, seen places where a block isn't used in this way, but instead is passed into a class and stored there. In that case you need to define the block as a function in Python. - Lennart Regebro

(1)
blocks can also be used to implement lazy evaluation - horseyguy

(3)
Can you 'mixin Enumerable' against a generator and instantly get 30 new and wonderful iterators? You need to look at the language in the whole before you understand why blocks/Procs are great. - bias

Python doesn't have Enumerable, but generating 30 iterators in one go is not a problem. - Lennart Regebro

8

[+12]
[2009-07-16 19:43:13]
Christos Hayward

I'd like to suggest a variant of the original question, "What does Ruby have that Python doesn't, and vice versa?" which admits the disappointing answer, "Well, what can you do with either Ruby or Python that can't be done in Intercal?" Nothing on that level, because Python and Ruby are both part of the vast royal family sitting on the throne of being Turing approximant.

But what about this:

What can be done gracefully and well in Python that can't be done in Ruby with such beauty and good engineering, or vice versa?

That may be much more interesting than mere feature comparison.

a comment at best. still my +1 - nawfal

9

[+11]
[2009-07-11 19:20:50]
Dario

Python has an explicit, builtin syntax for list-comprehenions and generators whereas in Ruby you would use map and code blocks.

Compare

list = [ x*x for x in range(1, 10) ]

to

res = (1..10).map{ |x| x*x }

how list comprehensions are not a plain Python? and there is a map function in Python as well. - SilentGhost

But there is no list comprehension syntax in Ruby - Dario

Python: res = map(lambda x: x*x, range(1,10)) - GogaRieger

Python: res=map(2 .__rpow__, range(1,10)) - John La Rooy

10

[+11]
[2009-07-13 10:35:00]
mark

"Variables that start with a capital letter becomes constants and can't be modified"

Wrong. They can.

You only get a warning if you do.

(2)
If a language gives you a warning for an operation, it is my opinion that you very well can consider the operation "not possible". Anything else is madness. - porgarmingduod

11

[+11]
[2009-10-15 17:26:53]
Jack Lloyd

Somewhat more on the infrastructure side:

Python has much better integration with C++ (via things like
Boost.Python
[1],
SIP
[2], and
Py++
[3]) than Ruby, where the options seem to be either write directly against the Ruby interpreter API (which you can do with Python as well, of course, but in both cases doing so is low level, tedious, and error prone) or use SWIG (which, while it works and definitely is great if you want to support many languages, isn't nearly as nice as Boost.Python or SIP if you are specifically looking to bind C++).

Python has a number of web application environments (Django, Pylons/Turbogears, web.py, probably at least half a dozen others), whereas Ruby (effectively) has one: Rails. (Other Ruby web frameworks do exist, but seemingly have a hard time getting much traction against Rails). Is this aspect good or bad? Hard to say, and probably quite subjective; I can easily imagine arguments that the Python situation is better and that the Ruby situation is better.

Culturally, the Python and Ruby communities seem somewhat different, but I can only hint at this as I don't have that much experience interacting with the Ruby community. I'm adding this mostly in the hopes that someone who has a lot of experience with both can amplify (or reject) this statement.

(7)
Your second point is at best misinformed. You should start by looking at Rack and Sinatra - Max Ogden

(6)
I explicitly note that other Rails stacks exist; I just don't think anyone is actually using them. Checking Sinatra and Rack didn't exactly change that impression. Do you really think, say, Sinatra (94 SO questions total), or Camping (2 SO questions total), or any of the others, actually has a real userbase/community? Most of them don't even have real life users, as far as I can tell. Compare with Django (4K+) or Rails (7K+), or even web.py for that matter. - Jack Lloyd

(1)
Sinatra is actually rather popular for different, lightweight tasks due to its DSL. Its just less used because Rail's MVC provides more. Rails is actually built on Rack - That is what makes Phusion Passenger possible. - alternative

What's better about Ruby than Python? I'm sure there's something.
What is it?

Wouldn't it make much more sense to ask Ruby people this, rather than
Python people?

Might, or might not, depending on
one's purposes -- for example, if
one's purposes include a "sociological
study" of the Python community, then
putting questions to that community is
likely to prove more revealing of
information about it, than putting
them elsewhere:-).

Personally, I gladly took the
opportunity to follow Dave Thomas'
one-day Ruby tutorial at last OSCON.
Below a thin veneer of syntax
differences, I find Ruby and Python
amazingly similar -- if I was
computing the minimum spanning tree
among just about any set of languages,
I'm pretty sure Python and Ruby would
be the first two leaves to coalesce
into an intermediate node:-).

Sure, I do get weary, in Ruby, of
typing the silly "end" at the end of
each block (rather than just
unindenting) -- but then I do get to
avoid typing the equally-silly ':'
which Python requires at the
start of each block, so that's almost a wash:-). Other syntax
differences such as '@foo' versus
'self.foo', or the higher significance
of case in Ruby vs Python, are really
just about as irrelevant to me.

Others no doubt base their choice of
programming languages on just such
issues, and they generate the hottest
debates -- but to me that's just an
example of one of Parkinson's Laws in
action (the amount on debate on an
issue is inversely proportional to the
issue's actual importance).

Edit (by AM 6/19/2010 11:45): this is also known as "painting the
bikeshed" (or, for short,
"bikeshedding") -- the reference is,
again, to Northcote Parkinson, who
gave "debates on what color to paint
the bikeshed" as a typical example of
"hot debates on trivial topics".
(end-of-Edit).

One syntax difference that I do find
important, and in Python's favor --
but other people will no doubt think
just the reverse -- is "how do you
call a function which takes no
parameters". In Python (like in C),
to call a function you always apply
the "call operator" -- trailing
parentheses just after the object
you're calling (inside those trailing
parentheses go the args you're passing
in the call -- if you're passing no
args, then the parentheses are empty).
This leaves the mere mention of
any object, with no operator involved, as meaning just a reference
to the object -- in any context,
without special cases, exceptions,
ad-hoc rules, and the like. In Ruby
(like in Pascal), to call a function
WITH arguments you pass the args
(normally in parentheses, though that
is not invariably the case) -- BUT if
the function takes no args then simply
mentioning the function implicitly
calls it. This may meet the
expectations of many people (at least,
no doubt, those whose only previous
experience of programming was with
Pascal, or other languages with
similar "implicit calling", such as
Visual Basic) -- but to me, it means
the mere mention of an object may
EITHER mean a reference to the object,
OR a call to the object, depending on
the object's type -- and in those
cases where I can't get a reference to
the object by merely mentioning it I
will need to use explicit "give me a
reference to this, DON'T call it!"
operators that aren't needed
otherwise. I feel this impacts the
"first-classness" of functions (or
methods, or other callable objects)
and the possibility of interchanging
objects smoothly. Therefore, to me,
this specific syntax difference is a
serious black mark against Ruby -- but
I do understand why others would thing
otherwise, even though I could hardly
disagree more vehemently with them:-).

Below the syntax, we get into some
important differences in elementary
semantics -- for example, strings in
Ruby are mutable objects (like in
C++), while in Python they are not
mutable (like in Java, or I believe
C#). Again, people who judge
primarily by what they're already
familiar with may think this is a plus
for Ruby (unless they're familiar with
Java or C#, of course:-). Me, I think
immutable strings are an excellent
idea (and I'm not surprised that Java,
independently I think, reinvented that
idea which was already in Python),
though I wouldn't mind having a
"mutable string buffer" type as well
(and ideally one with better
ease-of-use than Java's own "string
buffers"); and I don't give this
judgment because of familiarity --
before studying Java, apart from
functional programming languages where
all data are immutable, all the languages I knew had mutable strings
-- yet when I first saw the immutable-string idea in Java (which I
learned well before I learned Python),
it immediately struck me as excellent,
a very good fit for the
reference-semantics of a higher level
programming language (as opposed to
the value-semantics that fit best with
languages closer to the machine and
farther from applications, such as C)
with strings as a first-class,
built-in (and pretty crucial) data
type.

Ruby does have some advantages in
elementary semantics -- for example,
the removal of Python's "lists vs
tuples" exceedingly subtle
distinction. But mostly the score (as
I keep it, with simplicity a big plus
and subtle, clever distinctions a
notable minus) is against Ruby (e.g.,
having both closed and half-open
intervals, with the notations a..b and
a...b [anybody wants to claim that
it's obvious which is which?-)], is
silly -- IMHO, of course!). Again,
people who consider having a lot of
similar but subtly different things at
the core of a language a PLUS, rather
than a MINUS, will of course count
these "the other way around" from how
I count them:-).

Don't be misled by these comparisons
into thinking the two languages are
very different, mind you. They aren't. But if I'm asked to compare
"capelli d'angelo" to "spaghettini",
after pointing out that these two
kinds of pasta are just about
undistinguishable to anybody and
interchangeable in any dish you might
want to prepare, I would then
inevitably have to move into
microscopic examination of how the
lengths and diameters imperceptibly
differ, how the ends of the strands
are tapered in one case and not in the
other, and so on -- to try and explain
why I, personally, would rather have
capelli d'angelo as the pasta in any
kind of broth, but would prefer
spaghettini as the pastasciutta to go
with suitable sauces for such long
thin pasta forms (olive oil, minced
garlic, minced red peppers, and finely
ground anchovies, for example - but if
you sliced the garlic and peppers
instead of mincing them, then you
should choose the sounder body of
spaghetti rather than the thinner
evanescence of spaghettini, and would
be well advised to forego the achovies
and add instead some fresh spring
basil [or even -- I'm a heretic...! --
light mint...] leaves -- at the very
last moment before serving the dish).
Ooops, sorry, it shows that I'm
traveling abroad and haven't had pasta
for a while, I guess. But the analogy
is still pretty good!-)

So, back to Python and Ruby, we come
to the two biggies (in terms of
language proper -- leaving the
libraries, and other important
ancillaries such as tools and
environments, how to embed/extend each
language, etc, etc, out of it for now
-- they wouldn't apply to all IMPLEMENTATIONS of each language
anyway, e.g., Jython vs Classic Python
being two implementations of the
Python language!):

Ruby's iterators and codeblocks vs Python's iterators and generators;

Ruby's TOTAL, unbridled "dynamicity", including the ability
to "reopen" any existing class,
including all built-in ones, and
change its behavior at run-time -- vs
Python's vast but bounded
dynamicity, which never changes the
behavior of existing built-in
classes and their instances.

Personally, I consider
1
[4] a wash (the
differences are so deep that I could
easily see people hating either
approach and revering the other, but
on MY personal scales the pluses and
minuses just about even up); and
2
[5] a
crucial issue -- one that makes Ruby
much more suitable for "tinkering",
BUT Python equally more suitable for
use in large production applications.
It's funny, in a way, because both
languages are so MUCH more dynamic
than most others, that in the end the
key difference between them from my
POV should hinge on that -- that Ruby
"goes to eleven" in this regard (the
reference here is to "Spinal Tap", of
course). In Ruby, there are no limits
to my creativity -- if I decide that
all string comparisons must become
case-insensitive, I CAN DO THAT!
I.e., I can dynamically alter the
built-in string class so that
a = "Hello World"
b = "hello world"
if a == b
print "equal!\n"
else
print "different!\n"
end WILL print "equal". In python, there is NO way I can do that.
For the purposes of metaprogramming,
implementing experimental frameworks,
and the like, this amazing dynamic
ability of Ruby is extremely
appealing. BUT -- if we're talking
about large applications, developed by
many people and maintained by even
more, including all kinds of libraries
from diverse sources, and needing to
go into production in client sites...
well, I don't WANT a language that is
QUITE so dynamic, thank you very much.
I loathe the very idea of some library
unwittingly breaking other unrelated
ones that rely on those strings being
different -- that's the kind of deep
and deeply hidden "channel", between
pieces of code that LOOK separate and
SHOULD BE separate, that spells
d-e-a-t-h in large-scale programming.
By letting any module affect the
behavior of any other "covertly", the
ability to mutate the semantics of
built-in types is just a BAD idea for
production application programming,
just as it's cool for tinkering.

If I had to use Ruby for such a large
application, I would try to rely on
coding-style restrictions, lots of
tests (to be rerun whenever ANYTHING
changes -- even what should be totally
unrelated...), and the like, to
prohibit use of this language feature.
But NOT having the feature in the
first place is even better, in my
opinion -- just as Python itself would
be an even better language for
application programming if a certain
number of built-ins could be "nailed
down", so I KNEW that, e.g.,
len("ciao") is 4 (rather than having
to worry subliminally about whether
somebody's changed the binding of name
'len' in the builtins module...).
I do hope that eventually Python does
"nail down" its built-ins.

But the problem's minor, since
rebinding built-ins is quite a
deprecated as well as a rare practice
in Python. In Ruby, it strikes me as
major -- just like the too powerful
macro facilities of other languages
(such as, say, Dylan) present similar
risks in my own opinion (I do hope
that Python never gets such a powerful
macro system, no matter the allure of
"letting people define their own
domain-specific little languages
embedded in the language itself" -- it
would, IMHO, impair Python's wonderful
usefulness for application
programming, by presenting an
"attractive nuisance" to the would-be
tinkerer who lurks in every
programmer's heart...).

(1)
In ruby you could simply freeze your array to change it to something immutable - user163365

Excellent post by Alex Martelli :) - Skilldrick

14

[+8]
[2009-07-11 19:26:02]
Lennart Regebro

I'm unsure of this, so I add it as an answer first.

Python treats unbound methods as functions

That means you can call a method either like theobject.themethod() or by TheClass.themethod(anobject).

Edit: Although the difference between methods and functions is small in Python, and non-existant in Python 3, it also doesn't exist in Ruby, simply because Ruby doesn't have functions. When you define functions, you are actually defining methods on Object.

But you still can't take the method of one class and call it as a function, you would have to rebind it to the object you want to call on, which is much more obstuse.

Ruby doesn't have functions at all. That said, TheClass.instance_method(:themethod).bind(anobject).call would be the equivalent ruby. - Logan Capaldo

Oh. So there is some sort of magic main class when you define a function that's not on an explicit class? - Lennart Regebro

Yes, methods defined at the top level are private methods of Object. - Logan Capaldo

you can get a reference to a method, to store them in a object, by calling the "method" method. - Geo

(1)
FWIW, it seems that in Python, functions and methods are actually the same type, and their different behavior comes from descriptors: users.rcn.com/python/download/…. - Bastien Léonard

@bias: And why would that mean a -1? It seems to me you just confirmed what I said. - Lennart Regebro

The first comment shows that you can use an unbound method by binding it to an object just like in the Python example - so I don't get why this is a language difference. Moreover, The answer implies that in Python functions and methods are conceptually closer than in Ruby. But, in Ruby they are exactly the same thing! - bias

(1)
But if you bind it to an object, then it's not unbound. Duh. :-) And they are the same thing in Python as well. It's just that Ruby doesn't actually have functions. And that means that my statement is correct. You can call an unbound method as if it was a function in Python. And that is actually useful, that means for example that you can call a method defined on a class on an object that doesn't have that class, which sometimes is useful. - Lennart Regebro

15

[+7]
[2009-07-13 12:46:18]
Giorgi

I would like to mention Python descriptor API that allows one customize object-to-attribute "communication". It is also noteworthy that, in Python, one is free to implement an alternative protocol via overriding the default given through the default implementation of the __getattribute__ method.
Let me give more details about the aforementioned.
Descriptors are regular classes with __get__, __set__ and/or __delete__ methods.
When interpreter encounters something like anObj.anAttr, the following is performed:

I wish I understood callcc. Can you give a more mundane application scenario than McCarthy's Ambiguous Operator, to appreciate its merrits? I mean something real-world, not that funky CS stuff?! - ThomasH

You can have code in the class definition in both Ruby and Python. However, in Ruby you have a reference to the class (self). In Python you don't have a reference to the class, as the class isn't defined yet.

An example:

class Kaka
puts self
end

self in this case is the class, and this code would print out "Kaka". There is no way to print out the class name or in other ways access the class from the class definition body in Python.

Can you provide more details (like code) for your first point? - Loïc Wolff

Example code is a good idea, I added that, even though this case is trivial. - Lennart Regebro

@SilentGhost: I can't think of one that isn't really obscure right now. :) - Lennart Regebro

you can access the class name inside the class in python: class foo(): def init__(self): print self.__class.__name__ - txwikinger

(1)
@txwikinger: yeah, but not within the class' body, which is executed at the same time as the class statement. - Bastien Léonard

You can define class methods in python whose first parameter, conventionally called 'cls', refers to the class like self refers to instances in instance methods. - Anon

True. I would be really interested in seeing a case where this is a useful convenience. Seems to me like when you are defining the class, you'd know its name and other attributes you'd be putting in there and so would already have whatever you'd use the class reference for... Anybody?? - Anon

Well, it can be used as a prettier syntax for thinks like the Zope component architectures implements(Interface), instead of for example __implements__ = (Interface). Although that's possible in Python as well (obviously as Zope runs on Python) but only involving some heavy magic using metaclasses and modification of locals(). - Lennart Regebro

You can print the class name in Python, try this in your class definition body: print inspect.getframeinfo(inspect.currentframe())[2] - truppo

@truppo: Sure, but the name isn't useful, you need that class object so you can modify it. - Lennart Regebro

This is still the feature in Ruby I miss most in Python. So I accept this as an answer, so Stack overflow stops nagging me that I should accept an answer. :) - Lennart Regebro

instead of typing puts self can we use puts 'Kaka' - Sriram

19

[+5]
[2009-07-11 13:24:40]
rasjani

Python has docstrings and ruby doesn't... Or if it doesn't, they are not accessible as easily as in python.

Ps. If im wrong, pretty please, leave an example? I have a workaround that i could monkeypatch into classes quite easily but i'd like to have docstring kinda of a feature in "native way".

(3)
doesnt have docstring, but, does have RDoc. So yes, not as easily accessible, but not 100% hidden. - Omar Qureshi

Ruby does not use docstrings. It does documentation in a different way. - Chuck

(1)
Omar: yes, i know about rdoc but afaik, they are not "as accessible" as as python's docstrings. For example, if i have a class and i want to output the rdoc documentation from within the class its pretty hefty job. What i have done is that i generate ri documentation which i try to keep up2date and then fetch that info vi ri itself. Definetly not up to the same level as python's docstrings.. - rasjani

Docstrings can be used to provide doctests. Is there something like that for Ruby? - Lennart Regebro

(2)
Yes, it's called "Ruby Doctest". As far as doctests are concerned, all that really matters is that you have readable documentation somewhere that includes testable code snippets -- it doesn't make a difference whether it's in a docstring or in a comment. - Chuck

Yeah, actually you are right, it doesn't matter for the doctest. - Lennart Regebro

You can read Python's docstrings in the interactive interpreter with the 'help' built-in. I.e. each piece of code that provides docstrings automatically provides interactive help. - ThomasH

ThomasH: same sort of behaviour is infact available in ruby but what the missing feature that ruby doesnt is to have easy access to that same information during the execution of the code without first generating the "ri" documentation and querying from there.. - rasjani

20

[+5]
[2009-07-11 15:01:16]
fortran

Ruby has sigils and twigils, Python doesn't.

Edit: And one very important thing that I forgot (after all, the previous was just to flame a little bit :-p):

(6)
Well, if you want to go down that road: both are Turing-complete. Everything else is just syntax. - Jörg W Mittag

Yes and a importax syntax difference ;-) - fortran

(1)
How is it important if you write @foo or self.foo? - Lennart Regebro

(1)
@Jörg: OK, call it something else than "syntax" then. The point is that @foo and self.foo does the same thing, it's not actually a functionality Ruby has and Python doesn't. - Lennart Regebro

@Lennart, The sigils are an annoying thing that Ruby has and Python hasn't :-p - fortran

@fortran: which is a matter of taste. - Lennart Regebro

@Lennart is a matter of readability, giving funny meanings for symbols when you can live perfectly without them only complicates things. - fortran

The word I'm looking for is "semantics" I think. It's just a name. If you think @foo or self.foo is more readable is still a matter of taste. I like the explicitness of self, and the way it make methods and functions be the same thing. Still, matters of taste. - Lennart Regebro

I would also faviour conceptual differences of the languages for this question, rather than "pure" syntactial differences. What language construct does one language have and the other doesn't? But then, it's not so easy to draw the line. E.g. do standard libraries count? Does Python's 'functools' count when it comes to functional programming? And some "syntactic sugar" can make a whole lot of a difference in ease of reading and writing code. So I would be interested to learn what "sigils" and "twigils" are, and which impact they have on the code being written. - ThomasH

They are just those annoying (from my point of view, of course) symbols (one in case a of a sigil, two in case of a twigil) that you have to preppend to variable names to indicate it's type, scope or whatever was thinking the designer (depending on the language those meanings change and usualy are completely arbitrary, so that's why I don't like them). - fortran

Larry once claimed that Ruby has twigils, but if it does, I've never seen them used. I think that Larry might have meant that Ruby has sigils that indicate scoping, and that in Perl 6, twigils would be used for this same purpose. So essentially, Ruby has sigils, but not twigils. - Bob Aman

how do you call this @@? it seems a twigil to me - fortran

21

[+5]
[2009-07-11 20:57:24]
Pinochle

Ruby has a line by line loop over input files (the '-n' flag) from the commandline so it can be used like AWK. This Ruby one-liner:

ruby -ne 'END {puts $.}'

will count lines like the AWK one-liner:

awk 'END{print NR}'

Ruby gets feature this through Perl, which took it from AWK as a way of getting sysadmins on board with Perl without having to change the way they do things.

(1)
I'd like to add that Python's command line support is rather weak. Besides the missing automatic loop you cannot put a couple of statements in a single line and pass it as a single-string command line argument to the interpreter. At least I failed to do so. - ThomasH

Of course you can. But you will (as with any otehr language) need to enclose is in quotes. - Lennart Regebro

Python is not made to be used on the commandline, since you have to be explicit about some things (like sys.stdin) if you want to use it that way python -c "import sys; print len(list(sys.stdin))" - u0b34a0f6ae

22

[+5]
[2009-07-16 17:53:47]
Scott Dugas

My python's rusty, so some of these may be in python and i just don't remember/never learned in the first place, but here are the first few that I thought of:

Whitespace

Ruby handles whitespace completely different. For starters, you don't need to indent anything (which means it doesn't matter if you use 4 spaces or 1 tab). It also does smart line continuation, so the following is valid:

def foo(bar,
cow)

Basically, if you end with an operator, it figures out what is going on.

Syntax is not a minor thing, it has a direct impact on how we think. It also has a direct effect on the rules we create for the systems we use. As an example we have the order of operations because of the way we write mathematical equations or sentences. The standard notation for mathematics allows people to read it more than one way and arrive at different answers given the same equation. If we had used prefix or postfix notation we would have created rules to distinguish what the numbers to be manipulated were rather than only having rules for the order in which to compute values.

The standard notation makes it plain what numbers we are talking about while making the order in which to compute them ambiguous. Prefix and postfix notation make the order in which to compute plain while making the numbers ambiguous. Python would already have multiline lambdas if it were not for the difficulties caused by the syntactic whitespace. (Proposals do exist for pulling this kind of thing off without necessarily adding explicit block delimiters.)

I find it easier to write conditions where I want something to occur if a condition is false much easier to write with the unless statement in Ruby than the semantically equivalent "if-not" construction in Ruby or other languages for example. If most of the languages that people are using today are equal in power, how can the syntax of each language be considered a trivial thing? After specific features like blocks and inheritance mechanisms etc. syntax is the most important part of a language,hardly a superficial thing.

What is superficial are the aesthetic qualities of beauty that we ascribe to syntax. Aesthetics have nothing to do with how our cognition works, syntax does.

This "comment" is three times as long as what's allowed in a comment, regardless of rep. - Andrew Grimm

This actually seems fine as an answer to me. Edited out the "this is a comment" bit. - Bill the Lizard

AFAIK Ruby has only positioned arguments because b=2 in the function declaration is an affectation that always append.

(3)
what does "Ruby has only positioned arguments because b=2 in the function declaration is an affectation that always append" even mean? - horseyguy

(3)
Dunno what planet you live on, but def my_method(param1, optional = false) works in Ruby 1.8.6, 1.8.7, and presumably 1.9! - Robert K

(5)
The Wicked Flea, and people that upvoted his comment, you didn't look at the example close enough. He's able to skip the b parameter in the func call and it still maintains its default. That is, b is the second argument in the signature, but he can skip it by prefixing the second parameter with c=. Ruby uses hashes to simulate this, but it's not exactly the same. - maček

25

[+3]
[2009-07-13 17:06:35]
MikeIsGo

Surprised to see nothing mentioned of ruby's "method missing" mechanism. I'd give examples of the find_by_... methods in Rails, as an example of the power of that language feature. My guess is that something similar could be implemented in Python, but to my knowledge it isn't there natively.

Python has get_attribute, which accomplishes basically the same thing as Ruby's method_missing. - mipadi

(3)
Why do python developers always get so butt hurt when ruby is mentioned ANYWHERE? You can't deny this isn't true. - aarona

method_missing can be emulated in Python in some cases: class M(): def __getattr__(self, n): return lambda: "Missing! " + n; M().hi(). However, there are slight differences and I doubt it's idiomatic in Python :-) - user166390

(1)
@DJTripleThreat: I deny that it is true. - Lennart Regebro

26

[+3]
[2009-12-30 17:45:19]
dormsbee

Another difference in lambdas between Python and Ruby is demonstrated by Paul Graham's
Accumulator Generator
[1] problem. Reprinted here:

Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i.
Note: (a) that's number, not integer, (b) that's incremented by, not plus.

Some folks might prefer the explicit Python approach as being clearer conceptually, even if it's a bit more verbose. You store state like you do for anything else. You just need to wrap your head around the idea of callable objects. But regardless of which approach one prefers aesthetically, it does show one respect in which Ruby lambdas are more powerful constructs than Python's.

[1] http://www.paulgraham.com/accgen.html

(3)
You can't increment numbers in Python, so that restriction makes no sense. In Python numbers are immutable. If we change it to "plus" instead, the class is unnecessary. Hence this doesn't demonstrate anything about the lambda difference, but the difference in how numbers work. Unless of course you create a mutable number class. :) - Lennart Regebro

(2)
The restriction is there to clarify the desired behavior. What the problem is asking for is: f = foo(10) f(2) >> 12 f(3) >> 15 ... lambda {|i| n + i } gives: f = foo(10) f(2) >> 12 f(3) >> 13 ... Numbers are immutable in Ruby as well -- you can't say 2 += 1 for instance. And n+=1 is fine in a regular Python function, but not a lambda. So it's a matter of what "n" is, the fact that it's created when the function is invoked and the lambda formed, that you can do assignment in a lambda (instead of just expressions), and that it can hold the value of n over multiple calls. - dormsbee

I don't think you need to go to such lengths in Python. Functions can be defined within other functions. def foo(n): def f(i): return n + i return f. - FMc

(2)
It's still not the same though, and your example is equivalent to the Python lambda in the comment above. The Ruby version creates a lambda which keeps state between calls. The example you posted lets you configure a starting value for n, but the function that foo returns will always have that start value. The Ruby version increments. So let's say f = foo(10). The Python version: f(1) => 11, f(1) => 11. The Ruby version f.call(1) => 11, f.call(1) => 12. - dormsbee

@JF: Nice! I didn't realize you could do that. Thank you. Can you do straight up assignments in lambdas in Python3? I realize you just demonstrated it as a function, but I'm a lazy typist. ;-) Thanks again. - dormsbee

@dormsbee: Assignment is a statement so you can't use it in lambdas (single expression). btw, if you use @full name: syntax then full name SO user is notified about your comment. - jfs

And in fact, you can do exactly the same thing in python as in the ruby example: def foo(n): return lambda i: i+n. f = foo(3); print f(7.0) will print 10.0. This answer do not demonstrate any difference at all. - Lennart Regebro

@Lennart Regebro: It's not the same. Because with the code you've posted, invoking f(7) and then f(1) gives you 4. The point of the Accumulator problem is that it keeps state. So f(7) would give 10, but then saying f(1) after it would give 11. J.F. Sebastian's answer shows a way to get that functionality in Python without a wrapper class, though he still doesn't use a lambda because assignment can't happen in Python lambdas. I'm not claiming it's earth shattering power, but it is a difference in the way the languages treat lambdas. - dormsbee

@dormsbee: OK, gotcha. Probably got it the first time I saw this as well. :) In any case it's not a difference in the lambdas, really. In Python assignments being a statement, and not an expression, return nothing, so even if n+=i was allowed in lambdas, it would return None. - Lennart Regebro

27

[+2]
[2009-07-16 15:46:57]
ko-dos

Ruby has embedded documentation:

=begin
You could use rdoc to generate man pages from this documentation
=end

(5)
The docstrings end up as a part of the methods/classes you set them on. So you can do help(class) and it will show you the docstrings, etc. - Lennart Regebro

This should rather have been a comment, not a new answer. - Lennart Regebro

30

[+1]
[2010-11-05 08:06:14]
user166390

I like the fundamental differences in the way that Ruby and Python method invocations operate.

Ruby methods are invoked via a form "message passing" and need not be explicitly first-class functions (there are ways to
lift methods
[1] into "proper" function-objects) -- in this aspect Ruby is similar to Smalltalk.

Python works much more like JavaScript (or even Perl) where methods are functions which are invoked directly (there is also stored context information, but...)

While this might seem like a "minor" detail it is really just the surface of how different the Ruby and Python designs are. (On the other hand, they are also quite the same :-)

One practical difference is the concept of method_missing in Ruby (which, for better or worse, seems to be used in some popular frameworks). In Python, one can (at least partially) emulate the behavior using __getattr__/__getattribute__, albeit non-idiomatically.

Really, the difference isn't as great as you describe. Ruby has closures (functions + contexts) all over, the difference is mostly how to get at them. You mentioned lifting methods in Ruby, but really the do / end blocks are far more pervasive an idiom. (Many people don't realize they're making a lambda function at first.) Another way of putting it: Ruby makes lambdas easy but function passing a bit awkward; Python makes function passing easy, but lambdas a bit awkward. - Benjamin Oakes

31

[0]
[2011-02-24 18:43:50]
David

The nested lexical scope example that someone gave gives several benefits.

"Safer" globals

It is one method to embed DSL's into your program.

I think that is a very good example of the differences between the two languages. Ruby is simply more flexible. Python can be flexible, but you often have to do extreme contortions to get there, which makes it not worth the hassle.

Sorry for not posting under the original answer, I guess I don't have privileges to do that.

32

[0]
[2011-04-06 02:32:44]
manu

More about Ruby's blocks

It has being suggested that Ruby's blocks may be "substituted" by Python's context managers. In fact, blocks allow more than Python's context managers can do.

The receiving method of a block could execute the block within the context of some object, thus allowing the block to call methods otherwise unreacheable. Python's generators can't do that either.

Once that lambda is invoked, global is out of scope, but you can set it(only once in this example) and then access it anywhere in your program. Hopefully the value of this is clear.

Creating a DSL is much easier in Ruby than in Python. Creating something like Rake or RSpec in Python is possible but what a nightmare it would be. So to answer your question Ruby has much more flexibility than Python. It is not at the flexibility level of Lisp, but is arguably the most flexible OO language.

Python is great and all but it is so stiff compared to Ruby. Ruby is less verbose, more readable(as in it reads much closer to a natural language), python reads like english translated to french.

Python is also annoying in that its community is always in lock-step with Guido, if Guido says that you don't need feature X, everyone in the community believes it and parrots it. It leads to a stale community, kind of like the Java community that simply can't understand what anonymous functions and closures buy you. The Python community is not as annoying as Haskell's, but still.

(1)
"You can get a reference to any method and pass that around." has always been true for python. And the thing you call Singleton methods, too. As for annoying communities, well..... - Marco Mariani

Noone mentioned singleton methods because you can do exactly the same thing in Python, so there is no difference. No, the value of what you call "easy nested lexical scope" compared to what you do in Python is not obvious. In fact, the only correct thing I can see in your answer above is that Python indeed do not have a switch statement. I'm not convinced using "elif"s is any less readable, though, but that's a matter of opinion, of course. With regards to the community, you are dead wrong. - Lennart Regebro

34

[-3]
[2011-01-30 01:15:14]
Harry Matsumoto

Ruby gets inheritance right with Single Inheritance

Ruby gets inheritance right with Single Inheritance! Needing to use multiple inheritance to express domain relationships is a symptom of an improperly designed system. The confusion multiple inheritance creates isn't worth the added functionality.

Say you have a method called kick:

def kick
puts "kick executed."
end

What if kick is defined in both class Ninjutsu and class Shaolin? Multiple Inheritance fails here and that's why Python fails:

In Ruby if you need a Ninja, you create an instance of the Ninja class. If you need a Shaolin master, you create an instance of the Shaolin class.

ninja = Ninjutsu.new
ninja.kick
or
master = Shaolin.new
master.kick

Ruby gets inheritance right with Mixins

There might be the off chance that both a Ninja and a Shaolin master share the same kick technique. Read that again - both share the same behavior - nothing else! Python would encourage you to roll a whole new class. Not with Ruby! In Ruby you simply use a Mixin:

This is in no way the biggest difference; I'm sure people rarely use MI in Python at any rate. I'd be more inclined to look at open classes, metaclasses all the way down, blocks, freer syntax ... - Asherah

(1)
"Multiple Inheritance fails here" No it doesn't. "The confusion multiple inheritance creates isn't worth the added functionality." I've worked with Zope and Plone for ten years, it uses loads of Multiple inheritance, and there has never once been any confusion. "In Ruby you simply use a Mixin:" And how is that different from using a mixin class? Oh, right, it isn't. So the difference is that Python has multiple inheritance and Ruby hasn't. Framing it as Ruby gets it right goes from stating a difference to silly religious wars. - Lennart Regebro

35

[-4]
[2009-07-11 13:56:01]
wr.

While the functionalty is to a great extent the same (especially in the
Turing
[1] sense), malicious tongues claim that Ruby was created for Pythonistas that could not split up with the Perlish coding style.

[1] http://en.wikipedia.org/wiki/Turing_completeness

(14)
Actually, it was created for Smalltalkers that want to break out of the image. - Jörg W Mittag