Hello!  I'm new to ruby-talk, and mostly new to ruby.  I'm making a document
of some differences between python and ruby, to help reduce the confusion of
other newcomers from python.  But to do that, I need some help reducing my
*own* confusion :)

I don't mean to stir up any flames, and if I get responses to some of these,
I'll put them in a python_to_ruby faq so there will be recorded documentation
for why ruby is the way it is.  Even if it sounds like it sometimes, I'm *not*
saying "ruby should be different, so it's more familiar to me".  More like,
"Ruby does this.  What's the rationale?"  Especially since ruby was created to
fill a similar niche as python et al. so every difference must have a reason.

Also, note that I *like* ruby.  I'm having a good time writing ruby.  And I
decided not to post to comp.lang.misc, on the assumption that I would get a
more insightful discussion on the list (although I am an English-speaking ruby
user, and would use comp.lang.ruby if it existed).  Also, the list is a more
private place and I thought it more polite to get the input of the ruby
community first.  Also, wading through a high-volume mailing list over a 28.8
modem is a Big Bundle of No Fun.

---

Ruby has many types of bindings, with different scopes:
@instance_variable
$globals
local_variable          
Constant

Python has one type of binding.

---

Some ruby bindings (@instance_variables, $globals) spring perlishly into
existence when looked at, with the value nil.  The others raise NameErrors.

Python always raises a NameError.  Nothing springs anywhere.

---

In ruby, there are two ways to access attributes of an object.  '.' is used to
access methods of an instance.  '::' is used to access constants of a class
*and* methods of an instance.  Unlike python, you can only see methods from
instances, and constants from the class:
class B
    C = 'blah'
    def m
        'hello'
    end
end
b = B.new
b.C     -> NameError
B.C     -> NameError
B::C    -> "blah"
b.m     -> "hello"
b::m    -> "hello"

I'm not clear on why this is the case (I mean sorta-similar two access
operators.  I understand the reasoning behind data hiding :).

In python, there is one way to access attributes of an object, which are
always visible in both class and instance.

So, here are some comparisions between attribute access in ruby and python:
                            ruby            python
method (in class def)       meth            object.meth # obj is self
attribute (in class def)    @attr           object.attr # obj is self
method (everywhere else)    object.meth     object.meth
Constant                    Class::Const    object.Const
in general                  depends         object.attr

---

There are two ways to slice lists in ruby.  '..' seems to be the familiar
python way, and ',' seems to indicate first index and *number of indexes
afterward*, which is a strange concept to me.

There is one way to slice lists in python.

---

Characters are integers in ruby.
'hello'[0]  -> 104

There are no characters in python.  Just strings of length one.
'hello'[0]  -> 'h'

I prefer python's way.  I don't expect to see a character's underlying ascii
representation, except in C, cuz it's weakly typed.  And I think "strings
are arrays of characters (which are 1-length strings)" is more intuitive than
"strings are arrays of integers which are the ascii representation of
characters and are displayed as characters when in a string-array".

---

Ruby has perl-esque control-statements-that-also-work-as-modifiers:
'foo' if 1      -> "foo"
'foo' if nil    -> nil

Python doesn't.

---

C has continue and break for loop control.  Python does exactly the same as C.
Perl calls those next and last.  Ruby compromises by using next and break.
Umm?

---

Ruby has iterators, where objects can define their own control structures,
which are sort of like methods that take some code as an argument, and can
invoke that code via the yield statement.  Since sequence objects provide
iterators, for and while loops are unnecessary:

lst.each { |i|
    print i
}

is the same as

for i in lst
    print i
end

but ruby has both syntaxes, presumably because many people are going to find
the for idiom more familiar.  I personally find it more difficult to learn,
use, and read *two* idioms, one familiar and one less familiar, than just
*one* idiom which may be unfamiliar.  And if two are there, people will use
both.  I think this is a point of divergence for me from the perl crowd.

---

Not a problem with the language, and I'm sure this will improve, but: English
documentation is minimal, and not very clear, to me at least.  The user's
guide seems to skip a lot of things (and be unclear about other things).  The
reference manual is better, but is difficult to learn the language from.

I'm sure things are much better on the Japanese side of things.

Python has an excellent and complete English documentation.  The Japanese
story may be different :)

---

Suppose you write "defined? foo".  defined?  has to evaluate its arguments,
which makes me think it ought to throw a NameError if foo isn't defined'.  I'm
confused.

In python, there's no way to write the identifier foo without it being
evaluated, which is what I expect from a non-strict language.

---

Ruby uses

begin
    ...
rescue
    ...
ensure
    ...
end

for exceptions.  It's just word choice, I guess.  begin could be anything.
rescue sounds exception-like.  ensure sounds like an eiffel postcondition.

Ruby has 'retry' which can be used in an exception handler to retry the
sequence, which is nice (Although it resumes from 'begin', instead of resuming
from the statement that raised the exception, so it only really works if you
have a short begin clause.  And it's a nice way to make an infinite loop.).

Ruby also has
catch (:foo) {
    throw :foo, "hello"
}                               -> "hello"

I'm not sure what the exact difference is between the two forms, or why there
are two in the first place.

Ruby also uses 'fail' in addition to 'except'.  Why use one over the other?  I
guess it could be important if you want to preserve the poetic rhythm of your
code: 'fail' has one syllable while 'except' has two, with stress on the
second.

Python has one way to raise an exception, and one way to catch it.

---

Ruby uses single character global variables $_, $@, etc. ala shell (or perl)
that hold special values magically updated by special methods, and which can
be more clearly (I think) obtained explicitly.  Some of them ($_, $~) don't
even act like globals!

Python doesn't.  Some things which cannot be obtained otherwise are given
descriptive names and put in sys, to avoid namespace clutter.

---

Ruby has single-inheritance to reduce complexity, which is a nice idea.  But
in return we get *four* ways to import modules and/or extend classes:
include, extend, load, and require.  And I'm not clear as to the exact
difference between these.  Documentation seems to be sparse here.

And some more ways to extend a class:
class Daughter < Parent # plain inheritance
end

class << d       # singleton class for d
end

def d.foo        # singleton method for d
end

Python has two ways to import a module 'import module' and
'from module import ...' which is already perhaps more than enough :)  It has
one way to extend a class (via inheritance).  Also, in python, modules are
automatically created for a file, and therefore always have the same name as
the filename.  In ruby, you have to explicitly create the module, which could
be named anything, and I'm still trying to figure out the exact semantics for
them (which seem to be sort of mostly class-like).

---

Ruby has ||, "or", &&, and "and" operators (eek).  And they function slightly
differently (faq 4.10).

j = nil or 1        -> 1        # strange...
j                   -> nil

Python has single "or" and "and" operators.

---

Methods are not first class in ruby.  This means there is a seperate concept
of a binding to a method and a binding to an object.  This gives rise to proc
{} objects, which are sort of like methods.  They can be created in a number
of different ways:

{ code } # which gets confused with the hash constructor, and can only be used
         # in special places (iterators and methods that expect &blocks)
proc { code }
Proc.new { code }
lambda { code }
do code end # only in special places, like { code }, and is *mostly* like
            # { code } except precedence is slightly different

And of course, arguments of "normal" methods and Proc objects are handled
differently:

def f(foo, bar) foo * bar end
f = Proc.new { |foo, bar| foo * bar }

And apparently default args and the like don't work for || arg lists.

And the scoping rules are different:
i = 0
p = proc {|n| i = n}
p.call(5)
i           -> 5

And then we have private, public, module_function, protected, and all sorts of
other stuff.  Careful perusing of the Class, Module, Object, and Kernel
documentation is required.

So, despite ruby's description as a 'pure object oriented language', methods
are not objects, unlike python, where everything is an object (sorry, couldn't
resist :)

Python has one way of defining a method.  There is one 'kind' of binding.

---

Dog = Class.new(super = Animal,
    bark = Method.new([:times],
        { (['arf'] * times).join(' ') }
    )
)
hmmm... smalltalk... maybe not :)

---

The fact that methods are not first class in ruby means you have to remember
two mutually exclusive different ways to do things, depending on whether the
value is a method or not:

                                python          ruby binding    ruby method
create new name for object:     new = old       new = old       alias new old
delete binding for object:      del obj         ?               undef meth

---

"\n" and '\n' are different strings in ruby, which has a similar quoting
concept as the unix shell (and therefore perl).

"\n" and '\n' are the same in python.

---

irb, the interactive ruby toplevel, still has some problems.  It tends to get
into a weird state, and some things that are valid ruby will not compile
(<<-EOF here documents).

% irb
irb(main):001:0> m
NameError: undefined local variable or method `m' for #<Object:0x401c0ed4>
(irb):1:in `irb_binding'
irb(main):002:0> def m
irb(main):003:1>   5
irb(main):004:1> end
nil
irb(main):005:0> m
NameError: undefined local variable or method `m' for #<Object:0x401c0ed4>
(irb):5:in `irb_binding'
irb(main):006:0> ^D
% irb
rb(main):001:0> def m 
irb(main):002:1>   5
irb(main):003:1> end
nil
irb(main):004:0> m
5
irb(main):005:0>

Python's toplevel works fine, albeit having a slightly different grammar (need
an extra blank line after the last block).

---

ruby uses dylan-esque
    def +(arg) end
    def -(arg) end
to override operators.

Python has less pretty-looking __add__ __radd__, etc. methods for that.

---

Ruby allows some special characters like ?! only at the end of methods to
allow dylan / scheme-like naming conventions: obj.destructive!(foo)
obj.predicate?(bar)  It doesn't allow real scheme-style-function-names,
though.

Python allows no special characters in any identifiers.

---

Ruby has an implicit self: msgs with no receiver are sent to self.

Python has an explicit self.  msgs with no receiver are simply functions.

---

The only things that are false in ruby are nil, false, NIL, and FALSE:
if 0 then 'hello' end   -> "hello"
nil and false, while mostly similar, have 'different behaviours elsewhere'
(faq 7.4), but I'm not sure what that means.  Careful with that 0 is true
stuff, it's easy to forget that if you're not used to it.  I'm also not sure
why true, nil, and false have UPPERCASE equivalents.  I guess nil and false
could be useful for 'three value logic' which sometimes pops up (usually in
databases).

Python has no special purpose booleans.  None, 0, __nonzero__() returns 0, and
len returns 0 are false.  Everything else is true.  None and 0 can be used for
three value logic.