CSC/ECE 517 Fall 2009/wiki1a 11 f1,: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
Line 11: Line 11:
==Language Features==
==Language Features==


===Private methods and variables ===
===Access levels for methods and instance variables ===


To make methods and instance variables private in Python, one '''always''' needs to write __ in front of the name. In Ruby, instance variables are private by default. Methods defined after the method call private are private.
To make methods and instance variables private in Python, one '''always''' needs to write __ in front of the name. In Ruby, instance variables are private by default. Methods defined after the method call ''private'' are private.


===Functions and methods ===
===Functions and methods ===
Line 45: Line 45:
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.
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” ===
=== First parameter of method definition ===
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++.
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++.


Line 52: Line 52:
=== Ruby continuations vs Python Generators ===
=== Ruby continuations vs Python Generators ===


The use of continuations seem rather limited, and hard to understand, but it’s there in Ruby, and not in Python.  
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''.
Continuations are useful when it comes to ''usecases''. However, they can be replicated in Python 3.1 with passing variables into ''.next()'' .
<pre>
def loop
  cont=nil
  for i in 1..4
    puts i
    callcc {|continuation| cont=continuation} if i==2
  end
  return cont
end
</pre>
 
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
 
<pre>
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())
</pre>
 
 


Python has generators. You can fake them in Ruby by using '''blocks''', or use continuations. Python generators are easy and clean.
=== Ruby Blocks and Python Lambdas===

Revision as of 06:33, 5 September 2009

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 levels for methods and instance variables

To make methods and instance variables private in Python, one always needs to write __ in front of the name. In Ruby, instance variables are private by default. Methods defined after the method call private are private.

Functions and methods

In Ruby, 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.

First parameter of method definition

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

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())


Ruby Blocks and Python Lambdas