views:

13988

answers:

32

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)

Or

def function(here):
    many=lines+of+code
    goes(here)

amethod(function)     # `function` is a callback

Interestingly, the convenience statement in Ruby for calling a block is called "yield", which in Python will create a generator.

Ruby:

def themethod
    yield 5
end

themethod do |foo|
    puts foo
end

Python:

def themethod():
    yield 5

for foo in themethod():
    print foo

Although the principles are different, the result is strikingly similar.

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

myList.map(&:description).reject(&:empty?).join("\n")

Python:

descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))

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

docs.python.org has this generator example:

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

Contrast this with the above block examples.

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.

def frobnicate(bar):
    """frobnicate takes a bar and frobnicates it

       >>> bar = Bar()
       >>> bar.is_frobnicated()
       False
       >>> frobnicate(bar)
       >>> bar.is_frobnicated()
       True
    """

Ruby's equivalent are similar to javadocs, and located above the method instead of within it. They can be retrieved at runtime from the files by using 1.9's Method#source_location example use

Python has more libraries

Python has a vast amount of available modules and bindings for libraries.

Python has multiple inheritance

Ruby does not ("on purpose" -- see Ruby's website, see here how it's done in Ruby). It does reuse the module concept as a type of abstract classes.

Python has list/dict comprehensions

Python:

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

Ruby:

res = (0..9).map { |x| x * x }

Python:

>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7c1ccd4>
>>> list(_)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Ruby:

p = proc { |x| x * x }
(0..9).map(&p)

Python 2.7+:

>>> {x:str(y*y) for x,y in {1:2, 3:4}.items()}
{1: '4', 3: '16'}

Ruby:

>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}

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

+5  A: 

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:

def 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.

Lennart Regebro
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
what is the use case?
SilentGhost
@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
@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
@Anon: Still not in the class body...
Lennart Regebro
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
+24  A: 

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

Then you can invoke this like so:

# Add five to each element.
[1, 2, 3, 4].each{ |e| puts e + 5 }
> [6, 7, 8, 9]

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.

John Feminella
That last line would in Python be [print e+5 for e in [1,2,3,4]] so this example is unclear. It looks like Python has it...
Lennart Regebro
@Lennart: apart from your example just beeing horrible it is syntactically wrong, too.
unbeknown
@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
@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 [email protected] I'm not saying it's equivalent, I'm saying it's not obvious what the difference is from your [email protected], 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
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
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
Readded it. :-)
Lennart Regebro
Those are just anonymous functions. Why try to give them another name and pass as something new?
RommeDeSerieux
@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
@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
@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
@zgchurch: sinatra is nice; look at web.py http://webpy.org/
J.F. Sebastian
@RommeDeSerieux: They're anonymous functions, yes, but the difference from Ruby blocks and Python lambdas is that blocks are not first-class citizens. Contrary to the "everything is an object" philosophy that seems to otherwise pervade Ruby, blocks are not objects and you have to box them and unbox them. For some interesting details see http://innig.net/software/ruby/closures-in-ruby.rb and http://stackoverflow.com/questions/2946603/ruby-convert-proc-to-lambda
Vojislav Stojkovic
@Vojislav Stojkovic: Thanks, i didn't know that. What do you think, that peculiarity of blocks a good thing?
RommeDeSerieux
+5  A: 

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".

rasjani
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
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
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
+9  A: 

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.

These are mostly shared with Perl. First-class built-in regular expressions, $-Variables, useful command line options like Perl (-a, -e) etc.

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.

haffax
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
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.
The Wicked Flea
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: http://www.zenspider.com/Languages/Ruby/QuickRef.html#17It 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
A: 

Ruby has ugly syntax, Python does not. :P

Jani Hartikainen
You fail at reading the question.
Lennart Regebro
I think he knew that ... ;-)
behindthefall
And he's damn right xD
fortran
not appropriate!
rubiii
Beauty is obviously in the eye of the beholder.
Greg
A: 

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

wr
Actually, it was created for Smalltalkers that want to break out of the image.
Jörg W Mittag
+9  A: 

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.

Chuck
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
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
@Lennart: Multiline blocks are used all the time in Ruby -- more often than I see lambdas used in idiomatic Python code, actually. For a common example, see http://info.michael-simons.eu/2007/08/06/rails-respond_to-method/.
Chuck
Since I'm not a Ruby programmer, I'm glad Chuck responded. While looking out there for examples, I found this interesting proposal for Ruby-style blocks in Python: http://tav.espians.com/ruby-style-blocks-in-python.html
Anon
@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
@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
blocks can also be used to implement lazy evaluation
banister
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
+12  A: 

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.

For example, Ruby:

>> PI = 3.14
=> 3.14
>> PI += 1
(irb):2: warning: already initialized constant PI
=> 4.14

Python:

>>> PI = 3.14
>>> PI += 1
>>> PI
4.1400000000000006
Jason Baker
Do you like this(python) way of thinking yourself? Just curious.
Dykam
*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
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
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.
musicfreak
@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. :)
musicfreak
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
@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
-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
@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
@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
+3  A: 

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):

Python has a JIT compiler (Psyco), a sightly lower level language for writing faster code (Pyrex) and the ability to add inline C++ code (Weave).

fortran
True, but that's just syntax.
Lennart Regebro
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
How is it important if you write @foo or self.foo?
Lennart Regebro
@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
+6  A: 

Ruby has builtin continuation support using callcc.

Hence you can implement cool things like the amb-operator

Dario
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
"Funky CS stuff" is real. Take some time to learn: http://intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons
Stephen Eilert
+8  A: 

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 }
Dario
Can you give code examples?
Lennart Regebro
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
well, too bad for Ruby
SilentGhost
???????????????
Dario
Python: res = map(lambda x: x*x, range(1,10))
GogaRieger
Python: `res=map(2 .__rpow__, range(1,10))`
gnibbler
+6  A: 

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.

Lennart Regebro
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
FWIW, it seems that in Python, functions and methods are actually the same type, and their different behavior comes from descriptors: http://users.rcn.com/python/download/Descriptor.htm#functions-and-methods.
Bastien Léonard
@Logan, @Geo: Ugh... Thanks for the answers.
Lennart Regebro
-1 Ruby has bound and unbound functions. Too much Ruby confusion!
bias
@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
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
+8  A: 

Some others from:

http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-python/

(If I have misintrepreted anything or any of these have changed on the Ruby side since that page was updated, someone feel free to edit...)

Strings are mutable in Ruby, not in Python (where new strings are created by "changes").

Ruby has some enforced case conventions, Python does not.

Python has both lists and tuples (immutable lists). Ruby has arrays corresponding to Python lists, but no immutable variant of them.

In Python, you can directly access object attributes. In Ruby, it's always via methods.

In Ruby, parentheses for method calls are usually optional, but not in Python.

Ruby has public, private, and protected to enforce access, instead of Python’s convention of using underscores and name mangling.

Python has multiple inheritance. Ruby has "mixins."

And another very relevant link:

http://c2.com/cgi/wiki?PythonVsRuby

Which, in particular, links to another good one by Alex Martelli, who's been also posting a lot of great stuff here on SO:

http://groups.google.com/group/comp.lang.python/msg/028422d707512283

Anon
In ruby you could simply freeze your array to change it to something immutable
ChaosR
Excellent post by Alex Martelli :)
Skilldrick
+16  A: 

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?

Geo
Oh, right! Python likes namespaces. Isn't that the case in Ruby? You don't `import bla; bla.foo()` in Ruby?
Lennart Regebro
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
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
I think it does. That's what I hate about Ruby modules.
Geo
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
you can selectively add in ruby: http://eigenclass.org/hiki/Rename+and+reject+methods+from+included+modules
rogerdpack
you can also use http://ruby-doc.org/stdlib/libdoc/forwardable/rdoc/index.html in Ruby
rogerdpack
+4  A: 

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.

Pinochle
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))"`
kaizer.se
+15  A: 

Python Example

Functions are first-class variables in Python. You can declare a function, pass it around as an object, and overwrite it:

def func(): print "hello"
def another_func(f): f()
another_func(func)

def func2(): print "goodbye"
func = func2

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.

def func; p "Hello" end
def another_func(f); method(f)[] end
another_func(:func)      # => "Hello"

def func2; print "Goodbye!"
self.class.send(:define_method, :func, method(:func2))
func                     # => "Goodbye!"

method(:func).owner      # => Object
func                     # => "Goodbye!"
self.func                # => "Goodbye!"    
Glenn Maynard
by that token common lisp's functions aren't 'firstclass' nor scala's...
banister
You're badly confused. First-class objects are assigned by assignment: `x = y`, not by calling `self.class.send(:define_method, :func, method(:func2))`. Your "counterexample" shows just how Ruby's functions are not first-class. If you disagree, feel free to post your own answer; don't stick your confusion in mine.
Glenn Maynard
@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
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](http://stackoverflow.com/questions/1113611/what-does-ruby-have-that-python-doesnt-and-vice-versa/1113624#1113624).
rampion
@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
@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
@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
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
@Glenn Check out the SO FAQ section "Other people can edit my stuff?!" - this is a Community Wiki.
bias
@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
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
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
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
Vojislav Stojkovic
+1  A: 

python has named optional arguments

def func(a, b=2, c=3):
    print a, b, c

>>> func(1)
1 2 3
>>> func(1, c=4)
1 2 4

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

what does "Ruby has only positioned arguments because b=2 in the function declaration is an affectation that always append" even mean?
banister
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!
The Wicked Flea
+9  A: 

"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.

Ah, right you are.
Lennart Regebro
+5  A: 

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:

  • __getattribute__ method of anObj is invoked
  • __getattribute__ retrieves anAttr object from the class dict
  • it checks whether abAttr object has __get__, __set__ or __delete__ callable objects
  • the context (i.e., caller object or class, and value, instead of the latter, if we have setter) is passed to the callable object
  • the result is returned.

As was mentioned, this is the default behavior. One is free to change the protocol by re-implementing __getattribute__.

This technique is lot more powerful than decorators.

Giorgi
+2  A: 

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
Why do python developers always get so butt hurt when ruby is mentioned ANYWHERE? You can't deny this isn't true.
DJTripleThreat
+2  A: 

Ruby has embedded documentation:

 =begin

 You could use rdoc to generate man pages from this documentation

 =end
ko-dos
hm, i thought this might fit nicely to pythons docstrings
ko-dos
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
+4  A: 

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.

Mixins

Ruby has mixins which can extend instances instead of full classes:

module Humor
  def tickle
    "hee, hee!"
  end
end
a = "Grouchy"
a.extend Humor
a.tickle    »  "hee, hee!"

Enums

I'm not sure if this is the same as generators, but as of Ruby 1.9 ruby as enums, so

>> enum = (1..4).to_enum
=> #<Enumerator:0x1344a8>

Reference: http://blog.nuclearsquid.com/writings/ruby-1-9-what-s-new-what-s-changed

"Keyword Arguments"

Both of the items listed there are supported in Ruby, although you can't skip default values like that. You can either go in order

def foo(a, b=2, c=3)
  puts "#{a}, #{b}, #{c}"
end
foo(1,3)   >> 1, 3, 3
foo(1,c=5) >> 1, 5, 3
c          >> 5

Note that c=5 actually assigns the variable c in the calling scope the value 5, and sets the parameter b the value 5.

or you can do it with hashes, which address the second issue

def foo(a, others)
  others[:b] = 2 unless others.include?(:b)
  others[:c] = 3 unless others.include?(:c)
  puts "#{a}, #{others[:b]}, #{others[:c]}"
end
foo(1,:b=>3) >> 1, 3, 3
foo(1,:c=>5) >> 1, 2, 5

Reference: The Pragmatic Progammer's Guide to Ruby

Scott Dugas
Your second example foo(1,c=5) does not do what you think it does. Ruby does not have named parameters.
banister
Thanks, I corrected the syntactic typo.
Scott Dugas
Python has *implicit line continuation* inside brackets `(`, `[` or `{`
kaizer.se
+7  A: 

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.

JonathanHayward
+10  A: 

From Ruby's website:

Similarities As with Python, in Ruby,...

  • There’s an interactive prompt (called irb).
  • You can read docs on the command line (with the ri command instead of pydoc).
  • There are no special line terminators (except the usual newline).
  • String literals can span multiple lines like Python’s triple-quoted strings.
  • Brackets are for lists, and braces are for dicts (which, in Ruby, are called “hashes”).
  • Arrays work the same (adding them makes one long array, but composing them like this a3 = [ a1, a2 ] gives you an array of arrays).
  • Objects are strongly and dynamically typed.
  • Everything is an object, and variables are just references to objects.
  • Although the keywords are a bit different, exceptions work about the same.
  • You’ve got embedded doc tools (Ruby’s is called rdoc).

Differences Unlike Python, in Ruby,...

  • Strings are mutable.
  • You can make constants (variables whose value you don’t intend to change).
  • There are some enforced case-conventions (ex. class names start with a capital letter, variables start with a lowercase letter).
  • There’s only one kind of list container (an Array), and it’s mutable.
  • Double-quoted strings allow escape sequences (like \t) and a special “expression substitution” syntax (which allows you to insert the results of Ruby expressions directly into other strings without having to "add " + "strings " + "together"). Single-quoted strings are like Python’s r"raw strings".
  • There are no “new style” and “old style” classes. Just one kind.
  • You never directly access attributes. With Ruby, it’s all method calls.
  • Parentheses for method calls are usually optional.
  • There’s public, private, and protected to enforce access, instead of Python’s _voluntary_ underscore __convention__.
  • “mixin’s” are used instead of multiple inheritance.
  • You can add or modify the methods of built-in classes. Both languages let you open up and modify classes at any point, but Python prevents modification of built-ins — Ruby does not.
  • You’ve got true and false instead of True and False (and nil instead of None).
  • When tested for truth, only false and nil evaluate to a false value. Everything else is true (including 0, 0.0, "", and []).
  • It’s elsif instead of elif.
  • It’s require instead of import. Otherwise though, usage is the same.
  • The usual-style comments on the line(s) above things (instead of docstrings below them) are used for generating docs.
  • There are a number of shortcuts that, although give you more to remember, you quickly learn. They tend to make Ruby fun and very productive.
kruczkowski
+9  A: 

Somewhat more on the infrastructure side:

  • Python has much better integration with C++ (via things like Boost.Python, SIP, and Py++) 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.

Jack Lloyd
Your second point is at best misinformed. You should start by looking at Rack and Sinatra
max ogden
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
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.
mathepic
+3  A: 

Another difference in lambdas between Python and Ruby is demonstrated by Paul Graham's Accumulator Generator 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.

In Ruby, you can do this:

def foo(n)
  lambda {|i| n += i }
end

In Python, you'd create an object to hold the state of n:

class foo(object):
    def __init__(self, n):
        self.n = n
    def __call__(self, i):
        self.n += i
        return self.n

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.

dormsbee
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
The restriction is there to clarify the desired behavior. What the problem is asking for is:f = foo(10)f(2)>> 12f(3)>> 15...lambda {|i| n + i } gives:f = foo(10)f(2)>> 12f(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`.
FM
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
`def foo(n): L=[n] def f(i): L[0] += i return L[0] return f`. In Python3 you could use `nonlocal` keyword.
J.F. Sebastian
@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.
J.F. Sebastian
+6  A: 

Shamelessly copy/pasted from: Alex Martelli answer on "What's better about Ruby than Python" thread from comp.lang.python mailing list.

Aug 18 2003, 10:50 am

Erik Max Francis wrote:
> "Brandon J. Van Every" wrote:

>> 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 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!):

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

2. 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] 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] 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...).

Alex 
OscarRyz
+1  A: 

In Ruby, when you import a file with require, all the things defined in that file will end up in your global namespace.

With Cargo you can "require libraries without cluttering your namespace".

# foo-1.0.0.rb
class Foo
  VERSION = "1.0.0"
end

# foo-2.0.0.rb
class Foo
  VERSION = "2.0.0"
end
>> Foo1 = import("foo-1.0.0")
>> Foo2 = import("foo-2.0.0")
>> Foo1::VERSION
=> "1.0.0"
>> Foo2::VERSION
=> "2.0.0"
Jonas Elfström
+3  A: 

At this stage, Python still has better unicode support

gnibbler