mirror of
https://github.com/mistergibson/gxg-web-client.git
synced 2026-08-15 11:34:29 -07:00
96 lines
2.7 KiB
Ruby
96 lines
2.7 KiB
Ruby
module Rubinius
|
|
class Mirror
|
|
class Array < Mirror
|
|
self.subject = ::Array
|
|
|
|
def self.reflect(object)
|
|
m = super(object)
|
|
|
|
if Rubinius::Type.object_kind_of? m.object, ::Array
|
|
m
|
|
elsif ary = Rubinius::Type.try_convert(m.object, ::Array, :to_ary)
|
|
super(ary)
|
|
else
|
|
message = "expected Array, given #{Rubinius::Type.object_class(object)}"
|
|
raise TypeError, message
|
|
end
|
|
end
|
|
|
|
# TODO: implement mirror_attribute :name
|
|
def total
|
|
Rubinius.invoke_primitive :object_get_ivar, @object, :@total
|
|
end
|
|
|
|
def total=(value)
|
|
Rubinius.invoke_primitive :object_set_ivar, @object, :@total, value
|
|
end
|
|
|
|
def tuple
|
|
Rubinius.invoke_primitive :object_get_ivar, @object, :@tuple
|
|
end
|
|
|
|
def tuple=(value)
|
|
Rubinius.invoke_primitive :object_set_ivar, @object, :@tuple, value
|
|
end
|
|
|
|
def start
|
|
Rubinius.invoke_primitive :object_get_ivar, @object, :@start
|
|
end
|
|
|
|
def start=(value)
|
|
Rubinius.invoke_primitive :object_set_ivar, @object, :@start, value
|
|
end
|
|
|
|
# Implementation based on the binomial_coefficient
|
|
# implemented on MRI array.c.
|
|
def binomial_coefficient(comb, size)
|
|
comb = size-comb if (comb > size-comb)
|
|
return 0 if comb < 0
|
|
descending_factorial(size, comb) / descending_factorial(comb, comb)
|
|
end
|
|
|
|
# Implementation based on the rb_ary_combination_size
|
|
# implemented on MRI array.c.
|
|
def combination_size(num)
|
|
binomial_coefficient(num, @object.size)
|
|
end
|
|
|
|
# Implementation based on the descending_factorial
|
|
# implemented on MRI array.c.
|
|
# Comment from there:
|
|
# Returns the product of from, from-1, ..., from - how_many + 1.
|
|
# http://en.wikipedia.org/wiki/Pochhammer_symbol
|
|
def descending_factorial(from, how_many)
|
|
cnt = how_many >= 0 ? 1 : 0
|
|
while (how_many) > 0
|
|
cnt = cnt*(from)
|
|
from -= 1
|
|
how_many -= 1
|
|
end
|
|
cnt
|
|
end
|
|
|
|
# Implementation based on the rb_ary_permutation_size
|
|
# implemented on MRI array.c.
|
|
def permutation_size(num)
|
|
n = @object.size
|
|
if undefined.equal? num
|
|
k = @object.size
|
|
else
|
|
k = Rubinius::Type.coerce_to_collection_index num
|
|
end
|
|
descending_factorial(n, k)
|
|
end
|
|
|
|
def repeated_combination_size(combination_size)
|
|
return 1 if combination_size == 0
|
|
return binomial_coefficient(combination_size, @object.size + combination_size - 1)
|
|
end
|
|
|
|
def repeated_permutation_size(combination_size)
|
|
return 0 if combination_size < 0
|
|
@object.size ** combination_size
|
|
end
|
|
end
|
|
end
|
|
end
|