Add Array#first= and Array#last= to std lib

Hi,

just today I came across a situation where I needed Array#last=
because I wanted to do

an_array.last += 1

Does anybody else see this as useful? Any issues with this? If not
I'll open an RCR.

Kind regards

robert

···

--
use.inject do |as, often| as.you_can - without end

Is there a problem with doing something like this:

an_array[-1] += 1

Joe

···

On Dec 27, 2007 4:59 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

Hi,

just today I came across a situation where I needed Array#last=
because I wanted to do

an_array.last += 1

Does anybody else see this as useful? Any issues with this? If not
I'll open an RCR.

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

I'll bite... :wink:

What would you expect this to do?

  .last = 1

Regards,
George.

···

On Dec 27, 2007 8:59 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

Hi,

just today I came across a situation where I needed Array#last=
because I wanted to do

an_array.last += 1

Does anybody else see this as useful? Any issues with this? If not
I'll open an RCR.

There's already array#last and array#first

you csn do what you want with an_array[0] and an_array[-1]

irb(main):006:0> an_array = [3, 5, 7, 11, 9, 2]
=> [3, 5, 7, 11, 9, 2]
irb(main):007:0> an_array.last
=> 2
irb(main):008:0> an_array.first
=> 3
irb(main):009:0> an_array[0] = 19
=> 19
irb(main):010:0> an_array[-1] = 1
=> 1
irb(main):011:0> an_array.last
=> 1
irb(main):012:0> an_array.first
=> 19
irb(main):013:0>

···

On Dec 27, 4:59 am, Robert Klemme <shortcut...@googlemail.com> wrote:

Hi,

just today I came across a situation where I needed Array#last=
because I wanted to do

an_array.last += 1

Does anybody else see this as useful? Any issues with this? If not
I'll open an RCR.

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

George wrote:

What would you expect this to do?

.last = 1

The same thing as "[-1] = 1", I'd imagine.
The problem I'm seeing would be this: If you allow arr.last = x, you'd also
have to allow arr.last(n) = x if you want to be consistent, but that's not
syntactically possible.

···

--
NP: Katatonia - Endtime
Jabber: sepp2k@jabber.org
ICQ: 205544826

Well, yes. But I don't want to. Instead I'd rather use last= and first= in some circumstances much the same way as I sometimes rather use last and first instead of [0] and [-1].

So far the only argument against I have seen so far is the question about assignment to an empty array. In that case I'd say, either raise an exception or silently add the element. Have to think about this a bit.

Cheers

  robert

···

On 27.12.2007 22:18, bbiker wrote:

On Dec 27, 4:59 am, Robert Klemme <shortcut...@googlemail.com> wrote:

Hi,

just today I came across a situation where I needed Array#last=
because I wanted to do

an_array.last += 1

Does anybody else see this as useful? Any issues with this? If not
I'll open an RCR.

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

There's already array#last and array#first

you csn do what you want with an_array[0] and an_array[-1]

Agree. It's tempting to treat #first / #last as 0 / -1, but in
actuality they are method calls and simply return a value; they don't
subscript an array. Setting #last is not semantically different than
[1,2,3].pop = 4, it's just that #last is just a bit more subtle.

Regards,
Jordan

···

On Dec 27, 9:55 am, Sebastian Hungerecker <sep...@googlemail.com> wrote:

George wrote:
> What would you expect this to do?

> .last = 1

The same thing as "[-1] = 1", I'd imagine.
The problem I'm seeing would be this: If you allow arr.last = x, you'd also
have to allow arr.last(n) = x if you want to be consistent, but that's not
syntactically possible.

--
NP: Katatonia - Endtime
Jabber: sep...@jabber.org
ICQ: 205544826

Hi, Robert,

In this case, I think the best way for you is to do it by yourself.
You can override an existing class in Ruby, even the one is a standard library class.

Provide a source file containing:

class Array
   def first=(v)
     self[0] = v
   end

   def last=(v)
     self[-1] = v
   end
end

and require it as you like.
And then you can use Array#first= and Array#last= as other standard methods for the class.

Yu-raku-an.

Robert Klemme wrote:

···

On 27.12.2007 22:18, bbiker wrote:

On Dec 27, 4:59 am, Robert Klemme <shortcut...@googlemail.com> wrote:

Hi,

just today I came across a situation where I needed Array#last=
because I wanted to do

an_array.last += 1

Does anybody else see this as useful? Any issues with this? If not
I'll open an RCR.

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

There's already array#last and array#first

you csn do what you want with an_array[0] and an_array[-1]

Well, yes. But I don't want to. Instead I'd rather use last= and first= in some circumstances much the same way as I sometimes rather use last and first instead of [0] and [-1].

So far the only argument against I have seen so far is the question about assignment to an empty array. In that case I'd say, either raise an exception or silently add the element. Have to think about this a bit.

Cheers

    robert

--------------------------------------
Easy + Joy + Powerful = Yahoo! Bookmarks x Toolbar
http://pr.mail.yahoo.co.jp/toolbar/

Robert Klemme wrote:

So far the only argument against I have seen so far is the question
about assignment to an empty array. In that case I'd say, either raise
an exception or silently add the element. Have to think about this a bit.

I really don't think that's much of an argument. Since last= would be
equivalent to [-1]= in every other case, it should behave like it in
this case as well (meaning raise an exception) and if last= uses =
(which I assume, it would) that would automatically be the case anyway.

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

I don't see what you are getting at here. #pop is destructive, #last
is not. What does #last return when it is called? It returns a
reference to the last element. So why would #last= do anything other
then set the reference of the last element? Seems obvious to me. So we
can't do last(n) = x, due to syntax constraints, oh well. It would
still be convenient to have the obvious n=1, no arg case. I find that
my programs are usually easier to read when I can use words rather non-
alphabetic symbols.

T.

···

On Dec 27, 12:54 pm, MonkeeSage <MonkeeS...@gmail.com> wrote:

On Dec 27, 9:55 am, Sebastian Hungerecker <sep...@googlemail.com> > wrote:

> George wrote:
> > What would you expect this to do?

> > .last = 1

> The same thing as "[-1] = 1", I'd imagine.
> The problem I'm seeing would be this: If you allow arr.last = x, you'd also
> have to allow arr.last(n) = x if you want to be consistent, but that's not
> syntactically possible.

> --
> NP: Katatonia - Endtime
> Jabber: sep...@jabber.org
> ICQ: 205544826

Agree. It's tempting to treat #first / #last as 0 / -1, but in
actuality they are method calls and simply return a value; they don't
subscript an array. Setting #last is not semantically different than
[1,2,3].pop = 4, it's just that #last is just a bit more subtle.

MonkeeSage wrote:

It's tempting to treat #first / #last as 0 / -1, but in
actuality they are method calls and simply return a value

Ok, I'm confused. You seem to be saying that first and last are different than
using because they are methods and return a value, right? Does that mean
that you mean to imply that Array# is not a method or that it doesn't return
a value?
I'm asking because it is starting to look to me like that is what you're
saying, but Array# most certainly is a method and it most certainly does
return a value.

···

--
NP: Jon Oliva's Pain - Walk Alone
Jabber: sepp2k@jabber.org
ICQ: 205544826

George wrote:

What would you expect this to do?
  .last = 1

The same thing as "[-1] = 1", I'd imagine.
The problem I'm seeing would be this: If you allow arr.last = x, you'd also
have to allow arr.last(n) = x if you want to be consistent, but that's not
syntactically possible.

I do not see why allowing last= would make lasts(n)= necessary. Array#last and Array#first index exactly one argument - no need for additional indexing.

Agree. It's tempting to treat #first / #last as 0 / -1, but in
actuality they are method calls and simply return a value; they don't
subscript an array.

Array# and Array#= are method calls as well.

> Setting #last is not semantically different than

[1,2,3].pop = 4, it's just that #last is just a bit more subtle.

#last is non destructive while #pop is destructive. Not the same.

Regards

  robert

···

On 27.12.2007 18:53, MonkeeSage wrote:

On Dec 27, 9:55 am, Sebastian Hungerecker <sep...@googlemail.com> > wrote:

I am aware of that, thanks. The whole point of this discussion was to
find out whether there are serious reasons why one should not have
this in the standard lib. Array#first and #last *are* in the standard
lib already and at the moment I do not see any reason why Array#first=
and Array#last= should not be.

Kind regards

robert

···

2007/12/28, Yu-raku-an <yu_raku_an@yahoo.co.jp>:

Hi, Robert,

In this case, I think the best way for you is to do it by yourself.
You can override an existing class in Ruby, even the one is a standard
library class.

--
use.inject do |as, often| as.you_can - without end

IOW, #pop returns a value, and this is just what #last does. One could
argue that #last and #[-1] *should be* synonymous (which may be the
point of the proposal); but as it currently stands, #last means the
same thing as `def l(a); a[-1]; end` so it makes no sense to have a
setter for it. Unless the semantics change, (to me at least) it is non-
sense to have #last=. It's the same as a.pop = 3.

Regards,
Jordan

···

On Dec 27, 12:52 pm, Trans <transf...@gmail.com> wrote:

On Dec 27, 12:54 pm, MonkeeSage <MonkeeS...@gmail.com> wrote:

> On Dec 27, 9:55 am, Sebastian Hungerecker <sep...@googlemail.com> > > wrote:

> > George wrote:
> > > What would you expect this to do?

> > > .last = 1

> > The same thing as "[-1] = 1", I'd imagine.
> > The problem I'm seeing would be this: If you allow arr.last = x, you'd also
> > have to allow arr.last(n) = x if you want to be consistent, but that's not
> > syntactically possible.

> > --
> > NP: Katatonia - Endtime
> > Jabber: sep...@jabber.org
> > ICQ: 205544826

> Agree. It's tempting to treat #first / #last as 0 / -1, but in
> actuality they are method calls and simply return a value; they don't
> subscript an array. Setting #last is not semantically different than
> [1,2,3].pop = 4, it's just that #last is just a bit more subtle.

I don't see what you are getting at here. #pop is destructive, #last
is not. What does #last return when it is called? It returns a
reference to the last element. So why would #last= do anything other
then set the reference of the last element? Seems obvious to me. So we
can't do last(n) = x, due to syntax constraints, oh well. It would
still be convenient to have the obvious n=1, no arg case. I find that
my programs are usually easier to read when I can use words rather non-
alphabetic symbols.

T.

Robert Klemme wrote:

I do not see why allowing last= would make lasts(n)= necessary.

For consistency. I believe that any method foo= should be equivalent to the
method foo except for the fact that it sets the value instead of getting it,
which in this case isn't possible (without changing the language). I mean,
that's not a major problem, but it'd feel a tad incosistent to me.

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

>
> > George wrote:
> > > What would you expect this to do?
>
> > > .last = 1
>
> > The same thing as "[-1] = 1", I'd imagine.
> > The problem I'm seeing would be this: If you allow arr.last = x, you'd also
> > have to allow arr.last(n) = x if you want to be consistent, but that's not
> > syntactically possible.
>
> > --
> > NP: Katatonia - Endtime
> > Jabber: sep...@jabber.org
> > ICQ: 205544826
>
> Agree. It's tempting to treat #first / #last as 0 / -1, but in
> actuality they are method calls and simply return a value; they don't
> subscript an array. Setting #last is not semantically different than
> [1,2,3].pop = 4, it's just that #last is just a bit more subtle.

I don't see what you are getting at here. #pop is destructive, #last
is not. What does #last return when it is called? It returns a
reference to the last element. So why would #last= do anything other
then set the reference of the last element? Seems obvious to me. So we
can't do last(n) = x, due to syntax constraints, oh well. It would
still be convenient to have the obvious n=1, no arg case. I find that
my programs are usually easier to read when I can use words rather non-
alphabetic symbols.

T.

Amen, big +1, I guess lots of us define #last= and #first=, I do it,
it is just that readable and I did not even check the
doc before trying to use it first, I hate to be disappointed by my
favorite language :wink:

Cheers
Robert

···

On Dec 27, 2007 7:52 PM, Trans <transfire@gmail.com> wrote:

On Dec 27, 12:54 pm, MonkeeSage <MonkeeS...@gmail.com> wrote:
> On Dec 27, 9:55 am, Sebastian Hungerecker <sep...@googlemail.com> > > wrote:

--

http://ruby-smalltalk.blogspot.com/

---
All truth passes through three stages. First, it is ridiculed. Second,
it is violently opposed. Third, it is accepted as being self-evident.
Schopenhauer (attr.)

MonkeeSage wrote:

IOW, #pop returns a value, and this is just what #last does.

How is different in that regard? That only returns a value, too.

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

no it is not!

irb(main):018:0> p an_array
[19, 5, 7, 11, 9, 3]
=> nil
irb(main):019:0> an_array.last
=> 3
irb(main):020:0> p an_array
[19, 5, 7, 11, 9, 3]
=> nil
irb(main):022:0> an_array.pop
=> 3
irb(main):023:0> p an_array
[19, 5, 7, 11, 9]
=> nil

Note that pop actually removes the last item

irb(main):025:0* an_array.pop = 3
NoMethodError: undefined method `pop=' for [19, 5, 7, 11, 9]:Array
        from (irb):25

irb(main):029:0> p an_array
[19, 5, 7, 11, 10]
=> nil
irb(main):030:0> an_array[-1] += 1
=> 11
irb(main):031:0> p an_array
[19, 5, 7, 11, 11]

There's is no need for Array#last= or Array#first=

since you can simply use an_array[-1] += 1 or an_array[0] += 1

···

On Dec 27, 2:15 pm, MonkeeSage <MonkeeS...@gmail.com> wrote:

On Dec 27, 12:52 pm, Trans <transf...@gmail.com> wrote:

> On Dec 27, 12:54 pm, MonkeeSage <MonkeeS...@gmail.com> wrote:

> > On Dec 27, 9:55 am, Sebastian Hungerecker <sep...@googlemail.com> > > > wrote:

> > > George wrote:
> > > > What would you expect this to do?

> > > > .last = 1

> > > The same thing as "[-1] = 1", I'd imagine.
> > > The problem I'm seeing would be this: If you allow arr.last = x, you'd also
> > > have to allow arr.last(n) = x if you want to be consistent, but that's not
> > > syntactically possible.

> > > --
> > > NP: Katatonia - Endtime
> > > Jabber: sep...@jabber.org
> > > ICQ: 205544826

> > Agree. It's tempting to treat #first / #last as 0 / -1, but in
> > actuality they are method calls and simply return a value; they don't
> > subscript an array. Setting #last is not semantically different than
> > [1,2,3].pop = 4, it's just that #last is just a bit more subtle.

> I don't see what you are getting at here. #pop is destructive, #last
> is not. What does #last return when it is called? It returns a
> reference to the last element. So why would #last= do anything other
> then set the reference of the last element? Seems obvious to me. So we
> can't do last(n) = x, due to syntax constraints, oh well. It would
> still be convenient to have the obvious n=1, no arg case. I find that
> my programs are usually easier to read when I can use words rather non-
> alphabetic symbols.

> T.

IOW, #pop returns a value, and this is just what #last does. One could
argue that #last and #[-1] *should be* synonymous (which may be the
point of the proposal); but as it currently stands, #last means the
same thing as `def l(a); a[-1]; end` so it makes no sense to have a
setter for it. Unless the semantics change, (to me at least) it is non-
sense to have #last=. It's the same as a.pop = 3.

Regards,
Jordan- Hide quoted text -

- Show quoted text -

George wrote:

What would you expect this to do?
  .last = 1

The same thing as "[-1] = 1", I'd imagine.
The problem I'm seeing would be this: If you allow arr.last = x, you'd also
have to allow arr.last(n) = x if you want to be consistent, but that's not
syntactically possible.
--
NP: Katatonia - Endtime
Jabber: sep...@jabber.org
ICQ: 205544826

Agree. It's tempting to treat #first / #last as 0 / -1, but in
actuality they are method calls and simply return a value; they don't
subscript an array. Setting #last is not semantically different than
[1,2,3].pop = 4, it's just that #last is just a bit more subtle.

I don't see what you are getting at here. #pop is destructive, #last
is not. What does #last return when it is called? It returns a
reference to the last element. So why would #last= do anything other
then set the reference of the last element? Seems obvious to me. So we
can't do last(n) = x, due to syntax constraints, oh well. It would
still be convenient to have the obvious n=1, no arg case. I find that
my programs are usually easier to read when I can use words rather non-
alphabetic symbols.

T.

IOW, #pop returns a value, and this is just what #last does. One could
argue that #last and #[-1] *should be* synonymous (which may be the
point of the proposal); but as it currently stands, #last means the
same thing as `def l(a); a[-1]; end` so it makes no sense to have a
setter for it.

This is getting weirder and weirder. I do not follow your argument here at all. If you say that #last is synonymous to [-1] then it would make even more sense to make #last= synonymous to [-1]=.

Unless the semantics change, (to me at least) it is non-
sense to have #last=. It's the same as a.pop = 3.

Definitively not, as has been pointed out: pop is destructive, last is not.

  robert

···

On 27.12.2007 20:15, MonkeeSage wrote:

On Dec 27, 12:52 pm, Trans <transf...@gmail.com> wrote:

On Dec 27, 12:54 pm, MonkeeSage <MonkeeS...@gmail.com> wrote:

On Dec 27, 9:55 am, Sebastian Hungerecker <sep...@googlemail.com> >>> wrote:

Robert Klemme wrote:
> I do not see why allowing last= would make lasts(n)= necessary.

For consistency. I believe that any method foo= should be equivalent to the
method foo except for the fact that it sets the value instead of getting it,
which in this case isn't possible (without changing the language). I mean,
that's not a major problem, but it'd feel a tad incosistent to me.

You're right. Actually I was not aware that you could actually use an
argument with last. Thanks for pointing that out!

And I agree, that changes the situation a bit. As a workaround you
could implicitly use the number of elements when assigning an Array
but I doubt it's a good idea. What if you wanted the last element to
be that array and not replace the last n elements? That situation
could not be distinguished. Hm...

Re your other posting: yes, making last= behave like [-1]= is
certainly a good idea. So it's "throw an exception".

irb(main):004:0> a=
=>
irb(main):005:0> a[-1]=123
IndexError: index -1 out of array
        from (irb):5:in `='
        from (irb):5

Also a tad inconsistent:

irb(main):006:0> a[0]=123
=> 123
irb(main):007:0> a
=> [123]

So at least I now have an idea why last= is absent from the std lib.
So the discussion was definitively worthwhile.

Kind regards

robert

···

2007/12/28, Sebastian Hungerecker <sepp2k@googlemail.com>:
        from :0

--
use.inject do |as, often| as.you_can - without end