From: Robert Klemme Date: 2009-12-23T01:46:56+09:00 Subject: Re: Ruby's implementation of Fixnum-assignment 2009/12/22 RichardOnRails : > On Dec 22, 9:40 am, Robert Klemme wrote: >> 2009/12/22 Rick DeNatale >> >> >> >> > On Tue, Dec 22, 2009 at 3:24 AM, Robert Klemme >> > wrote: >> > > 2009/12/21 RichardOnRails : > Thanks for honoring me with responses to what you guys must view as > drivel.  And I accept the assertion that Ruby recognizes "a=1" as an > assignment statement rather than an invoking a apparently mythical "=" > operator. On syntax level it's an operator as many others but underneath it is quite different. If you think about it for a moment this is the only operation which can change an object's state for all non built in classes. >>> Actually, I believe all this reasoning about Fixnums being immediate >>> values is totally overdone.  From a Ruby programmer's perspective it >>> is completely irrelevant (if you put performance aside for the >>> moment). [snip] >> Agreed. > > I see your point.  But I've got a "burr under my intellectual saddle." That must hurt... > Both Robert and Matz responded a few weeks ago on a question I raised > about implementing a Fixnum ++ operator in Ruby functionally > equivalent to C's prefix_++ operator.  I'm not lobbying for such a > change; I merely suggested that it's possible.  The response was such > an operator would be functionally equivalent to "turning 1 into 2." > > But I see the following: > a = 1 # ID = 3 > a = 2 # ID = 5 > b = 1 # ID = 1 > b++   # implemented as b.++() which increments b's object's ID by 2 > and checks for edge cases; Please forget your idea of object ids being modified. An object id is just a derived bit of data. And, btw, object ids *never* change because the identity of an object does not change. > I don't see such an implementation as > disturbing any other object, at least none on my machine's hardware > and software state. You are probably overlooking effects on consistency of the whole language. While it would be technically doable to introduce ++ into the language the consequences are undesirable. 1. prefix ++ operator would change the state of an instance if you wanted to roughly retain C++ semantics. 2. This means, that for other (non Fixnum) classes this will happen: a = anything_but_Fixnum() b = a ++a b == a # => true b.equal? a # => true, identity does not change But, if what you wrote were followed (no other object is affected): a = any_Fixnum() b = a ++a b == a # => false b.equal? a # => false, identity has changed 3. Also, if Fixnums should behave like other classes, suddenly a Fixnum becomes mutable, which cannot be since Fixnums are immediate and do not have a place to store state that can change. 4. The only salvation is to make "++a" syntactic sugar for "a += 1" or rather "a = a + 1" (or maybe even "a = a.succ"), i.e. an expression which contains an assignment. Then "b == a" under 2. above would return "false" as well and everything is consistent again (assuming standard implementations of + which do not change the instance but return a new one). I believe Matz decided against because a) there is a pretty short idiom which does this already ("a += 1") and b) that existing idiom has an equals sign in there thus making the assignment obvious; "++a" on the contrary does not have an equals sign anywhere and thus would obscure the fact that under the hood an assignment is taking place. This would make the code harder to read while not bringing any benefits to the language. >> "a=1" is an assignment meaning, it >> takes whatever object reference the evaluation of the expression on >> the right side yields and puts it into the storage location denoted by >> "a".  There is no method invoked, certainly no method on "a" which - >> as I said - is no object but just a place in storage. > > But aside from copying (in this case) 1's ID, Ruby must first look up Not "1's ID" is copied but the "reference to 1". "1" is only special in that the reference does not point to an actual object. > a's > presence in the current scope's portion of the symbol table and if not > present, insert it, or otherwise deal with the existing ID for the "a" > entry: (i) if the ID is an actual address of data in some pool, > decrement its reference count if positive; or (ii) do nothing for > Fixnums, true, false and nil). AFAIK Ruby has a mark and sweep garbage collector which does not employ reference counting. http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29 > I wouldn't even have posted my ++ question if I could follow my way > through Ruby's C or C++ implementation.  But in about my last decade > before retirement, I was the debugger/enhancer of several > organization's apps,  so I know daunting the hunt through C/C++ code > is, especially an app as big as Ruby.  But if you pointed me to Ruby's > Finite State Machine (there's GOT to be one), I'd ... I find that hard as well... Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/