Hi, 

In message "[ruby-talk:01528] ruby <=> python"
    on 00/02/20, Quinn Dunkan <quinn / envy.ugcs.caltech.edu> writes:

>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.

I think your decision is not bad.  I hope c.l.ruby will be created but
I would not agree Conrad's proposal such that we should discuss at
c.l.misc only.  I can't read or post timely to usenet; most of usenet
articles are behind one week at my host. 

# Of course, I admire Conrad for his activities on usenet :-)

---

>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

Interesting :)

Another viewpoint is avairable. 

  class Foo
    X = 'Constant'
    Y = 'Constant'
    def Foo.X; 'method' end
  end
  Foo::X      #=> "Constant"
  Foo::X()    #=> "method"
  Foo.X       #=> "method"
  Foo.Y       #!!NameError: undefined method `Y' for Foo:Class

I think the primary meaning of <module>::<identifier> is name space
identification whareas <module>.<identifier> is method call. In the
latter, <module> can be considered as a receiver, i.e., an object. 

---

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

If I may add, "hello"[0].chr == "h".  Note that String object is not
always a character string, String can represent a octet (byte) string. 

---

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

I hope this situation will be improved.  Unfortunately, I can't take
times for English documentation.  (One reason is I'm bad at Engilsh;
Another is I'm also bad at scheduling myself, I always face many
deadlines)

---

>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.

`defined?' is a kind of operator, and its argument is checked by the
parser.  I understand it is similar to sizeof operator in C. 

---

>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.

catch-throw doesn't raise an exception. See [ruby-talk:01286]
and [ruby-talk:01344]. 

---

>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.

Well, 

`extend'  appends functions of a module to an object;
`include' appends features of a name space (i.e. module) to another space; 
`load'    inserts code included a file to other program; 
`require' is similar to `load' except never read file twice. 

Maybe `extend' isn't familiar.  

  module M
    def x; 1 end
  end
  a = "a"
  a.extend M
  a.x #=> 1

By the way, `a.extend M' is interpreted as `M.extend_object(a)', and
`include M' as `M.append_features(self)'.  I wrote a toy using this
mechanism:

#
#  flyweightfactory.rb
#
#    class Foo
#      include FlyweightFactory
#    end
#
#    Foo[arg]                   #=> an object which is unique for arg
#    Foo[arg].id == Foo[arg].id #=> true
#    Foo.new(arg)               #!!NameError
#

module FlyweightFactory
  def FlyweightFactory.append_features(mod)
    super
    mod.private_class_method :new
    mod.const_set("HASHTABLE", {})

    def mod.[](key)
      self::HASHTABLE[key] || self::HASHTABLE[key] = new(key)
    end
  end
end

---

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

You don't like operator? ;)

  text = ARGF.read || ""
  puts text.gsub(....)

  text = ARGF.read or exit 1
  text.each do |line| .... end

---

>Methods are not first class in ruby.  

However, bounded method is available:

  plus_one = 1.method(:+)  #=> #<Method: Fixnum#+>
  plus_one.call(10)        #=> 11
  plus_one[10]             #=> 11

---

>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

No way to delete (if I'm not mistaken). 

---

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

I'm guessing it comes from Lisp.  ALIASEs are left for historical
reason.  


Hope this helps,

-- Gotoken