Questions/suggestions from a Ruby newbie

Hi,
first of all let me say I really really like Ruby, and I look forward
to use it in my projects.

There are however a couple of questions I have and features I miss from
my other languages (mainly Fortran and C++... I am not a CS ^_^) and I
would like to know more if Ruby implements something similar, and if it
does not if there is any possibilities it may do so in the future
(after all Ruby seems to take the best feature from the various
languages).

Here it's a list of my current problems:

-Is there a way to have multidimentional arrays in Ruby? Ie something
like variable[3][2]? One could use arrays of arrays but it does not
look quite as clear when reading the code.

-Fortran 95 had a really nice feature when using arrays: you could
assign values using ranges. I am glad to see something similar exist in
Ruby too, (eg. variable[0..100]=0)
However F95 went a bit further, since the ranges could include an
optional parameter, the step. In F95 it would look something like:
variable[min:max:step] = 0
There's a lot of cases when something like this is really convinient. I
know you can produce a similar effect using a few more lines, but I
think a feature like a range+step would have several advantages, namely
that it would look more clear in less code (a common feature in Ruby)
and it's closer to the way we think to be very desirable. Has there
been any talk about such a feature in future Ruby?

-What is the difference between the << and + concatenation for strings?
Is it just that the former modifies the string while the second one
returns a new string? Why then not use something like +! (just as an
alternative)?

-I read the discussion about the use of the "end" keyword, and possible
alternatives. Instead of trying to change that, I think it would be
easier and more consistent with Ruby's syntax to change the way if,
unless and while work so that they take a block as an argument. Then
if/while would work more consistently as the other methods, and in
particular the iterators: in both cases you could delimit the code with
a keyword like "end" or the curly bracket. For example these would be
all acceptable:

if(x==y) do
  #code
end

if(x==y) {
  #code
}

(the first one would pretty much look like it already does, and one
could decide that "do" can be omitted to make it compatible with
existing code.)

In other words it would look just like for iterators (more consistent
Ruby) and at the same time make happy those that want brackets instead
of keywords to delimit if/while/unless: two birds with one stone.

Thank you very much. Anyway Ruby keeps being a great language and I
really love it (though I have not use it much yet).

Diego Virasoro

Hi --

Hi,
first of all let me say I really really like Ruby, and I look forward
to use it in my projects.

Cool!

Here it's a list of my current problems:

-Is there a way to have multidimentional arrays in Ruby? Ie something
like variable[3][2]? One could use arrays of arrays but it does not
look quite as clear when reading the code.

How about:

   variable[3][2]

? :slight_smile: As long as both variable and variable[3] respond to "", you
should be OK. (They don't even have to be arrays.)

-I read the discussion about the use of the "end" keyword, and possible
alternatives. Instead of trying to change that, I think it would be
easier and more consistent with Ruby's syntax to change the way if,
unless and while work so that they take a block as an argument. Then
if/while would work more consistently as the other methods, and in
particular the iterators: in both cases you could delimit the code with
a keyword like "end" or the curly bracket. For example these would be
all acceptable:

if(x==y) do
#code
end

if(x==y) {
#code
}

(the first one would pretty much look like it already does, and one
could decide that "do" can be omitted to make it compatible with
existing code.)

That starts to tie the language in knots. For one thing, if can take
a method with a block:

   if x { }; y end

I think things would start to get much too messy, especially with an
optional "do".

In other words it would look just like for iterators (more consistent
Ruby) and at the same time make happy those that want brackets instead
of keywords to delimit if/while/unless: two birds with one stone.

I don't think people wanting brackets, as a general matter, is a
"bird" in the first place :slight_smile: Consistency isn't really an issue here
either, since if isn't a method; and if if were a method, but the "do"
were optional, it wouldn't be consistent anyway.

In other words, if is a syntactic construct, and code blocks are also
syntactic constructs; but there's no inherent reason why they should
be unified. (I know Smalltalk and maybe other languages handle
conditionals as methods, but I don't think it would mesh well with
Ruby.)

I would recommend living with these constructs for a while, on their
own terms. I'm reasonably certain that it will cease to feel like
something is missing or wrong.

Thank you very much. Anyway Ruby keeps being a great language and I
really love it (though I have not use it much yet).

It's great, isn't it? :slight_smile:

David

···

On Wed, 22 Mar 2006, Diego.Virasoro@gmail.com wrote:

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

-Fortran 95 had a really nice feature when using arrays: you could
assign values using ranges. I am glad to see something similar exist in
Ruby too, (eg. variable[0..100]=0)
However F95 went a bit further, since the ranges could include an
optional parameter, the step. In F95 it would look something like:
variable[min:max:step] = 0
There's a lot of cases when something like this is really convinient. I
know you can produce a similar effect using a few more lines, but I
think a feature like a range+step would have several advantages, namely
that it would look more clear in less code (a common feature in Ruby)
and it's closer to the way we think to be very desirable. Has there
been any talk about such a feature in future Ruby?

Not that I heard of. It doesn't sound like it was too difficult to implement though.

-What is the difference between the << and + concatenation for strings?
Is it just that the former modifies the string while the second one
returns a new string?

Right.

> Why then not use something like +! (just as an

alternative)?

That's ugly IMHO and also just syntax. "<<" is well known in other languages (namely C++) for stream appending which is basically what it is. Also operator "+!" might introduce problems in the syntax.

Kind regards

  robert

···

Diego.Virasoro@gmail.com wrote:

-Fortran 95 had a really nice feature when using arrays: you could
assign values using ranges. I am glad to see something similar exist in
Ruby too, (eg. variable[0..100]=0)
However F95 went a bit further, since the ranges could include an
optional parameter, the step. In F95 it would look something like:
variable[min:max:step] = 0
There's a lot of cases when something like this is really convinient. I
know you can produce a similar effect using a few more lines, but I
think a feature like a range+step would have several advantages, namely
that it would look more clear in less code (a common feature in Ruby)
and it's closer to the way we think to be very desirable. Has there
been any talk about such a feature in future Ruby?

I don't think this is doable with things as they are, since Ruby's
support for range indices differs from Fortran's (IIRC - I think
var[0:10:2] = 0 would set 0,2,4,6,8,10 ?).

In Ruby, when providing a range to Array#= it serves to select a
continuous range of elements that are to be replaced with a single
element (the RHS):

a = [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j]
# => [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j]

a[0..3] = 0
# => 0

a
# => [0, :e, :f, :g, :h, :i, :j]

-What is the difference between the << and + concatenation for strings?
Is it just that the former modifies the string while the second one
returns a new string? Why then not use something like +! (just as an
alternative)?

I agree with David and Robert; when I first came over to Ruby I saw
plenty of stuff that could be 'made better', but now I'm used to it I
wouldn't change much at all. << is pretty consistently used throughout
Ruby and makes lots of stuff easy thanks to duck typing (string? array?
file? something else? who cares... :))

Thank you very much. Anyway Ruby keeps being a great language and I
really love it (though I have not use it much yet).

Give it a couple of months and you'll be using it for everything from
shuffling your music to documenting C code :slight_smile:

···

On Wed, 2006-03-22 at 23:38 +0900, Diego.Virasoro@gmail.com wrote:

--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk

Welcome Diego,

first let me say it may not be the wisest thing to introduce oneself to
a language group by suggesting to change that language. (this may
explain the relative low volume of replies you got)

-Is there a way to have multidimentional arrays in Ruby? Ie something
like variable[3][2]? One could use arrays of arrays but it does not
look quite as clear when reading the code.

This comes up ever so often, and i don't get it. I think arrays of
arrays is the more flexible and general case. Perhaps this is enough to
make you happy?

class MultiArray
  def MultiArray.new *args
    Array.new(args.shift) {args.empty? ? nil : MultiArray.new(*args)}
  end
end

usage:

m = MultiArray.new(2, 3, 4)
m[1][2][3] = 'O'
p m

#=>[[[nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, nil]],
[[nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, "O"]]]

-Fortran 95 had a really nice feature when using arrays: you could
assign values using ranges. I am glad to see something similar exist in
Ruby too, (eg. variable[0..100]=0)
However F95 went a bit further, since the ranges could include an
optional parameter, the step. In F95 it would look something like:
variable[min:max:step] = 0
There's a lot of cases when something like this is really convinient. I
know you can produce a similar effect using a few more lines, but I
think a feature like a range+step would have several advantages, namely
that it would look more clear in less code (a common feature in Ruby)
and it's closer to the way we think to be very desirable. Has there
been any talk about such a feature in future Ruby?

Not that i know of, and to be honest I'm having a hard time imagining a
case where i would like to use it. But nevertheless i think one of the
greatest thinks about Ruby is that you can create nearly everything by
yourself, so creating a ComplexRange class and enabling Array to handle
it correctly should be possible. (ok, you loose some of the syntactic
sugar, granted)

-What is the difference between the << and + concatenation for strings?
Is it just that the former modifies the string while the second one
returns a new string? Why then not use something like +! (just as an
alternative)?

Never saw that before and have no desire to see it again, ever.
(sorry i don't want to be rude, but i would suggest to learn and get
used to a language that evolved for some years now before making such
suggestions)

-I read the discussion about the use of the "end" keyword, and possible
alternatives. Instead of trying to change that, I think it would be
[...]
In other words it would look just like for iterators (more consistent
Ruby) and at the same time make happy those that want brackets instead
of keywords to delimit if/while/unless: two birds with one stone.

Of course this would break existing code also, perhaps more subtle but
thats even more dangerous than a syntax error. Blocks are full closures
and - for example - introduce a new scope.

Thank you very much. Anyway Ruby keeps being a great language and I
really love it (though I have not use it much yet).

Again, you are very welcome! Try to ask concrete questions on real
problems and I'm quite sure you will get friendly and very helpful
answers which make your head spin and let your jaw drop when you see
whats possible even without changing the language.
(it happened to me, at least :slight_smile: )

Diego Virasoro

cheers

Simon

dblack@wobblini.net wrote:

-Is there a way to have multidimentional arrays in Ruby? Ie something
like variable[3][2]? One could use arrays of arrays but it does not
look quite as clear when reading the code.

How about:

  variable[3][2]

? :slight_smile: As long as both variable and variable[3] respond to "", you
should be OK. (They don't even have to be arrays.)

Also, it's not too difficult to write a multi dimensional array class. Basically you need to make and = accept multiple arguments. Note also, that there is a Matrix class (for n=2).

That starts to tie the language in knots. For one thing, if can take
a method with a block:

  if x { }; y end

I think things would start to get much too messy, especially with an
optional "do".

I think there's also a scoping issue involved: if and while do not introduce a new scope while blocks do:

if something
   a = 10
else
   a = 20
end

puts a # ok

[1].each do
   b = 30
end

puts b # not ok

I would recommend living with these constructs for a while, on their
own terms. I'm reasonably certain that it will cease to feel like
something is missing or wrong.

+1

Kind regards

  robert

How about:
   variable[3][2]

? :slight_smile: As long as both variable and variable[3] respond to "", you
should be OK. (They don't even have to be arrays.)

Yes, thank you. I tried something like this before sending the post but
it failed. But after reading this I realised it was an error in how I
wrote it. It still isn't asgood as it could be, but it is a small
thing.

Also, it's not too difficult to write a multi dimensional array class.
Basically you need to make and = accept multiple arguments. Note
also, that there is a Matrix class (for n=2).

Oh, I really like the Matrix class. I did not know about these
libraries (yes, as I said I am very much a newbie, sorry). And I like
the fact it can be a matrix of any object, just like Arrays. That would
make it a good candidate for a table, as well as a numerical matrix
(which is what I had in mind.

Unfortunatly the Matrix class seems to be very lacking so far. In
particular there is no (or I could not find) any assignment such as =
and similar problems. I know I can write this but I would imagine
something this basic should be part of the class already. Is there any
place one can contribute with the code and have it discussed for review
and inclusion in the future... or just a place to propose future
improvements?

I don't think this is doable with things as they are, since Ruby's
support for range indices differs from Fortran's (IIRC - I think
var[0:10:2] = 0 would set 0,2,4,6,8,10 ?).

You are right, I see what you mean. They act very differently.

That's ugly IMHO and also just syntax. "<<" is well known in other
languages (namely C++) for stream appending which is basically what it
is. Also operator "+!" might introduce problems in the syntax.

Yes, I must agree it's quite ugly... well, happy to have understood the
difference anyway.

That starts to tie the language in knots. For one thing, if can take
a method with a block:
   if x { }; y end

I think things would start to get much too messy, especially with an
optional "do".

Well, imho that what you wrote is primarely messy because of the style:
like in every language I would imagine even Ruby can be difficult to
read if one does not use a good style. Still what you say is very true:
in this case however my gut feeling would suggest the problem is in
making "do" optional. (as I said I think consistency if very
important).

I think there's also a scoping issue involved: if and while do not
introduce a new scope while blocks do:

True, I did not think of that. Although personally I must say I find
that inconsistent and in fact a reason why using blocks would be
better: nothing I cannot get used to, of course, but...

(I know Smalltalk and maybe other languages handle
conditionals as methods, but I don't think it would mesh well with
Ruby.)

Is Smalltalk so? And could someone who knows both language explain the
advantages of not using conditionals as methods? Ruby seems to be
usually as consistent as possible for example making everything either
a class or a method, so why not use conditionals as methods too? Just
curiosity.

Give it a couple of months and you'll be using it for everything from
shuffling your music to documenting C code :slight_smile:

:slight_smile:

Diego Virasoro

first let me say it may not be the wisest thing to introduce oneself to
a language group by suggesting to change that language. (this may
explain the relative low volume of replies you got)

I am really sorry. I was not meaning to say how the language should be
changed. When I wrote something like: "Why does Ruby not have X?", I
was not trying to say "This is the way Ruby should be", but rather
something like "Why did you choose Ruby should work this way?" or "What
alternatives Ruby offers?".

I hoped my post would not sound as a strong critic to Ruby because I
started by expressing how much I like it and that these are small
problems. I also explicitly explained I am no computer scientist and
that I only know Fortran and C++: with such a premises I could not have
gone very far in seriously suggesting changes to Ruby! :slight_smile:

After reading a lot of commentaries about Ruby on the net, explaining
the philosophies behind it and its features, I found myself puzzled by
some of the decisions. I understand a lot of reasons could have
contributed to the final choices:
-preserving some older language syntax
-problems in interpreting certain syntaxes (eg. ambiguity)
-possible speed penalities
-philosophical/esthetical reasons
....and many more. I was just wondering what that reason was.

Just as an example coming from Fortran I wondered too why Ruby uses
"end" instead of something like "end if". Then I found a similar
question in another thread. It was explained that in fact Ruby did use
that syntax but then had to changed because of an ambiguity raised by a
new feature.

Finally as I work in science I am particularly interested in certain
topics such as matrices, which may not be at all interesting in other
fields.

I hope my point is clear now.

Anyway I am very happy with the replies I received (thanks again) and
as I wrote before they did answer most of the questions I had.

Diego Virasoro

Hi --

···

On Thu, 23 Mar 2006, Simon Kröger wrote:

Welcome Diego,

first let me say it may not be the wisest thing to introduce oneself to
a language group by suggesting to change that language. (this may
explain the relative low volume of replies you got)

-Is there a way to have multidimentional arrays in Ruby? Ie something
like variable[3][2]? One could use arrays of arrays but it does not
look quite as clear when reading the code.

This comes up ever so often, and i don't get it. I think arrays of
arrays is the more flexible and general case. Perhaps this is enough to
make you happy?

class MultiArray
def MultiArray.new *args
   Array.new(args.shift) {args.empty? ? nil : MultiArray.new(*args)}
end
end

usage:

m = MultiArray.new(2, 3, 4)
m[1][2][3] = 'O'
p m

#=>[[[nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, nil]],
[[nil, nil, nil, nil], [nil, nil, nil, nil], [nil, nil, nil, "O"]]]

This reminds me of my favorite way to create an pseudo-auto-vivifying
hash:

   Hash.new {|h,k| h[k] = h.dup }

:slight_smile: I don't think there's an equally concise way for the array thing.

David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

Hi --

<snip>

I don't think people wanting brackets, as a general matter, is a
"bird" in the first place :slight_smile: Consistency isn't really an issue here
either, since if isn't a method; and if if were a method, but the "do"
were optional, it wouldn't be consistent anyway.

<snip>

That's a hella confusing paragraph, especially that last sentence.

···

On 3/22/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

Hi,

···

In message "Re: questions/suggestions from a Ruby newbie" on Thu, 23 Mar 2006 05:33:52 +0900, "Diego Virasoro" <Diego.Virasoro@gmail.com> writes:

Unfortunatly the Matrix class seems to be very lacking so far. In
particular there is no (or I could not find) any assignment such as =
and similar problems. I know I can write this but I would imagine
something this basic should be part of the class already. Is there any
place one can contribute with the code and have it discussed for review
and inclusion in the future... or just a place to propose future
improvements?

ruby-core list is a good place to discuss about the proposal. We'd
like to hear from Matrix users, since we are not heavy users of
Matrix by ourselves.

              matz.

Unfortunatly the Matrix class seems to be very lacking so far. In
particular there is no (or I could not find) any assignment such as =
and similar problems. I know I can write this but I would imagine
something this basic should be part of the class already. Is there any
place one can contribute with the code and have it discussed for review
and inclusion in the future... or just a place to propose future
improvements?

irb:

m = Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

=> Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

m[0, 0]

=> 1

m[2, 1]

=> 8

m * m

=> Matrix[[30, 36, 42], [66, 81, 96], [102, 126, 150]]

m.determinant

=> 0

Matrix[[1,2], [3,4]].determinant

=> -2

Hi --

How about:
   variable[3][2]

? :slight_smile: As long as both variable and variable[3] respond to "", you
should be OK. (They don't even have to be arrays.)

Yes, thank you. I tried something like this before sending the post but
it failed. But after reading this I realised it was an error in how I
wrote it. It still isn't asgood as it could be, but it is a small
thing.

I'm sure we can help you fix it if you want to post it.

That starts to tie the language in knots. For one thing, if can take
a method with a block:
   if x { }; y end

I think things would start to get much too messy, especially with an
optional "do".

Well, imho that what you wrote is primarely messy because of the style:
like in every language I would imagine even Ruby can be difficult to
read if one does not use a good style. Still what you say is very true:
in this case however my gut feeling would suggest the problem is in
making "do" optional. (as I said I think consistency if very
important).

Well, whatever style you write it in, having if take a block, while
also having if take methods that take blocks, and so forth, could get
messy -- or, if you prefer, more difficult to do with good style --
with no gain, as far as I can see.

I think there's also a scoping issue involved: if and while do not
introduce a new scope while blocks do:

True, I did not think of that. Although personally I must say I find
that inconsistent and in fact a reason why using blocks would be
better: nothing I cannot get used to, of course, but...

But the judgment that this is inconsistent is based on the a priori
notion that they are under some obligation to be the same -- which
they're not :slight_smile: They're different constructs. One of the nice things
about Ruby is that there's very little of the, "Well, *this* looks a
certain way, so *that* has to imitate it." Instead, Matz makes
careful judgments, one at a time, about what will work best in the
overall system. And he's very good at it :slight_smile:

That doesn't mean you'll love every bit of Ruby, but it does mean that
"Code blocks are delimited with do/end or {}" is not actually evidence
that if-clauses should be so delimited.

(I know Smalltalk and maybe other languages handle
conditionals as methods, but I don't think it would mesh well with
Ruby.)

Is Smalltalk so? And could someone who knows both language explain the
advantages of not using conditionals as methods? Ruby seems to be
usually as consistent as possible for example making everything either
a class or a method, so why not use conditionals as methods too? Just
curiosity.

There are quite a few keywords in Ruby, though: if, and, not or, for,
next, class, module, def, etc. None of these are methods. I don't
know Smalltalk beyond the very little that's rubbed off on me from
knowing some Smalltalkers in the Ruby community, so I can't comment on
that in depth.

David

···

On Thu, 23 Mar 2006, Diego Virasoro wrote:

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

dblack@wobblini.net schrieb:

This reminds me of my favorite way to create an pseudo-auto-vivifying
hash:

  Hash.new {|h,k| h[k] = h.dup }

:slight_smile: I don't think there's an equally concise way for the array thing.

David, is this really working for you?

   x = Hash.new {|h,k| h[k] = h.dup }
   x[1] = "x1"
   x[2]
   p x # => {1=>"x1", 2=>{1=>"x1"}}

Maybe you mean

   Hash.new {|h,k| h[k] = h.dup.clear }

Regards,
Pit

Hi --

Hi --

<snip>

I don't think people wanting brackets, as a general matter, is a
"bird" in the first place :slight_smile: Consistency isn't really an issue here
either, since if isn't a method; and if if were a method, but the "do"
were optional, it wouldn't be consistent anyway.

<snip>

That's a hella confusing paragraph, especially that last sentence.

I'm surprised you find the first sentence clearer than the second, at
least out of context :slight_smile:

What I mean is: when it comes to killing two birds with one stone, the
"bird" of people wanting to wrap conditionals in curly braces isn't
something to worry about, because in general they don't. The second
point is that if "if" were a method, but you could still give it a
block that looked like this:

   if x
     y
   end

with an implicit "do" after "x", then it wouldn't be consistent with
other method calling syntax anyway. (Also, there's the further issue
of what would happen if x were, itself, a method call.)

David

···

On Fri, 24 Mar 2006, Joe Van Dyk wrote:

On 3/22/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

Ooops, nevermind. I didn't actually test =. Apologies.

···

On 3/22/06, Matthew Moss <matthew.moss.coder@gmail.com> wrote:

> Unfortunatly the Matrix class seems to be very lacking so far. In
> particular there is no (or I could not find) any assignment such as =
> and similar problems. I know I can write this but I would imagine
> something this basic should be part of the class already. Is there any
> place one can contribute with the code and have it discussed for review
> and inclusion in the future... or just a place to propose future
> improvements?

irb:

> m = Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
=> Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

> m[0, 0]
=> 1

> m[2, 1]
=> 8

> m * m
=> Matrix[[30, 36, 42], [66, 81, 96], [102, 126, 150]]

> m.determinant
=> 0

> Matrix[[1,2], [3,4]].determinant
=> -2

Hi --

···

On Thu, 23 Mar 2006, Pit Capitain wrote:

dblack@wobblini.net schrieb:

This reminds me of my favorite way to create an pseudo-auto-vivifying
hash:

  Hash.new {|h,k| h[k] = h.dup }

:slight_smile: I don't think there's an equally concise way for the array thing.

David, is this really working for you?

x = Hash.new {|h,k| h[k] = h.dup }
x[1] = "x1"
x[2]
p x # => {1=>"x1", 2=>{1=>"x1"}}

Maybe you mean

Hash.new {|h,k| h[k] = h.dup.clear }

Oh, I knew someone would find a problem with it :slight_smile: I think that's
right (the 'clear'). I'd only tested it, if it's worthy of the name
test, with things like: x[1][2][3].

Even so, I think it's still the most concise implementation of this
concept.

David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black