CSC/ECE 517 Fall 2009/wiki1a 11 f1,
Ruby and Python are both scripting languages whose popularity has sky rocketed in recent years. Both languages are High-Level, Garbage-collected, and Dynamically-typed. Both provide an interactive shell, standard libraries, and persistence support. So, what are the differences?
Points of comparison:
- Language Features
- Web programming environments
- Features exclusive to each
- Advantages of each over statically typed languages
- Project environments suited to each
Language Features
Access Protection
Ruby supports private, protected and public types of access (like java)to the elements of a class. By default all methods are public except the initialize method and all instance variables are private. One of the differences of Ruby compared to Python is that Ruby keeps all of its instance variables completely private to the class and only exposes them through accessor methods (attr_writer, attr_reader, etc).
Python's property descriptors are similar, but come with a tradeoff in the development process. If one begins in Python by using a publicly exposed instance variable and later changes the implementation to use a private instance variable exposed through a property descriptor, code internal to the class may need to be adjusted to use the private variable rather than the public property. Ruby removes this design decision
Functions and methods
In Ruby, the part which is different from Python is the fact that all operations are messages to objects. There are no separate functions and methods; all of them are methods.
string = 'Hello world' puts string.count('o'), string.length # prints 2, 11
In Python, there are separate methods and functions as shown in the example below.
string = 'Hello world' print string.count('o'), len(string) # prints 2, 11 – why not string.len()?
Ruby has reference to class in class body
Ruby:
class MyClass initialize_magick() end
Rubys variant is cleaner, as the magic stuff is done in the class definition, so you see that it’s being done when you look at the class.
Python:
class MyClass: pass initialize_magick(MyClass)
But it’s really not a big deal, because calling the initialise method after the class or as a decorator is really not a major drawback.
Self Reference
In Python, one needs to write self as the first parameter of a method definition (alike Perl). Furthermore, Python doesn’t require the variable name to be self. In Ruby, self is automatically available in a similar fashion as in C++.
Additionally, the method call self.method can be shortened to method, as self is the default receiver.
Ruby continuations vs Python Generators
Continuation is a "pointer" to the current position in your program, including calling stack and all variables. You can reuse that pointer to "go back in time" when needed. Continuations are useful when it comes to usecases.
def loop cont=nil for i in 1..4 puts i callcc {|continuation| cont=continuation} if i==2 end return cont end
Python doesn't support full continuations or even coroutines; instead it supports "generator" functions which create a kind of limited coroutine. A generator in python is implemented as a special syntax for creating an instance of an iterator object, which returns the values returned by the "function" definition you provide. Python generators are easy and clean. The equivalent code for the above code segment, in python is
from generator_tools import copy_generator def _callg(generator, generator_copy=None): for _ in generator: # run to the end pass if generator_copy is not None: return lambda: _callg(copy_generator(generator_copy)) def loop(c): c.next() # advance to yield's expression return _callg(c, copy_generator(c)) if __name__ == '__main__': def loop_gen(): i = 1 while i <= 4: print i if i == 2: yield i += 1 c = loop(loop_gen()) print("c:", c) for _ in range(2): print("c():", c())
Indentation
Python uses whitespace indentation, rather than curly braces or keywords, to delimit statement blocks (a feature also known as the off-side rule). An increase in indentation comes after certain statements; a decrease in indentation signifies the end of the current block. On the other hand, ruby doesn't need any indentation although it can be optionally used for clarity.
Other Differences
Feature | Ruby | Python |
---|---|---|
Higher-Order Functions | Implemented with procedure objects | Implemented as lambda expressions |
Arrays and hashes | supports Arrays and associative arrays (Hash) | has Lists and Tuples which are the same as arrays. |
Memory management | has a mark and sweep garbage collector | has a reference counting garbage collector. |
Parallel assignment | claims to do Operating System independent threading. | Threading available on many common platforms with some threading support |
Package support | Not available | Available
|
Web Programming Environments
* Ruby on Rails - A Ruby Application Server for web development * Zope - Like Ruby on Rails, but in Python
Both of these are
Advantages of each over statically typed languages
The term Dynamic language refers to high level programming language that allows the programmer to modify the code during run time. The modifications may include addition of new blocks of code or modifications to objects. Statically typed languages such as Java or C# need to have all expressions assigned to a particular type before being run (or during compile-time).
Apart from being dynamically typed, there are many features provided by dynamic languages that aren’t to be found in Static languages. These include blocks and closures, metaprogramming, and unbounded polymorphism and support for multiple programming paradigms.
Purely Object Oriented
Ruby does not have primitives; everything, including integers are full fledged objects.
0.zero? # => true 1.zero? # => false
Typed features
With Static typing in Java and C#, we need to declare the type of each variable (int, char, float etc.) while with Ruby you don't declare types for variables or functions. In Ruby objects are strongly and dynamically typed. Where ‘type’ refers to a set of values or a set of operations.
Java:
int val1=5; String value=String.valueOf(val1); if(value.equals("5"))
Python:
val1=5 value=str(val1) if value == "5"
Checked Exceptions
Checked exceptions force every method to deal with (catching or throwing) all exceptions that its child calls or may call.
Java If in the program, a method calls run as follows, A1() -> A2() -> A3() -> A4() and if A4() throws an Exception, and it is caught by A1(), then A2(), A3() must also throw the same Exception.
Python Exceptions propagate upwards and A2() and A3() do not need to throw the Exception.
Verbosity
Statically typed languages are verbose.
Java:
import java.io.*; BufferedReader file1=new BufferedReader(new FileReader(Filename));
Python:
file=open(Filename);
Relaxed syntax
All the statements below achieve the same functionality.
Ruby:
cat = Cat.new cat = Cat.new() cat = Cat.new();
More compact code
Java:
for (int i = 0; i < 100; i++) {}
Ruby:
100.times { |i| }
Default Arguments
Ruby and Python allows you to define default values to method arguments while Java does not.
Ruby:
def calc_cube(x=2,y=3) val=x**y end
Duck Typing
Ruby doesn't care about an object's class, just whether it has a method of the name used in the method call. For this reason, the dynamic approach has earned the name duck typing.
Ruby:
class Duck def sound puts "Quack" end end Class Frog def sound puts "Croak" end end def noises(duck) duck.sound end duckA=Duck.new frogB=Frog.new noises(frogB) Result: "Croak"