On Sat, Nov 24, 2012 at 2:39 AM, Nokan Emiro <uzleepito / gmail.com> 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