Post by Pieter HugoThanks for the quick responses and insights. While I understand the
issue now I must confess that it perturbs my 'least surprise'
expectation. Why was it decided that '<<' should reference the original
object but '+' should create a new object.
<< does not always modify the receiver
irb(main):001:0> n = 1
=> 1
irb(main):002:0> m = n << 5
=> 32
irb(main):003:0> n.equal? m
=> false
irb(main):004:0>
The semantic of "appending" something to an object was indeed
inherited from C++ as Brian explained.
Post by Pieter HugoWhen one works with a
variable one shouldn't need to worry about what other stuff is being
modified due to a unintentional reference?
OO is all about modifying state of objects. The state change is a
side effect of a method call - and this is intentional. That way you
can model how real world things behave. A bank account does not
change as the effect of you depositing 10 bucks. If it would, you
would get a new bank account number after every deposit or withdrawal.
For obvious reasons this is a bad idea. Objects work the same way:
you change their state but you do not get a new one every time. There
are of course special cases (such as Fixnum and Bignum in Ruby) where
objects are immutable. This does make sense as well (just think about
keys in a Hash, you would have to rehash all the time if key state
would change).
This means in turn that it is your task as a programmer in an OO
language to think about what classes and objects you need, what state
transitions of an object you want to reasonably allow and which not.
You create your application by picking deliberate choices. For some
classes someone else did that for you: that's all the built in stuff
and the standard library code - actually, every library's code that
you are using. In those cases you need to adjust your usage of that
code to the semantics and conventions determined by that code.
Post by Pieter HugoWhat other operators are
doing this? I noticed that the '.pop' array method was also modifying
the referenced array
a = [1,2]
b = a
b.pop
results in a and be being [1]
I worked around with
a = [1,2]
b = []
b += a
b.pop
Now b == [1] and a == [1,2], but its not as sleek. Is there maybe
another way?
Why do you want to have two copies of your Array? #push and #pop are
intended to allow usage of an Array as stack (AKA LIFO). If you want
to use an array as LIFO there is no point in creating two copies
during every push and pop operation because you want only a single
stack and you want everybody who sees the stack have the same idea of
it. Otherwise you would be able to pop the same top element off the
stack multiple times. That does not make sense.
If you only need to know what the last element is, you can use #last or a[-1].
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/