List assignment syntax

I'm a little dissatisfied with the list assignment syntax of ruby.
On an example:

    irb(main):001:0> a = [2, [3, 5], 8]
    => [2, [3, 5], 8]

This works:

    irb(main):002:0> x, (y, ), z = a
    => [2, [3, 5], 8]

But this doesn't, although I'd like to use it instead of the above.

    irb(main):003:0> x, (y), z = a
    SyntaxError: compile error
    (irb):3: syntax error
    x, (y), z = a
           ^
            from (irb):3

None of these work, so I know of no simple way to ignore an array element:

    irb(main):004:0> x, (), z = a
    SyntaxError: compile error
    (irb):4: syntax error
    x, (), z = a
          ^
            from (irb):4
    irb(main):005:0> x, (, ), z = a
    SyntaxError: compile error
    (irb):5: syntax error
    x, (, ), z = a
         ^
    (irb):5: syntax error
            from (irb):5
    irb(main):006:0>

These flexible list forms could imo be very useful. If ruby had the
array slicing idioms found in other languages (eg perl, mathematica),
for example if `a[[0, 2]]' returned `[a[0], a[2]]', there wouldn't
be so much need to this, as one would just say `x, z = a[[0, 2]]'.
(Does ruby have such a slicing method built in that I'm unaware of?)

I'd like to see your opinion about whether you think this kind of lhs syntax
are worth to be added to ruby, and especially whether it can cause any kind of
syntax ambugnuity or confusion.

And at last, two quick random thoughts:

1. Why does parse.y have the declaration `%token tRPAREN' if that token
type is apparently never used? (Even bison shows unused tokens in the
.output file if called with -d.)

2. It would be nice if irb printed a linefeed if you quit the readline
prompt by pressing control-d. This way it causes the shell prompt to be
printed in the same line as the ruby prompt. This, of course, causes
problem only to non-windows users that quit with control-d instead of
exit, and have readline in irb, which is a minority, but still...

Thanks in advance,

ambrus

Sorry, I've just found that this works instead: x, (*), z = a

ambrus

···

On Sat, Jan 08, 2005 at 07:28:46AM +0900, Zsban Ambrus wrote:

None of these work, so I know of no simple way to ignore an array element:
    irb(main):004:0> x, (), z = a
    irb(main):005:0> x, (, ), z = a

[snip]

These flexible list forms could imo be very useful. If ruby had the
array slicing idioms found in other languages (eg perl, mathematica),
for example if `a[[0, 2]]' returned `[a[0], a[2]]', there wouldn't
be so much need to this, as one would just say `x, z = a[[0, 2]]'.
(Does ruby have such a slicing method built in that I'm unaware of?)

  a = %w|help this foo perhaps bar does|
  puts a.values_at(-1,1,3,0)

regards,
andrew

···

On Sat, 8 Jan 2005 07:28:46 +0900, Zsban Ambrus <ambrus@math.bme.hu> wrote:

--
Andrew L. Johnson http://www.siaris.net/
      Perl can certainly be used as a first computer language, but
      it was really designed to be a *last* computer language.
          -- Larry Wall

Zsban Ambrus wrote:

I'm a little dissatisfied with the list assignment syntax of ruby.
On an example:

    irb(main):001:0> a = [2, [3, 5], 8]
    => [2, [3, 5], 8]

This works:

    irb(main):002:0> x, (y, ), z = a
    => [2, [3, 5], 8]

Personally, I would like being able to assign to nil in that case. I've seen "_" been used as a throw away assignment target, but that's just not as expressive as "nil", IMHO.

Good!
Not as subtle, but just in case it helps: :slight_smile:
             =>a = [2, [3, 5], 8] # Given.
[2, [3, 5], 8]

             =>x, y = [0,2].collect {|i| a[i]}
[2, 8]
             =>a.flatten
[2, 3, 5, 8]

Is there any reason this can't be changed to a.at(1,2,3,4)? It'd make
for a more consistent feel than specialcasing the one-argument case.

martin

···

Andrew Johnson <ajohnson@cpan.org> wrote:

  a = %w|help this foo perhaps bar does|
  puts a.values_at(-1,1,3,0)

That seems like a good idea.
T.

···

On Saturday 08 January 2005 07:11 am, Florian Gross wrote:

Zsban Ambrus wrote:
> I'm a little dissatisfied with the list assignment syntax of ruby.
> On an example:
>
> irb(main):001:0> a = [2, [3, 5], 8]
> => [2, [3, 5], 8]
>
> This works:
>
> irb(main):002:0> x, (y, ), z = a
> => [2, [3, 5], 8]

Personally, I would like being able to assign to nil in that case. I've
seen "_" been used as a throw away assignment target, but that's just
not as expressive as "nil", IMHO.

"Florian Gross" <flgr@ccan.de> wrote in message
news:34a0olF483uq0U2@individual.net...

Zsban Ambrus wrote:

> I'm a little dissatisfied with the list assignment syntax of ruby.
> On an example:
>
> irb(main):001:0> a = [2, [3, 5], 8]
> => [2, [3, 5], 8]
>
> This works:
>
> irb(main):002:0> x, (y, ), z = a
> => [2, [3, 5], 8]

Personally, I would like being able to assign to nil in that case. I've
seen "_" been used as a throw away assignment target, but that's just
not as expressive as "nil", IMHO.

Is there not a more general pattern-match + assign variables, much like
regular expressions do a pattern-match + assign?

Would it be nice to be able to pick up several pattern-matched variables
concisely for all ruby objects?

list_pattern = list
    # like example above
    # instead of: x = list[0]; y = list[1][0], z = list[2]

hash_pattern = hash
    # instead of: x = hash[:a]; y = hash[:b][:c]; z = hash[:d]

obj_pattern = obj
    # instead of: x = obj.a; y = obj.b.c; z = obj.d

And compose them:
[x, hash_pattern, z] = list_with_item_hash_items

And use them in parameter lists, for loops, etc.
    def f ( event_name, (start, end), response ); .... end
    for x, (y,), z in list_with_item_list_items do ... end

What do other Ruby-ists think?

Problem is with what gets returned.

  a=[1,2,5,7]
  a.at(1) => 2
  a.values_at(1) => [2]

T.

···

On Saturday 08 January 2005 11:46 am, Martin DeMello wrote:

Andrew Johnson <ajohnson@cpan.org> wrote:
> a = %w|help this foo perhaps bar does|
> puts a.values_at(-1,1,3,0)

Is there any reason this can't be changed to a.at(1,2,3,4)? It'd make
for a more consistent feel than specialcasing the one-argument case.

martin