From: Martin DeMello Date: 2012-11-24T19:59:22+09:00 Subject: Re: I'm exploiting Ruby references On Sat, Nov 24, 2012 at 2:39 AM, Nokan Emiro wrote: > I think I've found a nice example that shows the power of Ruby > usually *not* making copies of objects. But while I was trying to > take it further, I just bumped into a limitation: as far as I know it's > impossible to replace an object with any other and changing all > the references pointing to the new one at once. It is possible to do > it with #replace(other_obj) only if the type of the new object is still an > Array, Hash or String. But what if I want to change the underlying > type? Smalltalk supports this with the `become` method. Here's one ruby implementation I found on github: https://github.com/cout/become > Let me explain what I'm trying to do in a more details: [...] > Variables are always Strings, operators are Symbols, and compound statements > are represented by Arrays. Now suppose that I want to substitute values in > one > equation from another. For instance let's replace the variable "y" in the > equation > x = y * (...) with k+1 from the second equation (y = k+1): > > eq['x'][0] = eq['y'] > > > The equation system changes to this: > { > "k"=>12, > "y"=>["k", :+, 1], > "a"=>"y", > "x"=>[["k", :+, 1], :*, ["a", :+, "k", :+, 1]] > } If you're doing this sort of symbolic equation manipulation I'd actually advise you to express an equation as a tree, and implement some explicit tree rewriting code for variable substitution and simplifications. It's a bit of extra work up-front, but you'll have complete control of the way things are done. Your code is conceptually almost there - a minimal tweak without resorting to new datatypes would be to have the rule that values (numbers or variables) are always arrays, and that an operator combines two arrays to give a third array. Your use of ruby references will then work happily enough - one of your current problems is that fixnums are immediate values, so there is no way for two variables to point to the same fixnum. martin