From: Robert Klemme Date: 2009-11-25T18:31:36+09:00 Subject: Re: Difference between << and += for Strings and Arrays. Bug? 2009/11/24 Pieter Hugo : > Thanks 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. > When 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. > What 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/