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.
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).
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 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.
Thanks to the callcc statement. In Python you can create continuations by various techniques, but there is no support built in to the language.
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.
myList.map(&:description).reject(&:empty?).join("\n")
Python:
descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))
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]
docs.python.org [2] 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.
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.
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 [3]
Ruby does not ("on purpose" -- see Ruby's website, see here how it's done in Ruby [4]). It does reuse the module concept as a type of abstract classes.
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"}
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.
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
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 [1].
[1] http://nicolas-lara.blogspot.com/2009/01/emulating-ruby-blocks-in-python.htmlFunctions 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 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!"
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
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
UnboundMethod
can be a PITA, tho. - rampion
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:
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.
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
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?
import bla; bla.foo()
in Ruby? - Lennart Regebro
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
From Ruby's website [1]:
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,...
[1] http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-python/
- 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.
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.
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.
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
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
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.
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 }
res=map(2 .__rpow__, range(1,10))
- John La Rooy
"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.
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.
Shamelessly copy/pasted from: Alex Martelli [1] answer on " What's better about Ruby than Python [2]" thread from comp.lang.python [3] mailing list.
[1] https://stackoverflow.com/users/95810/alex-martelliAug 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/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...).
Alex
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
I'm unsure of this, so I add it as an answer first.
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.
TheClass.instance_method(:themethod).bind(anobject).call
would be the equivalent ruby. - Logan Capaldo
Object
. - Logan Capaldo
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__get__
, __set__
or __delete__
callable objectsAs 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.
Ruby has builtin continuation support using callcc
.
Hence you can implement cool things like the amb-operator [1]
[1] http://www.randomhacks.net/articles/2005/10/11/amb-operatorAt this stage, Python still has better unicode support
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.
class
statement. - Bastien Léonard
__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
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".
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 [1]), a sightly lower level language for writing faster code ( Pyrex [2]) and the ability to add inline C++ code ( Weave [3]).
[1] http://psyco.sourceforge.net/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.
python -c "import sys; print len(list(sys.stdin))"
- u0b34a0f6ae
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:
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.
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!"
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
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
(
, [
or {
- u0b34a0f6ae
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.
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.
def my_method(param1, optional = false)
works in Ruby 1.8.6, 1.8.7, and presumably 1.9! - Robert K
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
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.
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
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.
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.
[1] http://www.paulgraham.com/accgen.htmldef foo(n): def f(i): return n + i return f
. - FMc
def foo(n): L=[n] def f(i): L[0] += i return L[0] return f
. In Python3 you could use nonlocal
keyword. - jfs
@full name:
syntax then full name
SO user is notified about your comment. - jfs
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
Ruby has embedded documentation:
=begin
You could use rdoc to generate man pages from this documentation
=end
http://c2.com/cgi/wiki?PythonVsRuby
http://c2.com/cgi/wiki?SwitchedFromPythonToRuby
http://c2.com/cgi/wiki?SwitchedFromRubyToPython
http://c2.com/cgi/wiki?UsingPythonDontNeedRuby
http://c2.com/cgi/wiki?UsingRubyDontNeedPython
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 [1] 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"[1] http://github.com/soveran/cargo
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.
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
The nested lexical scope example that someone gave gives several benefits.
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.
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.
A simple example may help:
class Proxy
attr_accesor :target
def method &block
# Ruby 1.9 or in Rails 2.3
target.instance_exec &block
end
end
class C
private
def hello
puts "hello"
end
end
p = Proxy.new
c = C.new
p.target = c
p.method { hello }
In this example the method call within the block { hello }
has it true meaning in the context of the target object c
.
This example is for illustrative purposes, only. Real working code that uses this kind of execute in the context of another object is not uncommon. The monitoring tool Godm for instance, uses it.
I am surprised that no one has mentioned Singleton methods.
a=[]
b=[]
def b.some_method do ... end
b.some_method #fine
a.some_method #raises exception
It gives granular control over the open class concept. You can also use Eigenclasses to mixin a module into a specific object instead of all objects of a given class.
o=Object.new
class << o
include SomeModule
end
Python also doesn't have a switch statement without using ugly hacks which can decrease code readability.
Ruby has no statements,only expressions. This add a lot of flexibility.
You can get a reference to any method and pass that around.
a=[]
m=a.method :map #m is now referencing an instance of Method and can be passed like any other reference to an object and is invoked with the call method and an optional block
Easy nested lexical scope giving controlled global variables.
lambda {
global=nil
def Kernel.some_global= val
global||=val
end
def Kernel.some_global
global
end
}.call
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.
Did I mention Ruby has an EPIC community of developers. Ninja theme inspired by Object Oriented Ruby: Classes, Mixins and Jedi [1].
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:
class Mortal < Ninjutsu, Shaolin
def initialize
puts "mortal pwnage."
end
end
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
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:
module Katas
def kick
puts "Temporal Whip Kick."
end
end
and simply Mixin the Katas module into your Ruby Class:
require 'Katas'
class Moral < Ninjutsu
include Katas
def initialize
puts "mortal pwnage."
end
end
Then the behavior gets shared - which is what you were really going for. Not an entire class. That's the biggest difference between Ruby and Python - Ruby gets inheritance right!
[1] http://techoctave.com/c7/posts/46-object-oriented-ruby-classes-mixins-and-jediWhile 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
has_many :things
, which would look more awkward. And things that looks like special syntax, like Ruby'srequire
(equivalent ofimport
) andattr_accessor
, are actually just method calls. - Chuckfrom 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