Source: RubyConf 2003: Matz: The Top 10 Reasons The Ruby Programming Language Sucks

From WhyNotWiki

Jump to: navigation, search

Matz. The Top 10 Reasons The Ruby Programming Language Sucks (http://www.slideshare.net/vishnu/the-top-10-reasons-the-ruby-programming-language-sucks/). Retrieved on 2007-02-07 13:56. -- slideshow in Flash

Download Powerpoint version here: http://www.ruby-doc.org/whyruby

It's a fun, Tongue-in-cheek apology for Ruby from its creator, Matz.

Basically it takes a bunch of criticisms people have had about Ruby and shows how they're actually unjustified.

It makes fun of Ruby's popular criticism and shows that critics really have nothing to complain about. Their complaints can be turned around and shown to actually be features of the language: "Too flexible", "Too pretty", "Too easy to read", "Too powerful"... :-)

Contents

[edit] 10. Too young

[edit] No libraries

Ruby libraries:

  • 96 standard libraries
  • Ruby Application Archive (RAA) catalogs over 1,200 applications and libraries
  • RubyForge is hosting over 800 open source projects
  • RubyGems has served over 900,000 gems

[edit] No support


Documentation:

  • Core 100% documented
  • Standard library documentation in progress
  • Tutorials available for various skill levels
  • "Facets of Ruby" book series

Community:

  • Mailing lists in multiple languages
  • Usenet groups (with ML gateway)
  • Web forum

[edit] No one is using it


Companies using Ruby:

  • HP, Intel, NASA, and NOAA

Uses for Ruby:

  • Simulation, data munging, code generation, image processing, prototyping, and more

"Killer app": Ruby on Rails

  • Already being used in profitable web applications like Basecamp and Blinksale

[edit] Conclusion: Ahead of its time!

[edit] 9. Useless in obfuscation contests

[edit] Optional Syntax

  • No ;s needed
  • Drop the "\n" characters
  • Optional ()s
puts "Hello World!"

[edit] Objectified Syntax

  • obj.attribute = methods
  • dangerous! and query? methods
full = "james gray"
names = full.split

until names.empty?
  names.first.capitalize!
  puts names.shift
end

# Prints:
#   James
#   Gray

[edit] Simple, flexible syntax

  • Simple declarations:
    • local_var = ...
    • @instance_var = ...
    • $global_var = ...
  • do...end or {...}
  • Real exception handling, like Java
  • String interpolation: any Ruby code inside #{...}
nums = [1, 2, 3, 4, 5]

sum = nums.inject do |s, v|
  s + v
end
prod = nums.inject { |p, v|
  p * v
}

begin
  sum / 0
rescue ZeroDivisionError
  puts "Error: #{sum} / 0"
end

[edit] Compare with other languages

  • Ruby: puts "Hello world!"
  • Java: threeVeryLongLines.weHopeWork...
  • Perl: #$<!&;
  • Lisp: ((a(((b)))(c)))

[edit] Conclusion: Clean syntax!

[edit] 8. Object Oriented

[edit] Ruby is object oriented

  • Everything is an object
    • Numbers, code blocks, everything
  • Baked-in, not bolted-on
    • No need to use self everywhere, like [in] Python
3.times do
  puts "Hello" +
       "james".capitalize
end

# Prints:
#   Hello James
#   Hello James
#   Hello James

[edit] Ruby has many object orientation shortcuts

  • Automatic constructor generation, unlike Perl
  • Easy accessors
  • Define methods to interact with Core Ruby
class Greeter
  def initialize( greeting )
    @greeting = greeting
    @who      = "World"
  end
  attr_accessor :who
  def to_s
    "#{@greeting} #{@who}!"
  end
end
hello = Greeter.new("Hello")
hello.who = "James"
puts hello

[edit] Procedural code allowed

  • You can ignore the class system as needed
  • You can even mix and match objects with procedural code
def factorial( n )
  (2..n).inject do |p, v|
     p * v
  end
end

puts factorial(4)

# Prints:
#   24

[edit] Conclusion: Too flexible

[edit] 7. Uses Mix-ins

[edit] You can't win with multiple inheritance

  • Multiple inheritance allows a class to inherit from more than one parent
    • The good: Makes modeling complex object trees easier
    • The bad: The diamond inheritance problem
  • You can't please both sides

[edit] Ruby uses single inheritance...and "Mix-ins"

  • Similar to Java's interfaces, plus implementation
  • No limit to how many you use
  • The benefits of multiple inheritance, without the minuses
puts "10" > "2"

class Numeral < String
  def <=>( other )
    to_i <=> other.to_i
  end
  include Comparable
end
puts Numeral.new("10") >
     Numeral.new("2")

# Prints:
#   false
#   true

[edit] Conclusion: Makes too much sense!

[edit] 6. No loops

[edit] The well-known loops

Most languages Ruby
while { ... }</code while ... end
until { ... } until ... end
do { ... } while begin ... end while
do { ... } until begin ... end until
foreach { ... } each do ... end
for(...;...;...) { ... }     

[edit] Aren't loops proven to work by now?

  • "N + 1" errors
  • foreach { ... } is conceptually backwards
    • Objects should manage their own traversal

[edit] Iterators

  • Objects manage their own traversal
  • No more "N + 1" errors
  • Code blocks still allow customizing behavior
nums = (1..10).to_a

evens = nums.select do |n|
  n % 2 == 0
end
five = nums.find do |n|
  n > 4
end

nums.each do |num|
  puts "#{num} * 2 == " +
       "#{num * 2}"
end

[edit] Conclusion: Rebellious

[edit] 5. Code blocks everywhere

[edit] What is a code block?

  • Any method can accept a block
  • Blocks can be called immediately or stored for later use
  • Blocks are closures
def suffix( &block )
  block.call("I")
  block.call("II")
end

name = "James Edward Gray"
suffix do |s|
  puts "#{name} #{s}"
end

# Prints
#   James Edward Gray I
#   James Edward Gray II

[edit] What are they for?

  • Blocks can allow your code to react in according to user code
  • Blocks are a great way to pass around behavior
  • Blocks are ideal for transactions
count, total = 0, 0
File.open("prices") do |f|
  while l = f.gets
    if l =~ /\d+(?:\.\d+)?/
      total += $&.to_f
      count += 1
    end
  end
end
puts "Average price:  " +
     "#{total / count}"

[edit] Conclusion: Too powerful

[edit] 4. Wide open, even at runtime

[edit] Dynamic tools

  • Strong reflection
  • eval()
    • instance_eval()
    • class_eval() and module_eval()
  • Hooks for runtime events
class Greeter
  def initialize( greeting )
    @greeting = greeting
  end
  def method_missing( m )
    name = m.to_s.capitalize
    "#{@greeting} #{name}"!
  end
end

hello = Greeter.new("Hello")
puts hello.james

[edit] Classes are open

  • Add methods to a class at any time
    • Even a core class
  • Customize individual objects
  • Overload operators
  • Hook into Ruby's math and conversion operations
class Array
  def average
    inject do |sum, var|
      sum + var
    end / size
  end
end

nums = [1, 2, 3, 4, 5]
puts nums.average

# Prints:
#   3

Slide 84: ! at seven es l 4. Wide open, w a runtime L

[edit] Conclusion: Lawless

[edit] 3. Ruby gurus are obsessed with ducks

"If it walks like a duck and talks like a duck, it's a duck!"

[edit] The "Duck Typing" philosophy

  • We define an object by what it can do, not its type
  • Most of the time, you shouldn't even check for methods
def app_five( obj )
  obj << 5
end

File.open("five", "w") do |f|
  f.puts app_five([1, 3])  # [1, 3] << 5 => f.puts app_five([1, 3, 5])
  app_five(f)              # f << 5
end

# In file "five":
#  1
#  3
#  5
#  5

[edit] Conclusion: Too strange

[edit] 2. Includes too many great toys

[edit] 96 standard libraries

Read/Write CSV XML YAML
Talk to Email FTP Web
Serve Code Servlets XML-RPC
Work with Math Templates Threads
Tools for Debugging Docs Testing

[edit] Conclusion: Too distracting

[edit] 1. "It's entirely too fun and productive for most people."

Template:Cquote

Personal tools