Hi Robert,

Why do you think you need to redefine behavior of these operators?
>

Because I'm working on a type that behaves like any other Ruby class (in
terms that it accepts all operations and messages that a Numeric, an Array,
a Hash or anything else), but it collects all it's history into a huge Ruby
expression for further evaluation.  It works charmingly with the normal
ops like :+, :-, :*, :/, :[], :<< etc., but, of course, it fails with those
outside
of an object's own world.

irb(main):001:0> x = Accumulator.new :x
=> <<<  x  >>>
irb(main):002:0> y = x + 123
=> <<<  x + 123  >>>
irb(main):003:0> z = 2 * y
=> <<<  2 * (x + 123)  >>>
irb(main):004:0> q = 1 - z ** 2
=> <<<  1 - (2 * (x + 123)) ** 2  >>>
irb(main):005:0> q+z+y
=> <<<  1 - (2 * (x + 123)) ** 2 + 2 * (x + 123) + x + 123  >>>
irb(main):006:0>

It may be useful to drop in "spy objects" (like the x above) into black box
functions,
like crypto functions, hash calculations, numerical approximations, or even
well-known
calculations, just to wrap them up in a huge expression instead of looking
at them as
the code of a long method, or just look for algebric simplifications on the
result.  It can
help improving the original calculation or finding out more about the
method's internals.

There are two huge limitations of this. One is that if the function makes
decision
based on the value of the input, this will fail.  For instance, the
expression x > 0
does not have a boolean value, but the expression <<<  x > 0  >>> itself,
which
is an Accumulator object, and has a logical value of true in conditional
expressions,
since it's not nil nor false.  The second limitation is that methods can
contain
lines like x = y && z, or with other words I have no control over them and
they
can use &&, ||, and, or, and not in calculations that I can incorporate
into the
object's internal expression describing it's calculation history.  The
solution for
the first one could be to break the calculation and ask the user what to
answer
for a relation like x > 0, or the Accumulator could do a parallel
calculation with
normal values (Numerics, Arrays, etc) just to return acceptable values for
the
tested function. That's the easier part.  But it seems that it's impossible
to grab
"operations" like &&... :(

irb(main):001:0> x = Accumulator.new :x
=> <<<  x  >>>
irb(main):002:0> y = x && 123
=> 123
irb(main):003:0> y
=> 123           <<<---------  this should be  <<<  x && 123  >>> somehow...
irb(main):004:0> x
=> <<<  x  >>>
irb(main):005:0> def fib(n)
irb(main):006:1>   n < 2 ? 1 : fib(n - 2) + fib(n - 1)
irb(main):007:1> end
=> nil
irb(main):008:0> (0..6).each { |i| p fib i }
1
1
2
3
5
8
13
=> 0..6
irb(main):009:0> fib x
=> 1    <<<<---------------  Well, this is because x < 2 is <<<  x < 2
 >>>, which is true (at least not false or nil), so the ?: in fib() returns
1  :(
irb(main):010:0> x < 2
=> <<<  x < 2  >>>
irb(main):011:0>