On 30.12.2007 02:17, MonkeeSage wrote:
> On Dec 29, 6:06 pm, Gary Wright <gwtm...@mac.com> wrote:
>> On Dec 29, 2007, at 6:24 PM, MonkeeSage wrote:
>>> I wasn't arguing for or against #last=, per se; I was only trying to
>>> explain why it doesn't make sense, _to me_, "Unless the semantics [of
>>> #last] change," to have #last=. I.e., # subscripts the array and
>>> returns the value of the index, but #last returns the value of
>>> subscripting the array at index #length-1; it is another level of
>>> abstraction removed from #; so with those semantics, #last= would be
>>> like #length= (or #pop=), and you end up with exceptions when the
>>> value is immutable.
>> Why do you shift your terminology when talking about last? Using
>> your terminology but my mental model of arrays:
>> #[n] subscripts the array with n and returns the value of the index
>> #[-1] subscripts the array with (length-1) and returns the value of
>> the index
>> #last subscripts the array with (length-1) and returns the value of
>> the index
>> Why do you rephrase that last case as:
>> #last returns the value of subscripting the array at index #length-1
>> Are you suggesting that #last does something distinctly different than
>> subscripting via -1? If not then it would seem your argument against
>> last=
>> would apply just as well to 'array[-1] = x'. Are you suggesting that
>> element assignment with negative subscripts also don't make sense to
>> you?
>> Objections to last= and first= based on redundancy is one thing, but
>> you seem to be objecting based on semantics and I'm trying to understand
>> that objection because the semantics seem to be quite natural to me.
>> Gary Wright
> As I understand it, #last is semantically equivalent to this code:
> class Array
> def last
> self[self.length-1]
> end
> end
> Which means that #last is a specialized form of #, which means that
> it is another level of abstraction removed from #. So the result of
> #last is the same as #[-1], but the semantics of #last are more like
> #length or #pop, which are also a level of abstraction removed from
> #.
I do not understand your talking of "removing a level of abstraction".
Basically, I'd say #first and #last are more abstract than # because
they add semantics and they are (or at least could be) built on top of
#. You do not have to provide the detail of the index to access.
Then, comparing #, #first and #last with #length and #pop seems very
strange to me - for different reasons: #length has nothing to do with
element access (which is all #, #first and #last are about). #pop on
the other hand does deal with element access but it also modifies the Array.
> Once again, I'm not arguing against #last=, per se, but I fail to
> see how it differs at the present time from, for example:
> class Array
> def foo
> self[self.length-1]
> end
> end
Ah, I believe I start to see something: you do not seem to recognize #
and #= as _regular methods_. With the implementation of #foo that you
present above you can not do this assignment:
> [1,2,3].foo = 25
Consider this:
irb(main):001:0> class Foo
irb(main):002:1> def last;1;end
irb(main):003:1> end
=> nil
irb(main):004:0> f=Foo.new
=> #<Foo:0x7ff958ec>
irb(main):005:0> f.last
=> 1
irb(main):006:0> f.last = 10
NoMethodError: undefined method `last=' for #<Foo:0x7ff958ec>
from (irb):6
from :0
irb(main):007:0> class Foo
irb(main):008:1> def last=(x) puts "assigned"; end
irb(main):009:1> end
=> nil
irb(main):010:0> f.last = 10
assigned
=> 10
You have to implement #last= in order to be able to do the assignment.
You do not automatically get it for free when defining #last. So #last
corresponds to (or: "can be implemented in terms of") # while #last=
corresponds to #=. Similarly #last also works with frozen instances
(like # does) but #last= does not (like #= does not). Does this
make sense?
I do not know your (programming) background but if you think Ruby's
Array is similar to a C array then maybe you should drop that notion
because they are vastly different (note, this does not refer to the
implementation but to how they are used in each language).
> Or more simply, [1,2,3].length = 20.
As #length has nothing to do with element access I would expect the
_length_ of the Array to change when assigning to it (e.g. by pruning or
appending nils).
> Of course, one could implement those methods where they so inclined,
> but it would make the semantics of, e.g., #foo and #foo= very
> different. In this case of #last / #first, I don't think it is very
> confusing to have those different semantics; I was probably being too
> much of a stickler for "purism".
Again, this semantic difference you are talking about is still not clear
to me. The semantic between #last and #last= and #first and #first= I
can see at the moment is the lack of a parameter as has been mentioned:
while you can make #last and #first return a sub array you can only
assign to a single element with the assignment variants. But that seems
ok to me.
Kind regards
robert