Should I Learn Python or Ruby?
github.com
github.com
Seriously. They are relatively equivalent.
I'm a Python person and ex-Perl and ex-Tcl refugee.
If you're doing scientific stuff, use Python. It's got a great community around that. Web is probably a wash--Ruby/Rails is a canonical combination, but Python/Django somehow manages to impress me every time I touch it.
However, if you're doing web stuff, I'd probably go for Javascript nowadays on both server and client side.
I can handle a bunch of languages: Scheme, Erlang, Scala, Clojure, Lua, Javascript ... but when I just need to bang out code I tend to grab Python.
Ruby and Python are also similar enough that while there are a ton of differences they won't be difficult to digest.
I learned Perl in the CGI days of the mid-90's and never even continued on to PHP. As a network consultant now, I find Perl to be immensely helpful, when it comes time to script some monitoring or automated activity.
That said, a fellow networker had mentioned that many others had been switching. Most of my days are not spent programming, but I do occasionally bust out a project or two. Is it worth my time to make the switch?
Deliberate. I'll put my story below my advice so as not to bore the masses.
If you're good at Perl, it's probably not worth the time to make the switch until you have to. Python isn't sufficiently "better" to warrant the time investment required. The only caveat to that statement would be in two different cases: 1) your scripts have lifetimes longer than a few dozen months or 2) you have a a larger body of programmers who need to understand and modify your scripts.
WARNING! HORRIBLY BIASED OPINION INCOMING!
Perl 4/5 tended to create a weird problem in programmers in my experience. Everybody "learned" Perl, but everybody "learned" a different ... dialect, for want of a better word. So, when two Perl programmers got together to read a program, at least one of them was learning new corners of the language. Or one of them was remembering pieces that he had long forgotten. I was on all sides of that issue. It was so bad that eventually when I interviewed for VLSI jobs, I would bring along a nice piece of Perl code I had written, so that I would be discussing Perl on my terms instead of that of the interviewer. That cut short a lot of the "do you know Perl?" idiot questions.
So, what I found after I made the Python switch (I won't claim that I was prescient enough to realize beforehand), was that 1) I could come back to my scripts after 2 years and still understand them and 2) all the Python programmers seemed to pretty much wind up programming sort of the same way. For me, that cemented that I would never go back to Perl. Even after not programming in Python for a few months, I could go right back to it. A few months off from programming in Perl and it would take a couple of weeks to get back up to speed. Python just seems to have a smaller mental model--Perl aficionados would cite that as an inferior mental model. Shrug. I'm not a genius so I'll stick with the smaller mental model, thanks.
Back to why I switched. My reasons were both petty and selfish. :)
I wrote a lot of Perl scripts as a VLSI designer. A lot of munging data from this format to that format. Check that thing over there. Merge it with this thing with undocumented formats. Consequently, my scripts tended to have 1) lots of subtle edge cases and 2) lifetimes often measured in years because the effort to do it right is both enormous and highly specialized. (I had someone email me about a script I wrote 14 years ago early this year that reads formats that are over 30 years old!)
The problem was that I kept tripping over bugs--and nobody could explain to me what was going on. About 2/3 or the bugs were mine but required Perl near-gods to diagnose, 1/6 of the bugs were weird grammar edge cases in Perl, and 1/6 were actual bugs in Perl. This was in the 1994 to 1996 timeframe around the Perl 4 to Perl 5 transition (yeah, I've been doing this that long).
The bug which finally convinced me it was time to leave (there were many, but this was the last straw) Perl was when I wrote a program to merge static timing analysis cards from 3 different sites (3 different formats, naturally). 99.9% of the time it worked, but sometimes it would just die. I finally tracked it down to a bug in Perl 4, the Regex engine would do weird things if you fed it a pattern with 512 characters exactly. 511 and it worked. 513 and it worked. I sighed. Pulled down Perl 5 instead knowing things had been pretty much completely rewritten. And tripped over a different bug in the regex engine. Started looking for a new scripting language that day.
Pretty much the only options at that point were Tcl, Scheme, Lisp or Python at that point. I had abandoned Tcl (pretty much the standard for scripting in VLSI/EDA) for Perl originally because it was a similar disaster until the 8.0 rewrite. Scheme and Lisp were just starting to integrate the fact that Unix wasn't just a tiny blip until we got back to a real operating system so they had better start supporting operating system integration.
So, that left Python. Horrible whitespace dependency and all. :)
I'm kind of surprised that almost 20 years later I'm still using the same programming language. I really expected something significantly better to come along. Scala, Erlang, and Clojure all have made a good case--but they don't really bring anything to the table that warrants me switching completely in the general case. Scala was WAY too much mental model inload for me. Erlang didn't handle dynamic hash tables well enough for the amount of time you use them in programming (I tell my classes--70% of the time use a hash table; 30% of the time use a vector). Clojure was quite nice and probably made the best case, but it just wasn't better enough than Python for me to spend the time making it my primary language.
Side note: dynamic hash tables just hit Erlang THIS MONTH. So, that's probably not a good reason anymore.
Now, betcher sorry you asked that question, arn't cha? :)
What? Erlang's hashtables are called `ETS` and `DETS` and have been there since at least 1997.
What I believe you are referring to are `maps`, which while they have the syntax of scripting languages' hashes, are nothing but trees. Access is far from constant time. Then again Erlang had these a while ago. They are just adding syntax sugar and pattern matching.
Maps are what people coming from other languages expect to see, and I wanted to point out that now Erlang has them.
Argh, I hate the "learn both" conclusion. It doesn't help anyone.
If doing web programming? Ruby (+Rails).
Desktop / scientific computing? Python
As a general heuristic, just look at the types of projects you want to build and what they're built in. Then use that.
> Usage
> Python can be used for web development, sys admin, statistics, and scientific computation. Meanwhile, Ruby is used primarily for web development. Python has the upper hand here, but if you are looking to only do web development, Ruby is the way to go.
As the grandparent said, it really depends on your goals.
I wouldn't use either Chef or Puppet today for a greenfield project.
If you elect to go with puppet or chef, be prepared to use something as an orchestration tool compliment the configuration management. Ansible and Salt can both be used as orchestrators to compliment a puppet or chef based configuration.
Of course, if you're deploying something simple, it makes no difference what you use. They will all handle package installs, config file templating and service management. In this case, Ansible/Salt are probably better as they will contain the orchestration features.
Unless you are an engineer in school, diving straight into Python may not be the best option. Also, many people just learn Ruby to do Rails as well. This is shown with the infinite number of rails bootcamps popping up all across the country.
TL;DR The majority of people asking this question are probably new in general to programming and looking to do some web programming so learn Ruby in view to Rails.
I disagree. Python generally reads much more like English than Ruby.
Ruby:
a && b # `and` is available but is generally not recommended due to operator precedence
Python:
a and b
Ruby:
a = b ? c : d
Python:
a = c if b else d
Ruby:
"abc" =~ /[a-z]{3}/
Python:
re.match(r"[a-z]{3}", "abc")
Ruby:
[1,2,3].map { |n| n + 5 }
Python:
[n + 5 for n in [1,2,3]]
Ruby also encourages operators and sigils that would be quite confusing to brand new beginners, like `||=`, `@`, `@@`, as well as Perl special variables ("what the hell are $/ $* and $&?").
For && vs and, by the time you hit the need to differentiate those in ruby, you'll likely be at the port of operator precedence being a thing that is understandable.
The ternary operator shouldn't even come into play for a beginner in my not so humble opinion ruby/c/c++ or not.
Instead of using the ternary, for ruby i'd be advocating more:
a = if some_truthy_operation/variable
c
else
d
end
Way more verbose sure, but then when they get the hang of that, they can start to learn when the ternary operator is useful, if even. Generally I avoid it.For the regexp match, I'd rather show them "abc"[/[a-z]{3}/]. That makes a short leap into the === operator and all its varied uses. But to be more close you could also do /[a-z]{3}/.match("abc"), this is admittedly half a dozen of one 6 of the other.
I got nothing for the map bit, but I also know smalltalk so admittedly I'm going to be biased. :)
That said both Python and Ruby have good uses. I'm converting a bunch of my own Ruby stuff to Python for work, and the rest to good old C. So I'm biased, but generally don't give a shit. :D I'd be looking for more information on the background of the person learning and what they want to achieve from programming.
In the end, learning any language, I'll even begrudgingly include PHP in there (just picking on you guys) is a good thing.
They're low priority in both languages. I use and see others using `and` and `or` all the time. In 15 years I can't say I've blown my foot off yet.
> Ruby: a = b ? c : d
If I'm really wanting a oneliner I'll tend to write
a = if b then c else d end
You can of course spread it across a few lines: a = if b
c
else
d
end
More typically it's constructs like: a ||= b
a = b if c
a = b unless c
> Ruby: "abc" =~ /[a-z]{3}/ /[a-z]{3}/.match("abc")
If you prefer.But if they read some Python code that a seasoned veteran wrote, they're a lot less likely to see anything particularly confusing.
I think Ruby does generally look more elegant, but if I was a beginner again I sure as hell would have a much easier time reading Python code compared to Ruby code.
unless
...
else
... fib = lambda do |n|
return n if n < 2
fib[n-1] + fib[n-2]
end
puts fib[8]To say a Ruby programmer would create a Hash object that uses a block instead of write a function seems plain wrong, despite how the algorithm for generating items was implemented.
http://docs.python.org/3/library/functools.html#functools.lr...
What? I just started learning Ruby, and I intend to do some sys-admin tasks also. Am I going down the wrong path?
I know Homebrew is using Ruby as base language, and doing pretty fine.
Is this misleading or what?
Older systems frequently use Perl (for example, ticketing systems like RT or OTRS), or even older systems use Tcl.
Sysadmin tools are a tossup, driven mainly by whatever the rest of the ecosystem uses.
I don't think so. Ruby has for me replaced bash scripting along with sed, awk, and Perl. It's nice to do all these things with one consistent syntax. And be sure to check out Pry (http://pryrepl.org/)!
I'll give Python another look once v3 catches on.
Python is stricter and more explicit. Ruby has many convenience functions that I consider messy and some even dangerous. E.g. Ruby supports the same ` `-Syntax as the Unix shell, with all it's implications.
So in Ruby you could do:
output = `/some/app #{arg}`
And in Python you would do this: import subprocess
output = subprocess.Popen(["/some/app",arg],stdout=subprocess.PIPE).stdout.read()
Yes, it's more to write but it's more powerful and you don't have code injection problems. It feels to me that Python encourages you to do the proper clean thing while Ruby tries to be very concise and quick.Also compare regular expressions.
Ruby:
if "foo" =~ /f(oo)/
puts $1
end
Oh my god, it assigns a global(?)/magic variable as a side effect. Yes, there are other ways to do it and when I write Ruby code I am using these other ways, but when I see other peoples Ruby code its done like that. I do this: match = /f(oo)/.match("foo")
if match
puts match[1]
end
Python: import re
match = re.match("f(oo)","foo")
if match:
print(match.group(1))
If you evaluate the regular expression more than once you should compile it: import re
regex = re.compile("f(oo)")
match = regex.match("foo")
if match:
print(match.group(1))
Again in Python you tend to write it the clean way. Of course it's possible to write non-clean Python code and clean Ruby code, but the culture behind the languages encourage different things. You will find a lot of Ruby libraries/frameworks that extend (monkey patch) standard types. While this is also possible in Python (for non-builtin/-binding types) it is usually not done. Look at JavaScript: Prototype monkey patched a lot of standard types and messed up a lot. jQuery learned from that and tries not to monkey patch anything.Another issue is string encodings. Note that what I write here applies to Python 3. It's a bit more complicated/less clean in Python 2.
The idea in Python is that files/network streams etc. are binary data and thus somehow encoded. But you as a programmer don't care about encodings, you want to manipulate text (or sequences of unicode code points). So you read bytes and decode them into str(ing)s. After you are done processing the text you encode with a certain encoding again and write the bytes into the file/network stream. So there is the bytes (and bytearray) class that has a decode method and there is the str class that has an encode method. str objects are always valid unicode codepoint sequences. Encoding errors can only happen on decode/encode.
In Ruby there are only Strings. These strings have an encoding attached. Binary data has the "encoding" ASCII-8BIT. You can force a wrong encoding onto a string which will cause an InvalidByteSequenceError at some later point. If you try to concatenate two String objects that have a different encoding you will get a CompatibilityError. You can only hope that all your DB drivers return proper UTF-8 strings in all cases. I was told even Perl does this better (like Python).
Furthermore in Ruby strings are mutable, in Python they are immutable. This means if you get a string passed in Ruby and want to store it in a classes attribute and want to be sure it does not change under your but you have to make a copy.
So you can clearly see what language I think is cleaner. I write Ruby code for work but when I write some shell script to automate some task/write some small GUI tool I use Python (and PyQt).
Magic locals. You weren't actually unsure if they were global, right?
Ew, I didn't realise JS had them and implemented them like that. It's supposed to remind you of Perl, which probably made more sense 20 years ago.
> It get's confusing. And even as a local it is still bad. How is it that the =~ operator can assign local variables? Can other method calls do the same? If not, why not?
Actually, they're not locals, they're "virtual variables", going by the code. You can make your own using the C API - they just call back into a function:
rb_define_virtual_variable("$&", last_match_getter, 0);
Same way things like $LOADED_FEATURES, $_ and $SAFE get managed. It's probably just as well it's not exposed Ruby-side ;)Definitely!
Anecdotally, it was far easier for me to get a simple web app up and running with rails than it was with django, but this has much more to do with the resources I had available to me (like the ones I mentioned earlier) that walked me through rails that I didn't have for django.
At the end of the day, programming logic is all the same. If you understand how an algorithm works and have a solid knowledge of at least one language, you're all set.
Baptism by fire, baby.
Now get out of my yard.
video: http://www.youtube.com/watch?v=SNbBC2pSiVw
slides: https://speakerdeck.com/nuclearsandwich/sugar-free-ruby
Otherwise, python is probably more versatile