Source: RubyConf 2003: Matz: The Top 10 Reasons The Ruby Programming Language Sucks
From WhyNotWiki
Matz. The Top 10 Reasons The Ruby Programming Language Sucks (http://www.slideshare.net/vishnu/the-top-10-reasons-the-ruby-programming-language-sucks/). -- 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"... :-)
[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 profitable 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] Objectified Syntax
- obj.attribute = methods
dangerous!andquery?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...endor{...}- 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 define 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 | FTP | Web | |
| Serve | Code | Servlets | XML-RPC |
| Work with | Math | Templates | Threads |
| Tools for | Debugging | Docs | Testing |
