What do they mean when they say Ruby on Rails doesn't scale too well? What are some of the bad things about Ruby? I've heard it's pretty slow compared to PHP.
Name:
Anonymous2012-03-05 18:48
Ruby
Here's why one should be wise regarding Ruby:
- Ruby indulges obfuscation: Ruby has no keyword/optional arguments, so you'll have to use hash parameters as a substitute. This is an idiom that comes from Perl. Ugly, Perl-looking code, like proc {|obj, *args| obj.send(self, *args)} or (0..127).each { |n| p n.chr }, considered beautiful. Another confusing Perl borrowing are postfix `if` and `while` (line = file.readline while line != "needle" if valid line) and quirky variable names (partially due to naive environment design): @instance_var, @@class_var, CONSTANT_VAR, $global_var, :sym, &proc, $~[1], $!, $>, $@, $&, $+, $0, $~, $’, $`, $:, $., $* and $?. If A is [1,2,3] and B is [10,20,30], then A+B is [1,2,3,10,20,30], when you probably wanted [11,22,33]. If `a` and `b` are undefined, then "a = b" produces error, but "a = a" gives `nil`.
- Faulty syntax. Ruby cant distinguishing a method call from an operator: "a +b" can be both "a(+b)" and "a + b" - remove the space to the left of "+" or add a space to the right of "+", and it will be parsed as an addition. Same with "puts s *10", which is parsed as puts(s(*10)). Ruby's expressions terminate by a newline and you have to implicitly state that the expression is not over, using trailing + or \. That makes it easy to make a dumb syntactic mistake by forgeting to continue line. It also encourages putting everything onto a single line, producing messy looking code. A good amount of your code will consist of "begin end begin begin end end..." noise.
- Slow: JIT-compiling implementations exist, but they're still slow and incomplete, due to Ruby's complexity and bad design, which make Ruby difficult to optimize compared to other dynamic languages, like Lisp. For example, Ruby has to accomodate for somebody in another thread changing the definition of a class spontaneously, forcing compiler to be very conservative. Compiler hints, like `int X` from C/C++ or `declare (int X)` from Lisp, arent possible either.
- Ruby's GC is a naive mark-and-sweep implementation, which stores the mark bit directly inside objects, a GC cycle will thus result in all objects being written to, making their memory pages `dirty` and Ruby's speed proportional to the number of allocated objects. Ruby simply was not designed to support hundred thousand objects allocation per second. Unfortunately, that’s exactly what frameworks like Ruby on Rails do. The more objects you allocate, the more time you "lose" at code execution. For instance something as simple as 100.times{ ‘foo’ } allocates 100 string objects, because strings are mutable and therefore each version requires its own copy. A simple Ruby on Rails 'hello world' already uses around 332000 objects.
- OOP: Matz had a bit too much of the "OOP is the light and the way" philosophy in him, in effect Ruby doesn't have stand-alone functions and Ruby's blocks can't be used in exactly the same way as usual closures. Even high-order functions are attached to objects and produce verbose code: "names.map { |name| name.upcase }", instead of simple "map upcase names".
- Ruby (like most other scripting languages) does not require variables to be declared, as (let (x 123) ...) in Lisp or int x = 123 in C/C++. If you want a variable private to a block, you need to pick an unique variable name, holding the entire symbol table in your head. Ruby introduces new variables by just parsing their assignements, meaning "a = 1 if false; a" wont raise an error. All that means Ruby can't detect even a trivial typo - it will produce a program, which will continue working for hours until it reaches the typo. Local and global scopes are unintuitive. Certain operations (like regular expression operator) create implicit local variables for even more confusion.
- "def method_missing(*args)" is a blackhole, it makes language semantic overly cryptic. Debugging code that uses method_missing is painful: at best you get a NoMethodError on an object that you didn't expect, and at worst you get SystemStackError.
- Non-othogonal: {|bar| bar.foo}, proc {|bar| bar.foo}, lambda {|bar| bar.foo}, def baz(bar) bar.foo end - all copy the same functionality, where Lisp gets along with only `lambda`. Some Ruby's features duplicate each other: print "Hello", puts "Hello", $stdout<<"Hello", printf "Hello", p "Hello", write "Hello" and putc "Hello" -- all output text to stdout; there is also sprintf, which duplicates functionality of printf and string splicing. begin/do/then/end, {} and `:` also play role in bloating syntax, however, in some cases, precedence issues cause do/end and {} to act differently ({} binds more tightly than a do/end). More bloat comes from || and `or`, which serve the same purpose.
- Ruby as a language supports continuations via callcc keyword. Ruby's callcc is incredibly slow, implemented via stack copying. JRuby and IronRuby don't have continuations at all, and it's quite unlikely they will ever get them. There were also support breaches in mainline Ruby, where Ruby 1.9 has not supported continuations for a while. If you want your code to be portable, I'd suggest not using Ruby.
- Ruby was created "because there was no good scripting language that could handle Japanese text". Today it's mostly Rails hype and no outstanding feature, that makes the language, like the brevity of APL or simplicity and macros of Lisp. "There is some truth in the claim that Ruby doesn’t really give us anything that wasn’t there long ago in Lisp and Smalltalk, but they weren’t bad languages." -- Matthew Huntbach
>>1
Ruby isn't actually much worse than PHP, but PHP is horrible to begin with. The only reason rubyfags get fucked harder than PHP kiddies is that the former usually implement a lot of actual business logic in Ruby, whereas with PHP you wind up pushing most of it down to C functions and a database of some kind.
"Serious" web development frameworks written in PHP are a hundred times fouler than anything ever cooked up by rubyists, in terms of both performance and private areas of hax.
Name:
Anonymous2012-03-05 19:11
>>3
You're still a moron who has no possible future as a computer programmer.
Scale has to do with how well an application handles increasing loads. What they mean by Rails doesn't scale well is that it's fine for low traffic websites but starts to slow down when you have several per second. You would have to have several servers to match the speed of a single webserver running no framework.
PHP isn't the greatest, but Facebook uses it and they solved their scaling problems by building the HipHop compiler, which compiles PHP to machine code.
Twitter, which used to be built on Rails has migrated to Java.
Java is actually pretty fucking fast for serving dynamic web content because you get almost native code and good things like concurrency which let you serve multiple requests at the same time with a single running process.
Name:
Anonymous2012-03-05 19:38
>>3
Simply admitting that Ruby is worse than PHP is not enough to hide the fact that you are a professional Rails programmer. Better get back to work! There are toilets to scrub.