I have my own class
class Mutnum
attr_reader :value
def initialize(number)
raise TypeError, "Mutnum created on a non-numeric value" unless number.is_a? Numeric
@value = number
end
def ==(other)
if other.is_a? Mutnum
other.value == @value
else
@value == other
end
end
def set(newval)
@value = newval
end
def to_i
@value
end
def to_s
@value.to_s
end
def +(other)
if other.is_a? Numeric
@value + other
elsif other.is_a? Mutnum
Mutnum.new(@value + other.value)
end
end
def coerce(other)
if other.is_a? Numeric
[other, @value]
else
super
end
end
end
which functions essentially as a mutable number (as in, I can pass one to a function, change it in that function, and read the result from the location it was called). I'm using this to make using wxRuby and gosu in the same application less irritating.
I want to be able to say Array#[Mutnum]
as in, [1,2,3,4][Mutnum.new(3)]
should result in 4
.
What other functions should I add to Mutnum edit so that I can use Mutnums as array indices \edit? I suppose I can say [1,2,3,4][Mutnum.new(3).to_i]
, but then I have to do more debugging.
There is no such thing as mutable numbers. But there are data structures that can contain a number. MutableNumber
is not generally a good name for them. The way to use such container classes is:
class Container
attr_accessor :value
def initialize value
@value = value
end
end
A, B = Container.new( 42 ), Container.new( 43 )
For what you want to do, you will have to say
[1, 2, 3, 4][ Container.new( 3 ).value ]
Get over it. It is possible to delegate many methods to @value
assuming that this is of one of the Numeric
subclasses. But with Array#[]
method, it wont work, as its principles are different. The main point to get is, containers are actually not numbers.
You would have to define
class EasyArray < Array
def [] arg
index = arg.value rescue arg
super index
end
end
EasyArray[ 1, 2, 3, 4 ][ Container.new( 3 ) ] #=> 4
All in all, your best bet is not to define your own conntainer classes at all, but go with Petri nets from my YNelson
gem; gem install y_nelson
. After you install it, use Petri net places as containers:
require 'y_nelson' and include YNelson
P, Q = Place( m: 2 ), Place( m: 3 )
[ P, Q ].map &:value #=> 2, 3
Remember, when computer scientists want mutable numbers, they use Petri net places.