[#1263] Draft of the updated Ruby FAQ — Dave Thomas <Dave@...>

33 messages 2000/02/08

[#1376] Re: Scripting versus programming — Andrew Hunt <andy@...>

Conrad writes:

13 messages 2000/02/15

[#1508] Ruby/GTK and the mainloop — Ian Main <imain@...>

17 messages 2000/02/19
[#1544] Re: Ruby/GTK and the mainloop — Yasushi Shoji <yashi@...> 2000/02/23

Hello Ian,

[#1550] Re: Ruby/GTK and the mainloop — Ian Main <imain@...> 2000/02/23

On Wed, Feb 23, 2000 at 02:56:10AM -0500, Yasushi Shoji wrote:

[#1516] Ruby: PLEASE use comp.lang.misc for all Ruby programming/technical questions/discussions!!!! — "Conrad Schneiker" <schneiker@...>

((FYI: This was sent to the Ruby mail list.))

10 messages 2000/02/19

[#1569] Re: Ruby: constructors, new and initialise — Yukihiro Matsumoto <matz@...>

The following message is a courtesy copy of an article

12 messages 2000/02/25

[ruby-talk:01633] Re: ruby <=> python

From: Quinn Dunkan <quinn@...>
Date: 2000-02-28 18:20:45 UTC
List: ruby-talk #1633
Comments by yashi and gotoken:

> > Characters are integers in ruby.
> > 'hello'[0]  -> 104
> 
> no, there is only String class. all char is an instance of class
> String.  And, [] is a method in class String to get _char code_.

Ok, so it would have been more accurate to say:
Indexing a string in ruby gives you an Integer.

I'm still not clear on why this is the case, or how it's useful.  A few other
languages:
python:     string[0]   -> StringType
C:          stringp[0]  -> char
haskell:    string !! 0 -> Char
smalltalk:  string at: 1 -> Character
In perl, strings are not sequences and can't be indexed, so you have to use
substr, which gives a string.
ruby:       string[0]   -> Fixnum

The other languages approaches seem more intuitive.
For example, in the haskell prelude:
type String = [Char]    -- strings are lists of characters

So why doesn't ruby have a Char class?

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

Well, that's because Integers happen to respond to the chr message, it's still
an Integer ('hello'[0].type -> Fixnum).  Hmm, I think String objects *are*
always character strings, I think what you mean is that they are not always
*printable* character strings :)  But that's not for the language to decide,
whether or not it's printable depends on your character set, and neither has
any bearing on what [] should return.  If I index a binary string, I still
wouldn't expect to get a fixnum, since if I slice 4 elements I don't get a
32-bit int, but a string.

---

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

OK, I can understand the bit about <obj>.<ident> is a method call, wheras
<obj>::<ident> is a Constant retriever (not attribute retriever, since those
are just methods in ruby), even if I don't like it :)  But my real question
was "if '.' and '::' are used for different purposes, why does '::' work like
'.'?"  'Foo::X' -> "Constant" vs. 'Foo::X()' -> "method" just underlines that
question.  Does this seem a bit 'trap-like' to anyone else?  OK, I'm sure a
perl programmer, who is used to subtle changes when you put parentheses in,
wouldn't blink.  Ok, maybe a perl programmer would blink and be just as
confused as the rest of us, but he'd be more inclined to accept it without
question :)

---

> > 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.
> 
> if 'defined?' raise an exception, what's the point of having
> 'defined?'?
> 
> # I must be miss-understanding your question.
> 
> even in the toplevel, you are in an instance of class Object. so
> 'defined? foo' means defined? self.foo.  you can always check what
> method an instance has with method 'methods'.

Yes, well even 'self.defined? self.foo' has to evaluate self.foo.

> is there a way to get a list of variables that has been defined?

You tell me, I'm the newbie here :)  Based on my fuzzy understanding on ruby,
I'd say no, because defined variables are just methods of self, and there's no
way to tell what a method will give you unless you call it.  No wait, I'm
thinking of @attrs.

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

Ah, this makes more sense, defined? isn't a method at all.  I thought
everything was a message send in ruby? :)  It *could* be "just another message
send" if you spelled it 'defined? :foo' or 'defined? "foo"'.  So why not?

---

> > 
> > The only things that are false in ruby are nil, false, NIL, and FALSE:
> > if 0 then 'hello' end   -> "hello"
> 
> this one came up on ruby-talk, Matz said "it's matter of how far you
> define 'false'"

Hmm, I define false as:  "that which, when you put it in an 'if' expression,
evaluates the 'else' clause".  I have no problem with 0 being true.  It forces
you to write the (mostly) clearer 'if foo != 0', and be disciplined about what
is a boolean and what isn't, which seems like one of those ideas that sound
good for large systems, but just annoy quickie-script-hackers.  In, e.g.  But
if you're going down that road, it seems it only makes sense if you go *all*
the way, i.e.  only 'true' or 'false' is accepted by 'if' and friends.
Everything else throws an exception.  In e.g. haskell, True is true and False
is false, nothing else.  Of course, anything else would make the static typing
unhappy :)

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

1) Although there are no errors, you want to escape from one "mode"
    to another drastically.

(2) You want to escape from deeply nested loop drastically.

(3) You want to write obfuscated code.

Hmm, so I guess throw/catch is supposed to be a control structure, while
exceptions are supposed to be only for errors?  And throws can only be caught
in one place (which 1344 seems to imply)?

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

Ah, this is useful.  Perhaps useful enough to go in the FAQ?

So extend, since it applies to single objects, is sort of like include for
singletons?

---

> >Ruby has ||, "or", &&, and "and" operators (eek).  And they function slightly
> >differently (faq 4.10).
> 
> You don't like operator? ;)

Not ones that look the same and work *almost* the same.

>   text = ARGF.read || ""
>   puts text.gsub(....)
> 
>   text = ARGF.read or exit 1
>   text.each do |line| .... end

Or maybe what you really mean:

def f(x) x * 2 end
false or f 5        -> 10
false || f(5)       -> 10
false || f 5        -> SyntaxError

I think this just means that || binds too tightly.  So the question is "why,
then, do you need '||'?"  I know perl does this because perl tries to be just
as confusing as C or more, so it adopts all the traps of C in addition to
adding its own (but then goes and changes 'break' and 'continue'... go
figure).  I guess this is so confused C programmers will feel just as confused
in perl, maybe they're more comfortable that way :)


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

That's useful information (more efficient than wrapping them in lambdas, which
are not exactly methods anyway).  That "looks like array index, but is really
a method call" is a bit weird, but I guess not much worse than the "looks like
bit-shift, but is really stream-append" thing C++ loosed on the world.
Why not provide a () method like python's __call__?

---

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

Or maybe smalltalk.  But that still doesn't explain the 'different behaviours
elsewhere' bit (and the fact that nil != false).  If it were merely a case of
"can't decide whether to type 'nil' or 'false' so I'll let people use (and the
flip side: force people to read) both (like python != and <>), then they would
have been exactly equivalent.


And, finally, here's a real ruby question:
What's the general idiom for parallel iteration in ruby?

This is what I was able to figure out:
def zip(*a)
    r = []
    0.upto(a.collect {|i| i.length}.max - 1) { |i|
        r << a.collect {|elt| elt[i]}
    }
    r
end

zip(lst1, lst2, lst3).collect {|a, b, c| print a, b, c, "\n"}

Which seems to work.  I wasn't sure if ruby would do pattern matching, but it
appears it does, at least here.  However, I'm sure there is a better way that
doesn't require making my own function...

In This Thread